Skip to main content

Submit Sell Payout (Phase 2b)

Phase 2 of the two-phase off-ramp (sell) flow. Submit the customer's beneficiary details to trigger the fiat payout. The system obtains an FX quote (if cross-currency), maps the beneficiary fields to the payout provider, and initiates the bank transfer.

On success, the ramp intent automatically transitions to completed.

POSThttps://api.zenpays.com/payment/api/v1/off-ramp/sell/payout
Bearer · API key

Request​

Headers​

HeaderDescription
Content-Type
REQUIRED
application/json
x-request-id
OPTIONAL
Custom request ID for tracing
Public Endpoint

This endpoint does not require authentication headers.

Body Parameters​

ParameterTypeDescription
intentId
REQUIRED
stringRamp intent ID
cryptoDepositId
REQUIRED
stringDeposit ID from Phase 1 response
fiatCurrency
REQUIRED
stringTarget fiat currency (e.g. USD)
payoutType
OPTIONAL
stringPayout method (default: bank_transfer)
country
OPTIONAL
stringISO country code (default: US)
selectedTsp
OPTIONAL
stringPayout provider from Payout Preview response (e.g. zenpay_routing). When omitted, the system selects the best provider automatically.
beneficiaryDetails
REQUIRED
objectDynamic fields from Payout Preview

beneficiaryDetails Object​

The fields in this object are dynamic — they come from the requiredFields and optionalFields returned by the Payout Preview endpoint. Always call payout-preview first to discover which fields are needed for the target currency and country.

Common fields include:

ParameterTypeDescription
receiverFirstName
OPTIONAL
stringBeneficiary first name
receiverLastName
OPTIONAL
stringBeneficiary last name
receiverAccountNumber
OPTIONAL
stringBank account number
receiverBankName
OPTIONAL
stringBank name
receiverBankCode
OPTIONAL
stringSWIFT/BIC code
receiverCountry
OPTIONAL
stringISO country code
receiverAddressLine1
OPTIONAL
stringStreet address
receiverCity
OPTIONAL
stringCity
receiverState
OPTIONAL
stringState/province
receiverPinCode
OPTIONAL
stringPostal/ZIP code
receiverEmail
OPTIONAL
stringEmail address
receiverPhone
OPTIONAL
stringPhone number
remittancePurpose
OPTIONAL
stringPurpose of remittance (e.g. PAYP001 - Family Support)
sourceOfFund
OPTIONAL
stringSource of funds (e.g. PAYF001 - Salary)
relationship
OPTIONAL
stringRelationship to sender (e.g. PAYR001 - Self)
Field Requirements Vary

The required fields change based on the destination currency, country, and payout type. Always use the payout-preview response to determine which fields to collect. Do not hard-code field assumptions.

Response​

Success (200 OK)​

{
"success": true,
"data": {
"payoutId": "po_abc123def456",
"status": "processing",
"amount": 19.78,
"currency": "USD",
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8"
},
"message": "Sell payout submitted"
}

Response Fields​

ParameterTypeDescription
payoutId
OPTIONAL
stringPayout tracking ID
status
OPTIONAL
stringPayout status (processing)
amount
OPTIONAL
numberFiat payout amount
currency
OPTIONAL
stringFiat currency
intentId
OPTIONAL
stringThe ramp intent ID

Automatic Behaviors​

ConditionAction
Received crypto matches expected (±5%)Uses locked fiat amount from quote
Received crypto differs >5% from expectedRecalculates fiat amount proportionally with fee scaling
Same-currency payout (e.g. USD → USD)Skips FX quotation step
Cross-currency payoutObtains live FX quote from provider
Payout succeedsIntent auto-transitions to completed
Payout failsIntent receives payout_failed metadata

Error Responses​

CodeHTTPMessage
BAD_REQUEST400Deposit not confirmed, invalid amount, or FX quotation failed
NOT_FOUND404Intent or deposit not found
SELL_PAYOUT_FAILED500Payout submission failed

Examples​

curl -X POST https://api.zenpays.com/payment/api/v1/off-ramp/sell/payout \
-H "Content-Type: application/json" \
-d '{
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
"cryptoDepositId": "d4e5f6a7-b8c9-1234-5678-abcdef012345",
"fiatCurrency": "USD",
"country": "US",
"selectedTsp": "zenpay_routing",
"beneficiaryDetails": {
"receiverFirstName": "John",
"receiverLastName": "Doe",
"receiverCountry": "US",
"receiverAccountNumber": "123456789",
"receiverBankName": "Bank of America",
"receiverBankCode": "BOFAUS3N",
"receiverAddressLine1": "123 Main St",
"receiverCity": "New York",
"receiverState": "NY",
"receiverPinCode": "10001",
"remittancePurpose": "PAYP001 - Family Support",
"sourceOfFund": "PAYF001 - Salary",
"relationship": "PAYR001 - Self"
}
}'

Complete Two-Phase Flow​

Phase 1: Deposit                    Phase 2: Payout
───────────────── ──────────────────────
1. POST sell/checkout 4. GET payout-preview
→ Get deposit address → Get required fields

2. Customer sends crypto 5. Render beneficiary form

3. Wait for confirmation 6. POST sell/payout
(deposit → confirmed) → Trigger fiat transfer
→ Intent → completed

Next Steps​