Webhook setup

Stripe webhook endpoint

Stripe already signs every webhook with your endpoint's signing secret. stubkit verifies the HMAC-SHA256 with a five- minute replay tolerance and processes the event.

Endpoint to paste

https://api.stubkit.com/v1/webhooks/stripe/your-app

Use one endpoint per tenant — the signing secret is tenant-scoped.

Dashboard steps

  1. Stripe Dashboard → Developers → Webhooks → Add endpoint.
  2. URL: the endpoint above.
  3. Events to send (minimum):
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.paid
    • invoice.payment_failed
    • charge.refunded
  4. Copy the signing secret (whsec_...) and paste it into dash.stubkit.com → Apps → your app → Settings → Providers.

Tenant user routing

stubkit uses stubkit_user_id in the subscription metadata to map a Stripe subscription to a tenant user. Set it when you create the checkout session:

await stripe.checkout.sessions.create({
  mode: 'subscription',
  line_items: [{ price: 'price_123', quantity: 1 }],
  subscription_data: {
    metadata: {
      stubkit_user_id: currentUserId,
      stubkit_entitlement: 'pro',
    },
  },
});

What we store

The raw event body is archived under stripe/<tenant>/yyyy/mm/dd/<event.id>.json. stubkit uses event.id as the idempotency key, so re-sent webhooks (Stripe retries aggressively) never create duplicate state.