ManWei — 商戶 API 介接文件 (菲律賓)

ManWei — 商戶 API 介接文件 (菲律賓)

項目 內容
文件版本 v2.0(線上版)
更新日期 2026-10-05
適用對象 商戶端開發人員
API 版本 v1

目錄

  1. 快速開始
  2. 認證機制
  3. 通用約定
  4. 代收 API
  5. 代付 API
  6. 查詢類 API
  7. 對帳單 API
  8. Webhook 回調
  9. 錯誤碼
  10. 介接檢查清單
  11. 外幣下單(USDT)

1. 快速開始

1.1 環境與網址

環境 Base URL
正式環境 https://api.kawinpay-ph.com/api/v1
測試環境 請洽您的客戶經理索取

⚠️ 注意路徑中的 /api 不可省略。完整範例: https://api.kawinpay-ph.com/api/v1/collection/create 少了 /api 會得到 404,而非認證錯誤。

1.2 介接前準備

請向平台申請以下資訊:

項目 說明
API Key 識別您身分的金鑰,放在 X-API-Key 標頭
API Secret 用於計算簽章,請妥善保管、絕不可外洩或寫在前端程式碼
IP 白名單 您呼叫 API 的伺服器對外 IP。若您經過 NAT/Proxy,請提供實際的出口 IP
Webhook URL 接收交易結果通知的端點(需 HTTPS)
Webhook Secret 驗證回調來源的金鑰。僅在您於商戶後台設定 Webhook 時才有;若您是建單時帶 callbackUrl(per-order 回調),則改用 API Secret 驗章,見 8.3

API Secret 只在建立時顯示一次。若遺失,需請平台重新產生(舊的會立即失效)。

1.3 權限說明

每組 API Key 有其權限範圍:

權限 可呼叫的端點
READ 所有查詢類端點(query / list / balance / channels / institutions / statement)
WRITE 建立與取消類端點(create / cancel)
ALL 全部

權限不足時回 HTTP 403、errorCode = 0001010。

1.4 支援的交易類型

交易 是否支援 API
代收(Collection) ✅ 支援
代付(Payout) ✅ 支援
下發(Withdrawal) ❌ 不提供 API,請於商戶後台建立
轉帳(Transfer) ❌ 不提供 API,請於商戶後台建立

2. 認證機制

每一次請求都需要 API Key + HMAC-SHA256 簽章。

2.1 必要標頭

標頭 說明 範例
X-API-Key 您的 API Key sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
X-Timestamp Unix 時間戳,單位為「秒」 1704067200
X-Nonce 每次請求唯一的隨機字串(建議 UUID) 3f2a9c1e...
X-Signature HMAC-SHA256 簽章,Base64 編碼 a1b2c3d4...=
Content-Type application/json(POST 時)

⚠️ 最常見的三個錯誤:

  1. X-Timestamp 用了毫秒(應為秒)
  2. 簽章輸出用了 hex(應為 Base64)
  3. 簽章串接用了 | 或 ,(應為 .)

2.2 簽章演算法

待簽字串 = timestamp + "." + nonce + "." + payload
簽章     = Base64( HMAC-SHA256( 金鑰 = API Secret, 資料 = 待簽字串 ) )

關於 payload:

請求方法 payload 內容
POST 您實際送出的 request body 原始字串(逐位元組一致)
GET 空字串 ""(待簽字串會是 timestamp + "." + nonce + ".",結尾有一個點)

⚠️ 關鍵:必須簽「您實際送出的那串位元組」。 若您先用某種方式序列化來簽章、送出時又重新序列化(空白、欄位順序、浮點數格式不同), 簽章就會對不上,回 INVALID_SIGNATURE。 建議做法:先產生 JSON 字串,用該字串簽章,再把同一個字串當 body 送出。

2.3 時間戳與防重放

規則 說明
時間窗 伺服器時間 ±300 秒(5 分鐘)
Nonce 5 分鐘內不可重複使用,重複會回 INVALID_NONCE

請確保您的伺服器時間有做 NTP 校時。時間偏移超過 5 分鐘會導致所有請求失敗。 時間戳過期與簽章錯誤都回 INVALID_SIGNATURE,請先檢查時鐘。

2.4 完整範例

Python

import hmac, hashlib, base64, json, time, uuid, requests

API_KEY    = "sk_live_xxxxxxxx"
API_SECRET = "your_api_secret"
BASE_URL   = "https://api.kawinpay-ph.com/api/v1"

def call_api(path, body=None, method="POST"):
    payload = json.dumps(body, separators=(',', ':'), ensure_ascii=False) if body else ""
    ts    = str(int(time.time()))          # 秒
    nonce = uuid.uuid4().hex

    message   = f"{ts}.{nonce}.{payload}"
    signature = base64.b64encode(
        hmac.new(API_SECRET.encode(), message.encode(), hashlib.sha256).digest()
    ).decode()

    headers = {
        "Content-Type": "application/json",
        "X-API-Key":   API_KEY,
        "X-Timestamp": ts,
        "X-Nonce":     nonce,
        "X-Signature": signature,
    }
    if method == "POST":
        # 注意:送出的是與簽章時「完全相同」的字串
        return requests.post(BASE_URL + path, data=payload.encode(), headers=headers)
    return requests.get(BASE_URL + path, headers=headers)

resp = call_api("/collection/create", {
    "merchantOrderNo": "M202608080001",
    "amount": 1000.00,
    "currency": "PHP",
})
print(resp.json())

PHP

<?php
$apiKey    = 'sk_live_xxxxxxxx';
$apiSecret = 'your_api_secret';
$baseUrl   = 'https://api.kawinpay-ph.com/api/v1';

function callApi($path, $body = null) {
    global $apiKey, $apiSecret, $baseUrl;
    $payload = $body ? json_encode($body, JSON_UNESCAPED_UNICODE) : '';
    $ts      = (string) time();                       // 秒
    $nonce   = bin2hex(random_bytes(16));

    $message   = $ts . '.' . $nonce . '.' . $payload;
    $signature = base64_encode(hash_hmac('sha256', $message, $apiSecret, true));

    $ch = curl_init($baseUrl . $path);
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,   // 與簽章用的字串相同
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'X-API-Key: '   . $apiKey,
            'X-Timestamp: ' . $ts,
            'X-Nonce: '     . $nonce,
            'X-Signature: ' . $signature,
        ],
    ]);
    return json_decode(curl_exec($ch), true);
}

