XnPayAPI v1.0

XnPay API 文档

快速、安全、可靠的支付解决方案

API 特性
  • RESTful API 设计,简单易用
  • 支持 PHP、Python、Golang 等多种语言
  • 完整的支付流程:支付、查询、代付等
  • 实时回调通知
  • MD5 和 SHA256 签名验证

基本规则

Request URL

生产环境:

https://api.xnpurl.com/xnpurl-api
Request Method
POST
Content-Type
application/json

支付接口

API URL: /payment
创建新的支付订单
POST

请求参数

参数名说明类型必填例子
merchantCode商户号StringYtest
orderNumber用户订单号StringY1604384758793
amount金额IntegerY40000
phone电话StringY08123456789
emailEmailStringYtest@test.com
userName名称StringYJohn Doe
walletNumber钱包账号StringN08821900000 (DANA必填,格式08********;OVO收银台必传真实号码,否则不需要此参数)
channelCode渠道编码StringYM1(若为CASH,会使用收银台支付;其他编码请见渠道编码对照表)
returnUrl返回地址StringNhttp://test/return
callbackUrl回调地址StringYhttp://test/callback
sign签名StringYMD5(...)

签名规则

MD5(amount + callbackUrl + channelCode + merchantCode + orderNumber + md5_key)

响应参数

参数名说明类型例子
code返回码String000
message返回消息Stringsuccess
orderNumber订单号StringO3915CB3C93E445C9
accountNumber银行账号StringTEST0001 (VA才有)
paymentUrl支付地址Stringhttp://xxx.xxx/
qrcode二维码StringQRIS支付会返回二维码源码
merchantCode商户号Stringtest

请求示例

{
  "merchantCode": "test",
  "orderNumber": "1604384758793",
  "amount": 40000,
  "phone": "08123456789",
  "email": "test@test.com",
  "userName": "John Doe",
  "channelCode": "M1",
  "returnUrl": "http://test/return",
  "callbackUrl": "http://test/callback",
  "sign": "a1b2c3d4e5f6..."
}

响应示例

{
  "code": "000",
  "message": "success",
  "orderNumber": "O3915CB3C93E445C9",
  "paymentUrl": "http://xxx.xxx/",
  "qrcode": "data:image/png;base64,..."
}
代码示例
package com.customer.demo;

import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Map;

public class ZkpayPaymentDemo {

 public static void main(String[] args) {

 String url = "https://api.xnpurl.com/xnpurl-api/payment";

 String merchantCode = "test";
 String key = "Gjon5exBp34mkNUU0r4wk2delkbclF4i";
 String orderNumber = System.currentTimeMillis() + "";
 Integer amount = 40000;
 String phone = "08123456789";
 String email = "test@test.com";
 String userName = "John Doe";
 String channelCode = "M1";
 String returnUrl = "http://test/return";
 String callbackUrl = "http://test/callback";
 Digester md5 = new Digester(DigestAlgorithm.MD5);

 String signOrigin = amount + callbackUrl + channelCode + merchantCode + orderNumber + key;
 String sign = md5.digestHex(signOrigin);
 System.out.println(sign);
 Map<String, Object> param = new HashMap<>();
 param.put("merchantCode", merchantCode);
 param.put("orderNumber", orderNumber);
 param.put("amount", amount);
 param.put("phone", phone);
 param.put("email", email);
 param.put("userName", userName);
 param.put("channelCode", channelCode);
 param.put("returnUrl", returnUrl);
 param.put("callbackUrl", callbackUrl);
 param.put("sign", sign);

 String sendParam = JSON.toJSONString(param);
 System.out.println("request==> " + sendParam);

 String result = HttpUtil.post(url, sendParam, 10000);

 System.out.println("response==> " + result);

 }

}

支付查询

API URL: /checkPayment
查询支付订单状态
POST

请求参数

参数名说明类型必填例子
merchantCode商户号StringYtest
orderNumber用户订单号StringY1604384758793
sign签名StringYMD5(...)

签名规则

MD5(merchantCode + orderNumber + md5_key)

响应参数

参数名说明类型例子
code返回码String000
message返回消息Stringcomplete
userOrderNumber用户订单号String1604384968942
orderNumber平台订单号Stringtest16043849702603
amount支付金额Integer40000
merchantCode商户号Stringtest
phone电话String已隐藏,显示00
emailEmailString已隐藏,显示00
userName名称StringJohn Doe
channelCode渠道编码StringM1
status支付状态int0 待支付,1 支付成功,2 订单失败
createTime订单发起时间Date2020-11-03 13:29:30
payTime支付时间Date2020-11-03 13:39:30 支付成功时返回

请求示例

