Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.pickupbell.com/llms.txt

Use this file to discover all available pages before exploring further.

POST /api/billing/webhook

Verification

Every request is signature-verified using the payments provider’s standard mechanism and the BILLING_WEBHOOK_SECRET env var. Requests without a matching signature get 400 Bad Request and are not processed. This is the only PickupBell inbound webhook that enforces signature verification — it writes to billing state.

Events handled

Event typeAction
customer.subscription.createdUpsert the subscription row.
customer.subscription.updatedReconcile; status flips to active / past_due / canceled as reported.
customer.subscription.deletedStatus → canceled.
checkout.session.completedRetrieve the subscription, run the same reconciliation.
invoice.paidFetch subscription, reconcile (in case current_period_end moved).
invoice.payment_failedFetch subscription, reconcile (status → past_due).
All other event types are silently ignored after a 2xx ack so the provider stops retrying them.

Idempotency

Every processed event id lands in the stripe_events table (id PRIMARY KEY, type, location_id, processed_at, raw). On retry the handler looks up the id first and returns { "received": true, "duplicate": true } without re-processing.