Skip to content
Developer guide

Webhooks & signing

Subscribe to events with HMAC-SHA256 signed deliveries. Pick managed inbox (we host) or your own backend URL.

Context and key considerations

Subscribe to event types from your dashboard or via the API. Each delivery includes a signed header so you can verify the payload was issued by Key2Pay. There are two ways to receive events — use whichever best fits your stack.

1 / 5

End-to-end flow: provider → Key2Pay → you

For async payment methods (SPEI, OXXO, voucher, PIX, bank transfer) Key2Pay never relies on the customer to tell us they paid. The flow is always:

text
  ┌──────────────┐    1. customer pays      ┌─────────────────┐
  │  Customer    │ ───────────────────────▶ │ Upstream         │
  │ (browser /   │                          │ provider          │
  │  bank app)   │                          │ (PagSmile / etc) │
  └──────────────┘                          └────────┬────────┘
                                                     │ 2. signed webhook
                                                     ▼
                                            ┌─────────────────┐
                                            │   Key2Pay       │
                                            │   (verifies +   │
                                            │    updates tx)  │
                                            └────────┬────────┘
                                                     │ 3. signed webhook
                                                     ▼
                                            ┌─────────────────┐
                                            │  YOUR backend   │
                                            │  (this guide)   │
                                            └─────────────────┘
  • Step 2 — provider → Key2Pay. Every driver implements parseWebhook() with HMAC-SHA256 signature verification. We reject unsigned or invalid deliveries (HTTP 401) so a leaked providerTxId can't be used to mark a tx paid. Once the payload verifies, we update the transaction status, post the ledger entries, and enqueue settlement.
  • Step 2.5 — defense-in-depth. A 5-minute poll cron (pending-tx-poll-cron) ALSO reconciles any pending tx against the provider's status API, so even if a webhook delivery is lost we still detect the transition. We then fire our outbound webhook to you with the same signed envelope as a normal delivery — there is no separate "reconciled" event name.
  • Step 3 — Key2Pay → you. The moment a real-money transaction lands in completed / failed we POST payment.completed / payment.failed to every subscribed endpoint, with the HMAC headers documented below.
Implication for your handler: you should rely on payment.completed rather than polling GET /payments/{id}. The webhook is the canonical signal and is fired by BOTH the live upstream webhook path AND the safety-net reconcile cron, so coverage is symmetric. Polling is a fallback, not a primary signal.
Key2Pay Developer documentationAPI v1
Documentation
Dashboard