2.5 IP 白名單

若您的 API Key 啟用了 IP 白名單,只有名單內的 IP 可呼叫。支援格式:

格式 範例
精確 IP 203.0.113.10
CIDR 網段 203.0.113.0/24
萬用字元 203.0.113.*

不在名單內回 HTTP 403、errorCode = IP_NOT_ALLOWED。

提醒:請提供您伺服器的對外出口 IP。若經過 NAT、雲端 NAT Gateway 或 Proxy, 實際出口 IP 可能與伺服器本機 IP 不同。

2.6 流量限制

項目 限制
頻率 每個 API Key 每 60 秒 1000 次(涵蓋所有 /v1/* 端點合計)

每次回應都會帶以下標頭:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997
X-RateLimit-Reset: 1704067260000

超過限制回 HTTP 429,並帶 Retry-After: 60 標頭:

{ "success": false, "errorCode": "RATE_LIMIT_EXCEEDED", "message": "請求過於頻繁,請稍後再試", "retryAfter": 60 }

請依 X-RateLimit-Remaining 主動節流,並在收到 429 時依 Retry-After 退避重試。


3. 通用約定

3.1 回應格式

所有 /v1/* 端點都使用相同的封裝:

成功

{
  "success": true,
  "data": { },
  "timestamp": 1704067200000
}

失敗

{
  "success": false,
  "errorCode": "0001012",
  "message": "訂單不存在",
  "timestamp": 1704067200000
}

⚠️ 極重要:請務必檢查 body 中的 success 欄位,不要只看 HTTP 狀態碼。 部分業務失敗(例如查無訂單)會回 HTTP 200 但 success: false。

欄位 說明
success true / false,判斷成敗的唯一依據
data 成功時的資料內容;無資料時此欄位不出現
errorCode 失敗時才有。請視為不透明字串(格式不一,有數字碼也有英文碼)
message 失敗原因說明(中文)
timestamp 伺服器時間,Unix 毫秒

3.1.1 失敗回應的三種結構(重要)

平台的失敗回應不只一種結構,取決於錯誤發生在哪一層。請務必三種都能解析。

結構 A — 業務失敗(最常見)

通過認證、進到業務邏輯後才失敗。/v1/* 端點的絕大多數錯誤都是這種。

{
  "success": false,
  "errorCode": "0001011",
  "message": "餘額不足或凍結失敗: 可用餘額不足",
  "timestamp": 1704067200000
}

結構 B — 欄位格式驗證失敗

請求欄位不符規格(必填漏帶、超長、金額 ≤ 0 等),在進入業務邏輯之前就被擋下。

{
  "code": 400,
  "errorCode": "0001002",
  "message": "商戶訂單號不能為空, 金額必須大於0",
  "timestamp": "2026-08-08T12:00:00"
}

⚠️ 注意:這個結構沒有 success 欄位,且 timestamp 是 ISO 字串而非毫秒數。 多個欄位同時有誤時,message 會以 , 串接全部錯誤。 解析時請先判斷 success 是否存在,不存在時改看 code。

結構 C — 認證/流量限制失敗

在認證層被擋下,請求不會進到業務邏輯。

{
  "success": false,
  "errorCode": "INVALID_SIGNATURE",
  "message": "簽名驗證失敗",
  "timestamp": 1704067200000
}

流量限制(HTTP 429)會多一個 retryAfter 欄位(秒),並在回應標頭帶 Retry-After:

{
  "success": false,
  "errorCode": "RATE_LIMIT_EXCEEDED",
  "message": "請求過於頻繁,請稍後再試",
  "retryAfter": 60,
  "timestamp": 1704067200000
}

建議的解析順序

1. body 有 success 欄位?
   ├─ 有 → success === false 即失敗,讀 errorCode / message
   └─ 沒有 → 屬結構 B(欄位驗證失敗),讀 code / errorCode / message
2. 永遠不要只用 HTTP 狀態碼判斷成敗

3.1.2 關於 message 與 errorCode

用途
errorCode 程式判斷請用這個。值域穩定,不會隨版本變動措辭
message 僅供人工排查與記錄。內容是動態文字(例如 閘道呼叫失敗: ... 後面接實際通道回傳的原因),會隨情境與版本改變,請勿用字串比對來做邏輯判斷

特別是 0001011(業務規則錯誤):餘額不足、通道不可用、超出限額、風控攔截等都回這個碼, 實際原因只在 message。建議完整記錄 message 以利與平台對帳排查。

3.2 金額與時間格式

項目 格式
金額 數字,最多 2 位小數。整數部分上限 12 位
幣別 ISO 4217,如 PHP、HKD
時間 ISO 8601,如 2026-08-08T12:00:00(無時區位移,為伺服器當地時間)

建議:currency 請明確帶值,不要依賴系統預設。

3.3 訂單狀態

代收(Collection)

狀態 說明 是否終態
PENDING 已建立,等待付款 ❌
PROCESSING 處理中 ❌
SUCCESS 收款成功 ✅
FAILED 收款失敗 ✅
EXPIRED 逾期未付 ✅
CANCELLED 已取消 ✅

代付(Payout)

狀態 說明 是否終態
PENDING 待處理 ❌
PROCESSING 處理中 ❌
SUCCESS 付款成功 ✅
FAILED 付款失敗 ✅
REJECTED 已駁回 ✅
REVERSED 已沖正 ✅
CANCELLED 已取消 ✅

3.4 冪等機制(重要)

兩個建單端點都以 merchantOrderNo 做冪等控制:

重送相同 merchantOrderNo 時,系統會回傳「原本那筆訂單的當前狀態」, 並且 success: true——不會建立第二筆,也不會回錯誤。

因此:

強烈建議:每筆訂單都帶上您自己系統的唯一訂單號。


4. 代收 API

4.1 建立代收訂單

POST /v1/collection/create      權限:WRITE

請求欄位

欄位 型別 必填 限制 說明
merchantOrderNo string ✅ ≤64 您的訂單號,冪等依據
amount decimal ✅ ≥0.01,最多 2 位小數 訂單金額
currency string ≤10 幣別,建議明確帶值。可帶 USDT 等外幣,系統依平台匯率換算成 PHP 收款,詳見 §11
payerName string ≤100 付款人姓名,菲律賓站選填(通道回調可能覆寫)
payerAccount string ≤100 付款人帳號(通道回調可能覆寫)
merchantPayerAccount string ≤100 您的自訂識別(如會員 ID),不會被覆寫
channelCode string ✅ ≤50 指定支付方式,必填。PH1001 GCash QR/PH1002 QRPH。可用值請呼叫 /v1/channels 取得
remark string ≤500 備註
expireMinutes int 1–10080 訂單有效期,預設 15 分鐘;實際到期以回應的 expireAt 為準
invoiceNo string ≤64 發票號
callbackUrl string ≤500 本筆訂單專用的回調網址,覆蓋您在後台設定的 Webhook URL;留空則使用後台設定
returnUrl string ≤500 付款完成後的返回網址(2026-10-02 起)。須為 http / https 絕對網址,格式不符回 0001002。詳見下方說明
extraData string ≤1000 自訂資料,會原樣回傳,也會出現在 Webhook

回應欄位

欄位 型別 說明
merchantOrderNo string 您的訂單號
systemTransactionNo string 平台訂單號,請保存供後續查詢
amount decimal 訂單金額
fee decimal 手續費
netAmount decimal 實際入帳金額 = amount − fee
currency string 幣別
status string 訂單狀態
cashierUrl string 收銀台網址,請導向您的客戶前往付款
expireAt string 過期時間
createdAt string 建立時間
extraData string 原樣回傳
failureReason / failureCode string 失敗時才有

範例

// 請求
{
  "merchantOrderNo": "M202608080001",
  "amount": 1000.00,
  "currency": "PHP",
  "expireMinutes": 30,
  "returnUrl": "https://merchant.com/payment/result",
  "extraData": "{\"userId\":8891}"
}

// 回應
{
  "success": true,
  "data": {
    "merchantOrderNo": "M202608080001",
    "systemTransactionNo": "COL202608080001",
    "amount": 1000.00,
    "fee": 15.00,
    "netAmount": 985.00,
    "currency": "PHP",
    "status": "PENDING",
    "cashierUrl": "https://cashier.kawinpay-ph.com/pay/abcd1234",
    "expireAt": "2026-08-08T12:30:00",
    "createdAt": "2026-08-08T12:00:00",
    "extraData": "{\"userId\":8891}"
  },
  "timestamp": 1786000000000
}

代收手續費為內扣:訂單 1000、手續費 15 → 您實際入帳 985。

失敗回應範例

// 業務失敗(HTTP 400)— 例如商戶可入帳餘額已達上限
{
  "success": false,
  "errorCode": "0001011",
  "message": "商戶餘額將達上限,無法建立此筆代收。上限 1000000.00,目前可入帳上限剩餘 320.00",
  "timestamp": 1786000000000
}

// 欄位驗證失敗(HTTP 400)— 注意此結構沒有 success 欄位
{
  "code": 400,
  "errorCode": "0001002",
  "message": "商戶訂單號不能為空, 金額必須大於0",
  "timestamp": "2026-08-08T12:00:00"
}

本端點可能的失敗

HTTP errorCode 說明
400 0001002 欄位驗證失敗(結構 B)、callbackUrl 未通過安全檢查,或 returnUrl 不是 http / https 絕對網址
403 0001010 API Key 沒有寫入權限(需 WRITE)
400 0001011 業務規則錯誤,實際原因見 message。常見:餘額上限、單筆金額超限、代收功能已關閉、付款人黑名單、風控攔截、閘道呼叫失敗: ...(所有候選通道都送單失敗)
500 0001001 系統異常,退避後重試

payerName(付款人姓名)在菲律賓站為選填。

returnUrl 付款後返回商戶頁面(2026-10-02 起)

訂單成功、失敗或逾時後,收銀台會顯示倒數,約 3 秒後將付款人轉回 returnUrl, 並附加以下查詢參數(已 URL 編碼;原網址已有 ? 時以 & 接續):

參數 說明
status success(成功)/failed(失敗或已取消)/expired(逾時)
merchantOrderNo 您的訂單號
systemTransactionNo 平台訂單號

範例:https://merchant.com/payment/result?status=success&merchantOrderNo=M202608080001&systemTransactionNo=COL202608080001

⚠️ returnUrl 僅供頁面跳轉,不可作為入帳依據:網址參數可被付款人竄改。 訂單結果請一律以 Webhook 回調(§8)或查詢 API(§4.2)為準。 未帶 returnUrl 時,收銀台停留在結果頁,行為與先前相同。

重送同一 merchantOrderNo 不會重複建單:平台以商戶訂單號做冪等, 重送會直接回傳既有訂單的成功回應(見 §3.4)。

4.2 查詢代收訂單

POST /v1/collection/query       權限:READ

請求:merchantOrderNo 與 systemTransactionNo 至少擇一(兩者皆有時以後者優先)。

{ "merchantOrderNo": "M202608080001" }

回應:同 4.1 的訂單欄位。

情況 HTTP errorCode
兩個訂單號都沒帶 400 0001002
查無訂單 200 0001012(success: false)
訂單屬於其他商戶 403 1001004
系統異常 500 0001001

失敗回應範例

// 查無訂單 —— 注意這是 HTTP 200
{
  "success": false,
  "errorCode": "0001012",
  "message": "訂單不存在",
  "timestamp": 1786000000000
}

// 訂單屬於其他商戶(HTTP 403)
{
  "success": false,
  "errorCode": "1001004",
  "message": "無權訪問此訂單",
  "timestamp": 1786000000000
}

⚠️ 查無訂單回的是 HTTP 200,不是 404。若您的程式只檢查 HTTP 狀態碼, 會把「查無此單」誤判為查詢成功。請務必檢查 success 欄位。

4.3 查詢代收列表

POST /v1/collection/list        權限:READ

請求欄位

欄位 型別 必填 說明
status string 訂單狀態;帶入無效值會造成錯誤,請使用 3.3 節的合法值
startTime string ISO 8601,如 2026-08-01T00:00:00
endTime string ISO 8601
page int 從 1 起算,預設 1
pageSize int 1–100,預設 20

回應

{
  "success": true,
  "data": {
    "orders": [ /* 訂單陣列 */ ],
    "pagination": {
      "page": 1, "pageSize": 20, "totalCount": 150,
      "totalPages": 8, "hasNext": true, "hasPrevious": false
    }
  },
  "timestamp": 1786000000000
}

