> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cadanapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payout

> Send funds from wallets to beneficiaries worldwide

export const ApiExample = ({method = "GET", path, params, body, reference, tenantKey}) => {
  const baseUrl = "https://api.cadanapay.com";
  const query = params ? "?" + Object.entries(params).map(([k, v]) => `${k}=${v}`).join("&") : "";
  const url = `${baseUrl}${path}${query}`;
  const isPlatformPath = (/^\/(v1\/)?platform(\/|$)/).test(path || "");
  const includeTenantKey = tenantKey === undefined ? !isPlatformPath : tenantKey;
  let curl = `curl -X ${method} '${url}' \\\n  -H 'Authorization: Bearer YOUR_API_KEY'`;
  if (includeTenantKey) {
    curl += ` \\\n  -H 'X-MultiTenantKey: YOUR_BUSINESS_TENANT_KEY'`;
  }
  if (body) {
    const formatted = JSON.stringify(body, null, 2);
    curl += ` \\\n  -H 'Content-Type: application/json' \\\n  -d '${formatted}'`;
  }
  return <div>
      <CodeBlock language="bash" filename="bash" wrap>
        {curl}
      </CodeBlock>
      {reference && <div style={{
    marginTop: "-0.5rem",
    marginBottom: "1rem"
  }}>
          <a href={reference} style={{
    fontSize: "0.875rem"
  }}>
            Try it in the playground →
          </a>
        </div>}
    </div>;
};

Workers can send funds from their wallet to saved beneficiaries — bank accounts, mobile money, e-wallets, cards, and more across 100+ countries.

***

## Payment Methods & Requirements

Before adding a beneficiary, check which payment methods are available for the destination country and what fields are required.

### List available payment methods

<ApiExample method="GET" path="/v1/payment-methods" params={{ countryCode: "BR" }} reference="/api-reference/payments/resources/get-payment-methods" />

**Response:**

```json theme={null}
[
  {
    "country": "BR",
    "countryName": "Brazil",
    "paymentMethods": [
      { "type": "bank", "currency": "BRL", "status": "active" },
      { "type": "proxy", "currency": "BRL", "status": "active" },
      { "type": "swift", "currency": "BRL", "status": "active" }
    ]
  }
]
```

The response is an array — one entry per country matching the query.

### Get field requirements for a corridor

Each country + currency + payment method combination has specific field requirements. Use the payment requirements endpoint to get the JSON schema for the `paymentDetails` object.

<ApiExample method="GET" path="/v1/payment-requirements" params={{ countryCode: "CO", currency: "COP", paymentMethod: "bank" }} reference="/api-reference/payments/resources/payment-corridor-requirements" />

This returns a JSON Schema describing which fields are required, valid values for enums (e.g. bank codes), and validation rules.

### Get payout providers

For countries with multiple bank or mobile money providers, retrieve the list of supported providers.

<ApiExample method="GET" path="/v1/providers" params={{ countryCode: "BR" }} reference="/api-reference/payments/resources/get-payout-providers" />

### Supported payment methods

| Method   | Description         | Use case                   |
| :------- | :------------------ | :------------------------- |
| `bank`   | Local bank transfer | Most countries             |
| `momo`   | Mobile money        | Africa (M-Pesa, MTN, etc.) |
| `ach`    | ACH transfer        | United States              |
| `swift`  | SWIFT/wire transfer | International              |
| `wallet` | Cadana wallet       | User-to-user transfers     |
| `crypto` | Crypto wallet       | BTC, USDC, ETH, etc.       |
| `proxy`  | Proxy payment       | UPI (India), etc.          |

***

## Beneficiaries

A beneficiary is a saved payment destination. Each beneficiary has a payment method and is scoped to a specific user.

### Add a beneficiary

<ApiExample method="POST" path="/v1/users/{userId}/beneficiaries" body={{ name: "John Doe", email: "john.doe@example.com", countryCode: "KE", currency: "KES", paymentDetails: { preferredMethod: "momo", momo: { accountName: "John Doe", phoneNumber: { countryCode: "254", number: "700000000" }, providerCode: "MPESA", provider: "M-Pesa", currency: "KES" } } }} reference="/api-reference/wallets/beneficiaries/create-beneficiary" />

**Response:**

```json theme={null}
{
  "id": "7a7f80a6-1665-4f64-9ef3-d5f90f8f309b"
}
```

### Manage beneficiaries

