A+ · 開發者文件

A+ 商戶開發者文件

幣別 TWD(新台幣) · 台灣本地銀行轉帳 · Base URL https://api.aplusmall.cash
所有接口支援 POST / GET,Content-Type: application/x-www-form-urlencoded。 請先向我方取得商戶號 cus_code 與密鑰 secret_key。 回調來源 IP 54.199.155.234 請務必放行,否則收不到回調。 本站僅支援 台灣銀行轉帳(無支付寶/微信/人民幣)。

一、接口地址#

用途地址
代收提交POST /api/payment/deposit
代收查詢POST /api/payment/info
代付提交POST /api/charge/receive
代付查詢POST /api/charge/info
餘額查詢POST /api/inquire/account/info

二、簽名規則#

參數依 key 字母序排序、排除空值與 sign、value 做 URL-encode(空格編為 %20)、末尾接 &key=<secret_key>,整串取 MD5 小寫。金額固定兩位小數(如 1000.00)。

⚠️ 最常見的驗簽失敗:空格編成了 +。URL-encode 有兩種:表單式(PHP urlencode() / 線上「URL 編碼」工具)空格是 +;我方簽名用的是 RFC 3986(PHP rawurlencode() / JS encodeURIComponent() / Java URLEncoder.encode(...).replace("+","%20")),空格是 %20。
例:任何含空格的 value(如英文姓名 John Smith)驗簽時必須把空格拼成 %20(John%20Smith),不是 +(John+Smith)。

範例

參數:cus_code=MCH001, cus_order_sn=T20260921001, payment_flag=bank_twd, amount=1000.00
待簽字串:
amount=1000.00&cus_code=MCH001&cus_order_sn=T20260921001&payment_flag=bank_twd&key=你的密鑰
sign = md5(上面字串) 小寫

三、代收下單 /api/payment/deposit#

參數必填說明
cus_code✓商戶號
cus_order_sn✓貴司訂單號(唯一)
payment_flag✓bank_twd(台灣銀行轉帳)
amount✓金額(TWD,兩位小數字串)
notify_url選回調地址(不帶則用商戶預設)
payer_name✓付款人銀行帳號(卡號),完整帳號或末五碼,如有多組請以半形逗號 , 分隔(例:12345,67890),上限 200 字元。attach_data 只是附加資料(原樣回調返回、對帳用),不作此用途

請求範例

以 POST、Content-Type: application/x-www-form-urlencoded 表單送出。以下範例的密鑰假設為 abc123(請換成貴司密鑰),可用來核對自己的簽名程式。

curl -X POST https://api.aplusmall.cash/api/payment/deposit \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "cus_order_sn=T20261109001" \
  --data-urlencode "payment_flag=bank_twd" \
  --data-urlencode "amount=1000.00" \
  --data-urlencode "notify_url=https://www.example.com/notify" \
  --data-urlencode "payer_name=1234567834037" \
  --data-urlencode "sign=ba8f5d009f061167522e52f54a73a812"
待簽字串:
amount=1000.00&cus_code=MCH001&cus_order_sn=T20261109001&notify_url=https%3A%2F%2Fwww.example.com%2Fnotify&payer_name=1234567834037&payment_flag=bank_twd&key=abc123
sign = md5(上面字串) = ba8f5d009f061167522e52f54a73a812

響應

{
  "result": 1, "status": "200", "message": "Success",
  "order_info": {
    "order_sn": "A...",                 // 我方訂單號
    "cus_order_sn": "T20260921001",
    "currency_type": "TWD",
    "order_amount": "1000.00",
    "payment_uri": "https://cashier.aplusmall.cash/pay/xxxx",  // 收銀台,交付款人
    "order_status": "pending",
    "expired_at": "...", "created_at": "...",
    "payment_detail": {                 // 收款帳戶:請展示給付款人轉帳
      "bank_name": "388 全盈支付",      // 收款銀行(銀行代碼 + 名稱)
      "account_no": "1150000000421"     // 收款銀行帳號
    }
  }
}

⚠️ 銀行名稱與帳號不是下單參數,而是我方回給貴司的收款帳戶,在響應的 order_info.payment_detail。下單成功時一般會直接帶出,請展示給付款人轉帳;或直接把付款人導向 payment_uri(我方收銀台)。若響應中沒有 payment_detail,再以「五、查詢接口」取得(欄位相同)。收款人姓名不提供。

四、代付下單 /api/charge/receive#

參數必填說明
cus_code / cus_order_sn / amount / sign✓同代收
payment_flag✓pay_bank_twd(台灣銀行轉帳出款)
bank_account✓收款銀行帳號
bank_code✓收款銀行名稱。不限定格式,以下皆可:3 碼代號(822)、中文名稱(中國信託)、或兩者併寫(822 中國信託)。
本欄我方不做格式/存在性校驗,原樣轉給出款方 —— 內容不足以辨識銀行時,出款階段才會發現、訂單卡住待人工處理,建議以附錄的寫法為準。
notify_url / attach_data選回調地址 / 附加資料(原樣回傳)

請求範例

送出方式與代收相同(POST 表單)。密鑰同樣假設為 abc123。注意 bank_code 含空格,簽名時要編成 %20。

