Webhooks

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

EventWhen it fires
tap.approvedScheme authorised the tap.
tap.declinedScheme declined; includes decline_reason.
tap.reversedTap reversed before settlement (customer re-presented card, partial).

charge.* events

EventWhen it fires
charge.capturedAuthorisation captured; funds committed.
charge.refundedFull or partial refund processed.
charge.failedCapture failed (rare; usually scheme outage).

payout.* events

EventWhen it fires
payout.scheduledPayout queued for disbursement; includes ETA.
payout.paidBank confirmed receipt; includes wire reference.
payout.failedBank rejected (wrong account, frozen). Actionable.

dispute.* events

EventWhen it fires
dispute.openedChargeback received. Includes scheme deadline.
dispute.evidence_required48h before scheme deadline, last call.
dispute.closedWon, lost, or withdrawn. Final state.

submerchant.* events

EventWhen it fires
submerchant.kyb.approvedKYB complete, merchant live. Median ~35 min.
submerchant.kyb.rejectedKYB failed. Includes specific reason codes.
submerchant.risk_flaggedOngoing monitoring surfaced a concern.