Skip to main content

Prerequisites

  • An active Yala sandbox account. Request access from your Yala relationship manager or by emailing developers@useyala.com.
  • A sandbox API key (x-api-key) with CAN_INITIATE_PAYMENT permission.
  • A registered business with funded wallets in the currencies you plan to send.
  • Currency pairs enabled in your dashboard.
Newly generated API keys can take up to 20-30 minutes to fully propagate. During this window, requests may return 403 Forbidden.
New to Yala? Read the End-to-End Integration Flow guide first to understand how to integrate payout APIs into your application for your end users.

1. Configure environments

EnvironmentBase URL
Productionhttps://gateway.useyala.com/v1/payout-api/payouts
Sandboxhttps://gateway.staging.useyala.com/v1/payout-api/payouts
Sandbox tip: Use gateway.staging.useyala.com when testing against the sandbox app.
Save the x-api-key in your secret manager and inject it at runtime. Avoid hardcoding keys in source control.

2. Check wallet balances

Before requesting quotes or initiating payouts, check your available balances by currency:
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/wallets \
  -H "x-api-key: <SANDBOX_API_KEY>"
For full request/response fields and examples, see Get Wallet Balances.

3. Enable currency pairs

Before creating payouts, enable currency pairs in your Yala dashboard. Only enabled pairs are available via API.
# Check enabled pairs
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/pairs \
  -H "x-api-key: <SANDBOX_API_KEY>"

4. Get payment methods and rates

Call the methods endpoint to get available payment methods, current rates, and required beneficiary fields for your corridor.
curl "https://gateway.staging.useyala.com/v1/payout-api/payouts/methods?sourceCurrency=NGN&destinationCurrency=CNY&destinationCountryCode=CHN" \
  -H "x-api-key: <SANDBOX_API_KEY>"
Response includes:
  • Current exchange rate
  • Available payment methods (e.g., ALIPAY, WECHAT, SWIFT)
  • Required and optional beneficiary fields for each method
  • Fees and settlement times
Use the requiredFields array to dynamically render your payout form based on the selected payment method.

5. Initiate the payout

Important: You must generate an Idempotency-Key client-side before making the request. This prevents duplicate payouts if the request is retried.
// Generate idempotency key (client-side)
const idempotencyKey = crypto.randomUUID();
// OR use your order ID: `order-${orderId}`
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/initiate \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "x-api-key: <SANDBOX_API_KEY>" \
  -d '{
    "sourceAmount": 10000,
    "sourceCurrency": "NGN",
    "destinationCurrency": "CNY",
    "destinationCountryCode": "CHN",
    "method": "ALIPAY",
    "beneficiary": {
      "accountName": "Li Wei",
      "accountCurrency": "CNY",
      "alipayId": "user@alipay.com",
      "address": "123 Main St",
      "city": "Beijing",
      "postCode": "100000"
    },
    "narration": "Payment for services",
    "supportingDocument": "https://example.com/invoice.pdf"
  }'
Response includes:
  • id - Save this payout ID for tracking status
  • status - Initial status (PENDING)
  • Conversion details (exchange rate, amounts)
  • payoutRef - Human-readable reference
What happens:
  1. Debit is always from the source currency wallet—your NGN wallet is debited by the total (source amount + fees).
  2. System handles FX conversion automatically
  3. Payout created with status PENDING
Idempotency-Key is required. If the request fails (network error, timeout), retry with the same key + same body. The API will return the original payout (no duplicate created).

6. Track payout status

Query payout status using the payout ID from the initiate response:
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/{payoutId} \
  -H "x-api-key: <SANDBOX_API_KEY>"
Status values (same in API responses and webhooks):
  • PENDING - Payout created or awaiting approval; not yet sent for processing
  • PROCESSING - Payout is being processed (ops, bank, or treasury)
  • SUCCESSFUL - Completed; funds have been sent
  • FAILED - Processing failed (e.g. bank failure)
  • REJECTED - Rejected (e.g. compliance, initiation checks, or bank)
Subscribe to webhooks for real-time status updates:
  1. Activate webhook notifications in your Yala dashboard
  2. Configure your webhook endpoint URL
  3. Receive payout.status.changed.v1 events when status changes
The webhook payload includes the payout id so you can match it with your records.

Complete Example

// 1. Generate idempotency key
const idempotencyKey = crypto.randomUUID();

// 2. Get methods and rates
const methodsResponse = await fetch(
  'https://gateway.staging.useyala.com/v1/payout-api/payouts/methods?sourceCurrency=NGN&destinationCurrency=CNY&destinationCountryCode=CHN',
  {
    headers: { 'x-api-key': apiKey }
  }
);
const { methods, rate } = await methodsResponse.json();
console.log(`Rate: ${rate.rate}, Methods: ${methods.map(m => m.code).join(', ')}`);

// 3. Create payout
const payoutResponse = await fetch(
  'https://gateway.staging.useyala.com/v1/payout-api/payouts/initiate',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Idempotency-Key': idempotencyKey,  // Client-generated
      'x-api-key': apiKey,
    },
    body: JSON.stringify({
      sourceAmount: 10000,
      sourceCurrency: 'NGN',
      destinationCurrency: 'CNY',
      destinationCountryCode: 'CHN',
      method: 'ALIPAY',
      beneficiary: {
        accountName: 'Li Wei',
        accountCurrency: 'CNY',
        alipayId: 'user@alipay.com',
        address: '123 Main St',
        city: 'Beijing',
        postCode: '100000',
      },
      narration: 'Payment for services',
      supportingDocument: 'https://example.com/invoice.pdf',
    }),
  }
);

const payout = await payoutResponse.json();
console.log(`Payout created: ID=${payout.id}, Status=${payout.status}`);

// 4. Save payout.id for tracking
const payoutId = payout.id; // Use this ID to track status

// 5. Check status (or subscribe to webhooks for real-time updates)
const statusResponse = await fetch(
  `https://gateway.staging.useyala.com/v1/payout-api/payouts/${payoutId}`,
  {
    headers: { 'x-api-key': apiKey }
  }
);
const status = await statusResponse.json();
console.log(`Current status: ${status.status}`);

Testing with Postman

Quick start: Import the ready-to-use Postman collection with all payout API endpoints pre-configured at https://docs.useyala.com/resources/postman.json.
The Postman collection includes:
  • All payout API endpoints (pairs, methods, wallets, quote, initiate, get status, add documents)
  • Pre-configured headers (x-api-key, Idempotency-Key)
  • Example request bodies
  • Environment variable templates
Setup:
  1. In Postman, select Import and use https://docs.useyala.com/resources/postman.json
  2. Create environment with:
    • YALA_BASE_URL_LOCAL: https://gateway.staging.useyala.com/v1/payout-api/payouts (sandbox)
    • YALA_PAYOUT_API_KEY: Your API key
  3. Select the environment and start testing

Next steps