curl -X POST https://api.aplusmall.cash/api/charge/receive \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "cus_order_sn=W20261109001" \
  --data-urlencode "payment_flag=pay_bank_twd" \
  --data-urlencode "amount=5000.00" \
  --data-urlencode "bank_account=0123456789012" \
  --data-urlencode "bank_code=822 中國信託" \
  --data-urlencode "notify_url=https://www.example.com/notify" \
  --data-urlencode "sign=47838ad9b37b4b5a707277d37026b61f"
待簽字串:
amount=5000.00&bank_account=0123456789012&bank_code=822%20%E4%B8%AD%E5%9C%8B%E4%BF%A1%E8%A8%97&cus_code=MCH001&cus_order_sn=W20261109001&notify_url=https%3A%2F%2Fwww.example.com%2Fnotify&payment_flag=pay_bank_twd&key=abc123
sign = md5(上面字串) = 47838ad9b37b4b5a707277d37026b61f

響應

回 result: 1 代表訂單已建立、出款金額已從代付餘額凍結,此時狀態為 pending(處理中);出款結果以異步回調或代付查詢為準。

{
  "result": 1, "status": "200", "message": "Success",
  "order_info": {
    "order_sn": "AP20261109121044P3HV8N2D",  // 我方訂單號
    "cus_order_sn": "W20261109001",          // 貴司訂單號
    "payment_flag": "pay_bank_twd",
    "currency_type": "TWD",
    "original_amount": "5000.00",
    "order_amount": "5000.00",
    "fee_amount": "50.000",                  // 手續費(小數位數不固定,請以數值處理)
    "order_status": "pending",               // 處理中
    "created_at": "2026-11-09T12:10:44.123"  // 台灣時間(UTC+8)
  }
}

失敗響應範例

// 代付餘額不足(未建單、未凍結)
{ "result": "error", "status": 410, "message": "Insufficient withdrawal balance (available=3000.00, required=5050.00)" }

// 訂單號重複
{ "result": "error", "status": 406, "message": "Order already exists" }

失敗時不會建立訂單、也不會凍結餘額。required = 訂單金額 + 手續費。其他錯誤碼見九、錯誤碼。

五、查詢接口#

三個查詢接口都可用 POST 表單或 GET,簽名規則與下單相同(所有送出的參數都要參與簽名)。

接口參數說明
代收查詢 /api/payment/infocus_code + order_sn + signorder_sn 填我方訂單號或貴司訂單號(cus_order_sn)皆可:先以我方單號查,查不到再以貴司單號查
代付查詢 /api/charge/infocus_code + order_sn + sign
餘額查詢 /api/inquire/account/infocus_code + ut + signut = 當下 Unix 時間戳(秒),與我方時間相差超過 30 秒即拒絕(回 301);格式不對回 304

請求範例:代收查詢

密鑰同樣假設為 abc123。

curl -X POST https://api.aplusmall.cash/api/payment/info \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "order_sn=AP20261109120530K7Q2M9XA" \
  --data-urlencode "sign=dca754ce3bd1d19de051d781f71b66e6"
待簽字串:
cus_code=MCH001&order_sn=AP20261109120530K7Q2M9XA&key=abc123
sign = md5(上面字串) = dca754ce3bd1d19de051d781f71b66e6

請求範例:代付查詢(以貴司訂單號查)

curl -X POST https://api.aplusmall.cash/api/charge/info \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "order_sn=W20261109001" \
  --data-urlencode "sign=1a3982df922ef5bcf2a577fc84c9a53d"
待簽字串:
cus_code=MCH001&order_sn=W20261109001&key=abc123
sign = md5(上面字串) = 1a3982df922ef5bcf2a577fc84c9a53d

請求範例:餘額查詢

ut 每次都要用當下時間重新產生並重新簽名 —— 下面的 1794283200 只用來核對簽名算法,直接送出會因逾時被拒。

curl -X POST https://api.aplusmall.cash/api/inquire/account/info \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "ut=1794283200" \
  --data-urlencode "sign=39b6f07ef5dd0ed67c779bb153f5b5fe"
待簽字串:
cus_code=MCH001&ut=1794283200&key=abc123
sign = md5(上面字串) = 39b6f07ef5dd0ed67c779bb153f5b5fe

代收查詢響應(含收款資訊)

{
  "result": 1, "status": "200",
  "order_info": {
    "order_sn": "A...", "cus_order_sn": "T...",
    "order_amount": "1000.00", "receive_amount": "1000.00",
    "order_status": "pending",                 // pending 待付款 / success 成功 / cancel 取消 / fail 作廢
    "payment_uri": "https://cashier.aplusmall.cash/pay/xxxx",
    "payment_img": "https://.../qr.png",       // 收款 QR(有則顯示)
    "payment_detail": {                          // 收款帳戶(與下單響應相同)
      "bank_name": "388 全盈支付",               // 收款銀行(銀行代碼 + 名稱)
      "account_no": "1150000000421"             // 收款銀行帳號
    }
  }
}

⚠️ 下單響應沒有收款帳戶時 — 再輪詢查詢

  1. 收款帳戶一般在下單響應的 payment_detail 就會帶出,拿到就不必輪詢。
  2. 若下單響應沒有 payment_detail,每 2~3 秒呼叫 /api/payment/info,直到回出 payment_detail(或 payment_img)。
  3. 取得收款帳戶後展示給付款人;或直接導向 payment_uri(我方收銀台,配好會自動顯示)。
  4. 查到 order_status = success 即到帳(以異步回調為準),停止查詢。

