Stablecoins
Accept Stablecoin Payments
Kora's Stablecoin Wallets let you receive payments from your customers in stablecoins. Each wallet belongs to one customer and accepts one stablecoin on one network. Any payment made into a wallet is automatically linked to that customer.
You create one wallet for each combination of customer, stablecoin, and network, and reuse it for all subsequent payments. For example, a customer who pays in USDT on both Solana and Tron needs two wallets: one for USDT on SOL and one for USDT on TRX.
The guide below walks you through accepting stablecoin payments on Kora using our APIs.
Prerequisites
Before you begin:
- Create an account on Kora and ensure that all necessary compliance details and documents have been approved.
- Retrieve your API keys from the dashboard. See API Keys for more information.
Supported Stablecoins and Networks
We currently support these stablecoins:
- USDT, and
- USDC.
The networks available for each stablecoin depend on the networks we support at the time. We currently support the following networks: SOL, ETH, TRX, BSC, BNB, and MATIC.
When you create a wallet, you can choose its network with the network field. If you don't specify a network, the wallet is created on the default network for that stablecoin. If you request a network that isn't supported for that stablecoin, the request fails. The network field in the wallet response always shows the network the wallet was created on.
A wallet accepts a single stablecoin on a particular network. Ensure that your customers send funds on the same network as the wallet address; deposits sent on a different or unsupported network may not be recoverable.
How It Works
There are three steps to accepting stablecoin payments from your customers:
- Create a stablecoin wallet for the customer.
- Set up webhooks to be notified when a deposit is completed.
- Verify the transaction using the Charge Query API.
Step 1: Create a Stablecoin Wallet
To create a wallet for a customer, make a request to the Create Customer Wallet API.
In the request, reference is your own unique identifier for the wallet. Store it, because you use it to retrieve the wallet later and it is returned as merchant_reference in webhook notifications.
If the request is successful, you would receive a response containing the wallet address and its details. Here's an example:
{
"status": true,
"message": "Customer crypto wallet created successfully",
"data": {
"wallet_reference": "tre-cry-a396f73b4771e30b6a10c711611cc6c5cb54f311013cb4d300b5275f62a74287",
"reference": "cus_8f3k2m_usdt_sol",
"address": "yNoVKf58ZTBqNAYT3j5qcdsyuMNmPfYetW5v6JXmj54o",
"network": "SOL",
"currency": "USDT",
"customer": {
"name": "Jane Doe",
"email": "[email protected]"
},
"status": "active"
}
}| Field | Description |
|---|---|
wallet_reference | Kora’s unique identifier for the wallet. |
reference | The reference you supplied when creating the wallet. |
address | The wallet address your customer sends funds to. |
network | The network on which the wallet was created. Your customer must send funds on this network. |
currency | The stablecoin currency accepted on the wallet. |
customer | The customer for which the wallet is created. |
status | The status of the wallet. |
Customers are identified by email address. If a customer with the same email already exists on your account, the wallet is linked to that customer and customer.name returns the name already on record, not the name in your request.
Retrieving a Wallet
To retrieve the details of an existing wallet, make a request to the Get Customer Wallet API using the reference you supplied when creating the wallet, not the wallet_reference.
A successful response from that endpoint looks like this:
{
"status": true,
"message": "Customer crypto wallet retrieved successfully",
"data": {
"wallet_reference": "tre-cry-a396f73b4771e30b6a10c711611cc6c5cb54f311013cb4d300b5275f62a74287",
"reference": "cus_8f3k2m_usdt_sol",
"address": "yNoVKf58ZTBqNAYT3j5qcdsyuMNmPfYetW5v6JXmj54o",
"network": "SOL",
"currency": "USDT",
"customer": {
"name": "Jane Doe",
"email": "[email protected]"
},
"status": "active"
}
}Step 2: Set Up Webhooks
Stablecoin payments are initiated outside of our system: your customer sends funds directly to the wallet address from their own wallet or exchange. As a result, we can only notify you once the payment has been completed on-chain.
If configured, notifications are sent to your webhook URL when a deposit is completed. Visit Webhooks to learn how to set your webhook URL, and how to verify and handle webhook requests.
A sample notification for a successful stablecoin deposit of 25 USDT into the wallet created in Step 1 looks like this:
{
"event": "charge.success",
"data": {
"reference": "KPY-PAY-C3zmbxmZmyVaNIx",
"payment_reference": "KPY-PAY-C3zmbxmZmyVaNIx",
"currency": "USDT",
"amount": 25,
"fee": 1.5,
"payment_method": "Stablecoin",
"status": "success",
"stablecoin_transaction": {
"wallet_address": "yNoVKf58ZTBqNAYT3j5qcdsyuMNmPfYetW5v6JXmj54o",
"transaction_hash": "MASi45ub7Qe4ZE36UT5G6cU4ud8Fhhe4deS4F3cw9KTAb8dLcukC7edhDQ7cn5d4gEYkbUrMWeWQLGsCmrG6dLaY",
"wallet_reference": "tre-cry-a396f73b4771e30b6a10c711611cc6c5cb54f311013cb4d300b5275f62a74287",
"merchant_reference": "cus_8f3k2m_usdt_sol",
"network": "SOL"
},
"transaction_date": "2026-07-08T09:41:33.624Z"
}
}| Field | Description |
|---|---|
reference | Kora’s reference for the payment. Use it to verify the transaction in Step 3. |
amount | The transaction amount received in the wallet, before fees. |
fee | The total fee charged on the deposit, including VAT. This is deducted from amount. |
stablecoin_transaction.merchant_reference | The reference you supplied when creating the wallet. Use it to match the deposit to your customer. |
stablecoin_transaction.wallet_reference | Kora’s identifier for the wallet that received the deposit. |
stablecoin_transaction.transaction_hash | The on-chain hash of the deposit transaction. |
The webhook payload doesn’t include customer details. Use stablecoin_transaction.merchant_reference to identify the customer, or retrieve the full transaction in Step 3.
For more information, see webhooks.
Step 3: Verify the Transaction
To get the full details of a transaction, make a request to the Charge Query API using the reference from the webhook notification payload.
A successful response for the deposit in Step 2 looks like this:
{
"status": true,
"message": "Charge retrieved successfully",
"data": {
"reference": "KPY-PAY-C3zmbxmZmyVaNIx",
"status": "success",
"amount": "25.00",
"amount_paid": "25.00000000",
"fee": 1.5,
"currency": "USDT",
"description": "Deposit of 23.5 USDT successful",
"transaction_date": "2026-07-08T09:41:33.000Z",
"customer": {
"name": "Jane Doe",
"email": "[email protected]"
},
"stablecoin_transaction": {
"wallet_address": "yNoVKf58ZTBqNAYT3j5qcdsyuMNmPfYetW5v6JXmj54o",
"transaction_hash": "MASi45ub7Qe4ZE36UT5G6cU4ud8Fhhe4deS4F3cw9KTAb8dLcukC7edhDQ7cn5d4gEYkbUrMWeWQLGsCmrG6dLaY",
"wallet_reference": "tre-cry-a396f73b4771e30b6a10c711611cc6c5cb54f311013cb4d300b5275f62a74287",
"merchant_reference": "cus_8f3k2m_usdt_sol",
"network": "SOL"
}
}
}
amount_paidis the total amount your customer sent to the wallet, before fees. The amount credited to your balance isamount_paidminusfee, which is the amount shown indescription. In this example, 25 USDT was received, a 1.5 USDT fee was charged, and 23.5 USDT was credited.
Updated about 14 hours ago