For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
RegisterLoginSandbox Login
GuidesRecipesAPI Reference
GuidesRecipesAPI Reference
  • Product Overview
    • Products & Features
    • Key Concepts
  • Getting Started
    • Account Setup
    • Quickstart
  • Checkout
    • Settlement Locations
  • Payouts
    • Payout Overview
    • What is a Payout
      • Coinflow Wallet
  • Subscriptions
    • Subscriptions Overview
  • Marketplaces
    • Marketplace Overview
    • How Marketplaces Work
    • Marketplaces Webhooks
    • Marketplaces Implementation
  • Developer Resources
    • Custom Branding
    • Checkout Implementation
    • Webhooks
  • Merchant Dashboard
    • Login & Account Access
    • Users and Roles
    • Rate Limits
    • Developer Contact
LogoLogo
RegisterLoginSandbox Login
On this page
  • How the flow works
  • Prerequisites
  • Implementation
  • Advanced
  • FAQ
  • Next steps
PayoutsSource of Funds for Payouts

Merchant Payouts from Your Coinflow wallet

Send payouts to your users' bank accounts and debit cards, funded by your Coinflow wallet.
Was this page helpful?
Previous

How To: Implement User Self-Custodial Wallet Payouts

Developers can use this documentation to implement a payout from an end-user’s wallet to their bank account.

Next
Built with

This is the most common payout flow for platforms that hold a user balance and disburse to that user when they request a withdrawal — gaming platforms, marketplaces, gig economy apps, reward programs, SaaS creator earnings, and similar.

Your backend tracks the balance. When a user requests a payout, you call Coinflow to (1) verify the user’s identity, (2) save where they want their money sent, and (3) initiate the payout. Funds come out of your Coinflow wallet.

Best for

Platforms where the merchant tracks user balances and initiates payouts on the user’s behalf.

Source of funds

Your Coinflow wallet — the same balance that receives proceeds from Coinflow Checkout.

Supported destinations

US bank account, US debit card (push-to-card), IBAN (EUR/GBP), PIX (BRL).

UI

API-driven. Coinflow optionally provides a pre-built Bank Authentication UI that handles KYC + linking a destination.

How the flow works


Prerequisites

Complete account setup first

This integration assumes you’ve completed the Account Setup prerequisites — sandbox merchant account, API key, team access, and any product-specific configuration (settlement location, chargeback protection, or wallet funding).

Before sending real payouts, you’ll need:

  1. A merchant account (register on sandbox) and an API key.
  2. A funded Coinflow wallet. In sandbox, contact the Coinflow team for test funds. In production, your balance fills from Coinflow Checkout proceeds.
  3. (Optional) Webhook endpoint configured to receive payout status updates — see Withdraw Webhooks.

Authorization Headers:

  • Authorization — Your API key from the merchant dashboard.
  • x-coinflow-auth-user-id — A unique customer ID from your own systems identifying the payer or payee.
  • x-coinflow-auth-session-key — A JWT that authorizes the payer. Valid for 24 hours; refresh after expiry.

Implementation

1

Step 1: Verify the withdrawer (KYC/KYB)

Every user must complete identity verification before their first payout. Once verified, the same user can be paid out repeatedly with no re-verification.

Choose the path that matches how you handle identity today:

Coinflow handles KYC (most common)
Upload identity documents
Share a token from an existing identity provider
Attest to your own KYC (KYC Reliance)

Pass the user’s details to Coinflow and we run identity verification end-to-end.

US withdrawers require full SSN, address, and date of birth.