查詢響應的金額欄位小數位數不固定(例如手續費可能是 41.750),請以數值比較,不要用字串比對。查詢響應不帶簽名,金額對帳請以異步回調為準。

代付查詢響應

{
  "result": 1, "status": "200", "message": "",
  "order_info": {
    "order_sn": "AP20261109121044P3HV8N2D",  // 我方訂單號
    "cus_order_sn": "W20261109001",          // 貴司訂單號
    "payment_flag": "pay_bank_twd",
    "currency_type": "TWD",
    "original_amount": "5000.00",
    "order_amount": "5000.00",
    "fee_amount": "50.000",                  // 手續費
    "order_status": "success",               // pending 處理中 / success 出款完成 / cancel 取消 / fail 作廢
    "created_at": "2026-11-09T12:10:44.123"  // 台灣時間(UTC+8)
  }
}

餘額查詢響應

{
  "result": 1, "status": "200", "message": "Success",
  "account_info": {
    "nickname": "MCH001", "email": "...", "contact_person": "...", "contact_phone": "...", "company": "...",
    "created_at": "2026-10-01T10:00:00",
    "total_deposit": "125000.000",   // 代收可用餘額
    "total_deduct": "80000.000",     // 代付可用餘額(可用來出款的金額)
    "product_wallets": []
  },
  "currency_rate": {},
  "customize_currency_transform_rate": {},
  "request_data": null
}

六、異步回調(notify_url)#

我方以 POST、Content-Type: application/json 推送結果到貴司 notify_url(來源 IP 54.199.155.234,請放行)。驗簽方式與下單一致。貴司處理成功後須回傳純文字 success,否則我方會重試(最多重試 5 次,約 8 分鐘內)。

欄位說明
order_sn / cus_order_sn我方 / 貴司訂單號
currency_typeTWD
original_amount / order_amount / exchange_amount原始 / 訂單 / 換匯後金額(兩位小數字串;TWD 三者相同)
statussuccess(成功)/ cancel(已取消,由客服人工取消)/ fail(原單已作廢:客服取消後改以新單補單時,原單轉為 fail)。cancel 與 fail 都代表該筆未完成,請同樣處理。
receive_amount / fee_amount實際到帳 / 手續費(僅代收回調)
pay_account_code付款人帳號末五碼(代收回調)。卡商或客服完成訂單時輸入、並經系統核對相符的值,可供貴司對帳。有值才出現;有出現時一併參與簽名
bank_name / bank_account / account_name / wallet_address代付收款資訊(僅代付回調)。下單時沒帶的欄位會以空字串送出,空字串不參與簽名
attach_data下單時附加資料,原樣回傳(有帶才出現)
messagesuccess / cancelled / failed(不含空格;判斷成敗請以 status 為準)
sign驗簽用

回調範例:代收成功

以下範例的密鑰假設為 abc123,可用來核對自己的驗簽程式。

POST https://www.example.com/notify
Content-Type: application/json

{
  "order_sn": "AP20261109120530K7Q2M9XA",
  "cus_order_sn": "T20261109001",
  "currency_type": "TWD",
  "original_amount": "1000.00",
  "order_amount": "1000.00",
  "exchange_amount": "1000.00",
  "receive_amount": "1000.00",
  "fee_amount": "41.75",
  "pay_account_code": "34037",
  "status": "success",
  "message": "success",
  "sign": "4c81e676681e89cb8f607618953146af"
}
待簽字串(去掉 sign、依 key 字母排序):
currency_type=TWD&cus_order_sn=T20261109001&exchange_amount=1000.00&fee_amount=41.75&message=success&order_amount=1000.00&order_sn=AP20261109120530K7Q2M9XA&original_amount=1000.00&pay_account_code=34037&receive_amount=1000.00&status=success&key=abc123
sign = md5(上面字串) = 4c81e676681e89cb8f607618953146af

回調範例:代付成功

注意 bank_name、account_name、wallet_address 是空字串,不放進待簽字串。

POST https://www.example.com/notify
Content-Type: application/json

{
  "order_sn": "AP20261109121044P3HV8N2D",
  "cus_order_sn": "W20261109001",
  "currency_type": "TWD",
  "original_amount": "5000.00",
  "order_amount": "5000.00",
  "exchange_amount": "5000.00",
  "status": "success",
  "message": "success",
  "bank_name": "",
  "bank_account": "0123456789012",
  "account_name": "",
  "wallet_address": "",
  "sign": "070271bd9066e415a8c41727deba47db"
}
待簽字串:
bank_account=0123456789012&currency_type=TWD&cus_order_sn=W20261109001&exchange_amount=5000.00&message=success&order_amount=5000.00&order_sn=AP20261109121044P3HV8N2D&original_amount=5000.00&status=success&key=abc123
sign = md5(上面字串) = 070271bd9066e415a8c41727deba47db

取消 / 作廢的回調格式相同,只是 status 為 cancel / fail、message 為 cancelled / failed。

驗簽程式範例(PHP)

