Stripe Webhook
Changed onHandle Stripe webhook events.
Verifies the Stripe signature, deduplicates by event id, and routes the event to its billing-lifecycle handler. Unprotected (no auth) but signature-verified.
Events handled: checkout.session.completed, invoice.paid, invoice_payment.paid, invoice.payment_failed, payment_method.attached / .detached, charge.refunded, charge.dispute.created / .closed, refund.updated / .created, customer.deleted, radar.early_fraud_warning.created.
invoice.paid and invoice_payment.paid share _handle_invoice_paid: Stripe emits both for a single payment on the pinned API version. They carry different event ids, so the ledger's event-id key does not dedupe one against the other -- record_refill_topup instead nominates invoice.paid as the only delivery that writes money, and the sibling returns having written nothing. The event-id key is what makes a redelivery of the same event safe.
invoice.payment_failed carries the terminal dunning signal as well as the retryable ones, and is the only route that suspends for non-payment. Stripe emits no explicit "collection is over" event -- reaching uncollectible always takes an operator or an Automation, neither of which exists here -- so exhaustion is read as a failed attempt carrying no next_payment_attempt on an invoice still open. If Billing Automations are ever enabled that field moves to invoice.updated and this design must be revisited; that caveat is a guardrail, not a reason to read the noisier event today. See services.billing.retry_exhaustion.
Args: request: Inbound FastAPI request carrying the raw Stripe payload. stripe_signature: Value of the stripe-signature header.
Returns: {"status": "success"} once the event is processed.
Raises: HTTPException: 500 when the webhook secret is unconfigured or processing fails; 400 for an invalid signature.
Request
- Base URLhttps://api.pioneer.ai (the document declares no server; this is the origin it was published from)
- Authnone required
- TypeScriptA function with typed inputs. Its response is checked against the schema.
Headers
Response
Successful Response
Changes
- warning
removed the optional property
from the response with the status - info
added the required property
to the response with the status
- warning
- breaking
the response's body type changed from no type to
objectfor status
- breaking