Skip to main content

Overview

A funding account is the API resource that powers onramps and offramps. It gives a customer either an NGN virtual account or a crypto address, and lets you control where the money settles after it arrives. Funding accounts are scoped to one customer and one rail:

What You Can Build

Use funding accounts to create the receive flow you need: For example, if you want to give a customer a reusable wallet address to collect USDC and keep the funds in your Daya balance, create a PERMANENT crypto funding account with settlement_destination.type: INTERNAL_BALANCE.
Reusable crypto address to Daya balance
The account or address the customer should pay into is returned in instructions. For NGN, instructions contains the bank account details:
provider identifies the funding provider. bank_name is the bank the customer pays. These values may be different, and two providers may return accounts from the same bank. 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 account-creation request. Treat the entries in instructions as independent payment options. Use each entry’s provider and status; do not infer special meaning from its array position. 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. This entry does not contain a virtual account number. Show it as a payment option only after its status becomes ACTIVE and account details are present. For crypto, asset identifies the stablecoin, chain identifies the network, and instructions contains the wallet address:
The product concepts are still onramps and offramps. New integrations create both with /v1/funding-accounts. The Legacy API section lists older /v1/onramps and /v1/offramps routes for existing integrations.

Account Types

Permanent NGN virtual accounts require the customer to have completed Tier 1 KYC.

Temporary crypto balance funding

Use TEMPORARY + CRYPTO_ADDRESS + INTERNAL_BALANCE to receive USDT or USDC into your merchant USD balance. Provide the ID of an existing customer who belongs to your merchant account.
Send this to Create a funding account with an API key that grants write and a unique X-Idempotency-Key. Reads require read.
  • Set asset and chain. Supported production chains are ETHEREUM, BSC, SOLANA, BASE, and POLYGON. Check deposit support for the asset with Supported Chains. Sandbox uses ETHEREUM.
  • Omit currency, rate_id, and payout destination fields. No FX quote is needed.
  • Optional amount is a positive integer estimate in major token units. When supplied, the response returns a decimal string, such as "500.00".
  • Optional developer_fee.percentage is a decimal string from 0 to 50, defaulting to 0. The bridge fee and limits do not apply to this funding flow.
Show the returned instructions[].address, asset, chain, and expires_at. The payment window is 30 minutes. Stop showing payment instructions at the deadline. Never reuse an address after expires_at; a later payment may not reach this account. Track each deposit through /v1/deposits and deposit.* webhooks. Credit the payment only on deposit.completed. A deposit with FUNDING_ACCOUNT_EXPIRED requires review; contact support@daya.co with its ID. Funding-account setup continues to use funding_account.* events. Retry creation with the same key and body to avoid another account. Retries preserve the original address and deadline. See idempotency. See sandbox checks. For a payment to an external address on another chain, use Bridges.

Permanent NGN Accounts

Permanent NGN funding accounts support two banking providers: FLUTTERWAVE and PAYSTACK. Complete Tier 1 KYC to create a permanent NGN funding account. Add the customer’s verified bank details and Nigerian phone number when you submit Tier 1 KYC, or update them later, so Paystack can verify the customer and provide another instruction. The phone number is not required when Tier 1 is submitted without bank details. Submitting bank details starts Paystack’s asynchronous bank account verification even when the customer does not yet have a permanent NGN funding account. If Paystack is temporarily unavailable, Daya keeps the verification pending and starts it automatically after the provider recovers. Subscribe to customer.bank_account_verification.succeeded and customer.bank_account_verification.failed for the result. After a successful result, Daya adds or activates the Paystack instruction on an existing permanent NGN funding account. If this makes a pending funding account usable, Daya sends funding_account.active; otherwise it sends funding_account.updated. If the customer does not have a permanent NGN funding account yet, Daya retains the verified result and uses it when you create one later. A failed Paystack verification does not prevent an available Flutterwave instruction from being created or used. Before submitting bank details, get the supported bank code from GET /v1/banks and verify the account with POST /v1/banks/resolve. The submitted account is not the funding account you give the customer. The create response returns the available instructions. Show the customer any instruction whose status is ACTIVE. There is no provider field in the create request. Calling create again with the same permanent account details does not create another live funding account. Daya returns the existing account with its latest instructions.

