Webhooks
TabEdge sends HTTPS POST notifications to your configured business webhook endpoint when supported payment events occur.
Configuration
Configure an HTTPS webhook URL and signing secret in your Business Developer Settings. Keep the signing secret on your server. Do not expose it in frontend code.
Supported Event
checkout.payment_succeeded — a successful checkout payment notification.
Example JSON Payload
{
"id": "webhook_delivery_id",
"type": "checkout.payment_succeeded",
"data": {
"checkoutId": "checkout_id",
"paymentId": "payment_id",
"businessId": "business_id",
"merchantReference": "ORDER-1001",
"amountCents": 2500,
"currency": "usd"
}
}The event ID is used to identify duplicate deliveries. The merchantReference value can be null.
Request Headers
| Header | Purpose |
|---|---|
| Content-Type | application/json |
| TabEdge-Webhook-Id | Webhook delivery ID |
| TabEdge-Webhook-Timestamp | Unix timestamp in seconds |
| TabEdge-Webhook-Signature | HMAC-SHA256 hexadecimal signature |
Verify the Signature
TabEdge signs the exact raw JSON request body using HMAC-SHA256. The signed message is the timestamp, a period, and the raw body. Verify the signature before processing an event.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyTabEdgeWebhook(
rawBody: string,
timestamp: string,
signature: string,
signingSecret: string
): boolean {
const timestampNumber = Number(timestamp);
if (
!Number.isSafeInteger(timestampNumber) ||
Math.abs(Date.now() / 1000 - timestampNumber) > 300 ||
!/^[a-f0-9]{64}$/i.test(signature)
) {
return false;
}
const expected = createHmac('sha256', signingSecret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
return timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(signature, 'hex')
);
}The five-minute timestamp tolerance is a recommended receiver-side replay protection policy, not a TabEdge delivery configuration. Use the original raw request body, not re-serialized JSON.
Delivery and Retries
Return an HTTP 2xx response to acknowledge successful delivery. Non-2xx responses and delivery errors are treated as failures. The delivery request has a four-second timeout.
By default, TabEdge allows up to six failed attempts with exponential retry delays beginning at one minute. Retry settings can be changed by platform administrators. Delivery is not guaranteed to occur exactly once.
Idempotency and Security
Store processed event IDs and prevent duplicate order fulfillment. Validate the signature, event type, business ID, payment amount and currency before performing business actions.
Signing secret rotation changes the secret used for subsequent delivery attempts. Update your receiver configuration when rotating the secret.