Skip to content

Settle to an External Address ​

External settlement sends funds accumulated in the merchant payment account to an address on the selected network. This is asynchronous: OOLIN validates the request, processes the on-chain transfer, and reflects the final result in the Wallet API.

text
Customer backend → create withdrawal → request processing
  → on-chain transfer → retrieve Wallet API result

Your backend creates the withdrawal through the Wallet API and retrieves its detail to confirm the final result.

Validate the destination and request a quote ​

Use a valid external Sepolia address. An address managed as another OOLIN account's deposit address may cause the request to be classified as an internal transfer.

bash
export TO_ADDRESS='{valid-testnet-address}'
export WITHDRAW_AMOUNT='1.00'

asset_response="$(
  wallet_request GET "/assets/by-type-network?asset_type_id=$ASSET_TYPE_ID&network_id=$NETWORK_ID"
)"
export ASSET_ID="$(printf '%s' "$asset_response" | jq -r '.data.asset_id')"

validate_body="$(jq -nc --arg address "$TO_ADDRESS" '{address:$address}')"
wallet_request POST "/assets/$ASSET_ID/validate-address" "$validate_body" | jq

When data.is_valid is true, request a quote.

bash
quote_body="$(jq -nc \
  --argjson account_id "$PAYMENT_ACCOUNT_ID" \
  --argjson asset_type_id "$ASSET_TYPE_ID" \
  --arg amount "$WITHDRAW_AMOUNT" \
  --arg to_address "$TO_ADDRESS" \
  --argjson network_id "$NETWORK_ID" \
  '{account_id:$account_id,asset_type_id:$asset_type_id,amount:$amount,to_address:$to_address,network_id:$network_id}')"

wallet_request POST '/withdrawals/quote' "$quote_body" | jq

Proceed only when can_withdraw is true and transfer_type is EXTERNAL. Review the fee, receive amount, and limits.

The reserved and debited account amount is amount + fee_amount; receive_amount is the recipient amount. A quote neither reserves funds nor guarantees success, so handle errors during creation as well.

Create the external withdrawal ​

Persist SETTLEMENT_REQUEST_ID with the settlement operation, amount, and destination before sending the request. Use the stored ID during recovery rather than generating another ID for the same settlement.

bash
export SETTLEMENT_REQUEST_ID="settlement-$(node -e 'process.stdout.write(require("crypto").randomUUID())')"

withdrawal_body="$(jq -nc \
  --argjson account_id "$PAYMENT_ACCOUNT_ID" \
  --argjson asset_type_id "$ASSET_TYPE_ID" \
  --arg amount "$WITHDRAW_AMOUNT" \
  --arg to_address "$TO_ADDRESS" \
  --argjson network_id "$NETWORK_ID" \
  --arg client_request_id "$SETTLEMENT_REQUEST_ID" \
  '{account_id:$account_id,asset_type_id:$asset_type_id,amount:$amount,to_address:$to_address,network_id:$network_id,client_request_id:$client_request_id}')"

withdrawal_response="$(wallet_request POST '/withdrawals' "$withdrawal_body")"
export WITHDRAWAL_ID="$(printf '%s' "$withdrawal_response" | jq -r '.data.withdrawal_id')"
printf '%s\n' "$withdrawal_response" | jq

Confirm the response has request_type: "EXTERNAL". Creation reserves the amount and fee in pending_withdraw_amount_raw; it does not mean the on-chain transaction is complete.

If the create response is lost, recover with the lookup below and store the returned withdrawal_id as WITHDRAWAL_ID. A single WITHDRAWAL_NOT_FOUND does not prove the request was never processed; follow the idempotency guide.

bash
wallet_request GET "/withdrawals/client-request/$SETTLEMENT_REQUEST_ID" | jq

Track the final result ​

bash
wallet_request GET "/withdrawals/$WITHDRAWAL_ID" | jq
user_statusMeaningBackend action
PENDINGRequest accepted and inspectedPoll at a bounded interval
PROCESSINGApproval or on-chain transfer processingKeep the settlement pending
COMPLETEDOn-chain withdrawal completedStore tx_hash and completed_at
FAILEDOn-chain processing failedRecord failure and verify balance recovery
REJECTEDProcessing rejectedRecord the reason and escalate operationally
CANCELLEDRequest cancelledClose the request and verify balance

Final success requires user_status: "COMPLETED", status: "COMPLETED", and a valid tx_hash.

Next: Collect and recover funds.

OOLIN is a digital asset operations infrastructure product by BPMG.