1. 文档说明

该文档为 PayingCloud API 接口文档

1.1. 版本说明

  • 2016-12-8
    开始编写

  • 2016-12-22
    修改部分错误描述

  • 2017-5-19
    添加多个银行支付渠道

  • 2017-6-9
    添加支付流程图,添加验签规则

1.2. 全局规则

  • 服务器地址为 https://api.payingcloud.cn

  • 数据传输类型为 json

  • 异步通知接口处理完成返回success

1.3. 签名规则

用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。

Signature
 HmacUtils.hmacSha1Hex(               (1)
                key,                  (2)
                verb + "\n" +         (3) (4)
                resource + "\n" +     (5)
                body + "\n" +         (6)
                timestamp + "\n");    (7)
1 使用hmacSha1进行签名转16进制
2 key 为AccessKeySecret,表示签名所需的密钥,该密匙是在控制台生成
3 verb 表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等
4 \n 表示换行符
5 resource 为参数拼接串,内容为请求接口的 path+?+query
6 body 表示请求体的json完整json内容
7 timestamp 表示时间戳表示此次操作的时间,且必须为GMT格式, 如"Sun, 22 Nov 2015 08:16:38 GMT",该时间戳也将加入到 Header 中,键为 Date
备注

没有请求体的HttpMethod的签名body用空字符串

代码示例
HmacUtils.hmacSha1Hex("3zKciJOwhWE4SSRUxXzCsABcIhJWd5Gb",
                      "POST" + "\n" +
                      "/charges?a=a&b=b&c=c" + "\n" +
                      "{"a":"a","b":"b","c":"c"}" + "\n" +
                      "Sun, 22 Nov 2015 08:16:38 GMT" + "\n"

再将签名前面加入accessKeyId进行base64编码,在结果前面加入Basic+空格组成Authorization

Authorization
"Basic " + Base64.encodeBase64String((accessKeyId + ":" + signature).getBytes()));
最终Header
Content-Type:application/json; charset=UTF-8
Authorization:Basic NTgzMTM1NDZlZjE5MGM1MWMwYmVhYzZmOjA2NzY2NTUwMzdhOTQyZDc5M2JjOGM5YzRmNzE5M2QzZTRhYjY5YjE=
Date:Tue, 13 Dec 2016 03:22:13 GMT

1.4. 验签规则

为防止黑客伪造交易结果给商户造成损失,PayingCloud对所有发给商户的交易结果异步通知都进行了RSA签名,并将签名进行Base64编码后放在Http请求头 sign 中,开发者需要使用SHA1WithRSA算法和PayingCloud提供的RSA公钥对其进行验证:

代码示例
// 从异步通知请求头中获取签名
String sign = request.getHeader("sign");
// 对签名Base64解码
byte[] signBytes = Base64.decodeBase64(sign)
// 获取异步通知请求体
String content = ...
// 对请求体进行UTF-8字符解码
byte[] contentBytes = content.getBytes("UTF-8")
// 采用SHA1WithRSA算法进行验证
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decodeBase64(PayingCloud.DEFAULT_PUBLIC_KEY); // 使用PayingCloud提供的RSA公钥
PublicKey key = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature.getInstance("SHA1WithRSA"); // 验签算法SHA1WithRSA
signature.initVerify(key);
signature.update(contentBytes);
return signature.verify(signBytes);
PayingCloud RSA公钥
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPymtLbRkHgvVfUT933LrwWns6YZHLPpT1pP9TKJ+cgIZiQwZ4mtqoqPHSVtiT5HA8fwFzWuJ/6qWaQhER7TOISUFUHZlHyBjNK/Z5px6PNB7rT4OrLP0KuZ7nuX5qdnOKuAbrj1MBLSinOHQ8tDJhPrPKxuZlKw3SeL5auHlKWwIDAQAB

2. API接口

2.1. 付款接口

2.1.1. 接口概述

支付流程如下图所示:

payment flowchart

2.1.2. 请求方式

POST /charges

2.1.3. 请求参数

字段名 变量名 必填 类型 示例值 描述