$data = json_decode(file_get_contents('php://input'), true);
$sign = isset($data['sign']) ? $data['sign'] : '';
unset($data['sign']);
ksort($data);
$parts = array();
foreach ($data as $k => $v) {
    if ($v === null || $v === '') continue;          // 空值不參與簽名
    $parts[] = $k . '=' . rawurlencode((string)$v);  // 用 rawurlencode(空格 %20),不要用 urlencode
}
$str = implode('&', $parts) . '&key=' . $secretKey;
if (md5($str) !== strtolower($sign)) { echo 'fail'; exit; }
// ……依 cus_order_sn 處理訂單……
echo 'success';

⚠️ 同一筆訂單可能收到不只一次回調(重試、或取消後轉為作廢)。請以 cus_order_sn 做冪等:已處理過的訂單也請回傳 success,否則我方會持續重試。

七、訂單狀態#

狀態說明
pending待付款 / 處理中
success付款成功 / 出款完成
cancel已取消
fail已作廢(取消後改以新單補單,原單轉為此狀態)

八、對接流程#

  1. 貴司放行回調 IP 54.199.155.234、提供 notify_url。
  2. 我方開通商戶號,回傳 cus_code + secret_key。
  3. 先代收/代付各一筆小額測試單,確認回調與驗簽通過後上量。

九、錯誤碼#

接口失敗時回統一結構(HTTP 200,以 result 判斷):

{ "result": "error", "status": 416, "message": "...", "request_data": null }
status說明
300缺少必填參數(訊息 Missing required parameter)/ 金額錯誤(金額 ≤ 0、手續費大於訂單金額、金額不在可受理區間)
301 / 304餘額查詢的 ut 與我方時間相差超過 30 秒 / ut 格式錯誤
302驗簽失敗(訊息 Invalid signature)
401商戶不存在 / 無權訪問該訂單(訊息 Access denied)
403帳號未開通該功能 / 未配置費率 / 該幣別+支付方式無費率 / 來源 IP 不在白名單(訊息 Access forbidden)
404訂單不存在(查詢接口)
406訂單號重複(cus_order_sn 已存在)
410代付餘額不足(訊息含可用金額與所需金額;所需 = 訂單金額 + 手續費)
412商戶帳號已停用,禁止交易
416無可用收款渠道/收款員,訂單失敗。同步配單模式下未配到收款員即回此碼(未成功建單,請重試或改期)
500系統內部錯誤,請稍後重試或聯繫我方

附錄、銀行對照表(台灣)#

代付 bank_code 不限定格式(3 碼代號 / 中文名稱 / 822 中國信託 併寫皆可), 本表僅供對照參考。共 295 筆,資料為台灣金融機構代號。 我方不校驗此欄,內容不足以辨識銀行時僅能在出款階段才發現,請盡量以本表的代號或名稱為準。

A+ · Developer Docs

A+ Merchant Developer Documentation

Currency TWD (New Taiwan Dollar) · Taiwan local bank transfer · Base URL https://api.aplusmall.cash
All endpoints accept POST / GET with Content-Type: application/x-www-form-urlencoded. Please obtain your merchant ID cus_code and secret key secret_key from us first. You must whitelist our callback source IP 54.199.155.234, otherwise callbacks will not reach you. This site supports Taiwan bank transfer only (no Alipay / WeChat / CNY).

1. Endpoints#

PurposeEndpoint
Pay-in (deposit) submitPOST /api/payment/deposit
Pay-in queryPOST /api/payment/info
Payout (withdrawal) submitPOST /api/charge/receive
Payout queryPOST /api/charge/info
Balance queryPOST /api/inquire/account/info

2. Signature#

Sort parameters by key in alphabetical order, exclude empty values and sign, URL-encode each value (space encoded as %20), append &key=<secret_key> at the end, then take the lowercase MD5 of the whole string. Amounts always use two decimal places (e.g. 1000.00).

⚠️ Most common signature failure: spaces encoded as +. There are two kinds of URL-encoding: form encoding (PHP urlencode() / online "URL encode" tools) turns a space into +; our signature uses RFC 3986 (PHP rawurlencode() / JS encodeURIComponent() / Java URLEncoder.encode(...).replace("+","%20")), where a space is %20.
Example: any value containing a space (such as the English name John Smith) must be encoded as John%20Smith when signing, not John+Smith.

Example

Params: cus_code=MCH001, cus_order_sn=T20260921001, payment_flag=bank_twd, amount=1000.00
String to sign:
amount=1000.00&cus_code=MCH001&cus_order_sn=T20260921001&payment_flag=bank_twd&key=YOUR_SECRET_KEY
sign = md5(string above), lowercase

3. Pay-in Order /api/payment/deposit#

ParameterRequiredDescription
cus_code✓Merchant ID
cus_order_sn✓Your order number (must be unique)
payment_flag✓bank_twd (Taiwan bank transfer)
amount✓Amount (TWD, string with two decimal places)
notify_urlOptionalCallback URL (merchant default is used if omitted)
payer_name✓Payer's bank account (card) number, full number or last 5 digits. For multiple accounts, separate them with a half-width comma , (e.g. 12345,67890); max 200 characters. attach_data is only extra data (returned as-is in the callback, for reconciliation) and is not used for this purpose

Request Example

Send as POST with Content-Type: application/x-www-form-urlencoded. The secret key in this example is assumed to be abc123 (replace with yours); you can use it to check your own signing code.

