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.When a payout fails or is returned
The amount goes back to your pool, and aFAILED 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 ownreference_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 return403 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.