商户收款单号

chargeNo

String(32)

20150806125346

商户系统内部订单号,要求8到32个字符、且在同一个应用下唯一,只能包含字母和数字

商品名

subject

String(32)

iPhone7-32G

展示在收银台的商品名称

收款金额

amount

Int

888

订单总金额,单位为分,不能小于1

备注

remark

String(128)

订单备注:1.XXXXXXXXX,2.XXXXXXXXX

订单备注

收款渠道

channel

String(20)

ALIPAY_WEB

具体渠道类型详见 渠道类型表

渠道额外参数

extra

Map<String, String>

{"returnUrl": "https://api.payingcloud.cn/returnUrl"}

用键值对的map存储不同渠道之间的渠道额外参数

元数据

metadata

String(512)

…​

元数据,用于携带自定义数据,原样返回,如类似json数据也必须转换为字符串格式

异步通知地址

notifyUrl

String(100)

https://api.payingcloud.cn/callback

支付成功后返回支付结果地址,必须为公网地址,如不填将发送到在控制台配置的Webhooks地址,如也没配置Webhooks地址的话将不发送通知

2.1.4. 同步返回参数

字段名 变量名 必填 类型 示例值 描述

应用id

appId

String(24)

583128ffef190c52ccec68a8

发起支付的应用id

商户收款单号

chargeNo

String(32)

20150806125346

商户系统内部订单号

商品名

subject

String(32)

iPhone7-32G

商品名称

备注

remark

String(128)

订单备注:1.XXXXXXXXX,2.XXXXXXXXX

订单备注

收款渠道

channel

String(20)

ALIPAY_WEB

具体渠道类型详见 渠道类型表

收款金额

amount

Int

888

订单总金额,单位为分

已退金额

refundedAmount

Int

100

已退款总额,单位为分

元数据

metadata

String(512)

元数据,用于携带自定义数据,原样返回,如类似json数据也必须转换为字符串格式

交易凭证

credentials

Map<String,String>

详见交易凭证样例

交易凭证,渠道最终返回的连接或者最终请求参数,用于客户端发起交易,见交易凭证详情

状态

status

String

SUCCEEDED

具体详见订单状态表

错误描述

errorMessage

String(128)

退款总额超出订单金额

发生错误时的错误描述参数

开始时间

startedAt

Date

1482389429010

从1970年1月1日00:00至今的毫秒时间

完成时间

completedAt

Date

1482389429010

从1970年1月1日00:00至今的毫秒时间。成功或失败时有值

2.1.5. 异步通知参数

字段名 变量名 必填 类型 示例值 描述

商户APP

appId

String(24)

583128ffef190c52ccec68a8

订单的发起appId

商户收款单号

chargeNo

String(32)

20150806125346

支付时订单号

商品名

subject

String(32)

iPhone7-32G

商品名称

备注

remark

String(1000)

退单备注:1.XXXXXXXXX,2.XXXXXXXXX

退单备注

收款渠道

channel

String(20)

ALIPAY_WEB

具体渠道类型详见 渠道类型表

订单金额

amount

Int

100

订单总金额,单位为分

已退金额

refundedAmount

Int

100

已退款总额,单位为分

元数据

metadata

String(512)

…​

元数据,用于携带自定义数据,原样返回,如类似json数据也必须转换为字符串格式

状态

status

String

SUCCEEDED

具体详见订单状态表

错误描述

errorMessage

String(128)

退款总额超出订单金额

发生错误时的错误描述参数

开始时间

startedAt

Date

1482389429010

退款申请成功的时间,从1970年1月1日00:00至今的毫秒时间

完成时间

completedAt

Date

1482389429010

从1970年1月1日00:00至今的毫秒时间。成功或失败时有值

2.2. 退款接口

2.2.1. 请求方式

POST /refunds

2.2.2. 请求参数

字段名 变量名 必填 类型 示例值 描述

商户收款单号

chargeNo

String(32)

20150806125346

支付时订单号

退款单号

refundNo

String(32)

1217752501201407033233368018

商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔

