Outbound events
Each app reports to one URL of your product: Apps → the app → Outbound webhook.
Events
session.paida payment went through (also each paid subscription cycle)
session.failedthe payment was declined
session.expiredthe checkout expired unpaid
session.refundedthe payment was refunded
session.disputedthe customer's bank opened a chargeback; data.session.dispute says how much, why and by when to answer
session.dispute_closedthe bank decided the dispute; data.session.dispute.status is won or lost
subscription.activatedfirst payment, or recovered after past_due
subscription.reneweda later cycle was paid
subscription.updateda field changed and the status did not: the period end known after activation, the next period, a cancellation scheduled on the gateway
subscription.past_duea renewal failed; the gateway keeps retrying
subscription.cancelinga cancellation was requested; still active until cancel_at
subscription.resumeda scheduled cancellation was taken back; cancel_at is null again
subscription.canceledthe subscription ended
pingSend test event on the app page
Payload
Every delivery is the same envelope: id (the delivery, also in X-Pay-Event-Id), type, created_at, livemode (false for sandbox gateways) and data. Session events carry data.session, the object GET /api/v1/sessions/:id answers; subscription events carry data.subscription, the one GET /api/v1/subscriptions/:id answers.
session.paid
{ "id": "0f8e2c4a-6d1b-4c3e-9a7f-2b5d8e1c4a90", "type": "session.paid", "created_at": "2026-09-25T12:00:00Z", "livemode": false, "data": { "session": { "id": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "status": "paid", "amount": "49.90", "refunded_amount": "0.0", "currency": "BRL", "method": "card", "connection_test": false, "subscription_id": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "gateway": { "id": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "name": "stripe-br", "provider": "stripe", "sandbox": true }, "metadata": { "plan": "pro", "account_id": "acc_42" }, "customer": { "id": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "external_ref": "user_42", "email": "[email protected]", "name": "Ana Souza", "document": "123.456.789-09", "phone": "+55 11 99999-0000", "address_line1": "Av. Paulista", "address_line2": null, "address_number": "1000", "neighborhood": "Bela Vista", "city": "São Paulo", "state": "SP", "zipcode": "01310-100", "country": "BR" }, "dispute": { "id": "dp_1QxYz", "status": "needs_response", "reason": "fraudulent", "amount": "49.90", "due_by": "2026-09-25T12:00:00Z", "opened_at": "2026-09-25T12:00:00Z", "closed_at": "2026-09-25T12:00:00Z" }, "return_to": "https://yourapp.com/billing/callback", "expires_at": "2026-09-25T12:00:00Z", "created_at": "2026-09-25T12:00:00Z", "updated_at": "2026-09-25T12:00:00Z" } } }
subscription.activated
{ "id": "0f8e2c4a-6d1b-4c3e-9a7f-2b5d8e1c4a90", "type": "subscription.activated", "created_at": "2026-09-25T12:00:00Z", "livemode": false, "data": { "subscription": { "id": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "status": "active", "amount": "49.90", "currency": "BRL", "interval": "month", "description": "Pro plan", "gateway": { "id": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "name": "stripe-br", "provider": "stripe", "sandbox": true }, "customer": { "id": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "external_ref": "user_42", "email": "[email protected]", "name": "Ana Souza", "document": "123.456.789-09", "phone": "+55 11 99999-0000", "address_line1": "Av. Paulista", "address_line2": null, "address_number": "1000", "neighborhood": "Bela Vista", "city": "São Paulo", "state": "SP", "zipcode": "01310-100", "country": "BR" }, "metadata": { "plan": "pro", "account_id": "acc_42" }, "current_period_end": "2026-09-25T12:00:00Z", "cancel_at_period_end": true, "cancel_requested_at": "2026-09-25T12:00:00Z", "cancel_at": "2026-09-25T12:00:00Z", "replaces": "7f3a9c1e-2b4d-4e8f-9a1b-3c5d7e9f0a12", "canceled_at": "2026-09-25T12:00:00Z", "created_at": "2026-09-25T12:00:00Z", "links": { "self": "https://example.com" } } } }
metadata is what your product sent to /connect, echoed back; a subscription's renewal cycles carry it too, plus description and billing_reason. customer.external_ref is your own id. The API reference describes every field.
Delivery
- 1Answer 2xx to accept. Anything else, including redirects, is retried with growing waits, 8 attempts in all.
- 2Deduplicate on X-Pay-Event-Id: a resend keeps the same id.
- 3Custom headers (an Authorization token your app expects, say) are set with the URL, on the app page.
- 4Webhooks → Sent lists every delivery with its response and a Resend button.
Next: Verify the signature