Provider Availability

Each provider-backed instruction includes provider_availability so your integration can explain provider delays and outages. For permanent NGN accounts, Daya evaluates Flutterwave and Paystack independently:
  • If both providers are available, the response includes both provider instructions.
  • If Flutterwave is UNAVAILABLE and Paystack can accept the request, Daya continues through Paystack when the customer has verified bank details. The response still includes the Flutterwave entry with provider_availability.status: UNAVAILABLE.
  • If Paystack is UNAVAILABLE, Daya can continue through Flutterwave. The Paystack entry remains visible with provider_availability.status: UNAVAILABLE.
  • If neither provider can accept a new permanent NGN request, creation returns HTTP 503 with error code PROVIDER_UNAVAILABLE and the configured message.
Temporary NGN accounts and crypto accounts use a single provider. Their creation returns 503 PROVIDER_UNAVAILABLE when that provider is unavailable.

Developer Fees

Developer fees let you keep a percentage of each deposit received through a funding account. Add developer_fee.percentage when creating the funding account. Use a decimal string from 0 to 50. Omit developer_fee to use 0%. developer_fee.percentage uses percentage values, not basis points. For example, 0.5 means 0.5%, 2 means 2%, and 50 means 50%. This differs from rate fee_bps, where 50 means 0.5%. The percentage is stored on the funding account and applies to every deposit received through that account. Funding account responses include developer_fee.percentage. Deposit responses and deposit webhooks include developer_fee and customer_amount after Daya calculates the split, so you can reconcile your fee separately from Daya fees. The developer fee is deducted before the final customer amount is calculated. It is not added as a separate charge. Use developer_fee.amount and developer_fee.currency to track the fee your merchant account kept, and use customer_amount as the amount left for the customer. Flat developer fees, such as NGN 500 or $1 per transaction, are not currently supported through developer_fee.

Settlement Destinations

Settlement destination controls where received funds are delivered after the funding account receives money. Balance destinations have different owners: See Customer NGN balances to create customer-owned balances, read them, and spend them through customer-scoped transfers. For an NGN virtual account that should automatically deliver USDT to a customer wallet, use ONCHAIN with destination_asset: USDT. BNB Smart Chain (BSC) and Polygon are supported in production when GET /v1/supported-chains returns withdraw_enabled: true for USDT on the selected chain. For NGN_PAYOUT, fetch supported banks with GET /v1/banks, verify the account with POST /v1/banks/resolve, then send the verified destination_bank.account_number and destination_bank.bank_code.

Lifecycle

Funding accounts move through these statuses: Permanent active funding accounts can rotate settlement destination with PATCH /v1/funding-accounts/{id}/settlement-destination. Rotation does not create new payment details.

Webhooks

Funding account setup emits: The webhook data object is the same public funding account response returned by the API. Bank account verification is reported separately: See Webhook Events for the result fields and payload examples.

Deposits from Funding Accounts

When money arrives through a funding account, Daya creates a deposit. Deposit API responses and deposit webhook payloads include funding_account_id so you can connect the incoming money back to the funding account the customer paid into. Funding-account instruction IDs stay internal. Your integration should store the public funding_account_id and the deposit id.
If settlement requires background delivery work, track the merchant-facing lifecycle with deposit.* events. Funding-account settlement does not emit separate payout webhooks.

Next Steps

Create Funding Account

Create NGN or crypto payment details.

Onramps

Collect NGN from customers.

Offramps

Collect stablecoins from customers.

Webhook Events

Track funding account and deposit state changes in real time.