准备工作Setup
接入方需向我方提供 AES 密钥 与 RSA 密钥。
AES 密钥:用于数据加解密,128 位(Base64 编码)。
RSA 密钥:用于请求签名验证,2048 位(Base64 编码)。
接入方需提供固定出口 IP 以加强通讯安全。
接入方需提供 回调地址用于风控。(回调地址列表仅用于风控,实际回调以下单参数为准)
The integrating party must provide an AES Key and an RSA Key.
AES Key: for data encryption/decryption, 128-bit (Base64 encoded).
RSA Key (PKCS#8): for request signature verification, 2048-bit (Base64 encoded).
Provide a static egress IP to enhance communication security.
Provide callback URLs for risk control. (The callback URL list is for risk control only; actual callbacks are based on the order parameters.)
我方 RSA 公钥(用于响应验签): Our RSA Public Key (for response signature verification):
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5v6bAbCEpyvrk0T/Jhnj qepjuKgAg40/9cQ1fJMEA0P17Lxa3VG5lCQ/mQECbKDNbq7JSK/zhJvK3obs2YrS Z4kEQW5mhQJtbTpdeQQp3Axq03FD/wPiw6hewpV4T7O3D2Zmq4oQxBLk/63JOqRF zwYlIZvkEQvWib2qoGBilXZyPdfukhqPyKV5YTKLFIq6wTayhzgXvETcrbfPNidH VAe/wtLzzsVB4p6KYLL6AiRW0qW2rm8J2buDazmB3ulWNuT49cFV4F7eIr6WcMgc DjllrssvtGMb6BOMt3mTR3uVhjWkrdVGaRmwxv5j1aWLk343uGQ0XNFgmK3RNU6+ ewIDAQAB
概述Overview
• 数据格式:请求体与响应体均为 JSON,字符编码 UTF-8,请求头需携带
Content-Type: application/json。• 公共参数:所有请求与响应的 Header 中包含公共字段,详见「公共参数」。
• 安全机制:所有请求与响应均经过 AES-GCM 加密 和 RSA 签名,详见「加密」与「签名」。 • Protocol: All endpoints use HTTPS with the POST method.
• Data format: Request and response bodies are JSON with UTF-8 encoding. Include the header
Content-Type: application/json.• Common parameters: All request/response headers contain shared fields — see Common Parameters.
• Security: All requests and responses are protected by AES-GCM encryption and RSA signature — see Encryption & Signature.
• 响应头
x-code = 10000 表示请求成功;业务结果需进一步解析响应体判断。•
x-code ≠ 10000 时,请从响应头 x-msg 获取错误原因。此时不会返回响应体(响应体为密文,请求异常时无法保证接入方可正常解密)。验签要求
• 必须对所有响应和回调的
x-sign 进行验签,以确认数据来源于我方且未被篡改。
Response Status• Response header
x-code = 10000 indicates request success; business result must be determined by parsing the response body.• When
x-code ≠ 10000, get the error reason from response header x-msg. No response body is returned in this case (the body is encrypted and cannot be guaranteed decodable on error).Signature Verification
• You MUST verify
x-sign on all responses and callbacks to confirm data integrity and authenticity.
公共参数Common Parameters
公共请求头Common Request Headers
| 名称Name | 说明Description |
|---|---|
| x-merchant-id | 接入方的 merchantIdIntegrator's merchantId |
| x-request-id | 请求唯一流水号Request ID, UUID recommended |
| x-timestamp | 请求时间戳(秒)Request timestamp |
| x-version | 版本号,固定为 2.0Version, fixed as 2.0 |
| x-sign | RSA 请求签名RSA request signature |
公共响应头Common Response Headers
| 名称Name | 说明Description |
|---|---|
| x-merchant-id | 请求头原路返回Echoed from request header |
| x-request-id | 请求头原路返回Echoed from request header |
| x-timestamp | 响应时间戳Response timestamp |
| x-version | 固定为 2.0Fixed as 2.0 |
| x-sign | RSA 响应签名RSA response signature |
| x-code | 响应码Response code |
| x-msg | 响应消息Response message |
加密Encryption
接入方与我方需使用 AES/GCM/NoPadding 对请求体和响应体进行加密与解密, 加密结果统一采用 Base64 编码。
接入方需提前提供 128 位 AES 密钥(Base64 编码),详见「准备工作」。 To ensure data security, all requests and responses are encrypted.
Both parties use AES/GCM/NoPadding for encryption/decryption, with results encoded in Base64.
Provide a 128-bit AES key (Base64 encoded) in advance — see Setup.
• GCM 认证标签长度:128 位
• 随机初始向量(IV):12 字节
• 加密后需将 IV + 密文 合并:
payload 前 12 字节为随机 IV,后续为密文 ⚠ Important GCM Notes
• GCM auth tag length: 128 bits
• Random Initialization Vector (IV): 12 bytes
• After encryption, concatenate IV + ciphertext:
First 12 bytes of payload = random IV, remainder = ciphertext
请求体加密Request Body Encryption
原始请求体字段含义详见各 API 说明。 See each API section for original request body field definitions.
接入方处理流程: Integrator workflow:
- 使用 AES 密钥对原始请求体进行加密Encrypt the original request body with the AES key
- 将加密结果进行 Base64 编码Base64-encode the encrypted result
- 编码后的字符串作为
payload字段发送Send the encoded string as thepayloadfield
我方处理流程: Our workflow:
- 对
payload进行 Base64 解码Base64-decode thepayload - 使用 AES 密钥进行解密Decrypt with the AES key
- 得到原始请求体Obtain the original request body
原始请求体示例: Original request body example:
{
"key_1": "value_1",
"key_2": "value_2",
"key_3": "value_3"
}
实际请求体示例: Actual request body example:
{
"payload": "8YryQ8hYkTL3UzzEdvlUGGrL...9lvPN+U0iERGz9wpHtxvA=="
}
响应体加密Response Body Encryption
原始响应体字段含义详见各 API 说明。 See each API section for original response body field definitions.
我方处理流程: Our workflow:
- 对原始响应体进行 AES 加密AES-encrypt the original response body
- 对加密结果进行 Base64 编码Base64-encode the encrypted result
- 编码后的字符串作为
payload返回Return the encoded string aspayload
接入方处理流程: Integrator workflow:
- 对
payload进行 Base64 解码Base64-decode thepayload - 使用 AES 密钥进行解密Decrypt with the AES key
- 得到原始响应体Obtain the original response body
原始响应体示例: Original response body example:
{
"key_1": "value_1",
"key_2": "value_2",
"key_3": "value_3"
}
实际响应体示例: Actual response body example:
{
"payload": "8YryQ8hYkTL3UzzEdvlUGGrL...9lvPN+U0iERGz9wpHtxvA=="
}
签名Signature
SHA256withRSA,签名结果经 Base64 编码后写入请求头 / 响应头的 x-sign 字段。密钥体系(共 2 对 RSA-2048 密钥):
• 我方密钥对(T):私钥 T 用于对响应签名,公钥 T 已在「准备工作」中公开,供接入方验签。
• 接入方密钥对(U):私钥 U 用于对请求签名,公钥 U 需提前提供给我方用于验签,详见「准备工作」。
简言之:私钥签名,公钥验签。双方各持一对,互相验证。 Algorithm:
SHA256withRSA. The signature is Base64-encoded and placed in the x-sign request/response header.Key System (2 RSA-2048 key pairs in total):
• Our key pair (T): Private key T signs responses; public key T is published in Setup for integrators to verify.
• Your key pair (U): Private key U signs requests; public key U must be provided to us in advance for verification — see Setup.
In short: Private keys sign, public keys verify. Each party holds one pair and verifies the other.
请求待签字符串Request String-to-Sign
所有字段按如下顺序使用 | 连接:Concatenate fields in the following order with |:
merchantId | version | requestId | timestamp | payload
| 字段Field | 来源Source |
|---|---|
merchantId | 请求头Request header |
version | 请求头Request header |
requestId | 请求头Request header |
timestamp | 请求头Request header |
payload | 请求体中 payload 字段payload field in request body |
| 角色Role | 操作Action |
|---|---|
| 接入方Integrator | 使用私钥 U 对待签字符串签名 → Base64 编码 → 写入请求头 x-signSign with private key U → Base64-encode → set as x-sign request header |
| 我方Our side | 对 x-sign 进行 Base64 解码 → 使用公钥 U 验证签名Base64-decode x-sign → verify with public key U |
响应待签字符串Response String-to-Sign
所有字段按如下顺序使用 | 连接:Concatenate fields in the following order with |:
merchantId | version | requestId | timestamp | payload
| 字段Field | 来源Source |
|---|---|
merchantId | 响应头Response header |
version | 响应头Response header |
requestId | 响应头Response header |
timestamp | 响应头Response header |
payload | 响应体中 payload 字段payload field in response body |
x-code 与 x-msg 确认请求成功后,再解析 payload。
Note: Always parse x-code and x-msg from the response header to confirm success before parsing the payload.
| 角色Role | 操作Action |
|---|---|
| 我方Our side | 使用私钥 T 对待签字符串签名 → Base64 编码 → 写入响应头 x-signSign with private key T → Base64-encode → set as x-sign response header |
| 接入方Integrator | 对 x-sign 进行 Base64 解码 → 使用公钥 T 验证签名Base64-decode x-sign → verify with public key T |
发起付款Payout
tradeMode only supports IMPS. The order is considered submitted only when BOTH code layers equal 10000 (other codes should be treated as failure). For successful orders, update business status based on tradeStatus.
PAY_ING 支付中Processing
PAY 成功Success
PAY_FAIL 失败Failed
• 出现错误代码 500 或请求超时(此时不会返回订单状态),不可视为失败。
• 请求一旦发出,未收到明确响应或未查询到明确状态,均不能判定为失败。
• 需持续查询订单状态,订单可能堆积处理中,一时查不到属正常现象。
• 必须查询到具体的订单状态代码作为最终状态。
• 长时间查不到订单,可联系客服确认。我方对此类情况不承担责任。 Timeout / 500 Error Handling
• If you receive error code 500 or a timeout (no order status returned), do NOT treat it as failure.
• Once a request is sent, if no clear response or definitive status is received, do NOT mark the order as failed.
• Keep querying the order status — orders may be backlogged and temporarily unavailable.
• You must obtain a definitive status code as the final result.
• Contact support for orders that remain unresolved. We are not liable for such cases.
发起付款Initiate Payment
Request:
| 字段名Field | 说明Description | 长度 / 类型Length / Type | 是否必须Required | 备注Remarks |
|---|---|---|---|---|
| mchId | 商户 IDMerchant ID | 32 | Y | |
| outTradeNo | 商户单号Merchant order No. | 100 | Y | |
| notifyUrl | 回调地址Callback URL | 255 | Y | |
| tradeAmount | 交易金额Trade amount | (8,2) | Y | |
| Users(支付账户详情,仅支持一条记录) Users (payment account details, only one record supported) | ||||
| amount | 付款金额Payment amount | (8,2) | Y | |
| userId | 用户 IDUser ID | - | Y | |
| payerIp | 用户 IPUser IP | 20 | Y | 取玩家游戏中下单时的 IP,必须实时动态获取User's IP at order time, must be dynamically obtained |
| bankAccount | 收款人的确切姓名Exact name of the beneficiary | 100 | Y | |
| bankCardNo | UPI 渠道填写 UPI 账号,银行卡渠道填写银行账号UPI address for UPI channel, bank account number for bank channel | 100 | Y | |
| bankName | 银行名称Bank name | 100 | N | |
| tradeMode | 支付方式Payment method | 10 | Y | IMPS / UPI(当前仅支持 IMPS)IMPS / UPI (currently only IMPS) |
| bankCode | IFSC 银行代码IFSC bank code | 50 | N | 仅银行转账时需要Required only for bank transfer |
| mobileNumber | 用户手机号码User's mobile number | 20 | Y | |
| 用户电子邮件User's email | 50 | Y | ||
| userKey | Detail identification | long | N | |
| payTime | 支付时间Payment time | yyyy-MM-dd HH:mm:ss | N | |
Body:
{
"mchId": "20221010100015",
"notifyUrl": "https://pay.rupetech.net/pay/out/resp",
"outTradeNo": "529d3845c5f74f3bbc932e96750b87b4",
"tradeAmount": 105,
"users": [
{
"userId": "10001",
"payerIp": "0.0.0.0",
"amount": 105,
"bankAccount": "CHAGANTI SURENDER REDDY",
"bankCardNo": "50100562054556",
"bankCode": "HDFC0001639",
"bankName": "HDFC",
"email": "kpuppala02@gmail.com",
"mobileNumber": "9097634567",
"tradeMode": "imps",
"userKey": 1
}
]
}
Response:
| 字段名Field | 说明Description | 备注 / 枚举值Remarks / Enum |
|---|---|---|
| outTradeNo | 商户单号Merchant order No. | |
| tradeId | 交易IDTrade ID | |
| tradeStatus | 交易状态Trade status |
PAY_ING 支付中Processing
PAY 支付完成Completed
PAY_FAIL 支付失败Failed
|
| payType | 上游银行Upstream bank |
Body:
{
"code": "10000",
"currentTime": "1676445014225",
"data": {
"code": "10000",
"mchId": "20221010100015",
"msg": "The operation succeeded",
"outTradeNo": "377c7115f0064756915b6d3fa35e32ba",
"tradeId": "2023021510000009",
"tradeStatus": "PAY_ING"
},
"msg": "The operation succeeded"
}
回调Callback
• 请对回调请求进行验签,通知可能重复,请做好幂等判断。
• 响应纯文本(无需加密和签名):
SUCCESS 表示不再通知;WRONG 表示有异议。
• We will POST to your callback URL (notifyUrl) provided at order time.• Verify the callback signature. Notifications may repeat — handle idempotency.
• Respond with plain text:
SUCCESS to acknowledge; WRONG if disputed.
• 当
reversal = true 时,flowOrderId 和 reversalTime 才会有值。• 订单状态变化时首先触发回调(可能成功或失败),此时付款已扣款或退款。
• 当再次收到
reversal = true 的回调时,需执行相反操作:— 之前成功并扣款 → 执行退款
— 之前失败并退款 → 重新扣款 Reversal Mechanism
• When
reversal = true, flowOrderId and reversalTime will have values.• When order status changes, a callback fires first (success or failure) — payment is deducted or refunded.
• When a subsequent
reversal = true callback fires, perform the opposite action:— Previously successful (deducted) → process refund
— Previously failed (refunded) → re-deduct
Response:
{
"accountAmount": 509.5,
"mchId": "20221010100015",
"outTradeNo": "9f98a38478c54fd4b9741ee03c8f7e7d",
"payType": "T",
"tradeAmount": 500,
"tradeId": "202407101120000675",
"tradeStatus": "PAY",
"users": [
{
"accountAmount": 509.5,
"bankAccount": "1",
"bankCardNo": "116",
"bankCode": "3",
"bankName": "1",
"flowOrderId": 567135485075525,
"reversal": true,
"reversalTime": "2024-07-24 11:50:05",
"status": "PAY",
"tradeAmount": 500,
"userKey": 1,
"payTime": "2025-01-01 00:00:00",
"utr": "V2pNo0MEA_"
}
]
}
查询状态Query Status
Request:
| 字段名Field | 说明Description | 是否必填Required | 备注Remarks |
|---|---|---|---|
| tradeId | 交易 IDTrade ID | 是(二选一)Yes (one of two) |
tradeId / outTradeNo 二选一必须传其中之一One of these two is required |
| outTradeNo | 商户单号Merchant order No. | 是(二选一)Yes (one of two) | |
| mchId | 商户 IDMerchant ID | 是Yes |
Body:
{
"mchId": "20221010100015",
"tradeId": "2023021410000003"
}
Response:
| 字段名Field | 说明Description | 格式 / 类型Format / Type |
|---|---|---|
| accountAmount | 账户实际扣款金额Actual account deduction | (8,2) |
| tradeAmount | 交易金额Trade amount | (8,2) |
| payType | 上游银行Upstream bank | |
| details | 付款账户详情Payment account details | object |
| bankAccount | 收款人姓名Beneficiary name | |
| bankCardNo | 收款人账号Beneficiary account | |
| payTime | 付款时间Payment time | yyyy-MM-dd HH:mm |
| tradeMode | upi / imps | string |
| userKey | User ID | int |
| reversal | 是否发生逆转(true 是,false 否)Whether reversal occurred (true/false) | boolean |
| flowOrderId | 通过 flowOrderId 可查看扣款、冲销交易记录Use flowOrderId to view deduction/reversal records | int |
| reversalTime | 逆转发生的时间Reversal timestamp | yyyy-MM-dd HH:mm:ss |
| accountAmount | 账户实际扣款金额Actual account deduction | (8,2) |
| tradeAmount | 交易金额Trade amount | (8,2) |
| utr | UTR | 32 |
Body:
{
"code": "10000",
"currentTime": "1721810396184",
"data": {
"accountAmount": 509.50,
"code": "10000",
"createdAt": "2024-07-10 13:10",
"currency": "INR",
"details": [
{
"bankAccount": "1",
"bankCardNo": "116",
"bankCode": "3",
"bankName": "1",
"flowOrderId": "567135485075525",
"payTime": "2024-07-10 13:10",
"rate": 0.00,
"reversal": true,
"reversalTime": "2024-07-24 11:50:05",
"status": "PAY",
"tradeAmount": 509.50,
"tradeMode": "imps",
"userKey": "1",
"utr": "V2pNo0MEA_"
}
],
"msg": "The operation succeeded",
"nonceStr": "kjvnrocwyokv9qgea3vuggg0h5ukn8g2",
"orderNo": "202407101120000675",
"outTradeNo": "9f98a38478c54fd4b9741ee03c8f7e7d",
"payStatus": "PAY",
"sign": "bf6a7686000d49f57f8fdfd4619d2103",
"timestamp": 1721810396,
"tradeAmount": 500.00
},
"msg": "The operation succeeded"
}
账户查询Account Query
Request:
| 字段名Field | 说明Description | 备注 / 取值说明Remarks / Values |
|---|---|---|
| accountType | 账户类型Account type | PAYMENT_ACCOUNT PAYMENT_ACCOUNT |
| mchId | 商户IDMerchant ID |
Body:
{
"mchId": "20221010100015",
"accountType": "PAYMENT_ACCOUNT"
}
Response:
| 字段名Field | 说明Description | 长度 / 格式Length / Format |
|---|---|---|
| merchantNo | 商户IDMerchant ID | 32 |
| notTradeAmount | 不可交易金额Non-tradable amount | (10,2) |
| tradeAmount | 可交易金额Tradable amount | (10,2) |
Body:
{
"code": "10000",
"currentTime": "1676891873065",
"data": {
"code": "10000",
"merchantNo": "20221010100015",
"msg": "The operation succeeded",
"notTradeAmount": 13.26,
"totalAmount": 2504.19,
"tradeAmount": 2435.85
},
"msg": "The operation succeeded"
}