Payouts v3 Direct API Integration
CyberPay v3 creates a payout with one request to POST /v3/payout. As with v3 pay-ins, CyberPay can return a cashier redirect when the customer needs to supply missing information. Payouts also have an approval step when automatic approval is disabled for your brand.
Environments and authentication
| Environment | Base URL |
|---|---|
| Test | https://api.test.cyberpay.link |
| Production | https://api.cyberpay.link |
Make requests from your server using the brand's X-API-KEY. Send JSON bodies with Content-Type: application/json. Source-IP restrictions are optional and can be enabled per brand. When enabled, requests must come from an authorized IP address.
The two v3 endpoints use API-key authentication. The unversioned /settle-payout endpoint additionally requires X-Signature when body-signature enforcement is enabled for your brand; its responses are also signed. Follow the signature instructions.
1. Select a payout option
Call GET /v3/payout-options to discover the methods enabled for your brand. This step is optional if you already have the appropriate payout option ID. It does not create a session or transaction.
curl 'https://api.test.cyberpay.link/v3/payout-options?country=BR¤cy=BRL' \
-H 'X-API-KEY: YOUR_API_KEY'
All query parameters are optional:
| Parameter | Meaning |
|---|---|
country | Two-letter country code, such as BR. |
currency | ISO 4217 currency code, such as BRL. |
excludeCountries | Set to true to return empty availableCountries arrays. |
The response is an array of options containing id, name, logo, type, suboptions, and availableCountries. An empty array means no options match.
- To select a method, send its
idaspaymentOptionId. - To select a bank or another suboption directly, send its
suboptions[].idaspaymentOptionId. availableCountriesis an array of{ "code": "BR", "currencies": ["BRL"] }objects.WORLDWIDEandANYare fallback values when specific coverage is unavailable.
Discovery does not take an amount or return recipient form fields. CyberPay checks the payout's full country, currency, amount, and recipient details when it is submitted.
2. Create the payout
Call POST /v3/payout. The only fields required by request validation are paymentOptionId, currency, and amount. Provide the country and recipient details required by your method to allow processing without a data-collection redirect.
The following example includes customer context. Replace the illustrative option ID with one returned for your brand and fill paymentData with the recipient fields agreed for that method. The empty object shown here can result in a cashier redirect.
{
"paymentOptionId": "aeb6bc68-5b2f-4f80-8c43-9e660874ed3b",
"country": "BR",
"currency": "BRL",
"amount": 100,
"merchantReference": "withdrawal-2026-0001",
"paymentReference": "Withdrawal 0001",
"userId": "customer-123",
"redirectUrl": "https://merchant.example/withdrawals/return",
"notificationUrl": "https://merchant.example/webhooks/payouts",
"language": "EN",
"customer": {
"firstName": "Alex",
"lastName": "Silva",
"email": "[email protected]",
"phone": "+5511999999999",
"ip": "192.0.2.10",
"userDevice": "DESKTOP",
"address": {
"country": "BR",
"city": "Sao Paulo",
"street": "Example Street",
"streetNumber": "10",
"zipCode": "01001-000"
}
},
"paymentData": {}
}
paymentData contains method-specific bank or recipient fields. There is no universal payout form schema. Required fields vary by method, provider, country, and brand configuration. Identity-document details, when needed, belong under customer.document.number and customer.document.type.
Use a stable userId to associate the payout with your customer and a unique merchantReference for reconciliation. Existing customer profile data may fill missing details. A duplicate merchant reference for the same merchant and country is rejected; this does not provide idempotent replay.
notificationUrl overrides the brand's configured webhook URL for this payout. redirectUrl is your customer return URL. Payment-facilitator brands must also send merchantDomain matching a configured domain. The API reference lists all supported fields and limits.
3. Handle the result
The endpoint returns HTTP 201 with a business-result body. The body's numeric statusCode is separate from the HTTP status.
| Body statusCode | resultType | result.status | What to do |
|---|---|---|---|
200 | success | PENDING | Approve or decline the payout. |
200 | success | PROCESSING | Automatic approval submitted the payout. Await its final status. |
300 | redirect | PROCESSING | Redirect the customer to result.redirectUrl. |
900 | declined | DECLINED | Inspect result.errorCode and result.errorReason. |
999 | error | DECLINED | Submission failed during automatic approval. Inspect the error and transaction status. |
For example, a payout awaiting merchant approval returns:
{
"statusCode": 200,
"resultType": "success",
"result": {
"status": "PENDING",
"currency": "BRL",
"amount": 100,
"merchantReference": "withdrawal-2026-0001",
"transactionId": "f6ab9d53-db1e-4cd9-bafa-a8e31247054d",
"sessionId": "8a37d25f-bf46-4f58-920e-ed7c2a27c9fb"
}
}
Store result.transactionId, result.sessionId, and result.merchantReference. No earlier session-creation request is needed.
When resultType is redirect, send the customer to the exact returned URL. CyberPay may need a country, a bank selection, recipient information, or a step required by the brand. The cashier continues the existing transaction. Do not create another payout to supply the missing details.
HTTP errors such as 400, 401, and 404 use an error body with statusCode and message, which may be a string or an array. They do not use the v3 business-result envelope.
4. Approve or decline when required
When the transaction reaches PENDING, approve or decline it in the merchant portal or through POST /settle-payout:
{
"action": "APPROVE",
"transactionId": "f6ab9d53-db1e-4cd9-bafa-a8e31247054d"
}
Use DECLINE instead of APPROVE to reject the payout without sending funds. Only PENDING payouts can be settled. Approval requires an available provider and sufficient merchant balance.
Brands with automatic payout approval enabled submit prepared payouts directly; those transactions do not need this manual step.
The settlement endpoint retains its legacy format even for v3 payouts:
- An accepted approval returns HTTP
201, stringstatusCode: "000", a top-level transactionstatus, and a stringresult. - An intentional merchant decline returns HTTP
201, stringstatusCode: "999",status: "DECLINED", andresult: "Could not process payout.". The rejection has taken effect; do not retry it because of the legacy message. - A provider decline or error can also return
"999", with anerrorreason when available.
5. Confirm the final status
A success result, HTTP 201, or customer return does not prove the payout has completed. Process payout webhooks and use GET /payments/{transactionId} to retrieve the current transaction status when needed.
Verify webhook signatures and match notifications to the stored transaction ID and merchant reference. Treat COMPLETED as successful completion, and handle DECLINED or ERROR as unsuccessful outcomes.
The v3 payout endpoint does not implement Idempotency-Key replay. If submission times out or the response is lost, reconcile the transaction through notifications, a transaction query when you have its ID, or the merchant portal using your reference before submitting again.
Migrating from v2
| Previous flow | v3 flow |
|---|---|
POST /v2/payout-options creates a session using country, currency, and amount. | Optional GET /v3/payout-options lists methods. Put the payout amount and other transaction data in POST /v3/payout. |
POST /v2/payout-suboptions retrieves the next selection. | Suboptions are included in GET /v3/payout-options. Use the selected suboption's ID as paymentOptionId. |
POST /v2/direct-payout submits data against a session. | POST /v3/payout creates and prepares the payout in one call, returning the transaction and session IDs. |
| Legacy direct-payout response fields. | Numeric statusCode, lowercase resultType, and nested result on POST /v3/payout. |
POST /settle-payout approves or declines. | The same endpoint remains available for PENDING payouts and keeps its legacy response format. |