POST
/api/withdraw/kyc
1curl -X POST https://api-sandbox.coinflow.cash/api/withdraw/kyc \
2 -H "x-coinflow-auth-user-id: <apiKey>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "info": {
6 "email": "string",
7 "firstName": "string",
8 "surName": "string",
9 "physicalAddress": "string",
10 "city": "string",
11 "state": "string",
12 "zip": "string",
13 "country": "string",
14 "dob": "string",
15 "ssn": "string"
16 }
17}'
Try it
Response
1{
2 "withdrawer": {
3 "_id": "string",
4 "wallet": "string",
5 "blockchain": "solana",
6 "wallets": [
7 {
8 "wallet": "string",
9 "blockchain": "solana"
10 }
11 ],
12 "email": "string",
13 "availability": {
14 "status": "Functional",
15 "reason": "string",
16 "editor": "string",
17 "updatedAt": "2024-01-15T09:30:00Z"
18 },
19 "currency": "USD",
20 "merchant": "string",
21 "verification": {
22 "reference": "string",
23 "status": "pending",
24 "vendor": "middesk",
25 "name": "string",
26 "attested": true,
27 "shareToken": "string",
28 "shareTokenStatus": "string",
29 "sessionToken": "string"
30 },
31 "riskScoreOverride": true,
32 "country": "string",
33 "user": true,
34 "watchlistExempt": "Unknown",
35 "originalCurrency": "USD",
36 "geoBlockOverride": {
37 "reason": "string",
38 "setBy": "string",
39 "setAt": "2024-01-15T09:30:00Z",
40 "expiresAt": "2024-01-15T09:30:00Z"
41 },
42 "createdAt": "2024-01-15T09:30:00Z",
43 "dwolla": {
44 "customerId": "string",
45 "status": "pending",
46 "acceptedTerms": "2024-01-15T09:30:00Z",
47 "verification": {
48 "reference": "string",
49 "status": "pending",
50 "vendor": "middesk",
51 "name": "string",
52 "attested": true,
53 "shareToken": "string",
54 "shareTokenStatus": "string",
55 "sessionToken": "string"
56 }
57 },
58 "watchlistId": "string"
59 }
60}

Non-US withdrawers require email and country only at this step. The user completes identity verification through a hosted link returned in the response.

451 response? Coinflow needs additional info from the user. Redirect them to the verificationLink in the response body — they’ll upload a photo ID and complete a selfie verification. After they finish, poll GET /withdraw until verification.status === "approved".

2

Step 2: Check the withdrawer’s verification status

After KYC, fetch the withdrawer record to confirm verification status before adding a payout destination. You can call this at any time to look up a withdrawer.

GET
/api/withdraw
1curl https://api-sandbox.coinflow.cash/api/withdraw \
2 -H "x-coinflow-auth-wallet: <apiKey>"
Try it
Response
1{
2 "withdrawer": {
3 "_id": "string",
4 "wallet": "string",
5 "blockchain": "solana",
6 "wallets": [
7 {
8 "wallet": "string",
9 "blockchain": "solana"
10 }
11 ],
12 "email": "string",
13 "availability": {
14 "status": "Functional",
15 "reason": "string",
16 "editor": "string",
17 "updatedAt": "2024-01-15T09:30:00Z"
18 },
19 "currency": "USD",
20 "merchant": "string",
21 "verification": {
22 "reference": "string",
23 "status": "pending",
24 "vendor": "middesk",
25 "name": "string",
26 "attested": true,
27 "shareToken": "string",
28 "shareTokenStatus": "string",
29 "sessionToken": "string"
30 },
31 "riskScoreOverride": true,
32 "country": "string",
33 "bankAccounts": [
34 {
35 "last4": "string",
36 "accountHash": "string",
37 "alias": "string",
38 "token": "string",
39 "reference": "string",
40 "accountNumberOnlyHash": "string",
41 "isDeleted": true,
42 "isTokenized": true,
43 "accountNumber": "string"
44 }
45 ],
46 "cards": [
47 {
48 "last4": "string",
49 "token": "string",
50 "type": "VISA",
51 "disbursementStatus": "Immediate",
52 "createdAt": "2024-01-15T09:30:00Z",
53 "isDeleted": true,
54 "currency": "USD",
55 "nameOnCard": "string",
56 "expMonth": "string",
57 "expYear": "string"
58 }
59 ],
60 "ibans": [
61 {
62 "last4": "string",
63 "accountHash": "string",
64 "alias": "string",
65 "token": "string",
66 "reference": "string",
67 "sortCode": "string",
68 "bic": "string"
69 }
70 ],
71 "pixes": [
72 {
73 "key": "string",
74 "accountHash": "string",
75 "token": "string"
76 }
77 ],
78 "efts": [
79 {
80 "accountHash": "string",
81 "alias": "string",
82 "token": "string",
83 "reference": "string",
84 "mask": "string",
85 "isDeleted": true,
86 "accountNumber": "string",
87 "institutionId": "string",
88 "institution": "string",
89 "transit_number": "string"
90 }
91 ],
92 "p2cAvailable": true,
93 "applePayAvailable": true,
94 "bankCurrencyOptions": [
95 "USD"
96 ],
97 "originalCurrency": "USD",
98 "geoBlockOverride": {
99 "reason": "string",
100 "setBy": "string",
101 "setAt": "2024-01-15T09:30:00Z",
102 "expiresAt": "2024-01-15T09:30:00Z"
103 },
104 "createdAt": "2024-01-15T09:30:00Z",
105 "venmo": {
106 "alias": "string",
107 "token": "string",
108 "type": "venmo",
109 "isDeleted": true
110 },
111 "paypal": {
112 "alias": "string",
113 "token": "string",
114 "type": "paypal",
115 "isDeleted": true
116 },
117 "interac": {
118 "alias": "string",
119 "token": "string",
120 "type": "interac",
121 "isDeleted": true
122 }
123 }
124}
3

