Webhooks overview

Receive normalized, signed payment events from Tokeflow in real time — configure endpoints, understand the event envelope, and handle delivery and retries.

Webhooks let your platform react to payment activity the moment it happens. As transactions, refunds, disputes, and subscriptions change state across your connected providers, Tokeflow POSTs a normalized JSON event to the HTTPS endpoint(s) you configure.

Instead of polling the API, you subscribe once and let events come to you. Because Tokeflow normalizes webhooks across every provider you orchestrate, you write one handler — not one per provider — and the event shape stays the same no matter which acquirer processed the charge.

Tokeflow is payment orchestration infrastructure. Webhooks describe the lifecycle of operations Tokeflow coordinates; the underlying processing and settlement are performed by your connected payment providers.

Why webhooks

OutcomeHow webhooks help
React in real timeFulfill orders, grant access, or notify customers the instant a payment is authorized — no polling loop.
One handler, every providerEvents are normalized to a single schema, so provider-specific payloads never leak into your code.
Reliable deliveryFailed deliveries are retried with exponential backoff and recorded, so a brief outage on your side doesn't drop events.
Verifiable authenticityEvery request is signed with HMAC-SHA256 so you can confirm it came from Tokeflow and was not altered in transit.
Audit trailEvery delivery attempt is persisted and inspectable, giving you traceability for reconciliation and debugging.

How delivery works

  1. An event occurs. A transaction, refund, dispute, payment method, or subscription changes state.
  2. Tokeflow builds a normalized event and signs it with your endpoint's signing secret.
  3. Tokeflow POSTs the event to each matching endpoint as a JSON request body.
  4. Your endpoint responds. A 2xx status (returned quickly) marks the delivery as succeeded. Anything else triggers a retry.

Configure your endpoints

You register webhook endpoints in the Tokeflow Dashboard during onboarding (and any time afterward). For each endpoint you provide:

SettingDescription
Endpoint URLA publicly reachable HTTPS URL that accepts POST requests. You can register more than one.
Event filterAn optional allowlist of event types. Omit it to receive every event type.
Signing secretGenerated when the endpoint is created — a value prefixed whsec_. Use it to verify signatures.

Register separate endpoints for separate concerns — for example one URL for transaction.* events feeding fulfillment, and another for subscription.* events feeding your billing system. Each endpoint carries its own filter and signing secret.

The signing secret is shown when the endpoint is created. Store it securely (server-side only) — you'll need it to verify every incoming event. Treat it like any other credential.

The event envelope

Every webhook request body shares the same top-level shape. The data.object field carries the resource the event is about (a transaction, refund, subscription, and so on).

{
  "id": "evt_8f3c2a1b9d7e4f60",
  "type": "transaction.authorized",
  "created_at": "2026-01-15T12:30:00.000Z",
  "data": {
    "object": {
      "id": "tx_3n8Q2k1p7w",
      "merchant_id": "mrc_7Yh2Kd9",
      "external_order_id": "order-2026-0042",
      "customer": {
        "id": "cust_5Tg8Lp2",
        "email": "buyer@example.com"
      },
      "previous_status": "pre_authorized",
      "current_status": "authorized",
      "amount_authorized": 15000,
      "amount_captured": 15000,
      "currency": "BRL",
      "changed_at": "2026-01-15T12:30:00.000Z"
    }
  }
}
FieldTypeDescription
idstringUnique event identifier (prefix evt_). Use it to deduplicate.
typestringThe event type, e.g. transaction.authorized.
created_atstringISO 8601 UTC timestamp of when the event was generated.
data.objectobjectThe resource snapshot for this event. Its fields depend on type.

Monetary amounts are integers in minor units (cents). 15000 with currency: "BRL" means R$150.00. Always pair an amount with its ISO 4217 currency.

What data.object contains

The shape of data.object depends on the event family. See Event types for the full catalog and per-resource fields.