失敗回應範例

// 分頁參數超出範圍(HTTP 400,結構 B)
{
  "code": 400,
  "errorCode": "0001002",
  "message": "每頁筆數最大為 100",
  "timestamp": "2026-08-08T12:00:00"
}
HTTP errorCode 說明
400 0001002 page < 1 或 size 不在 1~100
403 0001010 API Key 沒有讀取權限
500 0001001 系統異常

⚠️ 請先確認參數格式:status 傳入非法值、或 startTime / endTime 非 YYYY-MM-DDTHH:mm:ss 格式時,目前會回 HTTP 500 0001001 而非參數錯誤。 查無資料不是失敗,會回 success: true 且列表為空陣列。

4.4 取消代收訂單

POST /v1/collection/cancel      權限:WRITE

請求:merchantOrderNo 或 systemTransactionNo(擇一)+ reason(選填,≤200)。

僅 PENDING 或 PROCESSING 狀態可取消,其他狀態回 HTTP 400、errorCode = 0001013。

失敗回應範例

// 狀態不允許取消(HTTP 400)
{
  "success": false,
  "errorCode": "0001013",
  "message": "當前狀態不允許取消",
  "timestamp": 1786000000000
}

// 查無訂單 —— HTTP 200
{
  "success": false,
  "errorCode": "0001012",
  "message": "訂單不存在",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
400 0001002 兩個訂單號都沒帶
200 0001012 查無訂單
403 1001004 訂單屬於其他商戶
403 0001010 API Key 沒有寫入權限
400 0001013 僅 PENDING / PROCESSING 可取消
500 0001001 系統異常

4.5 產生 QR Code

POST /v1/collection/qr/generate  權限:WRITE

此端點會同時建立一筆代收訂單並回傳 QR 相關資訊。

請求欄位:merchantOrderNo(必填)、amount(必填)、channelCode(必填)、currency、expireMinutes、remark(≤200)、extraData。

回應欄位:merchantOrderNo、systemTransactionNo、amount、currency、qrCodeUrl、qrCodeData(EMVCo 原始字串)、cashierUrl、deepLinkUrl、expireAt、createdAt、extraData。

注意:qrCodeUrl / qrCodeData / deepLinkUrl 是否有值,取決於實際路由到的支付通道。 部分通道不產生 QR,此時這些欄位為空,請改用 cashierUrl。

失敗回應範例

// 業務失敗(HTTP 400)
{
  "success": false,
  "errorCode": "0001011",
  "message": "閘道呼叫失敗: [通道選擇失敗] 無可用的代收通道,請檢查金額範圍和通道配置",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
400 0001002 欄位驗證失敗(結構 B)
403 0001010 API Key 沒有寫入權限
400 0001011 業務規則錯誤,與 §4.1 相同(本端點會實際建立一筆代收訂單)
500 0001001 系統異常

HK 站注意:本端點不傳 payerName,而 HK 站該欄為必填, 因此在 HK 站呼叫會回 0001011 + 付款人姓名不能為空。HK 站請改用 §4.1 建單。

4.6 查詢 QR Code

POST /v1/collection/qr/inquire   權限:READ

用於驗證一組 QR Code 是否有效、以及對應訂單的目前狀態。

請求

欄位 型別 必填 說明
qrCode string ✅ QR Code 的原始字串(EMVCo 格式)

回應欄位

欄位 說明
qrId QR 的關聯識別碼
merchantOrderNo / systemTransactionNo 對應的訂單號
merchantName QR 上的收款方顯示名稱
amount 應付金額
currency 幣別
status 見下表
isValid 是否仍可付款
expireAt / createdAt 時間
errorMessage 無法解析或查無訂單時的說明

status 對照

值 意義 isValid
VALID 有效,可付款 true
PAID 已完成付款 false
EXPIRED 已過期 false
CANCELLED 訂單已取消 false
FAILED 訂單已失敗 false
NOT_FOUND 查無對應訂單 false
INVALID 無法解析,或非本平台產生的 QR false
// 請求
{ "qrCode": "00020101021228...6304A1B2" }

// 回應
{
  "success": true,
  "data": {
    "qrId": "REF20260808001",
    "merchantOrderNo": "M202608080001",
    "systemTransactionNo": "COL202608080001",
    "amount": 1000.00,
    "currency": "PHP",
    "status": "VALID",
    "isValid": true,
    "expireAt": "2026-08-08T12:30:00",
    "createdAt": "2026-08-08T12:00:00"
  },
  "timestamp": 1786000000000
}

查詢他人的訂單會回 HTTP 403、errorCode = 1001004。


失敗回應範例

// QR 無法解析或非本平台產生 —— 注意 success 是 true
{
  "success": true,
  "data": {
    "status": "INVALID",
    "isValid": false,
    "errorMessage": "無法解析此 QR Code,或該 QR Code 非本平台產生"
  },
  "timestamp": 1786000000000
}

// 查無對應訂單 —— success 同樣是 true
{
  "success": true,
  "data": {
    "qrId": "REF123456",
    "status": "NOT_FOUND",
    "isValid": false,
    "errorMessage": "查無此 QR Code 對應的訂單"
  },
  "timestamp": 1786000000000
}

⚠️ 本端點是例外:QR 解析不出、或查無對應訂單時,回的是 success: true, 沒有 errorCode,錯誤說明在 data.errorMessage。 請改以 data.isValid 與 data.status(INVALID / NOT_FOUND)判斷。

HTTP errorCode 說明
403 0001010 API Key 沒有讀取權限
403 1001004 QR 對應的訂單屬於其他商戶
500 0001001 系統異常(含 QR 字串完全非 EMVCo 格式)

5. 代付 API

5.1 建立代付訂單

POST /v1/payout/create          權限:WRITE

⚠️ 重要:透過 API 建立的代付「不經過審核」,直接送出執行。 請在您自己的系統內做好風控與覆核,避免誤付。

請求欄位

欄位 型別 必填 限制 說明
merchantOrderNo string ✅ ≤64 您的訂單號,冪等依據
amount decimal ✅ ≥0.01,最多 2 位小數 付款金額
currency string ≤10 幣別,建議明確帶值。可帶 USDT 等外幣,系統依平台匯率換算成 PHP 收款,詳見 §11
beneficiaryName string ✅ ≤100 收款人姓名,須與帳戶登記名一致
beneficiaryAccount string ✅ ≤100 收款帳號
beneficiaryBank string ≤100 不需傳入;系統會由 institutionCode 自動帶出銀行名稱
institutionCode string ✅ ≤50 收款機構代碼,必填,請由 /v1/institutions 取得,勿自行拼湊
channelCode string ✅ ≤50 指定通道,必填。PH2001 InstaPay/PH2002 PESONet。可用值請呼叫 /v1/channels?productType=PAYOUT 取得
remark string ≤500 備註
callbackUrl string ≤500 本筆訂單專用的回調網址,覆蓋後台設定;留空則使用後台設定
extraData string ≤1000 自訂資料,原樣回傳

回應欄位

欄位 型別 說明
merchantOrderNo string 您的訂單號
systemTransactionNo string 平台訂單號
amount decimal 付款金額(收款人實收金額)
fee decimal 手續費
totalAmount decimal 您實際被扣款的金額 = amount + fee
currency string 幣別
beneficiaryName string 收款人姓名
beneficiaryAccount string 收款帳號(已遮罩,如 6228****6789)
status string 訂單狀態
completedAt / createdAt string 時間
failureReason string 失敗時才有
extraData string 原樣回傳

範例

// 請求
{
  "merchantOrderNo": "P202608080001",
  "amount": 5000.00,
  "currency": "PHP",
  "beneficiaryName": "Juan Dela Cruz",
  "beneficiaryAccount": "6228480123456789",
  "institutionCode": "BNORPHMM_TRIXON_INSTAPAY"
}

// 回應
{
  "success": true,
  "data": {
    "merchantOrderNo": "P202608080001",
    "systemTransactionNo": "APP202608080001",
    "amount": 5000.00,
    "fee": 25.00,
    "totalAmount": 5025.00,
    "currency": "PHP",
    "beneficiaryName": "Juan Dela Cruz",
    "beneficiaryAccount": "6228****6789",
    "status": "PENDING",
    "createdAt": "2026-08-08T12:00:00"
  },
  "timestamp": 1786000000000
}

代付手續費為外扣:收款人收到 5,000,您的餘額扣 5,025。 建單時系統會先凍結 totalAmount,餘額不足會建單失敗。

失敗回應範例

// 餘額不足(HTTP 400)
{
  "success": false,
  "errorCode": "0001011",
  "message": "餘額不足或凍結失敗: 可用餘額不足",
  "timestamp": 1786000000000
}

// 收款銀行未帶(HTTP 400)
{
  "success": false,
  "errorCode": "0001002",
  "message": "收款銀行不能為空",
  "timestamp": 1786000000000
}

本端點可能的失敗

HTTP errorCode 說明
400 0001002 欄位驗證失敗(結構 B)、callbackUrl 未通過安全檢查、或未帶 institutionCode(FPS 通道除外)
403 0001010 API Key 沒有寫入權限(需 WRITE)
400 0001011 業務規則錯誤,常見:餘額不足、單筆金額超限、代付功能已關閉、風控攔截、無效的通道代碼、商戶未配置該平台產品的供應商偏好
400 2001001 商戶不存在
500 0001001 系統異常

⚠️ 建單成功 ≠ 出款成功:本端點回傳成功只代表訂單已受理。 實際送往銀行/通道是非同步進行的,路由或閘道失敗不會反映在這個回應裡。 請務必透過 Webhook 回調(§8)或 §5.2 查詢代付訂單確認最終結果。

channelCode 常見誤用:此欄要填平台產品代碼(如 PH2001)或通道產品代碼, 不是銀行代碼。要指定收款銀行請用 institutionCode。

5.2 查詢代付訂單

POST /v1/payout/query           權限:READ

請求與行為同 4.2。

失敗回應範例

// 查無訂單 —— HTTP 200
{
  "success": false,
  "errorCode": "0001012",
  "message": "訂單不存在",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
400 0001002 兩個訂單號都沒帶
200 0001012 查無訂單
403 1001004 訂單屬於其他商戶
403 0001010 API Key 沒有讀取權限
500 0001001 系統異常

⚠️ 同 §4.2:查無訂單回 HTTP 200,請檢查 success 欄位。

5.3 查詢代付列表

POST /v1/payout/list            權限:READ

請求與回應格式同 4.3。

失敗回應範例

// 分頁參數超出範圍(HTTP 400,結構 B)
{
  "code": 400,
  "errorCode": "0001002",
  "message": "每頁筆數最大為 100",
  "timestamp": "2026-08-08T12:00:00"
}
HTTP errorCode 說明
400 0001002 page < 1 或 size 不在 1~100
403 0001010 API Key 沒有讀取權限
500 0001001 系統異常

⚠️ 同 §4.3:status 非法值或時間格式錯誤目前會回 HTTP 500。 查無資料不是失敗,會回 success: true 與空陣列。

5.4 取消代付訂單

POST /v1/payout/cancel          權限:WRITE

請求:merchantOrderNo 或 systemTransactionNo + reason(選填)。

僅未執行的訂單可取消。取消成功後狀態為 REJECTED。


失敗回應範例

// 狀態不允許取消(HTTP 400)
{
  "success": false,
  "errorCode": "0001013",
  "message": "當前狀態不允許取消",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
400 0001002 兩個訂單號都沒帶
200 0001012 查無訂單
403 1001004 訂單屬於其他商戶
403 0001010 API Key 沒有寫入權限
400 0001013 當前狀態不允許取消
500 0001001 系統異常

⚠️ API 建立的代付單無法用本端點取消:本端點僅接受 PENDING_APPROVAL / APPROVED 狀態,而透過 API 建立的代付單起始狀態為 PROCESSING, 呼叫必定回 0001013。如需中止,請聯繫平台人工處理。

6. 查詢類 API

6.1 查詢餘額

GET /v1/balance                 權限:READ
{
  "success": true,
  "data": {
    "merchantCode": "merchant01",
    "balances": [
      {
        "currency": "PHP",
        "availableBalance": 100000.00,
        "frozenBalance": 5000.00,
        "pendingBalance": 20000.00,
        "totalBalance": 125000.00
      }
    ]
  },
  "timestamp": 1786000000000
}
欄位 說明
availableBalance 可用餘額,可用於建立新交易
frozenBalance 鎖定中金額(代付/下發處理中)
pendingBalance 待結算金額(T+N 尚未到期)
totalBalance 總餘額

失敗回應範例

{
  "success": false,
  "errorCode": "2001001",
  "message": "商戶不存在",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
403 0001010 API Key 沒有讀取權限
400 2001001 商戶不存在(注意是 400,不是 404)
500 0001001 系統異常

6.2 查詢可用支付方式

GET /v1/channels?productType=COLLECTION      權限:READ

productType 可帶 COLLECTION 或 PAYOUT,留空回全部。

{
  "success": true,
  "data": {
    "channels": [
      {
        "channelCode": "PH1001",
        "channelName": "GCash QR",
        "channelType": "COLLECTION",
        "supportedCurrencies": ["PHP"],
        "minAmount": 1.00,
        "maxAmount": 50000.00,
        "available": true
      }
    ]
  },
  "timestamp": 1786000000000
}

只會回傳已為您開通的支付方式。channelCode 可直接用於建單的 channelCode 欄位。

失敗回應範例

{
  "success": false,
  "errorCode": "0001010",
  "message": "API Key 沒有讀取權限",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
403 0001010 API Key 沒有讀取權限
500 0001001 系統異常

查無可用通道不是失敗:會回 success: true,data.channels 為空陣列。

6.3 查詢收款機構清單

GET /v1/institutions            權限:READ
{
  "success": true,
  "data": [
    {
      "institutionCode": "BNORPHMM_TRIXON_INSTAPAY",
      "institutionName": "BDO Unibank",
      "institutionType": "BANK",
      "channelProductId": 12
    }
  ],
  "timestamp": 1786000000000
}

代付建單時的 institutionCode 請由此端點取得,不要自行拼湊。

失敗回應範例

{
  "success": false,
  "errorCode": "0001010",
  "message": "API Key 沒有讀取權限",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
403 0001010 API Key 沒有讀取權限
500 0001001 系統異常

查無機構不是失敗:會回 success: true 與空陣列。

6.4 查詢收付款帳號

POST /v1/payment-accounts/list  權限:READ

回傳您已設定的收付款帳號清單(id、accountName、accountType、status、currency、collectEnabled、payoutEnabled)。


失敗回應範例

{
  "success": false,
  "errorCode": "0001010",
  "message": "API Key 沒有讀取權限",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
403 0001010 API Key 沒有讀取權限
500 0001001 系統異常

7. 對帳單 API

7.1 查詢日結對帳單

POST /v1/statement/daily        權限:READ

請求:date(必填,YYYY-MM-DD)。

{
  "success": true,
  "data": {
    "date": "2026-08-07",
    "merchantCode": "merchant01",
    "currency": "PHP",
    "summary": {
      "collectionCount": 100, "collectionAmount": 50000.00, "collectionFee": 750.00,
      "payoutCount": 50,      "payoutAmount": 30000.00,     "payoutFee": 150.00,
      "withdrawalCount": 5,   "withdrawalAmount": 10000.00, "withdrawalFee": 50.00,
      "netSettlement": 19050.00,
      "openingBalance": 120000.00,
      "closingBalance": 139050.00
    },
    "details": [
      {
        "systemTransactionNo": "COL202608070001",
        "merchantOrderNo": "M202608070001",
        "transactionType": "COLLECTION",
        "channelCode": "PH1002",
        "amount": 1000.00,
        "fee": 15.00,
        "netAmount": 985.00,
        "status": "SUCCESS",
        "completedAt": "2026-08-07T09:15:22"
      }
    ]
  },
  "timestamp": 1786000000000
}

summary 欄位說明

欄位 說明
openingBalance 期初餘額(前一日收盤總餘額)
closingBalance 期末餘額(當日收盤總餘額)
netSettlement 淨結算 = 代收淨額 − 代付金額 − 下發金額

⚠️ 餘額欄位可能為 null:若該日尚無餘額快照(例如商戶當日才建立, 或查詢日期早於平台啟用),會回 null 而非 0,以便您分辨「餘額為零」與「無資料」。

details 欄位說明

欄位 說明
transactionType COLLECTION / PAYOUT / WITHDRAWAL
amount 訂單金額
fee 手續費
netAmount 代收 = 實際入帳(amount − fee);代付/下發 = 實際扣款(amount + fee)
completedAt 完成時間,明細依此由早到晚排序

統計與明細範圍皆僅含「成功」的交易。

⚠️ 明細筆數上限 1,000 筆。若當日成功交易超過此數量,details 會被截斷, 請改用 7.2 的 CSV 下載 取得完整明細。

失敗回應範例

{
  "success": false,
  "errorCode": "2001001",
  "message": "商戶不存在",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
403 0001010 API Key 沒有讀取權限
400 2001001 商戶不存在
500 0001001 系統異常

⚠️ date 格式必須是 YYYY-MM-DD:格式錯誤目前會回 HTTP 500 0001001, 而非參數錯誤,請於送出前自行校驗。

明細上限 1000 筆:超過時會靜默截斷只回前 1000 筆,回應中沒有截斷標記。 交易量大的日期請改用 §7.2 下載 CSV。

7.2 下載對帳單 CSV

GET /v1/statement/download?date=2026-08-07   權限:READ

回傳 text/csv(UTF-8),欄位依序為:

Transaction No, Merchant Order No, Type, Channel, Amount, Fee, Net Amount, Status, Completed At

僅含當日成功的代收與代付紀錄。


失敗回應範例

// 注意:本端點成功時回的是 CSV 純文字,只有失敗時才是 JSON
{
  "success": false,
  "errorCode": "0001010",
  "message": "API Key 沒有讀取權限",
  "timestamp": 1786000000000
}
HTTP errorCode 說明
403 0001010 API Key 沒有讀取權限
500 0001001 系統異常(含 date 格式錯誤、或未帶 date)

⚠️ 本端點的回應有兩種型別: 成功回 text/csv 純文字(帶 Content-Disposition: attachment), 失敗才回 JSON。請先檢查 Content-Type 再決定用哪種方式解析, 不要一律套用 JSON parser。

8. Webhook 回調

當訂單狀態變更時,平台會主動 POST 通知您設定的 Webhook URL。

8.0 指定單筆訂單的回調網址

建單時可帶 callbackUrl,只有這一筆訂單的通知會送到該網址,覆蓋您在後台設定的 Webhook URL。 適合「不同業務線用不同接收端點」的情境。留空則沿用後台設定。

限制(不符會回 HTTP 400、errorCode = 0001002):

規則 說明
協定 必須是 http 或 https 的絕對網址(建議用 https)
長度 ≤ 500 字元
禁止 不可指向 localhost、127.0.0.1 等本機位址
禁止 不可指向內部網段(10.x、192.168.x、172.16~31.x、169.254.x)

這些限制是為了防止回調被導向內部服務,屬平台安全機制。 請提供可從公網存取的網址。

相同規則也適用於商戶後台的 Webhook 設定(新增與修改皆會驗證)。 若您在後台儲存 Webhook URL 時收到「不可指向本機位址/內部網段」的提示,原因即在此。

8.1 事件類型

event 觸發時機
payment.success 代收成功
payment.failed 代收失敗
refund.success / refund.failed 退款結果
withdrawal.success / withdrawal.failed 代付結果/下發結果

8.2 回調格式

{
  "event": "payment.success",
  "timestamp": 1786000000,
  "data": {
    "merchantOrderNo": "M202608080001",
    "systemTransactionNo": "COL202608080001",
    "status": "SUCCESS",
    "amount": 1000.00,
    "fee": 15.00,
    "netAmount": 985.00,
    "currency": "PHP",
    "completedAt": "2026-08-08T12:05:30",
    "extraData": "{\"userId\":8891}"
  }
}
欄位 說明
event 事件名稱
timestamp Unix 時間戳,單位為「秒」
data 事件內容,欄位依事件類型而異

⚠️ data 內的欄位可能隨版本增加。請以「取用您需要的欄位」的方式解析, 不要用嚴格 schema 驗證,以免平台新增欄位時您的系統報錯。 請以 merchantOrderNo/systemTransactionNo 定位訂單,以 status 判斷結果。

代付/下發回調

代付(withdrawal.success / withdrawal.failed)的 data 範例:

{
  "event": "withdrawal.success",
  "timestamp": 1786000000,
  "data": {
    "merchantOrderNo": "P202608080001",
    "systemTransactionNo": "APP202608080001",
    "applicationNo": "APP202608080001",
    "status": "SUCCESS",
    "amount": 1000.00,
    "currency": "PHP",
    "beneficiaryName": "Juan Dela Cruz",
    "beneficiaryAccount": "09171234567",
    "beneficiaryBank": "GCASH",
    "completedAt": "2026-08-08T12:05:30"
  }
}
欄位 說明
merchantOrderNo 您的訂單號(建議以此定位訂單)
systemTransactionNo 平台訂單號,三種交易皆有此欄位,代付即為 applicationNo
applicationNo 代付申請單號(與 systemTransactionNo 同值)

💡 merchantOrderNo 與 systemTransactionNo 三種交易(代收/代付/下發)皆有, 若您想用同一套程式處理所有回調,直接取這兩個欄位即可。

相容欄位說明

為相容早期介接的商戶,部分回調的 data 內會同時出現蛇形命名的重複欄位 (例如 merchant_order_id 之於 merchantOrderNo、completed_at 之於 completedAt), 兩者值完全相同。

新介接請一律使用本文件列出的駝峰欄位;蛇形欄位屬過渡相容,未來版本會移除。

8.3 驗證回調簽章(必做)

回調請求會帶以下標頭:

X-Timestamp: 1786000000        (秒)
X-Nonce:     3f2a9c1e...
X-Signature: a1b2c3d4...=      (Base64)

驗證步驟:

  1. 取出 X-Timestamp、X-Nonce、X-Signature 與 raw body 原始字串

  2. 檢查 |現在時間 − X-Timestamp| ≤ 300 秒,超過則拒絕

  3. 檢查 X-Nonce 是否已處理過(請自行儲存 5 分鐘,防重放)

  4. 用簽章金鑰計算:

    Base64( HMAC-SHA256( 簽章金鑰, timestamp + "." + nonce + "." + raw_body ) )
    

    ⚠️ 用哪一把金鑰,取決於這筆回調怎麼設定的:

    情境 簽章金鑰
    建單時帶 callbackUrl(per-order 回調) API Secret(與您呼叫 API 用的同一把)
    在商戶後台設定 Webhook URL Webhook Secret

    兩者演算法完全相同,只差在金鑰。若您沒有在後台設定 Webhook、 只在建單時帶 callbackUrl,請直接用 API Secret 驗章。

  5. 與 X-Signature 比對(建議用常數時間比較函式)

  6. 全部通過才處理內容

Node.js 範例

const crypto = require('crypto');

function verifyWebhook(req, secret) {
  const ts    = req.headers['x-timestamp'];
  const nonce = req.headers['x-nonce'];
  const sig   = req.headers['x-signature'];
  const raw   = req.rawBody;                  // 必須是「原始字串」,不可用解析後再序列化的結果

  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  // 另需自行檢查 nonce 是否重複

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${ts}.${nonce}.${raw}`)
    .digest('base64');

  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

⚠️ 務必使用 raw body。若您的框架(如 Express 的 express.json())已把 body 解析成物件, 再 JSON.stringify() 回去,字串很可能與原始位元組不同,導致驗章失敗。 Express 請於 express.json({ verify: (req, res, buf) => { req.rawBody = buf.toString(); } }) 保留原文。

8.4 您應該回應什麼

2026-10-05 起,平台收到以下回應才視為「已送達」,否則視為失敗並依 8.5 重送:

項目 要求
HTTP 狀態碼 2xx
回應內容 必須為 SUCCESS 或 OK(不分大小寫,前後空白不影響)
回應時間 建議 5 秒內(逾時上限 30 秒)
您的回應內容 結果
SUCCESS、success、OK、ok ✅ 已送達,不再重送
"SUCCESS"(JSON 字串) ✅ 已送達
空白、FAILED、received、{"code":"SUCCESS"} 等其他內容 ❌ 視為失敗,依 8.5 重送
非 2xx(如 500)、逾時、無法連線 ❌ 視為失敗,依 8.5 重送

回應內容不符時,平台後台的訂單「失敗原因」會顯示您實際回覆的內容,方便雙方排查。

回應範例

# Python (Flask)
return "SUCCESS", 200, {"Content-Type": "text/plain"}
// Node.js (Express)
res.status(200).type("text/plain").send("SUCCESS");
// PHP
http_response_code(200);
echo "SUCCESS";
// Java (Spring)
return ResponseEntity.ok("SUCCESS");

建議做法:驗章通過後先回 SUCCESS,再非同步處理業務邏輯。 若您同步處理耗時過久導致逾時,平台會視為失敗並重送,可能造成重複處理。

驗章失敗或業務處理失敗、希望平台稍後重送時,回任何非 SUCCESS / OK 的內容即可(例如 FAILED)。

8.5 重試機制

回調失敗(非 2xx、逾時、無法連線,或回應內容不是 SUCCESS / OK)時,平台會自動重試,採指數退避:

次數 距上次的間隔
第 1 次重試 10 秒
第 2 次重試 20 秒
第 3 次重試 40 秒
第 4 次重試 80 秒
第 5 次重試 160 秒

預設共重試 5 次(首次發送後合計約 5 分鐘)。若您在商戶後台的 Webhook 設定中調整過重試次數或間隔,以您的設定為準。 全數失敗後即不再自動重送,訂單的回調狀態會標為「回調失敗」;請聯繫平台人工重送,或改用主動查詢(8.6)取得結果。

熔斷保護:若您的端點連續失敗 5 次,平台會暫停發送 5 分鐘,之後再嘗試恢復。

8.6 ⭐ 請務必實作主動查詢

Webhook 是「盡力送達」,不保證 100% 到達。

請務必額外實作主動輪詢機制:對於超過預期時間仍為 PENDING / PROCESSING 的訂單, 定期呼叫 /v1/collection/query 或 /v1/payout/query 確認最終狀態。

建議策略:建單後 5 分鐘、15 分鐘、30 分鐘各查詢一次,直到訂單進入終態。

8.7 冪等處理(必做)

由於有重試機制,同一筆通知可能送達多次。請以 merchantOrderNo 或 systemTransactionNo 為鍵做冪等控制,確保重複收到時不會重複入帳。


9. 錯誤碼

9.1 認證類(HTTP 401 / 403)

errorCode HTTP 原因 處理建議
MISSING_API_KEY 401 缺少 X-API-Key 檢查標頭
MISSING_SIGNATURE 401 缺少 X-Signature 檢查標頭
MISSING_TIMESTAMP 401 缺少 X-Timestamp 檢查標頭
MISSING_NONCE 401 缺少 X-Nonce 檢查標頭
INVALID_TIMESTAMP 400 時間戳格式錯誤 應為數字字串(秒)
INVALID_API_KEY 401 API Key 不存在 確認金鑰與環境是否對應
API_KEY_DISABLED 401 API Key 已停用 聯繫平台
API_KEY_EXPIRED 401 API Key 已過期 申請新金鑰
INVALID_SIGNATURE 401 簽章錯誤或時間戳超出 ±5 分鐘 先檢查伺服器時鐘,再檢查簽章串接與 Base64
INVALID_NONCE 401 Nonce 重複使用 每次請求產生新的 nonce
IP_NOT_ALLOWED 403 來源 IP 不在白名單 確認對外出口 IP 並請平台加入
MERCHANT_DISABLED 403 商戶帳號已停用 聯繫平台
API_DISABLED 403 商戶未開通 API 功能 聯繫平台

9.2 業務類

errorCode HTTP 意義 處理建議
0001002 400 參數錯誤(如兩個訂單號都沒帶) 檢查請求
0001010 403 API Key 權限不足 申請對應權限
0001011 400 業務規則錯誤(餘額不足、通道不可用、風控攔截等) 請看 message 內容判斷實際原因
0001012 200 查無訂單 確認訂單號
0001013 400 訂單狀態不允許此操作 先查詢當前狀態
1001004 403 該訂單不屬於您 檢查訂單號
0001001 500 系統異常 退避後重試;持續發生請聯繫平台
RATE_LIMIT_EXCEEDED 429 超過流量限制 依 Retry-After 退避

⚠️ 0001011 是通用業務錯誤碼。餘額不足、通道不可用、超出限額等都會回這個碼, 實際原因在 message 欄位。建議記錄完整 message 以利排查。

9.3 建議的錯誤處理策略

情況 建議
HTTP 401 / 403 不要重試,屬設定問題,記錄並告警
HTTP 429 依 Retry-After 退避後重試
HTTP 500 指數退避重試(最多 3 次)
網路逾時(建單) 可安全重試相同 merchantOrderNo,不會重複建單
success: false + 0001011 記錄 message,依業務判斷是否重試

10. 介接檢查清單

上線前請逐項確認:

認證

請求

回應處理

Webhook

金額


11. 外幣下單(USDT)

若貴商戶以外幣計價,建單時在 currency 帶入該幣別(例如 USDT), amount 直接填外幣數量,系統會依平台設定的匯率換算成 PHP:

11.1 建單範例

{
  "merchantOrderNo": "ORDER_20260921_001",
  "amount": 100,
  "currency": "USDT"
}

當時 USDT 收匯率為 58.00 → 系統建立一張 5800.00 PHP 的收款單。

11.2 回調範例

{
  "event": "payment.success",
  "data": {
    "merchantOrderNo": "ORDER_20260921_001",
    "amount": "100.00000000",
    "currency": "USDT",
    "settlementAmount": "5800.00",
    "settlementCurrency": "PHP",
    "exchangeRate": "58.000000000",
    "fee": "116.00",
    "status": "SUCCESS"
  }
}
欄位 說明
amount / currency 原幣別金額(與建單時完全一致,非換算回推)
settlementAmount / settlementCurrency 實際收付的 PHP 金額
exchangeRate 建單當下鎖定的匯率(1 外幣 = ? PHP)
fee 手續費,以 PHP 計算

既有介接無須修改:未帶 currency、或帶的就是 PHP 時,行為與過去完全相同, 回調也不會出現 settlementAmount 等欄位。

11.3 精度規則

項目 規則
外幣金額 最多 8 位小數(USDT 業界慣例)
PHP 金額 最多 2 位小數,超過會回錯誤
換算結果 四捨五入至 2 位小數

11.4 錯誤情形

情況 錯誤碼 訊息
該幣別未開通 0001002 不支援的幣別 XXX:查無 XXX 對 PHP 的有效匯率
只設了單邊匯率 0001002 幣別 XXX 尚未設定收款匯率 / 付款匯率
法幣小數超過 2 位 0001002 PHP 金額最多 2 位小數:...
換算後金額過小 0001002 換算後金額過小:...

需要開通新幣別或調整匯率,請聯繫平台管理員。


附錄:技術支援

介接過程如遇問題,請聯繫您的客戶經理,並提供:

  1. 完整的請求內容(請遮蔽 API Secret)
  2. 收到的完整回應(含 errorCode 與 message)
  3. 請求時間(精確到秒)
  4. merchantOrderNo 與 systemTransactionNo

文件結束