curl -X POST https://api.aplusmall.cash/api/payment/deposit \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "cus_order_sn=T20261109001" \
  --data-urlencode "payment_flag=bank_twd" \
  --data-urlencode "amount=1000.00" \
  --data-urlencode "notify_url=https://www.example.com/notify" \
  --data-urlencode "payer_name=1234567834037" \
  --data-urlencode "sign=ba8f5d009f061167522e52f54a73a812"
String to sign:
amount=1000.00&cus_code=MCH001&cus_order_sn=T20261109001&notify_url=https%3A%2F%2Fwww.example.com%2Fnotify&payer_name=1234567834037&payment_flag=bank_twd&key=abc123
sign = md5(string above) = ba8f5d009f061167522e52f54a73a812

Response

{
  "result": 1, "status": "200", "message": "Success",
  "order_info": {
    "order_sn": "A...",                 // our order number
    "cus_order_sn": "T20260921001",
    "currency_type": "TWD",
    "order_amount": "1000.00",
    "payment_uri": "https://cashier.aplusmall.cash/pay/xxxx",  // cashier page, give to the payer
    "order_status": "pending",
    "expired_at": "...", "created_at": "...",
    "payment_detail": {                 // receiving account: show it to the payer
      "bank_name": "388 全盈支付",      // receiving bank (bank code + name)
      "account_no": "1150000000421"     // receiving bank account number
    }
  }
}

⚠️ Bank name and account number are not request parameters. They are the receiving account we return to you, in order_info.payment_detail of the response. It is normally included as soon as the order is created; show it to the payer, or simply redirect the payer to payment_uri (our cashier page). If the response has no payment_detail, get it via "5. Query" (same fields). The account holder name is not provided.

4. Payout Order /api/charge/receive#

ParameterRequiredDescription
cus_code / cus_order_sn / amount / sign✓Same as pay-in
payment_flag✓pay_bank_twd (Taiwan bank transfer payout)
bank_account✓Beneficiary bank account number
bank_code✓Beneficiary bank name. No fixed format; any of the following works: 3-digit code (822), Chinese name (中國信託), or both (822 中國信託).
We do not validate the format or existence of this field; it is passed to the payout side as-is. If it is not enough to identify the bank, this will only be found at payout time and the order will be held for manual handling. Please follow the Appendix.
notify_url / attach_dataOptionalCallback URL / extra data (returned as-is)

Request Example

Sent the same way as pay-in (POST form). The secret key is again assumed to be abc123. Note that bank_code contains a space, which must be encoded as %20 when signing.

curl -X POST https://api.aplusmall.cash/api/charge/receive \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "cus_order_sn=W20261109001" \
  --data-urlencode "payment_flag=pay_bank_twd" \
  --data-urlencode "amount=5000.00" \
  --data-urlencode "bank_account=0123456789012" \
  --data-urlencode "bank_code=822 中國信託" \
  --data-urlencode "notify_url=https://www.example.com/notify" \
  --data-urlencode "sign=47838ad9b37b4b5a707277d37026b61f"
String to sign:
amount=5000.00&bank_account=0123456789012&bank_code=822%20%E4%B8%AD%E5%9C%8B%E4%BF%A1%E8%A8%97&cus_code=MCH001&cus_order_sn=W20261109001&notify_url=https%3A%2F%2Fwww.example.com%2Fnotify&payment_flag=pay_bank_twd&key=abc123
sign = md5(string above) = 47838ad9b37b4b5a707277d37026b61f

Response

result: 1 means the order has been created and the payout amount has been frozen from your payout balance; the status is pending (processing). The payout result is given by the async callback or the payout query.

{
  "result": 1, "status": "200", "message": "Success",
  "order_info": {
    "order_sn": "AP20261109121044P3HV8N2D",  // our order number
    "cus_order_sn": "W20261109001",          // your order number
    "payment_flag": "pay_bank_twd",
    "currency_type": "TWD",
    "original_amount": "5000.00",
    "order_amount": "5000.00",
    "fee_amount": "50.000",                  // fee (number of decimals varies; treat as a number)
    "order_status": "pending",               // processing
    "created_at": "2026-11-09T12:10:44.123"  // Taiwan time (UTC+8)
  }
}

Failure response examples

// Insufficient payout balance (no order created, nothing frozen)
{ "result": "error", "status": 410, "message": "Insufficient withdrawal balance (available=3000.00, required=5050.00)" }

// Duplicate order number
{ "result": "error", "status": 406, "message": "Order already exists" }

On failure no order is created and no balance is frozen. required = order amount + fee. See 9. Error Codes for other codes.

5. Query#

All three query endpoints accept POST form or GET. The signature rule is the same as for order submission (every parameter you send is included in the signature).

EndpointParametersNotes
Pay-in query /api/payment/infocus_code + order_sn + signorder_sn may be either our order number or your order number (cus_order_sn): we look up our number first, then yours
Payout query /api/charge/infocus_code + order_sn + sign
Balance query /api/inquire/account/infocus_code + ut + signut = current Unix timestamp (seconds); rejected with 301 if it differs from our clock by more than 30 seconds, 304 if malformed

Request example: pay-in query

The secret key is again assumed to be abc123.

curl -X POST https://api.aplusmall.cash/api/payment/info \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "order_sn=AP20261109120530K7Q2M9XA" \
  --data-urlencode "sign=dca754ce3bd1d19de051d781f71b66e6"
