Skip to main content
Tabby Webhooks are HTTPS callbacks that notify you about payment-related and token-related events. You register a URL once, and Tabby sends a POST request to it whenever an event related to your account occurs — even when the customer never returns to your site. This makes webhooks the most reliable way to catch authorized payments.

How They Work

1

Register an endpoint

Register a webhook for each merchant_code + secret key pair — the merchant code is passed in the X-Merchant-Code header (required):
The environment is determined by the key you register with: a production key (sk_...) registers webhooks for production payments, a test key (sk_test_...) — for test payments. Each pair can have up to 4 webhooks. The optional header signs the requests so you can verify their authenticity.
2

Receive notifications

Tabby sends a POST request to your URL whenever the payment status changes.
3

Acknowledge with 200

Respond with a 200 HTTP status code to confirm the reception, and check the auth header to verify the request. Any other response (or no response) counts as a delivery error and triggers retries.

Payload

Webhooks are POST requests with a JSON body:
Webhook payloads use lowercase statuses ("authorized"), while the Retrieve Request returns uppercase ("AUTHORIZED") — this is expected. See Payment Statuses.

Supported Events

The payload content depends on the event: The “expire” event is optional — ask the Tabby team to enable it for your store if you want notifications when a payment is cancelled by the customer or expires.

A Typical Payment

For a regular successful order you will receive three notifications:
  1. Payment authorized — the payload status is authorized. Check the order and process it in your OMS if it wasn’t processed yet, then send the Capture Request.
  2. Payment captured — the payload status is still authorized, with your capture added to the captures array. No action is required.
  3. Payment closed — the payload status is closed: the payment is completed and confirmed from both sides. No action is required.
Looking for notifications about disputes raised on your payments? See Dispute webhooks — a separate, opt-in webhook enabled by request to the Integrations Team.

Best Practices

  • Respond fast. Acknowledge the webhook with 200 right away and process it asynchronously, instead of holding the response until processing is done.
  • Expect disorder and duplicates. Webhooks are asynchronous: the delivery order is not guaranteed and the same event may occasionally arrive twice — ignore a notification you have already processed, and see Handling Edge Cases below.
  • Filter events. You receive notifications for all payment events — process only the ones you need.
  • Allowlist Tabby server IPs:
To test and debug webhooks, use a tool like Webhook.site to inspect the payload and headers Tabby sends to your endpoint.

Handling Edge Cases

These three situations occur in every production integration. Handling them wrong is the most common cause of “lost” payments and duplicate captures.

The webhook can arrive before your own order is saved

Tabby sends the authorized webhook as soon as the customer completes the payment — which can be before your checkout code has committed the order to your database. If your handler looks up the order, finds nothing, and still acknowledges with 200, that event is gone for good and the payment sits unprocessed. Do this instead: when the webhook references a payment you cannot match yet, respond with a non-200 status (e.g. 404). Tabby treats it as a delivery error and retries — by the next attempt your transaction has landed and the event processes normally. Acknowledge with 200 only when you either processed the event or deliberately chose to ignore it. It also pays to store the raw event before processing — an audit log of received webhooks makes every “where did the payment go” investigation trivial.

Statuses only move forward

A closed event can arrive before the authorized one. Treat payment status as a one-way street — authorizedclosed — and never downgrade: if your record already says closed, ignore a late authorized event instead of overwriting.

A capture confirmation is not a request to capture

The second notification in A Typical Paymentauthorized with your capture in the captures array — confirms your own capture. Before triggering a capture from a webhook, check that captures is empty; if it isn’t, the payment is already being settled and no action is needed.

Retry Attempts

A webhook request times out after 1 minute. If it times out or gets any response other than 200, Tabby resends it up to 4 more times with an exponential interval between attempts (1–4 minutes). Retries don’t block other notifications — Tabby keeps sending webhooks for other payment events as they occur.