Step 3: Add a payout destination

Save the place the user wants to receive funds. Available destinations depend on the country they verified under.

Want to skip building destination UI? Coinflow’s Bank Authentication UI embeds the entire KYC + destination flow in your app. If you use it, you can skip Step 1 and Step 3 — you’ll only need the quote and payout endpoints below.

US bank account
US debit card (push-to-card)
IBAN (EUR / GBP)
PIX (BRL)

For US ACH and RTP payouts.

POST
/api/withdraw/account
1curl -X POST https://api-sandbox.coinflow.cash/api/withdraw/account \
2 -H "x-coinflow-auth-user-id: <apiKey>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "alias": "string",
6 "routingNumber": "string",
7 "accountNumber": "string",
8 "type": "checking"
9}'
Try it
Response
1{
2 "withdrawer": {
3 "_id": "string",
4 "wallet": "string",
5 "blockchain": "solana",
6 "wallets": [
7 {
8 "wallet": "string",
9 "blockchain": "solana"
10 }
11 ],
12 "email": "string",
13 "availability": {
14 "status": "Functional",
15 "reason": "string",
16 "editor": "string",
17 "updatedAt": "2024-01-15T09:30:00Z"
18 },
19 "currency": "USD",
20 "merchant": "string",
21 "verification": {
22 "reference": "string",
23 "status": "pending",
24 "vendor": "middesk",
25 "name": "string",
26 "attested": true,
27 "shareToken": "string",
28 "shareTokenStatus": "string",
29 "sessionToken": "string"
30 },
31 "riskScoreOverride": true,
32 "country": "string",
33 "bankAccounts": [
34 {
35 "last4": "string",
36 "accountHash": "string",
37 "alias": "string",
38 "token": "string",
39 "reference": "string",
40 "accountNumberOnlyHash": "string",
41 "isDeleted": true,
42 "isTokenized": true,
43 "accountNumber": "string"
44 }
45 ],
46 "cards": [
47 {
48 "last4": "string",
49 "token": "string",
50 "type": "VISA",
51 "disbursementStatus": "Immediate",
52 "createdAt": "2024-01-15T09:30:00Z",
53 "isDeleted": true,
54 "currency": "USD",
55 "nameOnCard": "string",
56 "expMonth": "string",
57 "expYear": "string"
58 }
59 ],
60 "ibans": [
61 {
62 "last4": "string",
63 "accountHash": "string",
64 "alias": "string",
65 "token": "string",
66 "reference": "string",
67 "sortCode": "string",
68 "bic": "string"
69 }
70 ],
71 "pixes": [
72 {
73 "key": "string",
74 "accountHash": "string",
75 "token": "string"
76 }
77 ],
78 "efts": [
79 {
80 "accountHash": "string",
81 "alias": "string",
82 "token": "string",
83 "reference": "string",
84 "mask": "string",
85 "isDeleted": true,
86 "accountNumber": "string",
87 "institutionId": "string",
88 "institution": "string",
89 "transit_number": "string"
90 }
91 ],
92 "p2cAvailable": true,
93 "applePayAvailable": true,
94 "bankCurrencyOptions": [
95 "USD"
96 ],
97 "originalCurrency": "USD",
98 "geoBlockOverride": {
99 "reason": "string",
100 "setBy": "string",
101 "setAt": "2024-01-15T09:30:00Z",
102 "expiresAt": "2024-01-15T09:30:00Z"
103 },
104 "createdAt": "2024-01-15T09:30:00Z",
105 "venmo": {
106 "alias": "string",
107 "token": "string",
108 "type": "venmo",
109 "isDeleted": true
110 },
111 "paypal": {
112 "alias": "string",
113 "token": "string",
114 "type": "paypal",
115 "isDeleted": true
116 },
117 "interac": {
118 "alias": "string",
119 "token": "string",
120 "type": "interac",
121 "isDeleted": true
122 }
123 }
124}
4

