> ## 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.

# Payment Methods & Requirements

> Supported payment methods and required fields for each payment corridor

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>;
};

Cadana supports multiple payment methods depending on the destination country and currency. Each method has specific field requirements for creating beneficiaries. Use the discovery endpoints to determine what's available for a given corridor at runtime.

<Note>
  Available corridors are configured per business. If you need access to a corridor that isn't enabled on your account, contact the Cadana team.
</Note>

***

## Discovering Available Methods

Call [`GET /v1/payment-methods`](/api-reference/payments/resources/get-payment-methods) to list payment methods available for a country:

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

**Response:**

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

Call [`GET /v1/providers`](/api-reference/payments/resources/get-payout-providers) to list supported banks and mobile money providers:

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

**Response:**

```json theme={null}
{
  "data": [
    {
      "code": "01",
      "name": "Example Bank",
      "countryCode": "KE",
      "currency": "KES",
      "type": "bank"
    }
  ]
}
```

Use the returned `code` as the `bankCode` (or `providerCode` for mobile money) when creating beneficiaries.

### Resolve a Bank Provider

If you have a bank code, SWIFT code, or ACH routing number and need to look up the corresponding bank name and details, use [`GET /v1/providers/resolve`](/api-reference/payments/resources/resolve-bank-provider):

<ApiExample method="GET" path="/v1/providers/resolve" params={{ code: "341", currency: "BRL", paymentMethod: "bank" }} reference="/api-reference/payments/resources/resolve-bank-provider" />

The `paymentMethod` parameter determines how the code is resolved:

| `paymentMethod` | Resolves                                                     |
| :-------------- | :----------------------------------------------------------- |
| `swift`         | 8 or 11-character SWIFT/BIC code                             |
| `ach`           | 9-digit US ACH routing number                                |
| `bank`          | Bank code from Cadana's provider list for the given currency |

***

## Using the Requirements API

