Stripe HF Sandbox Manifest
{
"_comment": "Stripe SANDBOX-mode objects for HF appeals engagement. Created 2026-05-03 by Relic. Sandbox = OBB Holdings Stripe sandbox; account fingerprint 51TSp7B. When we move to live mode (post-Mercury-clear), recreate these in live with same names/metadata; live IDs will differ.",
"mode": "sandbox",
"account_fingerprint": "51TSp7BPo7Ey3D4jv",
"created_at": "2026-05-03T02:56:00Z",
"products": {
"hf_floor": {
"id": "prod_URjggsW934RV2b",
"name": "HF Appeals \u2014 Monthly Floor",
"description": "Hundredfold ERC appeals engagement \u2014 monthly minimum (Net-10, billed in advance)."
},
"hf_overage": {
"id": "prod_URjgbJK9C0o6dC",
"name": "HF Appeals \u2014 Per-Appeal Overage",
"description": "Hundredfold ERC appeals engagement \u2014 per-completed-appeal overage above monthly floor. $495/appeal, billed in arrears at month-close. First 20 appeals included in floor."
}
},
"prices": {
"hf_floor_monthly": {
"id": "price_1TSqCuPo7Ey3D4jvIovhasM2",
"product": "prod_URjggsW934RV2b",
"type": "recurring",
"interval": "month",
"usage_type": "licensed",
"unit_amount_cents": 990000,
"currency": "usd",
"billing_timing": "in_advance"
},
"hf_overage_metered": {
"id": "price_1TSqDfPo7Ey3D4jvg0Kw9Zkg",
"product": "prod_URjgbJK9C0o6dC",
"type": "recurring",
"interval": "month",
"usage_type": "metered",
"billing_scheme": "tiered",
"tiers_mode": "graduated",
"currency": "usd",
"billing_timing": "in_arrears",
"tiers": [
{
"up_to": 20,
"unit_amount_cents": 0,
"_note": "first 20 appeals included (covered by floor)"
},
{
"up_to": "inf",
"unit_amount_cents": 49500,
"_note": "$495 per appeal beyond 20"
}
]
}
},
"meters": {
"hf_completed_appeal": {
"id": "mtr_test_61UcEB1xhdKkFajuw41Po7Ey3D4jv2mG",
"event_name": "hf_completed_appeal",
"aggregation": "sum",
"customer_mapping_payload_key": "stripe_customer_id",
"value_payload_key": "value",
"_note": "Push usage events here when ERCie completes an appeal: POST /v1/billing/meter_events with event_name=hf_completed_appeal, payload.stripe_customer_id=cus_..., payload.value=1"
}
},
"subscription_template": {
"_comment": "Not a Stripe object \u2014 this is the recipe for creating a per-customer subscription that combines floor + overage.",
"items": [
{
"price": "price_1TSqCuPo7Ey3D4jvIovhasM2",
"quantity": 1,
"_note": "HF floor: $9,900/mo flat"
},
{
"price": "price_1TSqDfPo7Ey3D4jvg0Kw9Zkg",
"_note": "HF overage: tiered metered; do NOT pass quantity (metered)"
}
],
"collection_method": "send_invoice",
"days_until_due": 10,
"_known_tradeoff": "Stripe applies days_until_due subscription-wide. Floor invoice (in-advance) and overage invoice (in-arrears at period close) will both be Net-10. Engagement letter \u00a73.4 says floor=Net-10, overage=Net-30 \u2014 Stripe can't differentiate per-item. Workaround options: (a) accept Net-10 for both (operationally fine, contract Net-30 is the ceiling not the floor); (b) split into two separate subscriptions (one for floor Net-10, one for overage Net-30) \u2014 more objects, more exact terms; (c) use Stripe Invoicing API for overage, not subscription line item \u2014 gives full per-invoice control."
},
"webhook": {
"endpoint_id": "we_1TSqIqPo7Ey3D4jvPnTkmJVa",
"url": "https://obb-stripe-webhook.pages.dev/stripe",
"signing_secret_env_var": "STRIPE_WEBHOOK_SECRET_TEST",
"subscribed_events": [
"customer.subscription.created",
"customer.subscription.updated",
"customer.subscription.deleted",
"invoice.created",
"invoice.finalized",
"invoice.paid",
"invoice.payment_failed",
"payment_intent.succeeded",
"payment_intent.payment_failed",
"customer.created"
],
"delivery_target": "Discord webhook \u2192 #hf-dashboard channel",
"smoke_tested_at": "2026-05-03T03:04:00Z",
"smoke_test_result": "200 OK end-to-end (synthetic event \u2192 function \u2192 Discord post)",
"_repo": "/Users/lukeolson/relic-deliverables/stripe-webhook/"
},
"customer_portal": {
"configuration_id": "bpc_1TSqNbPo7Ey3D4jv9CnvnkDS",
"features": [
"customer_update (email/address/phone)",
"invoice_history",
"payment_method_update",
"subscription_cancel (at_period_end, with reason capture)"
],
"default_return_url": "https://obb-holdings.com",
"_note": "To generate a one-time portal session URL for a customer, POST /v1/billing_portal/sessions with customer= and return_url. URL expires after a few hours."
},
"meter_helper": {
"module_path": "/Users/lukeolson/discord-bot/stripe_meter.py",
"primary_function": "report_completed_appeal(stripe_customer_id, count=1, appeal_id=None)",
"_note": "ERCie (or any agent) calls this when an appeal completes (analyst signs off). Passes appeal_id as idempotency key to prevent duplicate counting on retries."
},
"test_customer": {
"id": "cus_URjm51K12aX1ri",
"email": "andrew-test@hundredfold.test",
"name": "Hundredfold Management Services (TEST)",
"_purpose": "Sandbox-mode validation only. Delete or repurpose at live-mode cutover."
},
"test_subscription": {
"id": "sub_1TSqJKPo7Ey3D4jvOQbp4X9s",
"items": [
"floor (price_1TSqCuPo7Ey3D4jvIovhasM2)",
"overage (price_1TSqDfPo7Ey3D4jvg0Kw9Zkg)"
],
"collection_method": "send_invoice",
"days_until_due": 10,
"status": "active"
},
"initial_partial_month_ramp": {
"_comment": "Not a static Price. Created per-customer at signing as a one-off Invoice Item.",
"formula": "(monthly_floor * 0.5) / days_in_signing_month * (days_in_signing_month - signing_day_of_month)",
"example_may_17_2026": {
"daily_rate_cents": 15968,
"billable_days": 14,
"total_cents": 223547,
"total_dollars": 2235.48
}
}
}