Step 4: Get a quote

Before initiating, fetch a quote so you can show the user fees, expected delivery time, and how much they’ll actually receive. The response includes every speed option available for their destination — card (instant), asap (RTP), same_day (Same-Day ACH), and standard (Standard ACH).

GET
/api/withdraw/quote
1curl -G https://api-sandbox.coinflow.cash/api/withdraw/quote \
2 -H "x-coinflow-auth-wallet: <apiKey>" \
3 -H "Content-Type: application/json" \
4 -d token=token \
5 -d amount=1.1 \
6 -d merchantId=merchantId
Try it
Response
1{
2 "asap": {
3 "fee": {
4 "cents": 250,
5 "currency": "USD"
6 },
7 "limit": {
8 "cents": 500000,
9 "currency": "USD"
10 },
11 "finalSettlement": {
12 "cents": 50250,
13 "currency": "USD"
14 },
15 "expectedDeliveryDate": "Today by 5 PM",
16 "expectedDeliveryDateISO": "2024-06-15T17:00:00Z",
17 "customFee": {
18 "cents": 150,
19 "currency": "USD",
20 "label": "Express processing fee"
21 }
22 },
23 "same_day": {
24 "fee": {
25 "cents": 150,
26 "currency": "USD"
27 },
28 "limit": {
29 "cents": 1000000,
30 "currency": "USD"
31 },
32 "finalSettlement": {
33 "cents": 50150,
34 "currency": "USD"
35 },
36 "expectedDeliveryDate": "Today by 11:59 PM",
37 "expectedDeliveryDateISO": "2024-06-15T23:59:59Z",
38 "customFee": {
39 "cents": 100,
40 "currency": "USD",
41 "label": "Same day service fee"
42 }
43 },
44 "standard": {
45 "fee": {
46 "cents": 50,
47 "currency": "USD"
48 },
49 "limit": {
50 "cents": 2000000,
51 "currency": "USD"
52 },
53 "finalSettlement": {
54 "cents": 50050,
55 "currency": "USD"
56 },
57 "expectedDeliveryDate": "In 3 business days",
58 "expectedDeliveryDateISO": "2024-06-18T17:00:00Z",
59 "customFee": {
60 "cents": 0,
61 "currency": "USD",
62 "label": "Standard withdrawal fee"
63 }
64 },
65 "card": {
66 "fee": {
67 "cents": 300,
68 "currency": "USD"
69 },
70 "limit": {
71 "cents": 100000,
72 "currency": "USD"
73 },
74 "finalSettlement": {
75 "cents": 50300,
76 "currency": "USD"
77 },
78 "expectedDeliveryDate": "Instant",
79 "expectedDeliveryDateISO": "2024-06-15T12:00:00Z",
80 "customFee": {
81 "cents": 200,
82 "currency": "USD",
83 "label": "Card processing fee"
84 }
85 },
86 "iban": {
87 "fee": {
88 "cents": 100,
89 "currency": "USD"
90 },
91 "limit": {
92 "cents": 1500000,
93 "currency": "USD"
94 },
95 "finalSettlement": {
96 "cents": 50100,
97 "currency": "USD"
98 },
99 "expectedDeliveryDate": "In 2 business days",
100 "expectedDeliveryDateISO": "2024-06-17T17:00:00Z",
101 "customFee": {
102 "cents": 50,
103 "currency": "USD",
104 "label": "IBAN transfer fee"
105 }
106 },
107 "pix": {
108 "fee": {
109 "cents": 20,
110 "currency": "USD"
111 },
112 "limit": {
113 "cents": 50000,
114 "currency": "USD"
115 },
116 "finalSettlement": {
117 "cents": 50020,
118 "currency": "USD"
119 },
120 "expectedDeliveryDate": "Instant",
121 "expectedDeliveryDateISO": "2024-06-15T12:00:00Z",
122 "customFee": {
123 "cents": 10,
124 "currency": "USD",
125 "label": "PIX network fee"
126 }
127 },
128 "eft": {
129 "fee": {
130 "cents": 75,
131 "currency": "USD"
132 },
133 "limit": {
134 "cents": 750000,
135 "currency": "USD"
136 },
137 "finalSettlement": {
138 "cents": 50075,
139 "currency": "USD"
140 },
141 "expectedDeliveryDate": "Next business day",
142 "expectedDeliveryDateISO": "2024-06-16T17:00:00Z",
143 "customFee": {
144 "cents": 25,
145 "currency": "USD",
146 "label": "EFT processing fee"
147 }
148 },
149 "venmo": {
150 "fee": {
151 "cents": 150,
152 "currency": "USD"
153 },
154 "limit": {
155 "cents": 200000,
156 "currency": "USD"
157 },
158 "finalSettlement": {
159 "cents": 50150,
160 "currency": "USD"
161 },
162 "expectedDeliveryDate": "Instant",
163 "expectedDeliveryDateISO": "2024-06-15T12:00:00Z",
164 "customFee": {
165 "cents": 100,
166 "currency": "USD",
167 "label": "Venmo transfer fee"
168 }
169 },
170 "paypal": {
171 "fee": {
172 "cents": 200,
173 "currency": "USD"
174 },
175 "limit": {
176 "cents": 300000,
177 "currency": "USD"
178 },
179 "finalSettlement": {
180 "cents": 50200,
181 "currency": "USD"
182 },
183 "expectedDeliveryDate": "Instant",
184 "expectedDeliveryDateISO": "2024-06-15T12:00:00Z",
185 "customFee": {
186 "cents": 150,
187 "currency": "USD",
188 "label": "PayPal processing fee"
189 }
190 },
191 "wire": {
192 "fee": {
193 "cents": 500,
194 "currency": "USD"
195 },
196 "limit": {
197 "cents": 5000000,
198 "currency": "USD"
199 },
200 "finalSettlement": {
201 "cents": 50500,
202 "currency": "USD"
203 },
204 "expectedDeliveryDate": "In 1-2 business days",
205 "expectedDeliveryDateISO": "2024-06-16T17:00:00Z",
206 "customFee": {
207 "cents": 300,
208 "currency": "USD",
209 "label": "Wire transfer fee"
210 }
211 },
212 "interac": {
213 "fee": {
214 "cents": 125,
215 "currency": "USD"
216 },
217 "limit": {
218 "cents": 100000,
219 "currency": "USD"
220 },
221 "finalSettlement": {
222 "cents": 50125,
223 "currency": "USD"
224 },
225 "expectedDeliveryDate": "Same day",
226 "expectedDeliveryDateISO": "2024-06-15T20:00:00Z",
227 "customFee": {
228 "cents": 75,
229 "currency": "USD",
230 "label": "Interac e-Transfer fee"
231 }
232 },
233 "quote": {
234 "cents": 50000,
235 "currency": "USD"
236 },
237 "gasFees": {
238 "gasFees": {
239 "cents": 300,
240 "currency": "USD"
241 },
242 "gasFeesWei": "1500000000000000000"
243 },
244 "swapFees": {
245 "cents": 450,
246 "currency": "USD"
247 }
248}
5

