Skip to main content

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

EnvironmentBase URL
Testhttps://api.test.cyberpay.link
Productionhttps://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&currency=BRL' \
-H 'X-API-KEY: YOUR_API_KEY'

All query parameters are optional:

ParameterMeaning
countryTwo-letter country code, such as BR.
currencyISO 4217 currency code, such as BRL.
excludeCountriesSet 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 id as paymentOptionId.
  • To select a bank or another suboption directly, send its suboptions[].id as paymentOptionId.
  • availableCountries is an array of { "code": "BR", "currencies": ["BRL"] } objects. WORLDWIDE and ANY are 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 statusCoderesultTyperesult.statusWhat to do
200successPENDINGApprove or decline the payout.
200successPROCESSINGAutomatic approval submitted the payout. Await its final status.
300redirectPROCESSINGRedirect the customer to result.redirectUrl.
900declinedDECLINEDInspect result.errorCode and result.errorReason.
999errorDECLINEDSubmission 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, string statusCode: "000", a top-level transaction status, and a string result.
  • An intentional merchant decline returns HTTP 201, string statusCode: "999", status: "DECLINED", and result: "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 an error reason 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 flowv3 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.