String to sign:
cus_code=MCH001&order_sn=AP20261109120530K7Q2M9XA&key=abc123
sign = md5(string above) = dca754ce3bd1d19de051d781f71b66e6

Request example: payout query (by your order number)

curl -X POST https://api.aplusmall.cash/api/charge/info \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "order_sn=W20261109001" \
  --data-urlencode "sign=1a3982df922ef5bcf2a577fc84c9a53d"
String to sign:
cus_code=MCH001&order_sn=W20261109001&key=abc123
sign = md5(string above) = 1a3982df922ef5bcf2a577fc84c9a53d

Request example: balance query

Generate ut from the current time and re-sign on every request — the 1794283200 below is only for checking your signature code; sending it as-is will be rejected as expired.

curl -X POST https://api.aplusmall.cash/api/inquire/account/info \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "cus_code=MCH001" \
  --data-urlencode "ut=1794283200" \
  --data-urlencode "sign=39b6f07ef5dd0ed67c779bb153f5b5fe"
String to sign:
cus_code=MCH001&ut=1794283200&key=abc123
sign = md5(string above) = 39b6f07ef5dd0ed67c779bb153f5b5fe

Pay-in query response (with receiving account)

{
  "result": 1, "status": "200",
  "order_info": {
    "order_sn": "A...", "cus_order_sn": "T...",
    "order_amount": "1000.00", "receive_amount": "1000.00",
    "order_status": "pending",                 // pending / success / cancel / fail (voided)
    "payment_uri": "https://cashier.aplusmall.cash/pay/xxxx",
    "payment_img": "https://.../qr.png",       // receiving QR (show if present)
    "payment_detail": {                          // receiving account (same as the submit response)
      "bank_name": "388 全盈支付",               // receiving bank (bank code + name)
      "account_no": "1150000000421"             // receiving bank account number
    }
  }
}

⚠️ If the submit response has no receiving account — poll the query endpoint

  1. The receiving account is normally returned in payment_detail of the submit response; if you have it, no polling is needed.
  2. If the submit response has no payment_detail, call /api/payment/info every 2–3 seconds until payment_detail (or payment_img) is returned.
  3. Show the receiving account to the payer, or simply redirect to payment_uri (our cashier page shows it automatically once matched).
  4. When polling returns order_status = success, the payment has arrived (the async callback is authoritative); stop polling.

Amount fields in query responses do not have a fixed number of decimal places (e.g. the fee may be 41.750); compare them as numbers, not strings. Query responses are not signed; use the async callback for amount reconciliation.

Payout query response

{
  "result": 1, "status": "200", "message": "",
  "order_info": {
    "order_sn": "AP20261109121044P3HV8N2D",  // our order number
    "cus_order_sn": "W20261109001",          // your order number
    "payment_flag": "pay_bank_twd",
    "currency_type": "TWD",
    "original_amount": "5000.00",
    "order_amount": "5000.00",
    "fee_amount": "50.000",                  // fee
    "order_status": "success",               // pending / success (paid out) / cancel / fail (voided)
    "created_at": "2026-11-09T12:10:44.123"  // Taiwan time (UTC+8)
  }
}

Balance query response

{
  "result": 1, "status": "200", "message": "Success",
  "account_info": {
    "nickname": "MCH001", "email": "...", "contact_person": "...", "contact_phone": "...", "company": "...",
    "created_at": "2026-10-01T10:00:00",
    "total_deposit": "125000.000",   // pay-in available balance
    "total_deduct": "80000.000",     // payout available balance (amount available for payouts)
    "product_wallets": []
  },
  "currency_rate": {},
  "customize_currency_transform_rate": {},
  "request_data": null
}

6. Async Callback (notify_url)#

We POST the result to your notify_url with Content-Type: application/json (source IP 54.199.155.234, please whitelist it). Signature verification is the same as for order submission. After processing successfully you must return the plain text success, otherwise we will retry (up to 5 retries, within about 8 minutes).

FieldDescription
order_sn / cus_order_snOur / your order number
currency_typeTWD
original_amount / order_amount / exchange_amountOriginal / order / exchanged amount (string with two decimal places; all three are equal for TWD)
statussuccess (succeeded) / cancel (cancelled manually by customer service) / fail (voided: when customer service cancels an order and re-issues it as a new order, the original order becomes fail). Both cancel and fail mean the order was not completed; handle them the same way.
receive_amount / fee_amountActual amount received / fee (pay-in callback only)
pay_account_codeLast five digits of the payer's account (pay-in callback). Entered when the order is completed and verified by the system, for your reconciliation. Present only when it has a value; when present it is included in the signature
bank_name / bank_account / account_name / wallet_addressBeneficiary information (payout callback only). Fields not provided when the order was submitted are sent as empty strings; empty strings are excluded from the signature
attach_dataExtra data from the order submission, returned as-is (present only if provided)
messagesuccess / cancelled / failed (no spaces; use status to determine the result)
signFor signature verification

Callback example: pay-in succeeded

The examples below assume the secret key is abc123; use them to check your own verification code.

POST https://www.example.com/notify
Content-Type: application/json

