curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-001' \
--data '{
"type": "TEMPORARY",
"rail": "NGN_VIRTUAL_ACCOUNT",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"currency": "NGN",
"amount": 50000,
"developer_fee": {
"percentage": "2.5"
},
"settlement_destination": {
"type": "ONCHAIN",
"rate_id": "550e8400-e29b-41d4-a716-446655440000",
"destination_asset": "USDT",
"destination_chain": "BSC",
"destination_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd18"
}
}'
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-002' \
--data '{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDC",
"chain": "BASE",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}'
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-003' \
--data '{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDT",
"chain": "TEMPO",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}'
Funding Accounts
Create a funding account
Create a way for a customer to send NGN or crypto into Daya
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-001' \
--data '{
"type": "TEMPORARY",
"rail": "NGN_VIRTUAL_ACCOUNT",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"currency": "NGN",
"amount": 50000,
"developer_fee": {
"percentage": "2.5"
},
"settlement_destination": {
"type": "ONCHAIN",
"rate_id": "550e8400-e29b-41d4-a716-446655440000",
"destination_asset": "USDT",
"destination_chain": "BSC",
"destination_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd18"
}
}'
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-002' \
--data '{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDC",
"chain": "BASE",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}'
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-003' \
--data '{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDT",
"chain": "TEMPO",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}'
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-001' \
--data '{
"type": "TEMPORARY",
"rail": "NGN_VIRTUAL_ACCOUNT",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"currency": "NGN",
"amount": 50000,
"developer_fee": {
"percentage": "2.5"
},
"settlement_destination": {
"type": "ONCHAIN",
"rate_id": "550e8400-e29b-41d4-a716-446655440000",
"destination_asset": "USDT",
"destination_chain": "BSC",
"destination_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd18"
}
}'
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-002' \
--data '{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDC",
"chain": "BASE",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}'
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: create-funding-account-003' \
--data '{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDT",
"chain": "TEMPO",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}'
Overview
Production supports NGN-to-USDTONCHAIN settlement on BNB Smart Chain (BSC) and Polygon. Before creating the account, confirm that the selected USDT token entry from GET /v1/supported-chains returns withdraw_enabled: true. Sandbox support is unchanged.
Create a funding account for an existing customer. The response includes the public funding account object and the payment details the customer can use once setup succeeds.
To maintain a separate NGN balance for the customer, create a permanent account with settlement_destination.type: CUSTOMER_NGN_BALANCE. Permanent NGN virtual-account deposits remain NGN; confirmed USDC and USDT deposits are converted to NGN. Read the result through GET /v1/customers/{id}/balances.
Permanent NGN funding accounts return provider instructions for Flutterwave and, when enabled, Paystack. Add the customer’s verified bank details and Nigerian phone number through Tier 1 KYC so Paystack can verify the customer. The phone number is optional when Tier 1 is submitted without bank details. Daya evaluates both providers when creating the account, so Paystack can supply the usable instruction while Flutterwave is unavailable. Show the customer any instruction whose status is ACTIVE; do not send a provider in this request.
customer.customer_id is required. This endpoint does not create customers inline.Authentication
string
required
Your active merchant API key with
write scope.string
required
Unique idempotency key for request deduplication
Request Body
string
required
Funding account type. Allowed values:
TEMPORARY, PERMANENT.string
required
Receive rail. Allowed values:
NGN_VIRTUAL_ACCOUNT, CRYPTO_ADDRESS.object
required
Existing customer details. Include
customer_id. For permanent NGN virtual accounts, the customer must have completed Tier 1 KYC.string
Required for
NGN_VIRTUAL_ACCOUNT. Must be NGN.string
Required for
CRYPTO_ADDRESS. Supported values: USDC, USDT.string
Required for
CRYPTO_ADDRESS. Allowed values: APTOS, BASE, BSC, CELO, ETHEREUM, POLYGON, SOLANA, SUI, TEMPO, TRON.Chain availability depends on the asset, environment, and direction. Use GET /v1/supported-chains as the authoritative live source. When enabled in production, TEMPO accepts USDT deposits only; it is not available in Sandbox.integer
Required for temporary NGN virtual accounts. Optional for temporary crypto balance funding, where it is a positive integer estimate in major token units. Accepted only for
TEMPORARY accounts. For temporary NGN virtual accounts, this is the principal amount requested before any payment-provider collection charge. Do not use the request value as the customer’s payment instruction; use amount from the create response.object
Optional fee that your merchant account keeps from each deposit received through this funding account. Omit to use
0%.Show developer_fee properties
Show developer_fee properties
string
required
Percentage of each received deposit that your merchant account keeps. Use a decimal string from
0 to 50. This is a percentage value, not basis points: 0.5 means 0.5%, 2 means 2%, and 50 means 50%.Example: "2.5"settlement_destination
settlement_destination is a nested object. Do not send dotted keys such as settlement_destination.type.
| Field | Type | Required when |
|---|---|---|
type | string | Always. Allowed values depend on the funding account rail and type; see the matrix below. |
rate_id | string | Required for temporary funding accounts: temporary NGN_VIRTUAL_ACCOUNT accounts settling to INTERNAL_BALANCE, NGN_BALANCE, or ONCHAIN, and temporary CRYPTO_ADDRESS accounts settling through NGN_PAYOUT. Do not send it for permanent accounts or temporary crypto balance funding. |
destination_asset | string | rail is NGN_VIRTUAL_ACCOUNT and type is ONCHAIN. Supported values: USDC, USDT. |
destination_chain | string | rail is NGN_VIRTUAL_ACCOUNT and type is ONCHAIN. |
destination_address | string | rail is NGN_VIRTUAL_ACCOUNT and type is ONCHAIN. |
destination_bank | object | rail is CRYPTO_ADDRESS and type is NGN_PAYOUT. Fixed request shape: account_number, bank_code. |
Allowed settlement destination types
rail | Funding account type | Allowed settlement_destination.type values |
|---|---|---|
NGN_VIRTUAL_ACCOUNT | TEMPORARY | INTERNAL_BALANCE, NGN_BALANCE, ONCHAIN |
NGN_VIRTUAL_ACCOUNT | PERMANENT | INTERNAL_BALANCE, NGN_BALANCE, CUSTOMER_NGN_BALANCE, ONCHAIN |
CRYPTO_ADDRESS | TEMPORARY | NGN_PAYOUT, INTERNAL_BALANCE |
CRYPTO_ADDRESS | PERMANENT | INTERNAL_BALANCE, CUSTOMER_NGN_BALANCE, NGN_PAYOUT |
NGN_PAYOUT for NGN_VIRTUAL_ACCOUNT funding accounts, and do not send ONCHAIN for CRYPTO_ADDRESS funding accounts.
CUSTOMER_NGN_BALANCE is available only for permanent accounts. On an NGN virtual account it retains the deposit for the funding account’s customer. On a permanent USDC or USDT crypto account it converts the confirmed stablecoin deposit to NGN and credits that customer’s balance. This differs from NGN_BALANCE, which credits the merchant’s NGN withdrawal balance.
destination_bank
| Field | Type | Required |
|---|---|---|
account_number | string | Yes |
bank_code | string | Yes |
destination_bank, fetch supported banks with GET /v1/banks, then verify the account with POST /v1/banks/resolve. Use the verified bank_code and account_number in the funding account request. Do not send account_name; Daya returns the resolved account name in the funding account response.
Settlement Destination Shapes
Internal balance
{
"settlement_destination": {
"type": "INTERNAL_BALANCE",
"rate_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Customer NGN balance (permanent account)
{
"settlement_destination": {
"type": "CUSTOMER_NGN_BALANCE"
}
}
Temporary crypto balance funding (
CRYPTO_ADDRESS with INTERNAL_BALANCE) must omit rate_id. Other temporary funding accounts require rate_id, and the rate is locked for the account’s validity window. For permanent funding accounts, omit rate_id; the rate is applied when each deposit is processed.NGN virtual account to USDT on BSC
{
"settlement_destination": {
"type": "ONCHAIN",
"rate_id": "550e8400-e29b-41d4-a716-446655440000",
"destination_asset": "USDT",
"destination_chain": "BSC",
"destination_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd18"
}
}
Crypto address to NGN payout settlement
{
"settlement_destination": {
"type": "NGN_PAYOUT",
"rate_id": "550e8400-e29b-41d4-a716-446655440000",
"destination_bank": {
"account_number": "0123456789",
"bank_code": "058"
}
}
}
NGN_PAYOUT, destination_bank has a fixed request shape: account_number and bank_code. Get the supported bank first, resolve the account, then send the verified details.
Request Examples
{
"type": "PERMANENT",
"rail": "NGN_VIRTUAL_ACCOUNT",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"currency": "NGN",
"settlement_destination": {
"type": "CUSTOMER_NGN_BALANCE"
}
}
{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDC",
"chain": "BASE",
"settlement_destination": {
"type": "CUSTOMER_NGN_BALANCE"
}
}
{
"type": "TEMPORARY",
"rail": "NGN_VIRTUAL_ACCOUNT",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"currency": "NGN",
"amount": 50000,
"developer_fee": {
"percentage": "2.5"
},
"settlement_destination": {
"type": "ONCHAIN",
"rate_id": "550e8400-e29b-41d4-a716-446655440000",
"destination_asset": "USDC",
"destination_chain": "BASE",
"destination_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd18"
}
}
{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDC",
"chain": "BASE",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}
{
"type": "PERMANENT",
"rail": "CRYPTO_ADDRESS",
"customer": {
"customer_id": "650e8400-e29b-41d4-a716-446655440000"
},
"asset": "USDT",
"chain": "TEMPO",
"settlement_destination": {
"type": "INTERNAL_BALANCE"
}
}
Create a separate permanent crypto funding account for each asset and chain combination you offer. Accounts using
CUSTOMER_NGN_BALANCE for the same customer all credit that customer’s NGN balance. Read it with GET /v1/customers/{id}/balances.Temporary crypto balance funding
CreateTEMPORARY + CRYPTO_ADDRESS + INTERNAL_BALANCE for a customer who belongs to your merchant account, with asset: USDT or USDC. Use ETHEREUM, BSC, SOLANA, BASE, or POLYGON, subject to the environment’s deposit support. Sandbox funding uses ETHEREUM. Omit currency, rate_id, and all payout destination fields. You can include an integer amount estimate and a decimal string developer_fee.percentage.
curl --request POST \
--url https://api.daya.co/v1/funding-accounts \
--header 'X-Api-Key: YOUR_API_KEY' \
--header 'X-Idempotency-Key: temporary-crypto-funding-001' \
--header 'Content-Type: application/json' \
--data '{
"type": "TEMPORARY",
"rail": "CRYPTO_ADDRESS",
"customer": { "customer_id": "650e8400-e29b-41d4-a716-446655440000" },
"asset": "USDC",
"chain": "ETHEREUM",
"settlement_destination": { "type": "INTERNAL_BALANCE" }
}'
201 response; the address is illustrative test data:
{
"object": "funding_account",
"id": "750e8400-e29b-41d4-a716-446655440000",
"type": "TEMPORARY",
"status": "ACTIVE",
"rail": "CRYPTO_ADDRESS",
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"asset": "USDC",
"chain": "ETHEREUM",
"developer_fee": { "percentage": "0" },
"settlement_destination": {
"type": "INTERNAL_BALANCE",
"expires_at": "2026-10-11T12:30:00Z"
},
"instructions": [
{
"type": "CRYPTO_ADDRESS",
"status": "ACTIVE",
"address": "0x1111111111111111111111111111111111111111",
"chain": "ETHEREUM",
"expires_at": "2026-10-11T12:30:00Z",
"failure": null,
"required_fields": []
}
],
"expires_at": "2026-10-11T12:30:00Z",
"created_at": "2026-10-11T12:00:00Z",
"updated_at": "2026-10-11T12:00:00Z"
}
amount is omitted when the request omits it. Ask the payer to pay within the 30-minute window and stop showing payment instructions at expires_at. Never reuse an address after expires_at; a later payment may not reach this account. A deposit with FUNDING_ACCOUNT_EXPIRED requires review. Both assets credit your USD balance. Read payment timing, fees, and retries.
If the service is unavailable, creation can return 503 FEATURE_NOT_ENABLED or 503 PROVIDER_UNAVAILABLE. Invalid combinations return 400; a missing or other-merchant customer returns 404.
Response
Returns afunding_account object. For NGN funding accounts, the bank account the customer should pay into is returned in instructions.
Read provider, status, provider_availability, and bank_name on every provider-backed instruction. provider identifies the funding provider; bank_name is the bank the customer pays. These values may be different.
bank_code is included when the provider returns it or Daya can safely resolve it from the assigned bank_name. If it is omitted, use the returned bank_name and account_number; do not substitute a code from the request.
Every permanent NGN funding account response includes Flutterwave and Paystack. If a Paystack account has not been requested because the customer’s bank details are missing, the Paystack entry is REQUIRES_INFORMATION and lists the fields you must submit. It has no virtual account number until Daya attempts provisioning and the provider returns account details. Show only ACTIVE instructions with account details to the customer.
For a temporary NGN funding account, the response
amount is the exact amount the customer must transfer. It may differ from the request amount because the payment provider can add a collection charge. Display and transfer the response value exactly; do not recalculate or round it.NGN funding account response
{
"object": "funding_account",
"id": "750e8400-e29b-41d4-a716-446655440000",
"type": "TEMPORARY",
"status": "ACTIVE",
"rail": "NGN_VIRTUAL_ACCOUNT",
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"currency": "NGN",
"amount": "50000.50",
"developer_fee": {
"percentage": "2.5"
},
"settlement_destination": {
"type": "ONCHAIN",
"rate_id": "550e8400-e29b-41d4-a716-446655440000",
"destination_asset": "USDC",
"destination_chain": "BASE",
"destination_address": "0x742d35cc6634c0532925a3b844bc9e7595f2bd18"
},
"instructions": [
{
"type": "NGN_VIRTUAL_ACCOUNT",
"provider": "FLUTTERWAVE",
"provider_availability": {
"status": "DEGRADED",
"message": "This provider is experiencing funding-account delays."
},
"status": "ACTIVE",
"bank_name": "Wema Bank",
"bank_code": "035",
"account_number": "1234567890",
"account_name": "Daya - Ada Lovelace",
"currency": "NGN"
}
],
"created_at": "2026-01-05T15:04:05Z",
"updated_at": "2026-01-05T15:04:10Z"
}
Provider availability
For provider-backed payment details,provider_availability describes the provider’s current funding-account service state:
| Field | Meaning |
|---|---|
status | Current provider state: OPERATIONAL, DEGRADED, or UNAVAILABLE. |
message | A user-facing explanation when service is disrupted. It is omitted when the provider is operational. You can show this message to affected customers. |
| State | Meaning |
|---|---|
OPERATIONAL | The provider is operating normally and accepts new requests. |
DEGRADED | The provider accepts new requests but is working with a known delay or limitation. Read message for current guidance. |
UNAVAILABLE | The provider is temporarily unavailable for new requests. Read message for the current guidance. |
UNAVAILABLE but Paystack can accept the request and the customer has verified bank details, creation continues through Paystack. Flutterwave remains in the returned instructions array with provider_availability.status: UNAVAILABLE. The same applies in reverse when Paystack is unavailable and Flutterwave can create the account.
Daya returns HTTP 503 with error code PROVIDER_UNAVAILABLE only when neither configured permanent NGN provider can accept the new request. Temporary NGN accounts and crypto accounts use one provider and return this error when that provider is unavailable.
For crypto funding accounts, asset identifies the stablecoin the address should receive, chain identifies the network, and instructions contains the wallet address.
Permanent NGN response
{
"object": "funding_account",
"id": "750e8400-e29b-41d4-a716-446655440000",
"type": "PERMANENT",
"status": "ACTIVE",
"rail": "NGN_VIRTUAL_ACCOUNT",
"customer_id": "650e8400-e29b-41d4-a716-446655440000",
"currency": "NGN",
"instructions": [
{
"type": "NGN_VIRTUAL_ACCOUNT",
"provider": "FLUTTERWAVE",
"provider_availability": {
"status": "UNAVAILABLE",
"message": "Flutterwave funding accounts are temporarily unavailable."
},
"status": "PENDING",
"currency": "NGN",
"required_fields": [],
"failure": null
},
{
"type": "NGN_VIRTUAL_ACCOUNT",
"provider": "PAYSTACK",
"provider_availability": {
"status": "OPERATIONAL"
},
"status": "ACTIVE",
"bank_name": "Wema Bank",
"bank_code": "035",
"account_number": "9876543210",
"account_name": "Ada Lovelace",
"currency": "NGN",
"required_fields": [],
"failure": null
}
]
}
PENDING, while its current service state is provider_availability.status: UNAVAILABLE; the Paystack instruction is ACTIVE and can be shown to the customer. Show only instructions with status: ACTIVE. For a pending account that becomes usable after Paystack verification, wait for funding_account.active. Later changes to an instruction are sent as funding_account.updated.
If an instruction is REQUIRES_INFORMATION, submit the fields listed in required_fields, then call this endpoint again with the same account details. Daya returns the existing live permanent funding account with its latest instructions.