首頁 / 開發者
商戶對接文件

代收代付 API,幾步接入

統一 HTTP + JSON 介面,SHA-256 簽章驗簽,非同步通知與主動查單。本文涵蓋簽章規則、全部介面欄位與請求範例。

概述

India Payme 面向商戶提供兩類核心交易功能:代收(Payin)——代商戶向終端使用者收款;代付(Payout)——代商戶向指定帳戶付款。所有對外介面均為 POST + JSON,且必須攜帶 API 簽章。平台處理完成後透過非同步通知回呼商戶,同時支援主動查單。

功能方法路徑
代收下單POST/transaction/payin/v1/apply
代收查單POST/transaction/payin/v1/query
代付下單POST/transaction/payout/v1/apply
代付查單POST/transaction/payout/v1/query
餘額查詢POST/transaction/payout/v1/balance

基底位址(正式環境閘道網域請以開戶後平台提供為準):

https://{閘道網域}

接入準備

登入商戶後台 → 應用程式金鑰,每個應用程式有一對憑證:appKeyappSecret。其中 appKey 即請求標頭 appIdappSecret 為簽章金鑰,僅用於本機計算簽章、不參與傳輸

所有請求需帶以下 HTTP 標頭,Content-Typeapplication/json

Header必填說明
appId商戶應用程式 ID(即 appKey)
timestamp毫秒級 Unix 時間戳記
nonce隨機字串,≥10 位,一次性不可重複使用
sign按下節規則計算的簽章

簽章規則

簽章演算法為 純 SHA-256(十六進位小寫),非 HMAC。appSecret 直接拼接在待簽字串末尾後再做 SHA-256。步驟:

  1. 取「請求主體頂層欄位(僅非空)」+「簽章標頭 appIdtimestampnonce」合併為一個 Map(sign 本身不參與);
  2. 按參數名稱 ASCII 升冪排序,拼成 key1=value1&key2=value2…
  3. 末尾直接拼接 appSecret(無分隔符),對整串取 SHA-256 十六進位小寫即得 sign
# 待簽字串 signString = "key1=value1&key2=value2…&keyN=valueN" + appSecret sign = SHA256_HEX(signString) // 小寫十六進位

有效期與防重放:

  • 時間戳記有效期 30 秒|伺服器時間 − timestamp| ≤ 30s,超出返回 timestamp has expired。請確保用戶端與閘道時鐘同步(NTP)
  • nonce 防重放:同一 nonce 只能用一次,重複則回報 nonce has been used(錯誤碼 900)。
  • 空值欄位不參與簽章——「參與簽章的欄位集合」須與「實際傳送的 JSON 欄位」完全一致。

Node.js 簽章範例:

const crypto = require('crypto'); function buildSign(appId, appSecret, timestamp, nonce, body) { const params = { ...body, appId, timestamp, nonce }; const signString = Object.keys(params) .filter(k => params[k] !== null && params[k] !== undefined) .sort() .map(k => `${k}=${params[k]}`) .join('&') + appSecret; return crypto.createHash('sha256').update(signString, 'utf8').digest('hex'); }

代收下單 POST

POST /transaction/payin/v1/apply —— 建立一筆收款訂單,回傳收銀台支付連結 payUrl,引導使用者完成支付。