The requirements endpoint returns a [JSON Schema (Draft-07)](https://json-schema.org/draft-07) describing all mandatory and optional fields for a given corridor:

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

### Understanding the Response

Here's an example response for Colombia (COP, bank transfer):

```json theme={null}
{
  "type": "object",
  "additionalProperties": false,
  "required": ["accountName", "accountNumber", "bankCode", "bankName", "accountType", "beneficiaryId", "address", "email"],
  "properties": {
    "accountName": { "type": "string", "maxLength": 60 },
    "accountNumber": {
      "type": "string",
      "pattern": "^[0-9]{9,16}$",
      "description": "9 - 16-digit Colombian account number"
    },
    "accountType": { "type": "string", "enum": ["Checking", "Saving"] },
    "bankCode": {
      "type": "string",
      "pattern": "^[A-Za-z0-9]{1,11}$",
      "description": "1-11 alphanumeric bank code"
    },
    "bankName": { "type": "string", "maxLength": 255 },
    "email": { "type": "string", "format": "email", "maxLength": 100 },
    "beneficiaryId": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "value"],
      "properties": {
        "type": { "type": "string", "enum": ["NIT", "CC", "CE", "TI", "PASS"] },
        "value": { "type": "string" }
      },
      "allOf": [
        {
          "if": { "properties": { "type": { "const": "NIT" } } },
          "then": { "properties": { "value": { "pattern": "^\\d{9,11}$" } } }
        },
        {
          "if": { "properties": { "type": { "const": "CC" } } },
          "then": { "properties": { "value": { "pattern": "^\\d{6,10}$" } } }
        },
        {
          "if": { "properties": { "type": { "const": "CE" } } },
          "then": { "properties": { "value": { "pattern": "^[A-Za-z0-9]{5,12}$" } } }
        },
        {
          "if": { "properties": { "type": { "const": "TI" } } },
          "then": { "properties": { "value": { "pattern": "^\\d{8,11}$" } } }
        },
        {
          "if": { "properties": { "type": { "const": "PASS" } } },
          "then": { "properties": { "value": { "pattern": "^[A-Za-z0-9]{5,15}$" } } }
        }
      ]
    },
    "address": {
      "type": "object",
      "additionalProperties": false,
      "required": ["line1", "city", "countryCode"],
      "properties": {
        "line1": { "type": "string", "maxLength": 70 },
        "line2": { "type": "string", "maxLength": 70 },
        "city": { "type": "string", "maxLength": 50 },
        "postalCode": { "type": "string", "maxLength": 10 },
        "state": { "type": "string", "maxLength": 50 },
        "countryCode": { "const": "CO" }
      }
    }
  }
}
```

Key parts of the schema:

| Keyword                | What it tells you                                                                              |
| :--------------------- | :--------------------------------------------------------------------------------------------- |
| `required`             | Fields that must be present                                                                    |
| `properties`           | Available fields with their types and constraints                                              |
| `pattern`              | Regex the value must match (e.g., `^[0-9]{9,16}$` for a 9-16 digit number)                     |
| `enum`                 | Allowed values (e.g., `["Checking", "Saving"]`)                                                |
| `const`                | Fixed value (e.g., `"CO"` for country code)                                                    |
| `maxLength`            | Maximum string length                                                                          |
| `format`               | Semantic format hint (e.g., `email`)                                                           |
| `additionalProperties` | When `false`, no extra fields beyond those in `properties` are accepted                        |
| `allOf` / `if-then`    | Conditional rules — e.g., if `beneficiaryId.type` is `"NIT"`, then `value` must be 9-11 digits |

### Building Dynamic Forms

You can use these schemas to dynamically generate beneficiary creation forms that automatically adapt to each corridor's requirements — no hardcoded field logic needed.

```
1. User selects country, currency, and payment method
2. Your app calls GET /v1/payment-requirements
3. Render form fields from the schema (required, types, enums, validation)
4. Validate input client-side against the schema before submitting
5. POST /v1/beneficiaries with the validated data
```

This approach means your UI automatically adapts when Cadana adds new corridors or updates field requirements, without code changes. Standard JSON Schema libraries (like [Ajv](https://ajv.js.org/) for JavaScript or [jsonschema](https://pypi.org/project/jsonschema/) for Python) can handle validation directly from the response.

<Info>
  Always use [`GET /v1/payment-requirements`](/api-reference/payments/resources/payment-corridor-requirements) as the source of truth. The examples below illustrate common patterns to help you plan your integration — they are not exhaustive.
</Info>

***

## Bank Transfer

Sends funds directly to a recipient's bank account through local clearing networks.

Set `preferredMethod` to `"bank"` and provide bank details in the `bank` object:

```json theme={null}
{
  "paymentDetails": {
    "preferredMethod": "bank",
    "bank": {
      "accountName": "John Doe",
      "accountNumber": "0123456789",
      "bankCode": "058",
      "bankName": "Example Bank"
    }
  }
}
```

Required fields vary by corridor. Bank transfer corridors range from 4 required fields to 10+, depending on the country's regulatory and clearing requirements.

### Simple — Nigeria (NGN)

Many corridors (e.g., NG, KE, GH, MX) require only basic bank details:

| Field           | Required | Format           | Notes                                                                                         |
| :-------------- | :------- | :--------------- | :-------------------------------------------------------------------------------------------- |
| `accountName`   | Yes      | String (max 60)  | Must match bank records                                                                       |
| `accountNumber` | Yes      | String (max 255) | Bank-specific format (e.g., 10-digit NUBAN for Nigeria)                                       |
| `bankCode`      | Yes      | String (max 255) | Bank code — use [`GET /v1/providers`](/api-reference/payments/resources/get-payout-providers) |
| `bankName`      | Yes      | String (max 255) | Bank name                                                                                     |

### Medium — United Kingdom (GBP)

Some corridors add fields like `sortCode`, `routingNumber`, or `iban` depending on the local clearing system:

| Field           | Required | Format           | Notes               |
| :-------------- | :------- | :--------------- | :------------------ |
| `accountName`   | Yes      | String (max 60)  | Account holder name |
| `accountNumber` | Yes      | 1-8 digits       | UK account number   |
| `bankCode`      | Yes      | String (max 255) | Bank code           |
| `bankName`      | Yes      | String (max 255) | Bank name           |
| `sortCode`      | Yes      | 6 digits         | Sort code           |

Other examples of this pattern: SEPA (adds `iban`, `beneficiaryAddress`), Canada (adds `sortCode`, `address`).

### Complex — Colombia (COP)

Corridors like Colombia, India, South Africa, and Peru require a combination of beneficiary identification, address, contact details, and conditional validation:

| Field                 | Required | Format                             | Notes                                                         |
| :-------------------- | :------- | :--------------------------------- | :------------------------------------------------------------ |
| `accountName`         | Yes      | String (max 60)                    | Account holder name                                           |
| `accountNumber`       | Yes      | 9-16 digits                        | Colombian account number                                      |
| `bankCode`            | Yes      | String (1-11 chars)                | Alphanumeric bank code                                        |
| `bankName`            | Yes      | String (max 255)                   | Bank name                                                     |
| `accountType`         | Yes      | `Checking` or `Saving`             | Account type                                                  |
| `beneficiaryId.type`  | Yes      | `NIT`, `CC`, `CE`, `TI`, or `PASS` | ID type                                                       |
| `beneficiaryId.value` | Yes      | String                             | ID number (format depends on type — see schema `allOf` rules) |
| `email`               | Yes      | Email (max 100)                    | Recipient email                                               |
| `address.line1`       | Yes      | String (max 70)                    | Street address                                                |
| `address.city`        | Yes      | String (max 50)                    | City                                                          |
| `address.countryCode` | Yes      | `CO`                               | Country code                                                  |

India (INR) follows this pattern: the corridor schema puts the IFSC code in `sortCode`, requires `ownerType` as `Individual` or `Business` (capitalized, per the schema's enum), and requires `email` and `phoneNumber`.

***

## ACH

Send funds to US bank accounts via the Automated Clearing House network.

Set `preferredMethod` to `"ach"` and provide details in the `ach` object:

```json theme={null}
{
  "paymentDetails": {
    "preferredMethod": "ach",
    "ach": {
      "accountName": "Jane Smith",
      "accountNumber": "123456789",
      "routingNumber": "000000000",
      "accountType": "Checking",
      "bankName": "Example Bank",
      "address": {
        "line1": "123 Main St",
        "city": "New York",
        "state": "NY",
        "postalCode": "10001",
        "countryCode": "US"
      }
    }
  }
}
```

***

## Mobile Money

Send funds directly to mobile money wallets. Widely used across Sub-Saharan African markets.

Set `preferredMethod` to `"momo"` and provide details in the `momo` object:

```json theme={null}
{
  "paymentDetails": {
    "preferredMethod": "momo",
    "momo": {
      "accountName": "John Doe",
      "phoneNumber": {
        "number": "700000000",
        "countryCode": "254"
      },
      "providerCode": "MPESA"
    }
  }
}
```

Use [`GET /v1/providers`](/api-reference/payments/resources/get-payout-providers) to get the available providers for a given country.

| Field                     | Required | Format | Notes                                                                                             |
| :------------------------ | :------- | :----- | :------------------------------------------------------------------------------------------------ |
| `accountName`             | Yes      | String | Account holder name                                                                               |
| `phoneNumber.number`      | Yes      | String | Phone number                                                                                      |
| `phoneNumber.countryCode` | Yes      | String | Country dialing code                                                                              |
| `provider`                | Yes      | String | Provider name (e.g., `mpesa`)                                                                     |
| `providerCode`            | Yes      | String | Provider code — use [`GET /v1/providers`](/api-reference/payments/resources/get-payout-providers) |

***

## Proxy

Proxy-based payment methods use an identifier (email, phone, or national ID) instead of traditional bank details. Used for corridors like Brazil Pix.

Set `preferredMethod` to `"proxy"` and provide details in the `proxy` object:

```json theme={null}
{
  "paymentDetails": {
    "preferredMethod": "proxy",
    "proxy": {
      "type": "email",
      "value": "recipient@example.com"
    }
  }
}
```

| Field   | Required | Format                        | Notes                |
| :------ | :------- | :---------------------------- | :------------------- |
| `type`  | Yes      | `email`, `mobile`, or `other` | Proxy key type       |
| `value` | Yes      | String (max 255)              | The proxy identifier |

Some corridors require additional fields like `beneficiaryId` or `address`. Use [`GET /v1/payment-requirements`](/api-reference/payments/resources/payment-corridor-requirements) to check the exact requirements for each corridor.

***

## SWIFT

For corridors without local payment rails, Cadana routes payments via SWIFT. Covers 180+ countries (USD and EUR).

Set `preferredMethod` to `"swift"` and provide details in the `swift` object. SWIFT payments typically require more information than local transfers, including the SWIFT/BIC code, recipient address, and either `iban` or `accountNumber` depending on the destination.

| Field           | Required | Format           | Notes                                                            |
| :-------------- | :------- | :--------------- | :--------------------------------------------------------------- |
| `accountName`   | Yes      | String (max 60)  | Account holder name                                              |
| `accountNumber` | Yes      | String (max 255) | Account number                                                   |
| `swiftCode`     | Yes      | 8 or 11 chars    | SWIFT/BIC code                                                   |
| `bankName`      | Yes      | String (max 255) | Bank name                                                        |
| `currency`      | Yes      | `USD` or `EUR`   | Payment currency                                                 |
| `iban`          | Yes      | String           | International Bank Account Number                                |
| `address`       | Yes      | Object           | Recipient address (`line1`, `city`, `postalCode`, `countryCode`) |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Making a Payment" icon="route" href="/payments/making-a-payment">
    Step-by-step payout integration
  </Card>

  <Card title="Supported Countries" icon="globe" href="/resources/supported-countries">
    Full list of supported countries and payment rails
  </Card>
</CardGroup>
