Appearance
Init withdrawal
Send money from your balance to a customer's bank account or e-wallet.
POST/api/v2/transfer-out/initBearer token + signature
Signed endpoint
The fields below are the inner payload. JSON-encode them, base64 them into {"data": "…"} and sign the request — see Request signing.
Payload
| Field | Type | Required | Description |
|---|---|---|---|
account_holder | string | required | Beneficiary's name as registered with the bank |
to_bank | string | required | Beneficiary bank — see values |
to_bank_account_no | string | required | Beneficiary account number, digits only |
amount | string | required | Amount as a decimal string. See limits |
invoice_no | string | required | Your unique reference for this withdrawal |
currency | string | optional | Only MYR is supported. Defaults to MYR |
user_id | string | optional | Customer / player name |
json
{
"account_holder": "John Doe",
"to_bank": "MAYBANK",
"to_bank_account_no": "172839812321",
"amount": "100.00",
"currency": "MYR",
"invoice_no": "WD-2026-0001",
"user_id": "John"
}Bank values
| Value | Bank |
|---|---|
MAYBANK | Maybank |
CIMB | CIMB Bank |
PUBLIC_BANK | Public Bank |
RHB | RHB Bank |
HLB | Hong Leong Bank |
AMBANK | AmBank |
AFFIN_BANK | Affin Bank |
ALLIANCE | Alliance Bank |
BANK_ISLAM | Bank Islam |
BANK_MUAMALAT | Bank Muamalat |
BANK_RAKYAT | Bank Rakyat |
BSN | Bank Simpanan Nasional |
AGRO_BANK | Agrobank |
MBSB | MBSB Bank |
OCBC | OCBC Bank |
UOB_MALAYSIA | UOB Malaysia |
HSBC_BANK_MALAYSIA | HSBC Bank Malaysia |
STANDARD_CHARTERED | Standard Chartered |
CITI | Citibank |
BANK_OF_CHINA | Bank of China |
GX | GXBank |
BOOST_BANK | Boost Bank |
TNG, TNG_EWALLET | Touch 'n Go eWallet |
BOOST_EWALLET | Boost eWallet |
BIG_PAY | BigPay |
SHOPEE_PAY | ShopeePay |
Not supported: AEON Bank, Ryt Bank. Availability of an individual bank can change — an unsupported bank returns 400/403.
Amount limits
| Min (MYR) | Max (MYR) |
|---|---|
| 50 | 5,000 |
Limits can differ per account. The withdrawal amount plus withdrawal fees must be covered by your balance. Large withdrawals may be held for manual approval (status: "UNVERIFIED").
Response
200 OKA 200 means the withdrawal was accepted, not completed. The final outcome is delivered to your withdrawal postback URL.
json
{
"message": "Transfer out request accepted",
"code": "success",
"data": {
"transaction_id": "9b3a1e44-7bce-4a85-9f12-d3ac82610e44",
"status": "VERIFIED",
"reference_number": "TO-20260512-000045",
"amount": 100.00,
"currency": "MYR",
"created_at": "2026-05-12T17:48:35+08:00"
}
}| Field | Type | Description |
|---|---|---|
data.transaction_id | string | Our ID for this withdrawal (matches id in the postback) |
data.status | string | VERIFIED (queued for payout) or UNVERIFIED (awaiting manual approval) |
data.reference_number | string | Our reference number |
data.amount | number | Amount (note: a JSON number here, not a string) |
data.currency | string | Currency |
data.created_at | string | Creation time (RFC 3339) |
Errors
| HTTP | When |
|---|---|
| 400 | Body can't be parsed, amount outside limits, or bank not supported |
| 401 | Access token or signature problem — see error codes |
| 403 | Bank not supported |
| 422 | A field failed validation (e.g. non-numeric to_bank_account_no) |
| 500 | Insufficient balance, duplicate invoice_no, or a server error |
| 503 | Withdrawals are temporarily unavailable |
json
{
"error": "amount should at least be 50.00",
"code": "unknown_error",
"message": "amount should at least be 50.00"
}Don't blindly retry a 500
A 500 can mean the withdrawal was rejected for insufficient balance or a duplicate invoice_no. Retrying with the same invoice_no is safe — a duplicate will never be paid out twice.
