Skip to main content

Overview

ZBD sends webhook events to your configured HTTPS endpoint when a widget cashout or reversal changes status. Your endpoint validates the signature, acknowledges receipt, and processes the event asynchronously. Webhook configuration is completed with ZBD during publisher onboarding. ZBD provides the shared signing secret used to sign each webhook request. The MVP does not support subscribing to individual event types. ZBD sends all widget webhook event types to the configured endpoint, and your system should filter by the event_type field.

Webhook Delivery Request

ZBD sends each event as an HTTP POST request:
POST <publisher webhook endpoint>
X-ZBD-Signature: <HMAC-SHA256 of request body using shared secret>
X-ZBD-Event-Id: <unique event identifier>
X-ZBD-Event-Type: <event type>
Content-Type: application/json
Your endpoint should return HTTP 200 within 10 seconds to acknowledge receipt. Any non-200 response, timeout, 5xx response, or connection failure triggers retry.
Validate the webhook signature against the raw request body before processing the event.

Webhook Event Types

Event typeDescription
cashout.initiatedThe user initiated a cashout against the publisher-funded balance, and ZBD submitted the ACH to the partner bank.
cashout.completedThe ACH settled successfully and funds landed in the user’s external bank account.
cashout.failedThe ACH was rejected before settlement, such as a closed account, invalid routing, or NSF response.
cashout.returnedThe ACH was reversed after settlement within the return window.
reversal.status_changedA reversal request previously submitted by the publisher changed status.

Cashout Webhook Events

Cashout lifecycle webhooks identify the event, reference the publisher’s user identifier, include the current status, include the amount, and include the time the event occurred at the bank or inside ZBD.

Cashout Initiated

{
  "event_id": "evt_a1b2c3",
  "event_type": "cashout.initiated",
  "user_reference_id": "1047-player-42",
  "amount_cents": 500,
  "status": "initiated",
  "occurred_at": "2026-07-15T17:45:00Z"
}

Cashout Completed

{
  "event_id": "evt_d4e5f6",
  "event_type": "cashout.completed",
  "user_reference_id": "1047-player-42",
  "amount_cents": 500,
  "status": "completed",
  "occurred_at": "2026-07-17T14:20:00Z"
}

Cashout Failed

{
  "event_id": "evt_g7h8i9",
  "event_type": "cashout.failed",
  "user_reference_id": "1047-player-42",
  "amount_cents": 500,
  "status": "failed",
  "reason_code": "R02",
  "reason_description": "account_closed",
  "occurred_at": "2026-07-16T09:12:00Z"
}

Cashout Returned

{
  "event_id": "evt_j1k2l3",
  "event_type": "cashout.returned",
  "user_reference_id": "1047-player-42",
  "amount_cents": 500,
  "status": "returned",
  "reason_code": "R10",
  "reason_description": "unauthorized_by_customer",
  "occurred_at": "2026-07-25T11:30:00Z"
}

Cashout Payload Fields

FieldTypeDescription
event_idstringUnique event identifier. Use this value for deduplication.
event_typestringOne of cashout.initiated, cashout.completed, cashout.failed, or cashout.returned.
user_reference_idstringYour stable user identifier from Create User.
amount_centsintegerCashout amount in USD cents.
statusstringCurrent cashout status.
reason_codestringBank reason code. Present on failed and returned events.
reason_descriptionstringHuman-readable bank reason. Present on failed and returned events.
occurred_atstringISO 8601 timestamp for when the event occurred.

Reversal Webhook Events

Reversal status webhooks identify the reversal action, the new status, the reversal method, the amount, and the timestamp.

Reversal Completed

{
  "event_id": "evt_m4n5o6",
  "event_type": "reversal.status_changed",
  "reversal_id": "R-002",
  "amount_cents": 500,
  "status": "completed",
  "method": "bank_reversal",
  "occurred_at": "2026-07-20T15:45:00Z"
}

Reversal Failed

{
  "event_id": "evt_p7q8r9",
  "event_type": "reversal.status_changed",
  "reversal_id": "R-002",
  "amount_cents": 500,
  "status": "failed",
  "method": "bank_reversal",
  "occurred_at": "2026-07-20T15:45:00Z"
}

Reversal Payload Fields

FieldTypeDescription
event_idstringUnique event identifier. Use this value for deduplication.
event_typestringAlways reversal.status_changed.
reversal_idstringUnique reversal identifier.
amount_centsintegerReversal amount in USD cents.
statusstringNew reversal status, such as completed or failed.
methodstringReversal method, such as bank_reversal for bank-level reversals.
occurred_atstringISO 8601 timestamp for when the status changed.

Webhook Event Sources

cashout.initiated events are generated when the user submits a cashout through the ZBD Widget and ZBD submits the ACH to the partner bank. cashout.completed, cashout.failed, and cashout.returned events are generated from partner bank webhook callbacks. ZBD translates the bank-level status update into the publisher-facing event. reversal.status_changed events are generated when a reversal transitions between states. Instant reversals emit on completion. Queued bank-level reversals emit when ZBD records the final outcome from the partner bank.

Retries

ZBD attempts initial delivery within seconds of event generation. If your endpoint does not return HTTP 200, ZBD retries with exponential backoff: roughly 1 minute, 5 minutes, 30 minutes, 2 hours, then 12 hours between attempts. After approximately five failed delivery attempts over roughly 15 hours, the event moves to a dead-letter queue and ZBD operations is alerted to investigate.

Idempotency

Webhook delivery is at least once. The same event may be delivered more than once if a retry happens. Store and deduplicate by event_id.

Auditability

ZBD logs each webhook delivery attempt, including the attempt timestamp, response or timeout reason, and final outcome.