{
  "order_sn": "AP20261109120530K7Q2M9XA",
  "cus_order_sn": "T20261109001",
  "currency_type": "TWD",
  "original_amount": "1000.00",
  "order_amount": "1000.00",
  "exchange_amount": "1000.00",
  "receive_amount": "1000.00",
  "fee_amount": "41.75",
  "pay_account_code": "34037",
  "status": "success",
  "message": "success",
  "sign": "4c81e676681e89cb8f607618953146af"
}
String to sign (sign removed, keys sorted alphabetically):
currency_type=TWD&cus_order_sn=T20261109001&exchange_amount=1000.00&fee_amount=41.75&message=success&order_amount=1000.00&order_sn=AP20261109120530K7Q2M9XA&original_amount=1000.00&pay_account_code=34037&receive_amount=1000.00&status=success&key=abc123
sign = md5(string above) = 4c81e676681e89cb8f607618953146af

Callback example: payout succeeded

Note that bank_name, account_name and wallet_address are empty strings and are not included in the string to sign.

POST https://www.example.com/notify
Content-Type: application/json

{
  "order_sn": "AP20261109121044P3HV8N2D",
  "cus_order_sn": "W20261109001",
  "currency_type": "TWD",
  "original_amount": "5000.00",
  "order_amount": "5000.00",
  "exchange_amount": "5000.00",
  "status": "success",
  "message": "success",
  "bank_name": "",
  "bank_account": "0123456789012",
  "account_name": "",
  "wallet_address": "",
  "sign": "070271bd9066e415a8c41727deba47db"
}
String to sign:
bank_account=0123456789012&currency_type=TWD&cus_order_sn=W20261109001&exchange_amount=5000.00&message=success&order_amount=5000.00&order_sn=AP20261109121044P3HV8N2D&original_amount=5000.00&status=success&key=abc123
sign = md5(string above) = 070271bd9066e415a8c41727deba47db

Cancelled / voided callbacks have the same format, with status = cancel / fail and message = cancelled / failed.

Verification example (PHP)

$data = json_decode(file_get_contents('php://input'), true);
$sign = isset($data['sign']) ? $data['sign'] : '';
unset($data['sign']);
ksort($data);
$parts = array();
foreach ($data as $k => $v) {
    if ($v === null || $v === '') continue;          // empty values are not signed
    $parts[] = $k . '=' . rawurlencode((string)$v);  // use rawurlencode (space = %20), not urlencode
}
$str = implode('&', $parts) . '&key=' . $secretKey;
if (md5($str) !== strtolower($sign)) { echo 'fail'; exit; }
// ... process the order by cus_order_sn ...
echo 'success';

⚠️ The same order may receive more than one callback (retries, or a cancelled order later becoming voided). Make your handling idempotent on cus_order_sn: return success for orders you have already processed, otherwise we will keep retrying.

7. Order Status#

StatusDescription
pendingAwaiting payment / processing
successPayment succeeded / payout completed
cancelCancelled
failVoided (cancelled and re-issued as a new order; the original order ends in this status)

8. Integration Steps#

  1. Whitelist our callback IP 54.199.155.234 and provide your notify_url.
  2. We open your merchant account and send you cus_code + secret_key.
  3. Place one small test order each for pay-in and payout; go live after callbacks and signatures are verified.

9. Error Codes#

On failure the API returns a unified structure (HTTP 200; check result):

{ "result": "error", "status": 416, "message": "...", "request_data": null }
statusDescription
300Missing required parameter (message Missing required parameter) / invalid amount (amount ≤ 0, fee greater than the order amount, or amount outside the accepted range)
301 / 304Balance query ut differs from our clock by more than 30 seconds / ut malformed
302Signature verification failed (message Invalid signature)
401Merchant not found / no access to this order (message Access denied)
403Feature not enabled for the account / fee rate not configured / no fee rate for this currency + payment method / source IP not whitelisted (message Access forbidden)
404Order not found (query endpoints)
406Duplicate order number (cus_order_sn already exists)
410Insufficient payout balance (message includes available and required amounts; required = order amount + fee)
412Merchant account disabled; transactions prohibited
416No available channel / payee, order failed. In synchronous matching mode this code is returned when no payee is matched (the order was not created; please retry later)
500Internal error, please retry later or contact us

Appendix: Bank Codes (Taiwan)#

The payout bank_code has no fixed format (3-digit code / Chinese name / 822 中國信託 are all accepted); this table is for reference only. 295 entries, Taiwan financial institution codes. We do not validate this field; if it is not enough to identify the bank, this will only be found at payout time. Please use the codes or names in this table whenever possible.