Step 5: Initiate the payout

Submit the payout. Your Coinflow wallet is debited; the user’s funds are sent to their selected destination.

speed valueMethodTypical delivery
cardPush-to-cardInstant (seconds)
asapRTP (Real-Time Payments)Instant (seconds)
same_daySame-Day ACHWithin business day
standardStandard ACH1–3 business days
ibanSEPA1–2 business days
pixPIXInstant (seconds)
POST
/api/merchant/withdraws/payout/delegated
1curl -X POST https://api-sandbox.coinflow.cash/api/merchant/withdraws/payout/delegated \
2 -H "Authorization: <apiKey>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "speed": "same_day",
6 "account": "card_4f3a2b1c9d8e7f6a",
7 "userId": "user_1234567890",
8 "idempotencyKey": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
9 "amount": {
10 "cents": 25000
11 }
12}'
Try it
Response
1{
2 "signature": "3045022100dff9a1b2c3d4e5f67890123456789abcdef0123456789abcdef0123456789ab02207c9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e",
3 "effectiveSpeed": "same_day"
4}

effectiveSpeed may differ from the speed you requested. Same-Day ACH requests above NACHA’s per-transaction limit ($1,000,000) are automatically downgraded to standard. Always read effectiveSpeed from the response to confirm how the payout was actually processed.

