Balance
Read your current balance, on-hold totals, lifetime aggregates, and the deposit addresses for top-ups.
All examples below assume Authorization: Bearer mer_live_… is set; see
Authentication.
Get balance
GET /api/v1/merchant/balancecurl --compressed https://merchant-api.tradeon.market/api/v1/merchant/balance \
-H "Authorization: Bearer mer_live_…"200 OK:
{
"available": 481.60,
"on_hold": 18.40,
"total_deposited": 1000.00,
"total_spent": 518.40,
"currency": "USD",
"deposit_addresses": {
"trc20": "TXY...USDT_TRC20_ADDRESS",
"bep20": "0x...USDT_BEP20_ADDRESS"
}
}Fields
| Field | Type | Notes |
|---|---|---|
available | decimal (USD) | Free balance — what you can spend right now. |
on_hold | decimal (USD) | Sum of in-flight purchases — every purchase whose public status is created, processing, or sent_to_steam. These amounts are already debited. Completion removes them from on_hold without crediting available; only an applied refund credits balance. |
total_deposited | decimal (USD) | Lifetime sum of confirmed deposits (Deposit ledger rows). |
total_spent | decimal (USD) | Lifetime net spend = sum of Purchase debits − sum of Refund credits. |
currency | string | Always "USD". |
deposit_addresses | object | Retained Heleket USDT addresses. Both fields are null until provisioned. Whitepay addresses are returned separately below. |
deposit_addresses.trc20 | string | null | USDT-TRC20 address (Tron network). |
deposit_addresses.bep20 | string | null | USDT-BEP20 address (BNB Smart Chain). |
How money moves
For an isolated purchase with max_price: 20.00, actual price $18.40 and an initial
available balance of $500.00:
| State | available | on_hold | Explanation |
|---|---|---|---|
| Before purchase | 500.00 | 0.00 | No debit yet. |
| Purchase created | 481.60 | 18.40 | Actual price is debited. The $20.00 ceiling is not reserved. |
| Delivered | 481.60 | 0.00 | Delivery does not return the purchase price. |
| Full refund applied instead of delivery | 500.00 | 0.00 | A confirmed $18.40 refund credits the balance. |
A failed status alone does not prove that money was returned. Check purchase detail,
refund events and current balance. Other simultaneous purchases, deposits and refunds can
change these totals; balance_after in an event is a snapshot, not a balance version.
Topping up
Send USDT to either deposit address (TRC-20 or BEP-20). The deposit is confirmed by our
upstream payment provider (Heleket) and credited to your available balance. You will
receive a balance.deposited webhook with the credited amount and the new
balance_after — use that as your post-confirmation signal rather than polling
/balance.
Sender-side network fees remain separate. Do not infer Whitepay deposit limits from the commission tiers: the provider’s network limits apply, and this API does not quote them.
If both fields in deposit_addresses are null, the addresses have not been provisioned yet — contact
the TradeOn admin team or check Whitepay availability below.
Whitepay wallets
Whitepay issuance is disabled by default and is not announced as live. These endpoints use your authenticated merchant identity; never submit another merchant ID. API-key and merchant-session authentication are supported. Cookie mutations also require an allowed Origin.
GET /api/v1/merchant/deposits/walletsReturns locally saved state only. It does not create wallets or call the payment provider.
{
"issuance_enabled": false,
"can_create": false,
"wallets": []
}issuance_enabled selects the provider for new merchant wallets. can_create additionally
requires writes and verified deposit settlement to be enabled. Existing Heleket addresses,
balances and history remain unchanged. If issuance is selected but unavailable, onboarding
does not fall back to creating new Heleket addresses.
When can_create is true, request one address for a network:
POST /api/v1/merchant/deposits/wallets
Content-Type: application/json{ "network": "tron" }Use tron for USDT TRC-20 or bsc for USDT BEP-20. The response contains id,
provider (whitepay), currency (USDT), network, status, nullable address
and memo, can_deposit, created_at and updated_at.
| Status | Meaning / next action |
|---|---|
prepared | Saved locally; provider creation has not started. You may explicitly request creation for the same network when available. |
creation_started | An attempt has started. Read or reconcile it; do not request a replacement. |
requires_reconciliation | The result is unknown. Read or reconcile the saved request. |
bound | The saved request has a validated provider address. Send funds only when can_deposit is true. |
A 200 response can represent a pending state; it does not guarantee that an address
was created. One durable request is retained per merchant/network. Repeated issuance
requests return that request; once provider creation starts, no second provider POST is sent.
After an HTTP error, cancellation or lost response, read the list to recover its ID.
Refreshing the panel never automatically submits a creation request.
To explicitly recover a pending request or refresh a bound wallet’s provider status:
POST /api/v1/merchant/deposits/wallets/{id}/reconcileReconciliation uses provider GETs only and remains available with new issuance disabled.
For bound wallets it refreshes the saved active/disabled status without changing credentials.
can_deposit reflects the last saved provider status, not a live provider call on every list read.
A missing or ambiguous provider result does not permit a new creation attempt. A wallet
from another merchant returns 404. A bound address remains saved when top-ups are disabled;
can_deposit: false means do not send funds. When shown, include the memo/tag separately;
the cabinet QR contains only the address.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | MERCHANT_WALLET_NETWORK_INVALID | Invalid or missing network. Malformed JSON/body may return HTTP validation problem details. |
| 403 | MERCHANT_NOT_ACTIVE | Merchant became inactive before the operation. |
| 404 | MERCHANT_WALLET_NOT_FOUND | No wallet with this ID belongs to your merchant. |
| 409 | MERCHANT_WALLET_ISSUANCE_DISABLED | New creation is unavailable. |
| 409 | WALLET_CREATION_NOT_STARTED | Reconciliation requested before an attempt started. |
| 502 | MERCHANT_WALLET_PROVIDER_UNAVAILABLE | Could not verify provider state; read saved state before continuing. |
Standard authentication, blocked-account and rate-limit errors also apply.
Deposit commission
A commission is withheld from the deposit amount before crediting your balance. Sender-side network fees remain separate. The rate depends on the amount you send:
| Deposit amount | Commission |
|---|---|
| Under $5,000 | 1% |
| $5,000 and above | 0.5% |
The credited amount is the confirmed payment amount minus the applicable commission. Example: send $1,000 → $990.00 credited.
The commission scale is also available programmatically. min_amount is inclusive and
max_amount is exclusive; null means there is no upper bound:
GET /api/v1/merchant/deposits/fees{
"currency": "USD",
"tiers": [
{ "min_amount": 0, "max_amount": 5000, "percent": 1.0 },
{ "min_amount": 5000, "max_amount": null, "percent": 0.5 }
]
}Errors
| HTTP | code | When |
|---|---|---|
| 401 | MERCHANT_API_KEY_MISSING | Authorization header missing or malformed, or API key invalid. |
| 403 | MERCHANT_BLOCKED | Account blocked. |
| 429 | MERCHANT_RATE_LIMITED | Per-merchant request budget exceeded. |
Deposit history
GET /api/v1/merchant/deposits?limit=50Returns confirmed deposits for the authenticated merchant. The response contains deposits
and next_cursor (null at the end). Pass a returned cursor as cursor for the next page.
limit is 1–200, default 50. API-key and merchant-session authentication are supported.
Each deposit contains id, provider (heleket or whitepay), amount (credited USD),
currency (USD), network (tron or bsc), destination, nullable tx_id,
status (paid) and created_at. amount is the credited amount after the tiered
commission, not the amount originally sent. Existing Heleket entries remain in the history.
For an internal WhiteBIT transfer, Whitepay may report an internal transaction identifier
in tx_id instead of a blockchain hash. The network still identifies the independently
confirmed deposit wallet; it does not prove that the transfer occurred on-chain.
The same merchant commission tiers apply to internal and on-chain deposits.
Whitepay deposit support is not enabled yet. The existing deposit_addresses fields
still contain Heleket addresses; they are not silently replaced with another provider’s addresses.
See also
- Webhooks → Event Catalogue — the authoritative
deposit-confirmation signal lives in the
balance.depositedevent.