Tutorial: Accept USDT from Users and Settle in Naira
This guide shows you how to use Bitnob’s Offramp APIs to receive USDT from a user on-chain (e.g., via TRC20) and automatically convert and settle it into Nigerian Naira (NGN) into a local bank account.
We’ll walk through the entire value flow, what each step means, and how you can provide a seamless user experience in your application.
Key Concepts
The Quote
Before you receive any crypto, you must lock in an exchange rate using a quote. The quote:
Tells you the exchange rate that will be used (e.g., 1 USDT = ₦1702)
Defines how many NGN the user will receive
Is valid for 15 minutes to avoid market volatility
Source of Funds
You're specifying:
source: "onchain" – meaning the user will send USDT from an external wallet
chain: "trc20" – which network the user will use to send the USDT (TRC20 is fastest and cheapest)
The Address
After the quote is accepted via the initiate step, Bitnob gives you a USDT address. This is what you show the user to send funds to.
Settlement
When funds arrive at the address:
Bitnob automatically detects the incoming USDT
Converts it using the locked-in quote rate
Settles the equivalent NGN into the bank account you provided
Full Flow Overview
Request a Quote
Step: Lock in the exchange rate.
Example Request
Example Response
What this means:
You must initiate and receive funds within this window
This is guaranteed for 15 minutes
You must initiate and receive funds within this window
Initiate the Payout
This step binds the quote to the destination bank account.
Example Request
Example Response
What you should do next:
Display the returned USDT address to the user
Prompt them to send exactly 1000 USDT on TRC20 to the address
Start tracking the reference and quoteId for this session
Simulate Deposit (Sandbox Only)
For testing purposes, you can simulate a deposit.
Example Request
Settlement Lifecycle (What Happens After Deposit)
This step binds the quote to the destination bank account.
It confirms receipt (usually within 1–2 blocks for TRC20)
Sends a payouts.asset.received webhook to your callbackUrl Converts the USDT to NGN at the locked quote rate
Sends the NGN to the provided bank account
Sends payouts.withdrawal.success webhook when completed
Handling Quote Expiry, Underpayment, or Failure
If the user sends less than quoted, Bitnob sends a payouts.asset.underpayment webhook.
If no deposit is received before expiry (15 min), Bitnob cancels the payout.
If a withdrawal fails (e.g., due to an invalid account), you’ll receive a payouts.withdrawal.failed webhook.
Best Practices
Always display the exact amount and chain to the user.
Poll the /payouts/:reference endpoint if you don’t implement webhooks yet.
Use a unique reference per payout — this is your trace ID.
Store the quoteId, reference, beneficiary, and address in your database for future reconciliation.
What This Flow Enables
You now have a programmable way to:
Receive USDT from anywhere in the world
Convert it automatically
Deliver it in local fiat to a verified bank account
Handle all messaging via webhooks
This is ideal for:
Remittance apps
Pay suppliers or gig workers in Nigeria
Crypto liquidation from global wallets