退款金额

amount

Int

100

退款总金额,订单总金额,单位为分,只能为整数

备注

remark

String(128)

退单备注:1.XXXXXXXXX,2.XXXXXXXXX

退单备注

元数据

metadata

String(512)

…​

元数据,用于携带自定义数据,原样返回,如类似json数据也必须转换为字符串格式

异步通知地址

notifyUrl

String(100)

https://api.payingcloud.cn/callback

支付成功后返回支付结果地址,必须为公网地址,如不填将发送到在控制台配置的Webhooks地址,如也没配置Webhooks地址的话将不发送通知

2.2.3. 返回结果

字段名 变量名 必填 类型 示例值 描述

商户app

appId

String(24)

583128ffef190c52ccec68a8

退款单的发起app

商户退款单号

refundNo

String(32)

1217752501201407033233368018

商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔

商户收款单号

chargeNo

String(32)

20150806125346

支付时订单号

收款渠道

channel

String(20)

ALIPAY_WEB

具体渠道类型详见 渠道类型表

退款金额

amount

Int

100

退款总金额,订单总金额,单位为分,只能为整数

备注

remark

String(128)

退单备注:1.XXXXXXXXX,2.XXXXXXXXX

退单备注

元数据

metadata

String(512)

…​

元数据,用于携带自定义数据,原样返回,如类似json数据也必须转换为字符串格式

状态

status

String

SUCCEEDED

具体详见订单状态表

错误描述

errorMessage

String(128)

退款总额超出订单金额

发生错误时的错误描述参数

开始时间

startedAt

Date

1482389429010

退款申请成功的时间,从1970年1月1日00:00至今的毫秒时间

完成时间

completedAt

Date

1482389429010

从1970年1月1日00:00至今的毫秒时间。成功或失败时有值

2.2.4. 异步通知参数

2.3. 订单查询

2.3.1. 请求方式

GET /charges/{chargeNo}

2.3.2. 请求参数

字段名 变量名 必填 类型 示例值 描述

商户订单号

chargeNo

String(32)

20150806125346

是在请求连接最后的部分添加的参数,是url参数

2.3.3. 返回参数

2.4. 退款单查询

2.4.1. 请求方式

GET /refunds/{refundNo}

2.4.2. 请求参数

字段名 变量名 必填 类型 示例值 描述

商户退款号

refundNo

String(32)

20150806125346

是在请求连接最后的部分添加的参数,是url参数

2.4.3. 返回参数

返回参数和[退款同步参数]相同

3. 备注

3.1. 渠道类型表

渠道名称 传输参数

民生银行T0清算支付宝扫码支付

CMBCPAY_T0_ALI

民生银行T1清算支付宝扫码支付

CMBCPAY_T1_ALI

民生银行T0清算微信扫码支付

CMBCPAY_T0_WX_QR

民生银行T1清算微信扫码支付

CMBCPAY_T1_WX_QR

民生银行T0清算微信公众号支付

CMBCPAY_T0_WX_JSAPI

民生银行T1清算微信公众号支付

CMBCPAY_T1_WX_JSAPI

民生银行T1清算QQ扫码支付

CMBCPAY_T1_QQ

民生银行T0清算QQ扫码支付

CMBCPAY_T0_QQ

微众银行微信扫码支付

WEBANKPAY_WX_QR

微众银行微信公众号支付

WEBANKPAY_WX_JSAPI

支付宝APP支付

ALIPAY_APP

支付宝即时到账

ALIPAY_DIRECT

支付宝扫描付

ALIPAY_QR

支付宝手机网页支付

ALIPAY_WAP

微信APP支付

WXPAY_APP

微信公众号支付

WXPAY_JSAPI

微信扫码支付

WXPAY_NATIVE

银联手机控件支付

UPACP_APP

银联网关支付

UPACP_GATEWAY

京东钱包PC网页支付

JDPAY_WEB

京东钱包移动网页支付

JDPAY_WAP

京东钱包扫码支付

JDPAY_QR

百度钱包PC网页支付

BDPAY_WEB