欄位類型必填說明
merchantOrderNostring商戶訂單號,不可重複
amountnumber訂單金額,小數(如 100.02
namestring使用者姓名。純英文、≥3 字母、可含空格、不含符號或數字
phonestring手機號碼
emailstring電子郵件
currencystring幣別:INR / PKR / USDT / BDT
productstring支付產品編碼,由平台按簽約協議下發
notifyUrlstring非同步通知位址;不傳則使用商戶預設通知位址
returnUrlstring支付成功後跳轉頁面
payTypestring電子錢包直付方式:JAZZCASH / EASYPAISA / BKASH / NAGAD
POST /transaction/payin/v1/apply { "merchantOrderNo": "ORD1751731200123", "amount": "600.00", "currency": "INR", "product": "{產品編碼}", "name": "John Doe", "phone": "9910099100", "email": "john@example.com", "notifyUrl": "https://shop.example/pay/notify" }
// 回傳 { "code": 0, "msg": "Success", "data": { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "currency": "INR", "payUrl": "https://{收銀台網域}/cashier/xxxx", "payStatus": 0 } }

取得 payUrl 後引導使用者跳轉支付,最終結果以非同步通知為準。

代付下單 POST

POST /transaction/payout/v1/apply —— 向指定帳戶發起付款。非同步處理:介面先做帳戶校驗與凍結,隨後非同步媒合通路出款,回傳一般為 payStatus=0(受理成功),最終以查單或通知為準。

欄位類型必填說明
merchantOrderNostring商戶訂單號
amountnumber付款金額,最小 100.00
accountNamestring收款人姓名。純英文、≥3 字母、可含空格
accountstring收款帳號
phonestring手機號碼
emailstring電子郵件
currencystring幣別:INR / PKR / USDT / BDT
bizCodestring出款業務類型:IMPS / UPI / BANK / JAZZCASH / EASYPAISA / BKASH / NAGAD / ECARD
payCodestring付款方式:CARD / WALLET / NBK / ITT / VC
branchCodestring清算代碼:印度填 IFSC;巴基斯坦填 bankcode;孟加拉按 bizCode 填寫
productstring付款產品編碼,由平台下發
bankNamestring銀行名稱
swiftCodestringSWIFT 代碼(跨境電匯 ITT 時使用)
POST /transaction/payout/v1/apply { "merchantOrderNo": "PO1751731200123", "amount": "1500.00", "currency": "INR", "product": "{產品編碼}", "accountName": "John Doe", "account": "1234567890", "bizCode": "IMPS", "payCode": "NBK", "branchCode": "HDFC0000001", "bankName": "HDFC", "phone": "9910099100", "email": "john@example.com" }

訂單查詢 POST

代收 POST /transaction/payin/v1/query、代付 POST /transaction/payout/v1/query。傳 merchantOrderNoorderNo 定位訂單。限流 5 次/秒

POST /transaction/payin/v1/query { "merchantOrderNo": "ORD1751731200123" }
// 回傳 data { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "realAmount": 600, "currency": "INR", "payStatus": 1 // 0處理中 / 1已收款 / -1已取消 }

餘額查詢 POST

POST /transaction/payout/v1/balance —— 查詢商戶帳戶餘額。限流 5 次/秒。

POST /transaction/payout/v1/balance { "currency": "INR" }
// 回傳 data { "accountNo": "ACC0001", "currency": "INR", "balance": 100000.00, // 總餘額 "balanceActive": 98500.00, // 可用餘額 "balanceFreeze": 1500.00 // 凍結餘額 }

非同步通知

訂單達到終態後,平台以 POST(JSON)通知商戶的 notifyUrl(未傳則用商戶預設位址),並隨通知下發同款簽章標頭(appId/timestamp/nonce/sign)。商戶應用自己的 appSecret 按相同規則重算簽章並比對,驗證通知真實性。

代收通知報文包含:merchantOrderNoorderNocurrencyproductamountrealAmountstatus(收款成功為 "1")。代付通知另含 utr(銀行流水號)與 statusDes(狀態描述),status"1"成功 / "2"失敗。

// 代收通知 body 範例 { "merchantOrderNo": "ORD1751731200123", "orderNo": "P1751731200999", "currency": "INR", "product": "{產品編碼}", "amount": "600.00", "realAmount": "600.00", "status": "1" }

商戶須回傳純文字 OKsuccess(不區分大小寫)。否則平台進入重試佇列:最多 5 次,間隔按分鐘遞增(1 / 2 / 5 / 10 / 30 / 60 / 120)。因此商戶介面須保證冪等(同一 orderNo 可能被通知多次)。

訂單狀態

商戶對接以下列對外狀態為準(內部狀態機更細,不直接暴露):

場景欄位取值
下單受理回傳payStatus0 建立 / 1 成功 / 2 失敗 / 3 取消
代收查單payStatus0 處理中 / 1 已收款 / -1 已取消
代付查單payStatus0 待付款 / 1 已付款 / -1 已取消
非同步通知status代收成功 "1";代付 "1" 成功 / "2" 失敗

錯誤碼

回應主體 code != 0 即失敗,msg 為提示。常見業務錯誤碼:

code說明
0成功
400參數錯誤 / 驗簽失敗(Sign invalid)
900重複請求 / nonce 重放
10000 / 10001應用程式不存在 / 應用程式不可用
10002幣別不支援
10003 / 10007商戶不可用 / 商戶帳戶不可用
10004產品未開通或協議過期
10005 / 10009暫無可用通路 / 通路暫不可用
10008帳戶餘額不足
10010IP 不在白名單
10011 / 10012產品無效 / 支付方式無效
10020商戶訂單號重複
30001 / 30002訂單號有誤 / 幣別有誤或帳戶未啟用

完整對接流程

以代收為例:

  1. 組裝業務請求主體(見「代收下單」欄位)。
  2. 產生 timestamp(毫秒)與 nonce(≥10 位隨機字串)。
  3. 按「簽章規則」計算 sign
  4. 帶 4 個簽章標頭 + JSON Body 發起 POST /transaction/payin/v1/apply
  5. code==0 則取 data.payUrl 引導使用者支付。
  6. 監聽非同步通知;同時可主動查單核對最終狀態。
  7. 收到通知後校驗簽章、處理業務,回傳純文字 OK

註:本文介面路徑、欄位與狀態碼均對應正式環境實作;正式環境閘道網域、可用 product 產品編碼、IP 白名單策略等以開戶後平台提供為準。

取得金鑰,開始建構

線上開戶即可獲得測試憑證與產品編碼,沙盒測試通過後一鍵切換正式環境。