Every state change, pushed to you. Signed, retried, idempotent.
Tapped emits webhooks the moment a transaction transitions state. Sign them, verify them, act on them, or walk away and we'll retry for 72 hours. Replay any event from the dashboard.
How webhooks work
You register an endpoint URL in the dashboard (or via API). When a subscribed event fires, Tapped delivers a POST to your URL with a JSON body and a set of signing headers. Respond with 2xx within 5 seconds to acknowledge. Any other response (or a timeout) triggers a retry.
One event, one delivery
Every event has a unique id. Use it to deduplicate, if your handler crashes mid-processing, retries may deliver the same event up to ~20 times.
Signature verification
Every delivery includes a Tapped-Signature header. The signature is an HMAC-SHA256 of the raw request body with your endpoint's signing secret. Use the SDK helper; if you're on REST, the verification is eight lines of code.
// Node, manual verification import { createHmac } from "crypto"; function verify(rawBody, header, secret) { const [ts, sig] = header.split(",").map(s => s.split("=")[1]); const expected = createHmac("sha256", secret) .update(`${ts}.${rawBody}`) .digest("hex"); return expected === sig; }
Retries & deduplication
Failed deliveries retry on an exponential backoff: 10s, 1m, 5m, 30m, 2h, 6h, 12h, 24h, 48h, 72h. After 72 hours of failures we mark the event failed in the dashboard. You can replay any event, failed or succeeded, with one click.
Order is not guaranteed. Two events with adjacent timestamps may arrive in either order. Design your handler around id, not arrival time.
Replaying events
Any event in the last 30 days can be replayed from the dashboard or via POST /v1/events/:id/redeliver. Replays include a header Tapped-Replayed: true so your handler can log them separately if you wish.
tap.* events
| Event | When it fires |
|---|---|
tap.approved | Scheme authorised the tap. |
tap.declined | Scheme declined; includes decline_reason. |
tap.reversed | Tap reversed before settlement (customer re-presented card, partial). |
charge.* events
| Event | When it fires |
|---|---|
charge.captured | Authorisation captured; funds committed. |
charge.refunded | Full or partial refund processed. |
charge.failed | Capture failed (rare; usually scheme outage). |
payout.* events
| Event | When it fires |
|---|---|
payout.scheduled | Payout queued for disbursement; includes ETA. |
payout.paid | Bank confirmed receipt; includes wire reference. |
payout.failed | Bank rejected (wrong account, frozen). Actionable. |
dispute.* events
| Event | When it fires |
|---|---|
dispute.opened | Chargeback received. Includes scheme deadline. |
dispute.evidence_required | 48h before scheme deadline, last call. |
dispute.closed | Won, lost, or withdrawn. Final state. |
submerchant.* events
| Event | When it fires |
|---|---|
submerchant.kyb.approved | KYB complete, merchant live. Median ~35 min. |
submerchant.kyb.rejected | KYB failed. Includes specific reason codes. |
submerchant.risk_flagged | Ongoing monitoring surfaced a concern. |