{
  "merchantCode": "test",
  "orderNumber": "1604384758793",
  "sign": "a1b2c3d4e5f6..."
}

响应示例

{
  "code": "000",
  "status": 1,
  "amount": 40000
}
代码示例
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import java.util.HashMap;
import java.util.Map;

public class CheckPaymentDemo {
  public static void main(String[] args) {
    String url = "https://api.xnpurl.com/xnpurl-api/checkPayment";
    String merchantCode = "test";
    String key = "Gjon5exBp34mkNUU0r4wk2delkbclF4i";
    String orderNumber = "1604384758793";
    
    Digester md5 = new Digester(DigestAlgorithm.MD5);
    String signOrigin = merchantCode + orderNumber + key;
    String sign = md5.digestHex(signOrigin);
    
    Map<String, Object> param = new HashMap<>();
    param.put("merchantCode", merchantCode);
    param.put("orderNumber", orderNumber);
    param.put("sign", sign);
    
    String sendParam = JSON.toJSONString(param);
    String result = HttpUtil.post(url, sendParam, 10000);
    System.out.println("response==> " + result);
  }
}

代付接口

API URL: /disbursement
发起代付请求
POST

请求参数

参数名说明类型必填例子
merchantCode商户号StringYtest
orderNumber用户订单号StringY1604384758793
amount金额IntegerY40000
bankAccount银行账号StringY100100100
bankCode银行编码StringYPERMATA
phone电话StringY08123456789
emailEmailStringYtest@test.com
userName对方名称StringYJohn Doe
channelCode渠道编码StringYALL
returnUrl返回地址StringNhttp://test/return
callbackUrl回调地址StringYhttp://test/callback
sign签名StringYSHA256(...)

响应参数

参数名说明类型例子
code返回码String000
message返回消息Stringsuccess
amount支付金额Integer40000
merchantCode商户号Stringtest

签名规则

SHA256(amount + bankAccount + bankCode + callbackUrl + channelCode + merchantCode + orderNumber + sha256_key)

PS

channelCode 可用通道:ALL 所有通道可用,ID IDN US ZH 不同国家,无特殊说明请使用ALL

请求示例

{
  "merchantCode": "test",
  "orderNumber": "1604384758793",
  "amount": 50000,
  "bankAccount": "1234567890",
  "bankCode": "BCA",
  "phone": "08123456789",
  "email": "test@test.com",
  "userName": "John Doe",
  "channelCode": "ALL",
  "returnUrl": "http://test/return",
  "callbackUrl": "http://test/callback",
  "sign": "a1b2c3d4e5f6..."
}

响应示例

{
  "code": "000",
  "message": "success",
  "orderNumber": "1604384758793"
}
代码示例
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import java.util.HashMap;
import java.util.Map;

public class DisbursementDemo {
  public static void main(String[] args) {
    String url = "https://api.xnpurl.com/xnpurl-api/disbursement";
    String merchantCode = "test";
    String key = "Gjon5exBp34mkNUU0r4wk2delkbclF4i";
    String orderNumber = "1604384758793";
    Integer amount = 50000;
    String bankAccount = "1234567890";
    String bankCode = "BCA";
    String callbackUrl = "http://test/callback";
    String channelCode = "B1";

    Digester sha256 = new Digester(DigestAlgorithm.SHA256);
    String signOrigin = amount + bankAccount + bankCode + callbackUrl + channelCode + merchantCode + orderNumber + key;
    String sign = sha256.digestHex(signOrigin);

    Map<String, Object> param = new HashMap<>();
    param.put("merchantCode", merchantCode);
    param.put("orderNumber", orderNumber);
    param.put("amount", amount);
    param.put("bankAccount", bankAccount);
    param.put("bankCode", bankCode);
    param.put("sign", sign);

    String sendParam = JSON.toJSONString(param);
    String result = HttpUtil.post(url, sendParam, 10000);
    System.out.println("response==> " + result);
  }
}

代付查询

API URL: /checkDisbursement
查询代付订单状态
POST

请求参数

参数名说明类型必填例子
merchantCode商户号StringYtest
orderNumber用户订单号StringY1604384758793
sign签名StringYSHA256(...)

响应参数

参数名说明类型例子
code返回码String000
message返回消息Stringcomplete
userOrderNumber用户订单号String1604384968942
orderNumber平台订单号Stringtest16043849702603
amount支付金额Integer40000
merchantCode商户号Stringtest
phone电话String已隐藏,显示00
emailEmailString已隐藏,显示00
userName对方名称StringJohn Doe
bankCode银行编码StringPERMATA
bankAccount银行账号String100100100
channelCode渠道编码StringM1
status支付状态int1 (0 待支付,1 代付成功,2 代付失败)
createTime订单发起时间Date2020-11-03 13:29:30
payTime支付时间Date2020-11-03 13:39:30 支付成功时返回

