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

Bitnob account setup process
1.

Request a Quote

Step: Lock in the exchange rate.

Endpoint

POST /api/payouts/quotes

Example Request

json
Note

The amount is in USDT cents (i.e., 100000 = 1000.00 USDT)

Example Response

json

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


2.

Initiate the Payout

This step binds the quote to the destination bank account.

Endpoint

POST /api/payouts/initiate

Example Request

json

Example Response

json

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


3.

Simulate Deposit (Sandbox Only)

For testing purposes, you can simulate a deposit.

Endpoint

POST /api/payouts/simulate-address-deposit

Example Request

json
Note

This tells the sandbox: "act like the user just sent 1000 USDT to this address."


4.

Settlement Lifecycle (What Happens After Deposit)

This step binds the quote to the destination bank account.

1.

It confirms receipt (usually within 1–2 blocks for TRC20)

2.

Sends a payouts.asset.received webhook to your callbackUrl Converts the USDT to NGN at the locked quote rate

3.

Sends the NGN to the provided bank account

4.

Sends payouts.withdrawal.success webhook when completed


5.

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.

Note

Always listen for webhooks to track transaction outcomes.


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

Did you find this page useful?