Skip to content

Withdrawal Flow ​

An external withdrawal sends customer wallet funds to an external address. Acceptance reserves the amount and fee; on-chain execution and its final result complete the workflow. An internal transfer sends funds to another OOLIN account through account balance movements.

External withdrawals and internal transfers ​

ConcernExternal withdrawalInternal transfer
DestinationExternal address on the selected networkAnother OOLIN account
Create APIPOST /withdrawalsPOST /withdrawals/internal
Main inputsSource account, asset type, network, address, amountSource/recipient accounts, asset type, amount
ProcessingAsynchronous on-chain execution after acceptanceImmediate account transfer
FeeCheck quote fee_amountZero
SuccessBoth completed states and a valid tx_hashBoth completed states and request_type: INTERNAL

Both use withdrawal_id for detail queries. Internal transfer completion does not require an external network or on-chain tx_hash.

Customer wallet withdrawal stages ​

text
Customer withdrawal application and authorization
  → validate the destination
  → quote and customer confirmation
  → persist the business request ID
  → create the withdrawal and reserve funds
  → retrieve detail to track the result
  → apply completion or failure

1. Validate the destination and quote ​

Verify the asset/network combination and validate address format with /assets/{asset_id}/validate-address. Then use POST /withdrawals/quote to check account state, amount, limits, fees, balance, and transfer type.

For an external withdrawal, require can_withdraw: true and transfer_type: EXTERNAL. Another OOLIN account's deposit address can be classified as internal, so address format alone does not determine transfer type.

Quote fieldMeaning
amountPrincipal to send
fee_amountFee added to the principal
receive_amountAmount received by the recipient
min_amount, max_amountRequest amount limits
can_withdraw, reasonCurrent eligibility and reason when unavailable

The account needs amount + fee_amount. A quote neither reserves funds nor guarantees success, so also inspect the create response.

2. Persist and create the request ​

Before submission, connect the withdrawal application to the account, asset, network, amount, destination, and unique client_request_id. Attach the returned withdrawal_id after successful creation.

client_request_id tracks one financial intent and must be unique across internal transfers and external withdrawals. Its purpose differs from the HMAC nonce on each HTTP request. Keep the business request ID during recovery while generating fresh HTTP authentication values.

3. Reserve funds and retrieve the result ​

If a customer holds 100 USDT and withdraws 20 USDT with a 1 USDT fee, acceptance reserves 21 USDT and leaves 79 USDT available. Total balance remains 100 USDT at this point; the withdrawal is not complete.

External success requires all of the following in detail:

  • request_type: EXTERNAL
  • status: COMPLETED
  • user_status: COMPLETED
  • A valid tx_hash

Without concurrent activity, total balance becomes 79 USDT after completion. After a reservation is released for failure, rejection, or cancellation, verify principal and fee recovery through the final balance. See Balances and Ledger for amount changes.

Lost responses and cancellation ​

If a create response is lost before receiving the transaction ID, retrieve the existing result with GET /withdrawals/client-request/{client_request_id}. A timeout does not prove financial failure. One WITHDRAWAL_NOT_FOUND also does not prove the original request was never processed; follow the idempotency guide.

You can request cancellation with POST /withdrawals/{withdrawal_id}/cancel, but the withdrawal must still be cancellable. Depending on processing progress, the API can return WITHDRAWAL_NOT_CANCELLABLE. Sending a cancellation request alone does not close the workflow; verify the API result and balance.

Account transfers and Digital Payment ​

General internal transfers move one asset type between two active accounts. They can serve transfers between a customer's accounts or sending funds to another user's account. Your backend authorizes the source account and action.

Digital Payment sets the customer USER account as sender and the merchant BUSINESS account as recipient, then links the transfer to an order. Merchant settlement follows the external withdrawal process above. Your order or settlement ID identifies the business operation; withdrawal_id identifies the Wallet API fund movement.

Follow Request an External Withdrawal and Track Withdrawal Status for customer wallet requests. See Transaction Status Model for state-dependent behavior.

OOLIN is a digital asset operations infrastructure product by BPMG.