6

Step 6: Monitor

Track payouts through whichever channel suits your operations:

  • Withdraw webhooks — recommended. Receive real-time status changes (initiated, settled, failed, returned).
  • Merchant dashboard — visual interface for support and ops teams.
  • Get Balance — check your remaining Coinflow wallet programmatically.

Advanced

Funding your Coinflow wallet

In sandbox, contact the Coinflow team to provision test funds — there’s no production money involved.

In production, your Coinflow wallet fills automatically from Coinflow Checkout proceeds. If you need to top up directly (e.g., to seed payouts before you’ve taken any pay-ins), contact the Coinflow team for wire instructions.

No pre-built UI for the full payout flow

Coinflow does not currently provide a drop-in UI for merchant-initiated payouts — this integration is API-driven. You can use Coinflow’s Bank Authentication UI for the KYC and destination-linking portion only, then call the quote and payout endpoints from your own UI for the rest of the flow.


FAQ

What does a 451 verification response mean?

Coinflow needs additional information from the withdrawer (commonly a photo ID and selfie). The response body includes a verificationLink — redirect the user there. Once they complete the steps, poll GET /withdraw and check verification.status === "approved".

Why is bank authentication required?

Bank authentication confirms the user owns the account they’re connecting. Per AML policy, Coinflow requires it before any withdrawal. It also prevents fraud, reduces failed payments, and protects against chargebacks.

How do I tokenize a debit card for push-to-card?

Raw card numbers must never reach your servers (PCI compliance). Coinflow provides PCI-compliant tokenization through hosted iframe components.

  • Without a PCI DSS AOC: use Tokenize Debit Cards for Withdraws.
  • With a valid AOC: use Tokenize Card Data via API for Debit Card Payouts.
How do I know if I have a valid PCI DSS AOC?

Merchants need a current Attestation of Compliance (AOC) from a Qualified Security Assessor. Sample formats: merchant AOC, service-provider AOC. If you’re implementing on behalf of a merchant, you need a service-provider AOC.


Next steps

Test in sandbox

Use the sandbox dashboard to watch test payouts move through the system.

Configure webhooks

Get real-time status updates for every payout.

Common errors

Troubleshoot failed verifications, declined cards, and payout failures.

Go live

Contact the Coinflow team to activate production access.