| Operation | Endpoint                                                                                                             |
| :-------- | :------------------------------------------------------------------------------------------------------------------- |
| List      | [`GET /v1/users/{userId}/beneficiaries`](/api-reference/wallets/beneficiaries/list-beneficiaries)                    |
| Get       | [`GET /v1/users/{userId}/beneficiaries/{beneficiaryId}`](/api-reference/wallets/beneficiaries/get-beneficiary)       |
| Delete    | [`DELETE /v1/users/{userId}/beneficiaries/{beneficiaryId}`](/api-reference/wallets/beneficiaries/delete-beneficiary) |

***

## Check Fees, Timelines & Limits

Before creating a transaction, look up the fees, delivery timeline, and transfer limits that apply to the user's corridor.

### Fetch the payout catalog

Pass `sourceCurrency` to quote every corridor's fee in that currency. It defaults to `USD` when omitted.

<ApiExample method="GET" path="/v1/users/{userId}/fees" params={{ sourceCurrency: "USD" }} reference="/api-reference/wallets/transactions/get-user-fees" />

To quote the catalog in a different currency:

<ApiExample method="GET" path="/v1/users/{userId}/fees" params={{ sourceCurrency: "EUR" }} reference="/api-reference/wallets/transactions/get-user-fees" />

### Get a concrete estimate

Supply `paymentMethod` and `destinationCurrency` to receive an `estimate` block alongside the catalog — a per-transaction fee, delivery ETA, and transfer limits for the requested corridor. Add `destinationCountry` when several countries share a currency (e.g. USD sent to Ecuador vs. USD sent to El Salvador) so the estimate resolves to the right country, and `sourceAmount` to resolve percentage-based fees into a concrete amount.

<ApiExample method="GET" path="/v1/users/{userId}/fees" params={{ sourceCurrency: "USD", paymentMethod: "bank", destinationCurrency: "AUD", destinationCountry: "AU", sourceAmount: "100" }} reference="/api-reference/wallets/transactions/get-user-fees" />

**Response:**

```json theme={null}
{
  "data": {
    "sourceCurrency": "USD",
    "payouts": [
      {
        "paymentMethod": "bank",
        "destinationCurrency": "AUD",
        "destinationCountry": "AU",
        "fee": { "type": "fixed", "value": 1, "min": 0, "max": 0 },
        "feeCurrency": "USD",
        "timeline": { "minDays": 1, "maxDays": 2, "businessDaysOnly": true }
      }
    ],
    "estimate": {
      "paymentMethod": "bank",
      "destinationCurrency": "AUD",
      "destinationCountry": "AU",
      "fee": { "value": "1.00", "currency": "USD" },
      "timeline": {
        "minDays": 1,
        "maxDays": 2,
        "businessDaysOnly": true,
        "estimatedArrival": "Apr 24, 2026 (excluding holidays)"
      },
      "limits": { "min": "2", "max": "20000", "currency": "AUD" }
    }
  }
}
```

<Note>
  `data.payouts` is always the full, unfiltered catalog — query parameters only shape the `estimate` block. `fee.type` is either `fixed` (denominated in `feeCurrency`) or `percentage` (a rate, e.g. `1.5` = 1.5%).
</Note>

***

## Get an FX Quote

Before creating a transaction, get an FX quote to lock in the conversion rate. Quotes are temporary — use the returned `id` as the `quoteId` when creating the transaction.

<ApiExample method="POST" path="/v1/fx-quotes" body={{ from: "USD", to: "PHP" }} reference="/api-reference/payments/fx/create-fx-quote" />

**Response:**

```json theme={null}
{
  "id": "57c74c5d-38a0-41e7-a19e-161f16dc4898",
  "from": "USD",
  "to": "PHP",
  "rate": "56.1234",
  "expirationTimestamp": "2025-05-29T21:42:52Z"
}
```

<Note>
  Quotes expire — check `expirationTimestamp` and request a new quote if the previous one has expired.
</Note>

<Note>
  A quote is required for **every** payout, including same-currency ones. For a same-currency payout (e.g., a USD wallet to a US bank account), request a quote with `from` and `to` set to the same currency — the rate is `1`.
</Note>

***

## Create a Transaction

Send funds from the user's wallet to a beneficiary. You can specify either a destination amount or a source amount — Cadana handles FX conversion using the quote rate.

### Send a specific destination amount