Event familydata.object representsExample types
TransactionsA payment transactiontransaction.authorized, transaction.failed, transaction.voided
RefundsA refundtransaction.refunded, transaction.partially_refunded, transaction.refund_failed
DisputesA chargeback / disputetransaction.dispute_created, transaction.dispute_won, transaction.dispute_lost
Payment methodsA stored payment instrumentpayment_method.action_required
SubscriptionsA subscriptionsubscription.created, subscription.dunning, subscription.cancelled

Request headers

Each delivery is an HTTP POST with a JSON body and these notable headers:

HeaderDescription
Content-TypeAlways application/json.
X-Tokeflow-SignatureHMAC signature of the event, in the form t=<unix-seconds>,v1=<hex>.
User-AgentIdentifies the request as originating from Tokeflow's webhook delivery system.

Always verify X-Tokeflow-Signature before trusting an event. The signature is computed over the raw request body bytes — read and verify the body before any JSON parsing or middleware re-serializes it. See Verifying signatures.

Responding to events

Your endpoint should acknowledge receipt fast and do the real work afterward.

  • Respond 2xx within a few seconds. Return the response as soon as you've safely persisted the event (for example, enqueued it). Tokeflow treats any 2xx as success.
  • Process asynchronously. Do slow work — fulfillment, emails, downstream calls — outside the request/response cycle so you never risk a timeout.
  • Deduplicate by id. Retries and at-least-once delivery mean the same event id can arrive more than once. Make handling idempotent: record processed event IDs and skip duplicates.
  • Don't depend on ordering. Events may arrive out of order, especially after a retry. Use the resource's status fields (and changed_at) rather than assuming arrival order reflects the true sequence.
// Express example — acknowledge fast, process async.
// Use a raw body parser on this route so signature verification sees exact bytes.
import express from "express";

const app = express();

app.post(
  "/webhooks/tokeflow",
  express.raw({ type: "application/json" }),
  (req, res) => {
    // 1. Verify the signature against the raw body (see Verifying signatures).
    if (!verifyTokeflowSignature(req)) {
      return res.status(400).send("invalid signature");
    }

    const event = JSON.parse(req.body.toString("utf8"));

    // 2. Deduplicate and enqueue for async processing.
    enqueueForProcessing(event); // your job queue

    // 3. Acknowledge immediately.
    return res.status(200).send("ok");
  },
);

Delivery, failures, and retries

Tokeflow records every delivery attempt for every endpoint, so you can audit exactly what was sent and how your endpoint responded.

A delivery is considered successful only when your endpoint returns an HTTP 2xx. A delivery fails when it returns a non-2xx status, times out, or is unreachable. Each request has a delivery timeout of 30 seconds — keep handlers well under that.

When a delivery fails, Tokeflow retries with exponential backoff:

AttemptDelay after previous attempt
1Immediate (initial delivery)
21 minute
35 minutes
430 minutes
52 hours
(final)24 hours

After the retry schedule is exhausted, the delivery is abandoned and no further attempts are made. The full delivery history — status codes, response snippets, attempt counts, and next retry time — is retained for inspection.

Because a single endpoint outage can produce a burst of retries once you recover, design your consumer to absorb spikes: return 2xx quickly, enqueue, and process from the queue. Idempotency on event id keeps retried events from being applied twice.

A persistently failing endpoint will be retried up to the limit above and then abandoned for that event. If your endpoint is down for an extended period, you may miss events; reconcile against the API once you recover, and keep your handler idempotent so replays are safe.

Security checklist

  • Verify every signature. Reject requests whose X-Tokeflow-Signature doesn't validate against the raw body and your whsec_ secret.
  • Enforce a timestamp tolerance. Reject events whose signature timestamp is outside a small window (for example, 5 minutes) to mitigate replay attacks.
  • Use HTTPS only. Endpoints must be HTTPS so payloads and signatures are protected in transit.
  • Keep secrets server-side. The webhook signing secret, like your sk_* API keys, must never appear in browser or client code.

Next steps

On this page