代碼Code機構名稱Institution
004台灣銀行
005土地銀行
006合作金庫銀行
007第一銀行
008華南銀行
009彰化銀行
011上海銀行
012台北富邦
013國泰世華
015中國輸出入銀行
016高雄銀行
017兆豐商銀
018農業金庫
020日商瑞穗銀行
021花旗銀行
022美國銀行
023泰國盤谷銀行
025首都銀行
040中華開發
048王道銀行
050台灣企銀
052渣打商銀
053台中銀行
054京城銀行
072德意志銀行
075東亞銀行
081匯豐銀行
082巴黎銀行
101瑞興銀行
102華泰銀行
103新光銀行
104台北五信
106台北九信
108陽信銀行
114基隆一信
115基隆二信
118板信銀行
119淡水一信
120淡水信合社
124宜蘭信合社
127桃園信合社
130新竹一信
132新竹三信
146台中二信
147三信銀行
158彰化一信
161彰化五信
162彰化六信
163彰化十信
165鹿港信合社
178嘉義三信
179嘉義四信
188台南三信
204高雄三信
215花蓮一信
216花蓮二信
222澎湖一信
223澎湖二信
224金門信合社
329印尼人民銀行
387連加支付
388全盈支付
389全支付
390悠遊付
391一卡通
392愛金卡
395橘子支付
396街口支付
397歐付寶
398簡單付
501蘇澳區漁會
502頭城區漁會
505頭城區漁會
506桃園區漁會
507新竹區漁會
508通苑區漁會
510南龍區漁會
511彰化區漁會
512雲林區漁會
513瑞芳區漁會
514萬里區漁會
515嘉義區漁會
516基隆區漁會
517南市區漁會
518南縣區漁會
519新化區農會
520高雄等漁會
521高雄等漁會
523屏東等漁會
524新港區漁會
525澎湖區漁會
526金門區漁會
538宜蘭市農會
541白河農會
542麻豆農會
547後壁農會
549下營農會
551官田農會
552大內農會
556學甲農會
557新市農會
558安定農會
559山上區農會
561左鎮農會
562仁德農會
564關廟區農會
565龍崎區農會
567南化農會
568七股區農會
570南投農會
573埔里農會
574竹山農會
575中寮鄉農會
577魚池鄉農會
578水里農會
579國姓農會
580鹿谷鄉農會
581信義鄉農會
582仁愛鄉農會
583東山農會
585頭城鎮農會
586羅東鎮農會
587礁溪鄉農會
588壯圍鄉農會
589員山鄉農會
596五結鄉農會
598蘇澳地區農會
599三星地區農會
600農金資中心
602中華民國農會中壢辦事處信用部
605高雄地區農會
606新北市地區農會
607宜蘭農會
608桃園地區農會
610新竹地區農會
612豐原神岡農
613名間集集農
614彰化等農會
615基隆市農會
616雲林等農會
617嘉義等農會
618台南等農會
619高雄等農會
620屏東等農會
621花蓮等農會
622台東等農會
624澎湖縣農會
625台中市農會
627連江縣農會
628鹿港農會
629和美鎮農會
631溪湖農會
632田中農會
633北斗農會
635線西農會
636伸港鄉農會
638花壇農會
639大村鄉農會
642社頭鄉農會
643二水農會
646大城農會
647溪州鄉農會
649埔鹽鄉農會
650福興農會
651彰化市農會
683北港鎮農會
685土庫鎮農會
693東勢鄉農會
696水林鄉農會
697元長鄉農會
698麥寮農會
699林內鄉農會
700中華郵政(郵局)
749內埔地區農會
762大溪農會
763桃園區農會
764平鎮區農會
765楊梅區農會
766大園區農會
767蘆竹區農會
768龜山區農會
769八德農會
770新屋區農會
771龍潭區農會
772復興農會
773觀音區農會
775土城區農會
776三重區農會
777中和地區農會
778新北市淡水區農會
779樹林區農會
780新北市鶯歌區農會
781三峽區農會
785蘆洲區農會
786新北市五股區農會
787新北市林口區農會
788泰山區農會
789新北市坪林區農會
790八里區農會
791金山地區農會
792瑞芳地區農會
793新店地區農會
795新北市深坑區農會
796石碇區農會
797新北市平溪區農會
798石門區農會
799三芝區農會
803聯邦銀行
805遠東銀行
806元大銀行
807永豐銀行
808玉山銀行
809凱基銀行
810星展銀行
812台新銀行
816安泰銀行
822中國信託
823將來銀行
824連線商業銀行
826樂天銀行
860中埔農會
866阿里山鄉農會
868東勢農會
869清水區農會
870梧棲區農會
871大甲農會
872沙鹿農會
874霧峰區農會
875太平農會
876烏日農會
877后里農會
878大雅農會
879潭子區農會
880石岡農會
881新社農會
882大肚區農會
883外埔農會
884大安農會
885龍井區農會
886和平農會
889神岡農會
891花蓮市農會
895瑞穗鄉農會
896玉溪地區農會
897鳳榮地區農會
898光豐地區農會
901大里市農會
902苗栗農會
903汐止區農會
904新莊市農會
906頭份市農會
907竹南農會
908通霄鎮農會
909苑裡鎮農會
910農漁會聯合資訊中心
912冬山鄉農會
913後龍鎮農會
914卓蘭農會
915西湖鄉農會
916草屯鎮農會
917公館農會
918銅鑼農會
919三義農會
920造橋農會
921南庄鄉農會
922台南地區農會
923獅潭農會
924頭屋農會
925三灣農會
926大湖農會
928板橋市農會
929關西鎮農會
930新埔鎮農會
931竹北市農會
932湖口鄉農會
933芎林鄉農會
934寶山鄉農會
935峨眉農會
936北埔鄉農會
937竹東地區農會
938橫山農會
939新豐農會
940新竹市農會
951新北市農會北區共用中心
953田尾鄉農會
954農漁會中區共用中心
984北投區農會
985士林區農會
986內湖區農會
987南港區農會
988木柵區農會
989景美區農會
995關貿網路
996台北區支付處
997信合社南區資訊中心
A+ · api.aplusmall.cash · 本文件為對接技術規範Technical integration specification