Fiat Payout Integration Guide
This guide explains how merchants can use quickpayout to create a fiat payout, handle verification webhooks, and query the final result.
Fiat payout is a three-step flow:
- Create the payout: call
POST /payment/quickpayoutto create and submit the payout instruction. - Verify and execute: Beyounger validates payout information asynchronously, may ask the merchant to verify it by webhook, and executes the payout after approval.
- Confirm the result: receive webhook notifications and query
GET /payment/payouts/{payout_id}for fallback confirmation and reconciliation.
One-Page Summary
Minimum API set:
POST /payment/quickpayoutGET /payment/payouts/{payout_id}
Minimum webhook set:
payout.verify.request: merchant-side verification, only when enabled for the accountpayout.execution.completed: payout succeededpayout.execution.failed: payout failed
Other events that may be delivered:
payout.review.approvedpayout.review.returnedpayout.review.rejectedpayout.execution.processing
Before Integration
Confirm these items before sending live payouts:
| Item | Why it matters |
|---|---|
| API key permissions | payment.payout.create is required. If submit=true, payment.payout.submit is also required. Use payment.payout.read for query and reconciliation. |
| Payout route | Beyounger must enable the merchant's currency, method, and provider route. |
method_id | Use the value assigned to the merchant account. For PayPal examples in this guide, the method is 1. |
| Webhook endpoint | The merchant should provide a reachable HTTPS notify_url and configure payout webhook signing/subscriptions. |
| Merchant storage | Store reference, client_request_id, payout_id, beneficiary_id, and beneficiary_account_id. |
Confirm Methods And Fields
Before the first integration, or before adding a new payout route, the merchant needs to know which payout method is available and which fields must be sent for the receiving account.
Recommended setup sequence:
- Call
GET /payment/payout-methods?currency=USDto find the available payout methods and getmethod_id. - Call
GET /payment/payout-networks?method_id=1¤cy=USD&include_schema=trueto find supported receiving networks and their field rules. - To inspect one network only, call
GET /payment/payout-networks/{code}/schema, for exampleGET /payment/payout-networks/PAYPAL/schema. - Build
beneficiary_account.fieldsfrom the schema values such asfield_key,required, andvalidation_rule.
Field mapping:
| Value needed | Source | Used in request |
|---|---|---|
| Payout method ID | method_id from GET /payment/payout-methods | method_id |
| Receiving network | code from GET /payment/payout-networks | beneficiary_account.network_code |
| Receiving account field | fields[].field_key | beneficiary_account.fields |
| Required flag | fields[].required | Decide whether the field must be sent |
| Validation rule | fields[].validation_rule | Validate before submitting the payout |
For example, the PayPal receiving email comes from the PAYPAL network schema and should be sent as:
{
"beneficiary_account": {
"network_code": "PAYPAL",
"fields": {
"paypal_email": "recipient@example.com"
}
}
}
These APIs are for setup and field discovery. They do not need to be called before every payout.
Core Sequence
Step 1: Create The Payout
Endpoint
POST /payment/quickpayout
Use this endpoint to create a fiat payout instruction. For live payout, set submit=true so the payout enters asynchronous validation and execution after creation.
Headers
Authorization: Bearer <api_key_jwt>
Content-Type: application/json
Accept: application/json
Request Fields
| Field | Required | Description |
|---|---|---|
client_request_id | Recommended | Merchant idempotency or trace ID. Use a unique value for each payout. |
currency | Yes | Payout currency, for example USD. |
amount | Yes | Payout amount, for example "0.5". |
method_id | Usually yes | Payout method configured for the merchant account. |
reference | Yes | Merchant business order number. Keep it unique. |
notify_url | Yes | Merchant callback URL for payout verification and result notifications. |
beneficiary | Yes | Recipient identity information. |
beneficiary_account | Yes | Receiving account information. Fields must follow the selected network schema. |
beneficiary_account_id | Optional | Reuse a receiving account that was created earlier. |
fee_bearer | No | Fee bearer. Defaults to merchant when omitted. |
submit | Recommended true | Whether to submit immediately after creation. |
For quickpayout, the recommended request includes both beneficiary and beneficiary_account. Beyounger creates or resolves the recipient and receiving account from those fields.
If the merchant has already created and stored a receiving account, beneficiary_account_id can be used to reuse it.
Beneficiary And Account Logic
beneficiary and beneficiary_account are submitted as one recipient-account pair:
| Object | Meaning | Key fields |
|---|---|---|
beneficiary | Recipient identity profile. This is the person or entity receiving funds. | name, fields.payee_id, fields.email, fields.first_name, fields.last_name, fields.country, fields.phone |
beneficiary_account | The destination account for this recipient under the selected network_code. For PayPal, this is the PayPal receiving account. | network_code, display_name, fields.paypal_email |
For /payment/quickpayout, the merchant should send beneficiary.fields.payee_id. It is the merchant-side unique recipient identifier, such as a user ID, seller ID, or customer ID in the merchant system. Keep it stable for the same recipient.
Beyounger enforces one receiving account per beneficiary under the same network_code. In one quickpayout request, send exactly one beneficiary and one matching beneficiary_account.
Beyounger uses method_id + payee_id to look for an existing active beneficiary. If the beneficiary already has an account under the same network_code and the account fields match, that account is reused. If the same beneficiary already has a different account under that network_code, the request is rejected and the merchant should either reuse the existing account or send a different payee_id for a different recipient.
If no matching beneficiary is found, Beyounger creates the recipient from beneficiary and creates the receiving account from beneficiary_account.
Do not put the PayPal receiving email only in beneficiary.fields.email. For PayPal payouts, the actual receiving email must be sent as beneficiary_account.fields.paypal_email.
Inline PayPal Recipient
{
"client_request_id": "po_202606190001",
"currency": "USD",
"amount": "0.5",
"method_id": 1,
"reference": "po_202606190001",
"notify_url": "https://merchant.example.com/webhooks/payout",
"beneficiary": {
"name": "PayPal Recipient",
"fields": {
"payee_id": "729921697",
"language": "en",
"country": "US",
"phone": "+1-4155550100",
"birthdate": "1990-01-01",
"email": "recipient@example.com",
"first_name": "PayPal",
"last_name": "Recipient",
"zip": "94105",
"city": "San Francisco",
"state": "CA",
"address": "1 Market St"
}
},
"beneficiary_account": {
"network_code": "PAYPAL",
"display_name": "PayPal Account",
"fields": {
"paypal_email": "recipient@example.com"
}
},
"submit": true
}
Successful Response
{
"code": 0,
"message": "OK",
"data": {
"payout": {
"payout_id": "payout_7b35b81fa57121c6",
"client_request_id": "po_202606190001",
"reference": "po_202606190001",
"currency": "USD",
"amount": "0.5",
"status": "pending_review",
"review_status": "pending_review",
"execution_status": "init",
"risk_status": "pending",
"beneficiary_id": "beneficiary_xxx",
"beneficiary_account_id": "bacc_xxx"
}
}
}
A successful response means Beyounger accepted the payout instruction. It does not mean the money has been sent.
Store these fields:
referenceclient_request_idpayout_idbeneficiary_idbeneficiary_account_idstatusreview_statusexecution_status
Step 2: Verify And Execute
After quickpayout is submitted, Beyounger validates the payout asynchronously. If merchant-side verification is enabled, Beyounger sends a payout.verify.request webhook before execution.
Verification Request
Example payload:
{
"payout_id": "payout_7b35b81fa57121c6",
"type": "payout.verify",
"account_id": "acct_xxx",
"reference": "po_202606190001",
"currency": "USD",
"amount": "0.5",
"status": "pending_review",
"review_status": "pending_review",
"execution_status": "init",
"beneficiary_id": "beneficiary_xxx",
"beneficiary_account_id": "bacc_xxx",
"beneficiary_name": "PayPal Recipient",
"network_code": "PAYPAL",
"account_type": "fiat",
"beneficiary_account": {
"network_code": "PAYPAL",
"display_name": "PayPal Account",
"fields_masked": {
"paypal_email": "r***@example.com"
}
},
"submitted_at": 1781789497,
"created_at": 1781789497
}
The merchant verification endpoint should:
- Verify the webhook signature.
- Process repeated requests idempotently by
payout_idorevent_id. - Check the merchant order, amount, currency, recipient, and receiving account.
- Return only a clear
verifieddecision.
Approve:
{
"verified": true
}
Reject:
{
"verified": false
}
If the response cannot be parsed or does not include a clear decision, Beyounger treats the attempt as retryable and does not execute the payout.
Result Webhooks
| Event | Meaning | Merchant action |
|---|---|---|
payout.review.approved | Verification or review approved the payout. | Mark review as approved and wait for execution. |
payout.review.returned | The payout was returned. | Mark it as returned and handle manually. |
payout.review.rejected | The payout was rejected before execution. | Mark it as rejected or failed in the merchant system. |
payout.execution.processing | Beyounger started execution. | Mark the payout as processing. |
payout.execution.completed | Execution succeeded. | Mark the payout as successful and reconcile. |
payout.execution.failed | Execution failed. | Mark the payout as failed and inspect the failure reason. |
Result webhook payloads use an event envelope plus payout data:
{
"event_id": "payout_payout_7b35b81fa57121c6_ab12cd34ef56",
"event_type": "payout.execution.completed",
"business_type": "payout",
"business_id": "payout_7b35b81fa57121c6",
"occurred_at": 1781789497,
"version": "v1",
"data": {
"payout_id": "payout_7b35b81fa57121c6",
"reference": "po_202606190001",
"currency": "USD",
"amount": "0.5",
"status": "completed",
"review_status": "approved",
"execution_status": "completed"
}
}
Important fields:
| Field | Description |
|---|---|
event_id | Webhook event ID. |
event_type | Event type. |
business_type | Always payout. |
business_id | Same as payout_id. |
data.payout_id | Beyounger payout ID. |
data.reference | Merchant business order number. |
data.amount / data.currency | Payout amount and currency. |
data.status | Top-level payout status. |
data.review_status | Verification or review status. |
data.execution_status | Execution status. |
data.execution_fail_reason | Failure reason when execution failed. |
Step 3: Query Payout Status
Endpoint
GET /payment/payouts/{payout_id}
Use this endpoint:
- After create, to read the initial state.
- After receiving a webhook, to confirm the latest state.
- When a webhook times out or is missing.
- During finance or operations reconciliation.
State Guide
review_status | execution_status | Meaning |
|---|---|---|
pending_review | init | Waiting for verification or review. |
approved | init | Approved and waiting for execution. |
approved | processing | Execution is in progress. |
approved | completed | Final success. |
approved | failed | Final execution failure. |
rejected | init | Rejected before execution. |
returned | init | Returned and needs handling. |
For final result handling, prioritize execution_status:
completed: final successfailed: final failureprocessing: still in progressinit: not executed yet; checkreview_status
Webhooks provide fast updates. The query endpoint is the fallback and reconciliation source.
PayPal Notes
| Field | Location | Description |
|---|---|---|
paypal_email | beneficiary_account.fields | PayPal receiving email. |
payee_id | beneficiary.fields | Merchant-side unique recipient identifier. Keep it stable for the same recipient. |
email | beneficiary.fields | Recipient identity email. |
first_name / last_name | beneficiary.fields | Recipient name. |
country | beneficiary.fields | Country or region. |
phone | beneficiary.fields | Recipient phone number. |
Notes:
- PayPal receiving email should be sent as
beneficiary_account.fields.paypal_email. beneficiary.fields.emaildescribes the recipient identity. It is not the receiving account field.beneficiary.fields.payee_idshould be the merchant's internal recipient ID, not the PayPal account email.- Recommended phone format:
+1-4155550100. - Do not send
beneficiary_account.account_typeunless Beyounger gives the exact accepted value. - Use the
method_idconfigured for the merchant account.
Common Questions
Does a successful quickpayout response mean payout success?
No. It only means the payout instruction was accepted. Final success is confirmed by webhook or query result.
Is payout.verify.request required?
It depends on account configuration. If merchant-side verification is enabled, the merchant must implement it and return {"verified": true} or {"verified": false}.
Should the merchant rely on webhook or query?
Use both. Webhook gives real-time state changes; query is the fallback for timeout, missing notification, and reconciliation.