2.5 Wallet Transfer (Deposit / Withdraw)
POST /api/v1/user/exchange/wallets/{external_player_id}/deposits
POST /api/v1/user/exchange/wallets/{external_player_id}/withdrawalsdeposits: wallet depositwithdrawals: wallet withdraw
Request Body (JSON)
| Field | Required | Type | Description |
|---|---|---|---|
| currency | TRUE | string | Must match the currency bound to the agent; see Supported Currencies |
| amount | TRUE | string | Amount change, represented as a string; per-transaction cap 10,000,000, up to 8 decimal places |
| ticket_id | TRUE | string | Idempotency key, a unique string, up to 256 characters; the same ticket_id will not take effect twice |
{
"currency": "CNY",
"amount": "10",
"ticket_id": "3e2178ba-269c-4649-2fdb-a2099d6479a6"
}TIP
ticket_id is the idempotency key: when a request is repeated with the same ticket_id, provided the request body (amount, currency) is identical, the system returns the original response from the first successful call (including the balance at that time) and does not post the entry again. If the body differs, 10050 is returned. That balance is a snapshot from the initial processing and does not reflect the current balance; for the latest balance, call the Balance Query API.
A player being in-game does not affect transfer operations; deposits / withdrawals can be initiated normally.
Response data
| Field | Type | Description |
|---|---|---|
| wallet.currency | string | Currency |
| wallet.balance | string | Balance snapshot after this transaction is processed |
| created_at | string | Initial processing time (RFC 3339, nanosecond precision) |
{
"code": 0,
"message": "success",
"data": {
"wallet": {
"currency": "CNY",
"balance": "251080.82"
},
"created_at": "2026-06-18T05:00:02.962216637Z"
}
}Idempotency and Deduplication Rules
IMPORTANT
The deduplication key for ticket_id is "player + ticket_id + transaction type" — it includes the transaction type. The same ticket_id therefore takes effect once on a deposit and once on a withdrawal. It is not a globally unique transaction ID; do not reuse it across directions.
Amount and currency are not part of the deduplication key; they are compared field by field against the first record:
| Scenario | Result |
|---|---|
Same ticket_id, amount and currency identical | Returns the original response of the first successful call; no second posting |
Same ticket_id, amount or currency differs | Returns 10050; do not retry — use a new ticket_id if the amount must change |
| Another request with the same ticket_id is still in flight | Returns 10040; the entry is never posted twice — resend the exact same request shortly to obtain the first result |
TIP
X-Idempotency-Key plays no part in transfer idempotency — the idempotency key for transfers is ticket_id. The same X-Idempotency-Key used on deposits and withdrawals therefore has no cross-effect; on this endpoint it is only a required signing field.
Only the Login API uses that header for idempotency: the same key returns the same token while that token is still valid, so send a new key with every login request.
Transfer-Specific Error Codes
| code | Meaning | Handling |
|---|---|---|
| 10040 | Another request with the same ticket_id is currently being processed | The entry is never posted twice. Resend the exact same request shortly to obtain the result of the first call |
| 10050 | The same ticket_id has already been used, but this call carries a different amount or currency | Do not retry. Use a new ticket_id if the amount must change |
| 20160 | Player balance is insufficient to complete the withdrawal | Confirm the balance before retrying |
The message for 10050 names the mismatched field and both values, for example:
ticket_id already used with a different amount (recorded 100, requested 100.5)Transaction Failures and Refund Handling
IMPORTANT
Before issuing a refund or reprocessing, you must first call the Transaction Status Query API to confirm the final status of the original transaction, to avoid duplicate refunds or refunding a transaction that was never actually charged.
On timeout, network error, or an ambiguous response, do not issue a refund directly. The correct procedure:
- Call the transaction status query API with the original
ticket_idto confirm whether the transaction was successfully posted. - After confirming it was not successful, issue the refund (deposit) with a new
ticket_id. - If confirmed successful, no action is needed, or initiate a separate refund flow according to your business requirements.