签名规则

SHA256(merchantCode + orderNumber + sha256_key)

请求示例

{
  "merchantCode": "test",
  "orderNumber": "1604384758793",
  "sign": "a1b2c3d4e5f6..."
}

响应示例

{
  "code": "000",
  "status": 1,
  "amount": 50000
}
代码示例
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import java.util.HashMap;
import java.util.Map;

public class CheckDisbursementDemo {
  public static void main(String[] args) {
    String url = "https://api.xnpurl.com/xnpurl-api/checkDisbursement";
    String merchantCode = "test";
    String key = "Gjon5exBp34mkNUU0r4wk2delkbclF4i";
    String orderNumber = "1604384758793";

    Digester sha256 = new Digester(DigestAlgorithm.SHA256);
    String signOrigin = merchantCode + orderNumber + key;
    String sign = sha256.digestHex(signOrigin);

    Map<String, Object> param = new HashMap<>();
    param.put("merchantCode", merchantCode);
    param.put("orderNumber", orderNumber);
    param.put("sign", sign);

    String sendParam = JSON.toJSONString(param);
    String result = HttpUtil.post(url, sendParam, 10000);
    System.out.println("response==> " + result);
  }
}

可用渠道查询

API URL: /queryChannel
查询可用支付渠道
POST

请求参数

参数名说明类型必填例子
merchantCode商户号StringYtest
timestamp时间戳StringY1604384758793
sign签名StringYMD5(merchantCode + timestamp + key)

响应参数

参数名说明类型例子
code返回码String000
message返回消息Stringquery success
channelCodeList渠道集合LIST
- channelCode渠道代码StringBT
- channelType渠道类型Integer0 支付渠道 1 代付渠道
- channelRate渠道费率Double7.0
- channelFee渠道服务费Integer200

签名规则

MD5(merchantCode + timestamp + key)

请求示例

{
  "merchantCode": "test",
  "timestamp": 1604384758793,
  "sign": "a1b2c3d4e5f6..."
}

响应示例

{
  "code": "000",
  "channels": [
    {
      "channelCode": "M1",
      "channelName": "QRIS",
      "minAmount": 1000,
      "maxAmount": 10000000
    }
  ]
}

余额查询

API URL: /checkBalance
查询商户余额
POST

请求参数

参数名说明类型必填例子
merchantCode商户号StringYtest
timestamp时间戳StringY1604384758793
sign签名StringYSHA256(merchantCode + timestamp + sha256_key)

响应参数

参数名说明类型例子
code返回码String000
message返回消息Stringbalance query success
merchantCode商户号String1604384968942
merchantBlance商户余额Integer540000
merchantFrozenAmount冻结金额Integer40000
canUseAmount可用金额Integer500000
settlementList待结算金额列表LIST
- settlementDate结算日期String2020-12-28
- settlementAmount待结算金额Integer44500

签名规则

SHA256(merchantCode + timestamp + sha256_key)

请求示例

{
  "merchantCode": "test",
  "timestamp": 1604384758793,
  "sign": "a1b2c3d4e5f6..."
}

响应示例

{
  "code": "000",
  "balance": 1000000
}

异步回调

支付回调

支付完成后,系统会向您配置的 callbackUrl 发送 POST 请求

回调参数

参数名说明类型示例
code返回码String000
message返回消息Stringcomplete
orderNumber用户订单号String1604384968942
amount支付金额Integer40000
merchantCode商户号Stringtest
phone电话(已隐藏)String00
emailEmail(已隐藏)String00
userName名称StringJohn Doe
channelCode渠道编码StringM1
status支付状态:0待支付,1成功int1
createTime订单发起时间(时间戳)Date1617695193459
payTime支付时间(时间戳,成功时返回)Date1617695193459
sign签名StringMD5(amount + channelCode + email + merchantCode + orderNumber + phone + userName + md5_key)

签名规则

MD5(amount + channelCode + email + merchantCode + orderNumber + phone + userName + md5_key)

回调示例

{
  "code": "000",
  "message": "complete",
  "orderNumber": "1604384968942",
  "amount": 40000,
  "merchantCode": "test",
  "phone": "00",
  "email": "00",
  "userName": "John Doe",
  "channelCode": "M1",
  "status": 1,
  "createTime": 1617695193459,
  "payTime": 1617695193459,
  "sign": "a1b2c3d4e5f6..."
}

应答:请返回状态值 200 确认收到回调

代付回调

代付完成后,系统会向您配置的 callbackUrl 发送 POST 请求

回调参数

