首页 / 开发者
商户对接文档

代收代付 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 白名单策略等以开户后平台提供为准。

拿到密钥,开始构建

在线开户即可获得测试凭证与产品编码,沙盒跑通后一键切生产。