Webhooks
Configure your app webhook URL to receive asynchronous updates. Verify every webhook signature before trusting the event body. The event vocabulary below is not a guarantee that every provider or operation publishes every type; core verified outcomes use payment.completed, payment.failed or payment.created for pending.
For retry behavior, delivery guarantees, and callback processing guidance, see Webhook delivery guarantees.
Event vocabulary and scope
payment.createdpayment.completedpayment.failedpayment.refundedpayment.partially_refundedpayment.refund_failedpayment.blockedpayment.updatedsubscription.createdsubscription.renewedsubscription.cancelledsubscription.reactivatedsubscription.pausedsubscription.trial_will_endinvoice.paidinvoice.failedsettlement.processed
Managed billing subscription events also carry billing_status and trial_ends_at. See Managed billing and trials.
{
"id": "evt_123",
"type": "payment.completed",
"source": "payment",
"timestamp": "2026-02-09T14:30:00Z",
"data": {
"reference": "TXN-abc123xyz",
"status": "success"
},
"meta": {
"app_id": "app_123",
"version": "1.0",
"gateway": "stripe"
},
"security": {
"signature": "sha256=<hex_signature>",
"algorithm": "HMAC-SHA256"
}
}Verify the raw wire payload
The backend signs an ordered envelope without security, with sorted map keys and Go JSON escaping. Rebuilding data/meta with JSON.stringify can change those bytes. The runnable diagnostic receiver retains the exact raw bytes and fails closed if the current wire shape or signature is invalid.
Use receiver.mjs from the first-payment exampleimport { createReceiver } from './receiver.mjs';
// Diagnostic logging only. Production fulfilment needs durable deduplication.
createReceiver(process.env.TINKER_WEBHOOK_SECRET, (evidence) => {
console.log(evidence); // IDs, type and normalized status only
}).listen(55194, '127.0.0.1');Do not trust status, return redirects or signature headers that the API does not send. Check security.algorithm and the in-body security.signature, reject malformed signatures, and use the application webhook signing secret rather than an API/provider key. A 2xx setup-test log proves acknowledgement of a signed event; it does not independently prove that a receiver verified it.
The sample receiver is diagnostic and uses in-memory deduplication. Production processing must atomically record event-ID uniqueness and business effects before responding 2xx, survive restarts and reconcile late events against current resource state.