Skip to main content
Use this model when you already have earnings logic, rules, and history in your own system. ZBD doesn’t keep a record of what users are owed. It pays out when you tell it to.
1

Create the user at signup

When a user signs up, call Create a User from your backend with your own ID for them. Store the ZBD user_id it returns.
2

Verify the user and collect a payment method

In the same signup flow, call Create a Session with flows: ["kyc", "payment_methods"] and open the widget with the session token. See Embedding the Widget.Users have to complete full verification before their first payout, because ZBD has no record of what they’ve earned to step them up against. The payment method selector shows each method’s fee as a percentage or flat amount, so users know what they’ll be charged.
3

Wait for the user to be ready

Your frontend gets a browser event when the user is verified and when they add a payment method. Until then, you can show the user as pending.
4

Get the payment method ID

Call List Payment Methods for the user and store the payment_method_id of the method they chose. ZBD holds the payment details, so you only ever handle the ID.
5

Send a payout

When the user should be paid, call Create a Payout with the user_id, payment_method_id, amount, and your own reference_id. Deduct the amount in your own system at the same time.Send a unique Idempotency-Key header with every payout, so a retry doesn’t pay the user twice. The payout is accepted with a 202 and the status INITIATED. The response includes fee_amount and net_amount, the amount the user receives.The amount comes out of your pool at that moment, so the pool has to cover it. If the payment method doesn’t belong to that user, the payout is rejected and nothing is debited.
6

Update your records from webhooks

Webhooks fire as the payout moves: PAYMENTS.V1.PAYOUT.PROCESSING, then COMPLETED or FAILED, and occasionally RETURNED. See Payout statuses.
You don’t need to manage payout limits. ZBD applies them, and if a user can’t be paid, the payout is rejected with an error code that says why.

When a payout fails or is returned

The amount goes back to your pool, and a FAILED or RETURNED webhook tells you. Add the amount back to what the user is owed in your own system, so they can be paid again once the problem is fixed. Returns can arrive well after a payout looks complete, so keep handling them for completed payouts too.

Reconciliation

Give every payout your own reference_id. It comes back in webhooks, and you can look payouts up by it with List Payouts to match ZBD’s records against yours.

What you don’t need

You don’t need the earnings endpoints. They’re for programs where ZBD tracks earnings, and they return 403 feature_not_enabled for yours. The widget’s cashout flow isn’t available to you either, because it pays out from earnings ZBD tracks. Your backend sends every payout, so you always control which user is paid, how much, and to which payment method.