Send exactly 500 PHP to the beneficiary. Cadana deducts the equivalent USD from the wallet.

<ApiExample method="POST" path="/v1/users/{userId}/transactions" body={{ type: "payout", beneficiaryId: "c871b333-e129-409c-aabd-7cfb55a967cc", quoteId: "57c74c5d-38a0-41e7-a19e-161f16dc4898", amount: { value: "500.00", currency: "PHP" }, sourceCurrency: "USD", reference: "3f70be8e-426f-4e89-b883-9c97a1c334d5" }} reference="/api-reference/wallets/transactions/create-transaction" />

### Send a specific source amount

Send 10 USD worth of the destination currency to the beneficiary.

<ApiExample method="POST" path="/v1/users/{userId}/transactions" body={{ type: "payout", beneficiaryId: "c871b333-e129-409c-aabd-7cfb55a967cc", quoteId: "57c74c5d-38a0-41e7-a19e-161f16dc4898", sourceAmount: { value: "10.00", currency: "USD" }, reference: "7a7f80a6-1665-4f64-9ef3-d5f90f8f309b" }} reference="/api-reference/wallets/transactions/create-transaction" />

**Response:**

```json theme={null}
{
  "id": "d0137ede-7df1-4a54-8206-b3ab7b03876f"
}
```

### Transaction fields

| Field                       | Required | Description                                                                         |
| :-------------------------- | :------- | :---------------------------------------------------------------------------------- |
| `type`                      | Yes      | `payout`                                                                            |
| `beneficiaryId`             | Yes      | The beneficiary to send to                                                          |
| `quoteId`                   | Yes      | FX quote ID from [`POST /v1/fx-quotes`](/api-reference/payments/fx/create-fx-quote) |
| `amount` + `sourceCurrency` | One of   | Destination amount — send exactly this amount in the destination currency           |
| `sourceAmount`              | One of   | Source amount — deduct exactly this amount from the wallet                          |
| `reference`                 | Yes      | Your unique reference for idempotency. Must be a UUID.                              |

***

## Track the Transaction

<ApiExample method="GET" path="/v1/users/{userId}/transactions/d0137ede-7df1-4a54-8206-b3ab7b03876f" reference="/api-reference/wallets/transactions/get-transaction" />

**Response:**

```json theme={null}
{
  "id": "d0137ede-7df1-4a54-8206-b3ab7b03876f",
  "type": "payout",
  "beneficiaryId": "c871b333-e129-409c-aabd-7cfb55a967cc",
  "quoteId": "57c74c5d-38a0-41e7-a19e-161f16dc4898",
  "amount": { "value": "500.00", "currency": "PHP" },
  "sourceAmount": { "value": "9.00", "currency": "USD" },
  "feeAmount": { "value": "0.10", "currency": "USD" },
  "fxRate": "56.1234",
  "reference": "3f70be8e-426f-4e89-b883-9c97a1c334d5",
  "status": "success",
  "createdTimestamp": 1748478276,
  "lastUpdatedTimestamp": 1748478276
}
```

### Transaction statuses

| Status       | Description                                 |
| :----------- | :------------------------------------------ |
| `initiated`  | Transaction created, processing has started |
| `processing` | Funds are being sent to the beneficiary     |
| `success`    | Funds delivered                             |
| `failed`     | Transaction failed                          |

`feeAmount` is omitted when no fee applies to the corridor.

### List all transactions

<ApiExample method="GET" path="/v1/users/{userId}/transactions" reference="/api-reference/wallets/transactions/list-transactions" />

Filter by `reference` or `type` using query parameters.

***

## Webhook Events

Subscribe to transaction events for real-time status updates:

| Event                   | Description                                    |
| :---------------------- | :--------------------------------------------- |
| `transaction.initiated` | Transaction created and processing has started |
| `transaction.succeeded` | Funds delivered to the beneficiary             |
| `transaction.failed`    | Transaction failed                             |

See [Events](/reference/events) for webhook payloads and [Webhooks](/reference/webhooks) to configure your endpoint.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Global Wallets" icon="wallet" href="/wallets/overview">
    Wallet product overview
  </Card>

  <Card title="Virtual Accounts" icon="building-columns" href="/wallets/virtual-accounts">
    Fund wallets via dedicated ACH accounts
  </Card>

  <Card title="Wallets API Reference" icon="code" href="/api-reference/wallets">
    Full API documentation
  </Card>
</CardGroup>