百度钱包移动网页支付

BDPAY_WAP

百度钱包扫码支付

BDPAY_QR

首信易支付PC网页支付

BJPAY_WEB

首信易支付微信支付

BJPAY_WX

首信易支付微信支付

CHINAPAY_WEB

易宝PC网页支付

YEEPAY_WEB

易宝移动网页支付

YEEPAY_WAP

快付通微信扫码支付

KFTPAY_WX

快付通支付宝扫码支付

KFTPAY_ALI

3.2. 交易凭证样例

"url":"<form name=\"punchout_form\"method=\"post\" action=\"https://pay.yizhifubj.com/prs/user_payment.checkit?v_md5info=b00a57dc732366cbfed3da03fe064af5&v_orderstatus=1&v_rcvname=9466&v_moneytype=0&v_oid=20161222-9466-585b77b5ab5c986f049a0faa&v_ymd=20161222&v_url=http%3A%2F%2F127.0.0.1%3A9000%2Forder%2Fcharge%2Freturn&v_rcvaddr=9466&v_ordername=9466&v_rcvtel=9466&v_mid=9466&v_amount=0.01&v_rcvpost=9466\">\n<input type=\"submit\" value=\"[0xe7][0xab][0x8b][0xe5][0x8d][0xb3][0xe6][0x94][0xaf][0xe4][0xbb][0x98]\" style=\"display:none\" >\n</form>\n<script>document.forms[0].submit();</script>"

3.3. 交易凭证详情

  • BDPAY_WEB

  • BDPAY_WAP

    • 从credentials中获取键: url

servletResponse.sendRedirect(charge.getCredentials().get("url"));
  • ALIPAY_DIRECT

  • BJPAY_WEB

  • CHINAPAY_WEB

  • JDPAY_WEB

  • JDPAY_WAP

  • YEEPAY_WAP

  • ALIPAY_WAP

    • 从credentials中获取键: html(utf-8)

servletResponse.setContentType("text/html;charset=UTF-8");
servletResponse.getWriter().write(charge.getCredentials().get("html"));
  • YEEPAY_WEB

    • 从credentials中获取键: html(gbk)

servletResponse.setContentType("text/html;charset=gbk");
servletResponse.getWriter().write(charge.getCredentials().get("html"));
  • BDPAY_QR

    • 从credentials中获取键: url(图片地址)

  • WXPAY_NATIVE

  • BJPAY_WX

  • ALIPAY_QR

  • KFTPAY_WX

  • KFTPAY_ALI

  • JDPAY_QR

  • CMBCPAY_T0_ALI

  • CMBCPAY_T1_ALI

  • CMBCPAY_T0_WX_QR

  • CMBCPAY_T1_WX_QR

  • CMBCPAY_T0_QQ

  • CMBCPAY_T1_QQ

  • WEBANKPAY_WX_QR

    • 从credentials中获取键: codeUrl(生成二维码的字符串)

  • WXPAY_JSAPI

  • CMBCPAY_T0_WX_JSAPI

  • CMBCPAY_T1_WX_JSAPI

  • WEBANKPAY_WX_JSAPI

    • 从credentials中获取键:

      • appId

      • timeStamp

      • nonceStr

      • package

      • signType

      • paySign

在页面调用微信jsSDk 详情见 微信公众号h5调用文档

3.4. 渠道额外参数

  • returnUrl : 同步返回地址

  • openId : 公众号支付必填

3.5. 订单状态表

参数名 含义

STARTED

支付开始(即支付中)

SUCCEEDED

支付成功

FAILED

支付失败

3.6. 退款状态表

参数名 含义

STARTED

退款开始

SUCCEEDED

退款成功

FAILED

退款失败

3.7. 其他常见问题

3.7.1. 微信公众号支付的相关问题:

1.调起支付的公众号必须是对应企业公众号的APPID,并且通过微信认证,以及请求的openId必须是该公众号下的。
2.支付目录:支付目录域名需通过ICP备案,头部要包含http或https,需细化到二级或三级目录,以左斜杠“/”结尾。