参数名说明类型示例
code返回码String000
message返回消息Stringcomplete
orderNumber用户订单号String1604384968942
amount代付金额Integer40000
merchantCode商户号Stringtest
phone电话(已隐藏)String00
emailEmail(已隐藏)String00
userName对方名称StringJohn Doe
bankCode银行编码StringPERMATA
bankAccount银行账号String100100100
channelCode渠道编码StringALL
status代付状态:1成功,2失败int1
createTime订单发起时间(时间戳)Date1617695193459
payTime支付时间(时间戳,成功时返回)Date1617695193459
sign签名StringSHA256(amount + bankAccount + bankCode + channelCode + email + merchantCode + orderNumber + phone + userName + sha256_key)

签名规则

SHA256(amount + bankAccount + bankCode + channelCode + email + merchantCode + orderNumber + phone + userName + sha256_key)

回调示例

{
  "code": "000",
  "message": "complete",
  "orderNumber": "1604384968942",
  "amount": 40000,
  "merchantCode": "test",
  "phone": "00",
  "email": "00",
  "userName": "John Doe",
  "bankCode": "PERMATA",
  "bankAccount": "100100100",
  "channelCode": "ALL",
  "status": 1,
  "createTime": 1617695193459,
  "payTime": 1617695193459,
  "sign": "a1b2c3d4e5f6..."
}

应答:请返回状态值 200 确认收到回调

支付渠道编码对照表

🇮🇩 印度尼西亚 (Indonesia)
channel_codechannel_name类型
QRISQRIS收款
VCCredit Card (Visa / Master)收款
BKBCA KlikPay收款
BCABCA Virtual Account收款
BBCBCA BC收款
M1Mandiri Virtual Account收款
MEMandiri eCash收款
MPMandiri PC收款
BTPermata Bank Virtual Account收款
PNPermata Net收款
A1ATM Bersama收款
B1CIMB Niaga Virtual Account收款
I1BNI Virtual Account收款
VAMaybank Virtual Account收款
M2UMaybank2U收款
FTRitel收款
OVOVO收款
LALINKAJA收款
DANADANA收款
SPShopee Pay收款
SAShopee Pay Apps收款
AGBank Artha Graha收款
S1Sahabat Sampoerna收款
NIBank Negara Indonesia收款
RIBank Rakyat Indonesia收款
RIEBRI ePay收款
ININDOMARET收款
ALALFAMART收款
DOBDanamon Online Banking收款
DVADanamon Virtual Account收款
AIAlto iDebit收款
JIBJenius IB收款
JAJAKONE收款
OCOcto Clicks收款
SKSakuku收款
ALFAlfagroup收款
KRKredivo收款
BLBTNONLINE收款
SVASinarmas Virtual Account收款
CASH收银台支付收款
ID_ALL印尼代付全渠道代付
🇵🇰 巴基斯坦 (Pakistan)
channel_codechannel_name类型
PK_JAZZJAZZ钱包收款
PK_EASYEASY钱包收款
PK_ALL巴基斯坦代付全渠道代付
🇧🇷 巴西 (Brazil)
channel_codechannel_name类型
BR_BRL二维码支付 (QR Code)收款
BR_ALLPIX代付渠道代付

银行编码对照表

银行编码列表

🇮🇩 印度尼西亚 (Indonesia)

bank_codebank_name
BCABank BCA
BRIBank BRI
MANDIRIBANK MANDIRI
BNIBANK BNI 46
CIMBBANK CIMB NIAGA
PERMATABANK PERMATA
BJBBank BJB
DANAMONBANK DANAMON INDONESIA
BTNBank BTN
MAYBANKBANK MAYBANK INDONESIA
SINARMASBANK SINARMAS
PANINBANK PANIN
BNI_SYRBANK BNI SYARIAH
MANDIRI_SYRBANK SYARIAH MANDIRI
DKIBPD DKI JAKARTA
MEGABANK MEGA
BSIBSI (Bank Syariah Indonesia)
BTPNBank BTPN
BRI_SYRBANK BRI SYARIAH
MUAMALATBANK MUAMALAT INDONESIA
OCBCBANK OCBC NISP
OVOOVO
SHOPEEPAYSHOPEEPAY
DANADANA
GOPAYGOPAY
LINKAJALINKAJA

🇵🇰 巴基斯坦 (Pakistan)

bank_codebank_name
PK_EASYEASY钱包 (EASY Wallet)
PK_JAZZJAZZ钱包 (JAZZ Wallet)

🇧🇷 巴西 (Brazil)

bank_codebank_name
BR_CPFCPF号码 (CPF Number)
BR_PHONE手机号 (Phone Number)
BR_EMAIL邮箱 (Email)