目录:
- 场景介绍
- 接入指引
2.1 准备工作
2.2 接口调用规范
2.2.1 请求说明 - 服务端API列表
3.1 获取支付开通渠道
3.2 交易结果查询接口
3.3 交易退款接口
3.4 交易退款结果查询接口
3.5 交易结果通知 - 客户端API列表
4.1 支付预下单接口 - app支付流程介绍
1. 场景介绍
商家APP调用聚合支付平台提供的SDK,SDK再调用支付宝/微信APP内的支付模块。如果用户已安装支付宝/微信 APP,商家 APP 会跳转到支付宝/微信中完成支付,支付完后跳回到商家APP内,最后展示支付结果。如果用户没有安装支付宝/微信 APP,商家 APP 内会调起支付宝/微信网页支付收银台,用户登录支付宝/微信账户,支付完后展示支付结果。
目前支持手机系统有:iOS(苹果)、Android(安卓)。
2. 接入指引
2.1 准备工作
第一步、获取开发者数据
调用聚合支付平台接口,需要与平台商务对接后,获取开发者ID(developId),密钥(privateKey),公钥(publicKey)和对称密钥(desKey),这些参数让商户拥有调用平台接口的权限,对请求的数据进行加密以保证数据的安全性。
- 开发者ID(developerId):
developerId在所有的请求中都需要传入,与密钥公钥信息相对应,鉴别请求是否是由平台商户发起。
- 密钥(privateKey):
密钥在接口请求中用于对数据进行RSA加密,生成签名sign。
- 公钥(publicKey):
公钥用于对签名进行解密
- 对称秘钥(desKey):
<body>标签的中的参数,需要通过des进行对称加解密,请求时使用密文,返回密文通过对称秘钥进行解密。
第二步、获取平台商户号
每个商户对接聚合支付平台,在第三方平台想要拥有的支付能力,需要在支付宝或者微信签约对应的支付方式,平台的商务会为每个商户分配一个平台商户号(merchantNo),该商户号账户下所有的交易流水都会进入到对应的支付宝和微信的账户下,并且平台账单流水都是以商户号进行隔离,这是一个非常重要的参数。
第三步、下载加解密sdk和demo
- java版本:下载demo
2.2 接口调用规范
2.2.1 请求说明
接口通信地址:
测试环境:http://onlinetest.bsoftpay.com/gatewayOnline/gateway/portal/execute
正式环境:由平台商务对接人员提供http请求格式:
Content-type:application/xml
实体对象为 xml 格式,严格区分大小写,xml格式如下:
<?xml version='1.0' encoding='UTF-8'?> <Root> <Head></Head> <Body> </Body> </Root>
公共参数说明:
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例 |
---|---|---|---|---|---|
MerchantNo | String | 是 | 10 | 注意:这是开发者id(developerId) |
12345 |
FuncId | String | 是 | 20 | 功能码 | P7005 |
Signature | String | 是 | 100 | 签名 | Sa/hb9jaTZZZq89mN62DDooLv/YTvfE9ayrbzgOMsucfIPZfJGmhUia6YWK8vQ5/NQana3Pub7BDswEenm0sBg== |
Timestamp | String | 是 | 100 | 当前时间戳(自1970-1-01 00:00:00.000 到当前时刻的时间距离【精确到毫秒】) | 1564120486130 |
RetCode | String | 是 | 30 | 0000:表示接口业务调用正常,9999:表示处理失败,如参数错误,验签失败等(注:RetCode并不表示交易行为成功或失败,某笔交易是否成功请根据对应接口返回报文的状态字段来判定) | 0000 |
RetMsg | String | 是 | 100 | 接口调用异常返回信息 | 验签失败 |
注意:Signature签名的生成过程,是先通过‘对称秘钥’对<Body>中的数据域进行DES加密,得到密文之后,再用‘私钥’对密文进行RSA加密
- 请求报文示例:
<?xml version='1.0' encoding='UTF-8'?> <Root> <Head> <MerchantNo>开发者id</MerchantNo> <FuncId>P7006</FuncId> <Timestamp>12312312312324</Timestamp> <Signature>kLRyaxQXe6yLu+ktZUOiB+afVgeY5Doq9fTB27rAkW7/MBMK10tcxWM7eVVtmzxju0Xi1rtW16D7cV5PgM+zDA==</Signature> </Head> <Body>ql1e6Mhtmrq7yA6wGuE4biskwAEq8ALzOFr5kJxbVoP7VuaeoasTxHkdf8GTwlLihUhSk+ZcGsnJWNJHfMCtr9valAWD/y8sOAQut1/sWhg=</Body> </Root>
注意:请求信息中MerchantNo 是开发者id
- 返回报文示例:
<?xml version="1.0" encoding="UTF-8"?> <Root> <Head> <MerchantNo>开发者id</MerchantNo> <FuncId>P7006</FuncId> <Timestamp>1533718324024</Timestamp> <Signature><![CDATA[hNCUjy30FibXT8YuqhEwaMFv6dzERMRWAVa0XjcKDmzjZ jkQ1DPXzJtJooe43QfLLmW+38eDLmeUK7Y17nMfjA==]]> </Signature> <RetCode>0000</RetCode> <RetMsg></RetMsg> </Head> <Body> <![CDATA[NLB9nF8xXHoJgCgwYtRkMG9vhJlpSl9hjIF6LMQduYoaNNwmDqKKhBfUVBn u6ZPH33q3DLWEfnzUP5E2Mvzz2gK7riCvIfe1yJ/D5b3Ia67vFkHI6HBPhykm6uVLsbdW 7Q1xSLuEv2jGqfwzSl35GPAJrwrd8wylCRp6B2aLv4x3DYmUROKXVk+fPObHTb0nU7a1Z Hkw7Nhj+15CPHnMLDj/s4jK9OOdkhKrWg/NTDvnZR65jFXsvqPfitPmkYsTEzuXwQSq88GF 9YAmP+dcVeHHxBpaYkcV0N+JdN9h1TJg+uENaZIgU4ayDF2N7dVhYO54+vgSd/3HLHloow zXUVo2XdPVZgrvDRpmyqpk3YA8Pe4njAgZnA7/RRXvqX1ueOyQVEt1br7i4F5mGwnSuM9 KOCDIkTNre9rvCdbsui5U0CpxgeM3WQ==]]> </Body> </Root>
注意:这里的返回数据域为密文,需要接入方使用‘对称秘钥’进行DES解密,即可得到原文数据。如果需要验证数据的有效性,可以利用‘公钥’对Signature进行验签
注意:返回信息中 MerchantNo 是开发者id
利用java工具类解密示例:
利用java工具类验签示例:String xml = SecurityUtil.decryptDes(Body,[your desKey], "utf-8");
boolean verify = SecurityUtil.verifyRSA(data, [your publicKey], Signature, "utf-8");
3. API列表
3.1 获取支付开通渠道
- 功能码:P2007
- 调用方:app支付商户-服务端
- 接口说明:调用此接口获取商户开通签约且拥有支付能力的支付渠道(如果未得到结果,请联系商务对接检查渠道签约情况)
- 请求参数:
<xml>
参数 | 名称 | 类型 | 长度 | 必填 | 说明 | 示例 |
---|---|---|---|---|---|---|
Mobile | 手机号 | String | 20 | 是 | 13212341234 | |
Amt | 金额 | Price | 10.2 | 是 | 本次支付/充值金额,用于控制健康钱包选项是否可选 | 0.01 |
MerchantNo | 收款商户号 | String | 15 | 是 | 聚合支付平台分配的商户号 | 809900000001 |
OptType | 操作类型 | String | 2 | 是 | 1 充值 2 支付 | 1 |
HealthCardId | 健康卡号 | String | 30 | 否 | 虚拟卡号 | 001 |
- 响应参数:
参数 | 名称 | 类型 | 长度 | 必输 | 说明 | 示例 |
---|---|---|---|---|---|---|
ChannelId | 渠道编号 | String | 10 | 是 | 2=支付宝;3=微信 | |
ChannelName | 渠道名称 | String | 30 | 是 | 支付宝 | |
Isuse | 是否可用 | String | 1 | 是 | 3=普通App支付可用且支持医保 2=普通App支付不可用仅支持医保 1=普通App支付可用 0=不可用 (有时不可用时可能在支付渠道列表中仍然显示,但为灰色,用户不可选择) |
|
Errmsg | 不可用原因 | String | 100 | 否 | 错误原因,如:账户余额不足 | 账户余额不足 |
Java请求示例:
public void P2007(){ String developerId = 【your developerId】; String privateKey =【your privateKey】; String desKey = 【your desKey】; String data = "<xml>" + "<Mobile>13212341234</Mobile>" + "<Amt>0.01</Amt>" + "<MerchantNo>809900000001</MerchantNo>" + "<OptType>2</OptType>" + "</xml>"; HeaderDTO header = new HeaderDTO(); header.setFuncId("P2007"); header.setMerchantNo(developerId); header.setTimestamp(System.currentTimeMillis() + ""); header.setSignature(SecurityUtil.signRSA(data, privateKey, "UTF-8")); // DataDTO dataDTO = new DataDTO(); dataDTO.setHeader(header); dataDTO.setBody(SecurityUtil.encryptDes(data, desKey , "UTF-8")); String content = XMLUtil.toXml(dataDTO, DataDTO.class, "UTF-8"); String resData = null; try { CloseableHttpResponse response = HttpClients.custom().build().execute(RequestBuilder.post().setUri("http://onlinetest.bsoftpay.com/gatewayOnline/gateway/portal/execute").setEntity(new StringEntity(content, ContentType.APPLICATION_XML.withCharset(Consts.UTF_8))).build()); String res = EntityUtils.toString(response.getEntity(), Consts.UTF_8); System.out.println(res); //解析返回xml DataDTO resultData = XMLUtil.fromXml(res, DataDTO.class); //回调成功-获取body内容 if ("0000".equals(resultData.getHeader().getRetCode())) { //解密body resData = SecurityUtil.decryptDes(resultData.getBody(), desKey,"UTF-8"); }else{ //异常信息 resData = resultData.getHeader().getRetMsg(); } } catch (Exception e) { e.printStackTrace(); } System.out.println(resData); }
返回示例:
<?xml version="1.0" encoding="utf-8"?> <Root> <Head> <MerchantNo>31331</MerchantNo> <FuncId>P2007</FuncId> <Timestamp>1564371431694</Timestamp> <Signature><![CDATA[exyYqyBEm5wX3HIv/EWFOPwdd5oLNY+ITc8hCXpN4GyyZCNdz4gTgwMkNJ9EfqPTumoMP0cyj4nRo37sAVrLkQ==]]></Signature> <RetCode>0000</RetCode> <RetMsg/> </Head> <Body><![CDATA[2Cbya1WvKQ1CzmfQgcwoBry4WoUdFNdgL6sjhuFPZQtfrsQ3MXHDPz8NYQKlAj7mEhrAdKV2CZrRNKL5xQnhDroYfIDqw1S59t6FSw9rNO3bnp1KwcgXRPQYWaZYmison/hVRM/0R40bbIevi0oP2Dkuh5rcaoelg8QKtShyHeQCuj5BsAeoCZ/4VUTP9EeNQpDXVvCc07PoQ7ADefzPge3+sbWIdpYdgMN9sH1mfyOltQumxUrnyp/4VUTP9EeNVUoAczh/n0jpDQO5otlDdczbI5dy83J76nu2fK3PK9poFp9NUt+MGPEX2GqMaDUJcOKP51+h2L5mrJxfu4RSEg==]]></Body> </Root>
返回信息中 MerchantNo 是开发者id'
对<Body>
des解密后得到结果示例:<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Data> <channels> <channel> <ChannelId>2</ChannelId> <ChannelName>支付宝</ChannelName> <Isuse>1</Isuse> </channel> <channel> <ChannelId>3</ChannelId> <ChannelName>微信</ChannelName> <Isuse>1</Isuse> </channel> </channels> </Data>
3.2 交易结果查询接口
- 功能码:P2005
- 接口说明:该接口提供所有支付订单的结果查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑,当商户在一定时间(建议3秒)没有收到支付平台异步通知时,可以主动调用该接口查询某笔订单的交易状态
- 请求参数:
<Data>
参数 | 名称 | 类型 | 长度 | 是否必填 | 说明 | 示例 |
---|---|---|---|---|---|---|
order_no | 业务单号 | String | 32 | 是 | 商户内部业务单号 | WX2019072200001 |
merchant_no | 收款商户号 | String | 32 | 是 | 商户号 | 809900000001 |
- 响应参数:
参数 | 名称 | 类型 | 长度 | 是否必输 | 说明 | 示例 |
---|---|---|---|---|---|---|
TradeNo | 平台流水号 | String | 32 | 是 | 聚合支付平台流水号 | 34411000 |
PayTradeNo | 渠道流水号 | String | 32 | 是 | 各个支付渠道返回的流水号 | 4200000376201907220000000000 |
OrderNo | 业务单号 | String | 32 | 是 | 商户内部业务单号 | WX2019072200001 |
Amt | 实际支付金额 | Price | 16.2 | 是 | 用户实际付款金额 | 0.01 |
PayTime | 实际支付时间 | String | 16 | 是 | yyyy-MM-dd hh:mm:ss | 2019-07-22 21:37:31 |
PayStatus | 支付状态 | String | 6 | 是 | 0=未支付;1=支付成功;2=支付失败;-1=关闭或撤销 | 1 |
receipt_amount | 商户收到的金额 | Price | 16.2 | 是 | 相当于订单支付金额 | 0.01 |
JAVA请求示例:
String data = "<Data>" + "<order_no>WX2019072200001</order_no>\n" + "<merchant_no>809900000001</merchant_no>\n"+ "</Data>"; HeaderDTO header = new HeaderDTO(); header.setFuncId("P2005"); header.setMerchantNo(【your developerId】); header.setTimestamp(System.currentTimeMillis() + ""); header.setSignature(SecurityUtil.signRSA(data, 【your privateKey】, "UTF-8")); // DataDTO dataDTO = new DataDTO(); dataDTO.setHeader(header); dataDTO.setBody(SecurityUtil.encryptDes(data, 【your desKey】 , "UTF-8")); String content = XMLUtil.toXml(dataDTO, DataDTO.class, "UTF-8"); String resData = null; try { CloseableHttpResponse response = HttpClients.custom().build().execute(RequestBuilder.post().setUri("http://onlinetest.bsoftpay.com/gatewayOnline/gateway/portal/execute").setEntity(new StringEntity(content, ContentType.APPLICATION_XML.withCharset(Consts.UTF_8))).build()); String res = EntityUtils.toString(response.getEntity(), Consts.UTF_8); System.out.println(res); //解析返回xml DataDTO resultData = XMLUtil.fromXml(res, DataDTO.class); //回调成功-获取body内容 if ("0000".equals(resultData.getHeader().getRetCode())) { //解密body resData = SecurityUtil.decryptDes(resultData.getBody(), 【your desKey】,"UTF-8"); }else{ //异常信息 resData = resultData.getHeader().getRetMsg(); } } catch (Exception e) { e.printStackTrace(); } System.out.println(resData);
对
<Body>
des解密后得到结果示例:<Data> <TradeNo>9000010155</TradeNo> <PayTradeNo>2019071622001473731042322248</PayTradeNo> <OrderNo>paymentTest201907160001</OrderNo> <Amt>0.01</Amt> <receipt_amount>0.01</receipt_amount> <PayStatus>1</PayStatus> </Data>
注意: P2005功能中数据域是用
<Data></Data>
包围
3.3 交易退款接口
- 功能码:P2008
- 接口说明:当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家(原路返回)。注意的地方:微信超过1年的订单无法提交退款,支付宝超过3个月的订单无法提交退款,可以一笔订单多次退款,但是累计金额不能超过原支付金额
- 请求参数:
<Data>
参数 | 名称 | 类型 | 长度 | 必填 | 说明 | 示例 |
---|---|---|---|---|---|---|
RequestNo | 退款订单号 | String | 32 | 是 | 商户内部唯一退款单号 | TK20190722001 |
PayType | 退款渠道 | String | 2 | 是 | 2=支付宝;3=微信 | 2 |
Amt | 退款金额 | Price | 16.2 | 是 | 退款金额不得超过原支付金额 | 0.01 |
TradeNo | 原支付业务单号 | String | 32 | 是 | 商户原支付订单号 | WX2019072200001 |
merchant_no | 商户号 | String | 32 | 是 | 平台商户号 | 809900000001 |
- 响应参数:
参数 | 名称 | 类型 | 长度 | 必输 | 说明 | 示例 |
---|---|---|---|---|---|---|
RequestNo | 退款订单号 | String | 32 | 是 | 申请退款订单号 | TK20190722001 |
Amt | 退款金额 | Price | 16.2 | 是 | 申请退款金额 | 0.01 |
- 请求数据域示例:
<Data> <RequestNo>MZ18007960352737_tk</RequestNo> <PayType>3</PayType> <Amt>0.01</Amt> <TradeNo>MZ18007960352737</TradeNo> <merchant_no>809900000001</merchant_no> </Data>
- 返回数据域示例:
<Data> <RequestNo>MZ18007960352737_tk</RequestNo> <Amt>66.6</Amt> </Data>
- 注意: P2008功能中数据域是用
<Data></Data>
包围
3.4 交易退款结果查询接口
- 功能码:P2009
- 接口说明:提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用微信零钱或者支付宝余额宝、花呗等支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态(20分钟、3 个工作日都是大概时间,不一定为准,有可能提前,有可能延迟)
- 请求参数:
<Data>
参数 | 名称 | 类型 | 长度 | 是否必填 | 说明 | 示例 |
---|---|---|---|---|---|---|
RequestNo | 退款订单号 | String | 32 | 是 | 商户内部唯一退款单号 | TK20190722001 |
PayType | 退款渠道 | String | 2 | 是 | 2=支付宝;3=微信 | 2 |
- 响应参数:
参数 | 名称 | 类型 | 长度 | 是否必输 | 说明 | 示例 |
---|---|---|---|---|---|---|
RequestNo | 退款订单号 | String | 32 | 是 | 申请退款订单号 | TK20190722001 |
Amt | 退款金额 | Price | 16.2 | 是 | 当code为1时这里会显示退款金额 | 0.01 |
Code | 退款状态 | String | 2 | 是 | -1交易不存在 1 成功 2 失败 | 1 |
Msg | 错误信息描述 | String | 100 | 是 | 当code为2时这里会显示错误信息 | 0.01 |
- 请求数据域示例:
<Data> <RequestNo>MZ18007960352737_tk</RequestNo> <PayType>3</PayType> </Data>
- 返回数据域示例:
<Data> <RequestNo>MZ18007960352737_tk</RequestNo> <code>1</code> <Msg></Msg> <Amt>66.6</Amt> </Data>
- 注意: P2009功能中数据域是用
<Data></Data>
包围
3.5 交易结果通知
- 功能码:P3001
- 接口说明:支付成功后,平台异步通知用户端(平台不保证异步通知能够准时到达,建议接入方有自己的定时主动查询策略,以异步通知作为辅助查询)。交易结果通知的地址,需要提前告知平台商务对接人员进行配置。
注意:商户在接受到支付平台回调后,如果业务成功,返回 success
,失败返回 fail
,注意都是小写,不要用空格或者换行。
支付平台服务器在没有收到业务成功回调信息时,会尝试重发消息,总共3
次通知(通知的间隔频率一般是:30s,1m,2m),3 次以后将不再通知,所以不保证通知最终能成功(建议以交易结果查询接口为主,异步通知为辅,如果 3 秒左右还没有接受到异步通知,就应该主动调用交易结果查询接口)
- 响应参数:
参数 | 名称 | 类型 | 长度 | 是否必输 | 说明 | 示例 |
---|---|---|---|---|---|---|
TradeNo | 支付平台交易流水号 | String | 32 | 是 | 支付平台交易流水号 | 32013134 |
PayTradeNo | 渠道流水号 | String | 32 | 是 | 第三方支付渠道流水号 | 20192323971391918391121 |
OrderNo | 业务单号 | String | 32 | 是 | 商户内部业务单号 | wx201907150001 |
Amt | 支付金额 | Price | 16.2 | 是 | 支付金额 | 0.01 |
PayTime | 实际支付时间 | String | 16 | 是 | yyyyMMddHHmmss | 20190725123012 |
PayStatus | 支付状态 | String | 6 | 是 | 0=未支付;1=支付成功;2=支付失败;-1=关闭或撤销 | 1 |
- 返回示例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Root> <Head> <MerchantNo>开发者id</MerchantNo> <FuncId>P3001</FuncId> <Timestamp>1564047104204</Timestamp> <Signature>O/qiP7mMk+aPrlyVursZRX7+lpcxpXyuwkD7wXLm2g+9k7jR2OVQUfeSUZz2ImsTwL1BwBbRNl/N8hIUrKmMJw==</Signature> </Head> <Body>q9bLT3/3k9fmPk5WBu4Z3BOLbGJBX9BoIymWbEp67FOrWlZRuBOyQ7OFyDRLRhi5RamJcI+WOsbD2vzG4KOYcZkXOgg/cU433T9URVZCxV8nUv8MlTHGSTg2Oz8Ws7slVrBTSfSuzkP6WIQ5FUSNen9UGSqVdpk155DK0iDi74TbF+5o9bSfO5fLFQVjIaqQayxjBSvOR3/3I9hKZaOVMpkIct/InCCGBliKd2dUIw1apNJJxhK75L+a1C0DD2gOyhOh8qKtFNA=</Body> </Root>
注:返回参数数据在<body>已经被DES加密,需要接入方利用对接时获取的“对称密钥”,对密文使用下载的加解密工具进行解密
注:这里回调参数中MerchantNo是开发者id
- 解密java示例:
String xml = SecurityUtil.decryptDes(body, [your 对称秘钥], "utf-8");
4. 客户端API列表
4.1 支付预下单接口
- 功能码:P2003
- 接口请求地址:
- 正式环境:由平台商务对接人员提供
- 测试环境:http://onlinetest.bsoftpay.com/gatewayOnline/gateway/portal/frontReq
- 接口说明:该接口应用场景为,app端通过调用支付宝/微信提供的官方sdk,然后唤起第三方支付客户端进行支付。
注:该接口的加密信息建议由服务端处理,然后再由app端向支付平台发起下单请求
- 客户端入参:
<xml>
参数 | 名称 | 类型 | 长度 | 必填 | 说明 | 示例 |
---|---|---|---|---|---|---|
MerchantNo | 开发者id | String | 30 | 是 | 聚合支付平台配置信息:developerId ☆由服务端传值☆ |
10467 |
FuncId | 功能码 | String | 30 | 是 | 聚合支付平台功能码 | P2003 |
Timestamp | 时间戳 | String | 30 | 是 | 当前时间戳(ms) | 1574737510560 |
PlatType | APP类型 | String | 30 | 是 | SDK平台类型:1=iOS;2=android | 1 |
BundleId | APP唯一标识 | String | 30 | 是 | 包路径配置需要与在聚合支付平台的配置保持一致 | com.healthpay |
Signature | 签名 | String | 30 | 是 | 对<Data>业务入参</Data> 内容,使用平台提供的私钥privateKey ,通过标准RSA(PKCS8)算法生成的签名 ☆由服务端传值☆ |
OME+Y8tXusMYFdmxpxd6ZUg3OtioZBCZnyaoYNaAlc7z6hw9Ph9iRdovRGtatNAK1wXQNhCEnKJT6g7UZPsuyg== |
Data | 业务单号 | String | 是 | 对<Data>业务入参</Data> 内容,使用平台提供的对称密钥desKey ,通过des加密算法加密得到的字符串 ☆由服务端传值☆ |
lAKWTa+eweVSoBEWErQEtwdHqDQqCjOg5y…… |
- 客户端出参:
<xml>
参数 | 名称 | 类型 | 长度 | 必填 | 说明 | 示例 |
---|---|---|---|---|---|---|
RetCode | 返回code | String | 30 | 是 | 0000:表示接口业务调用正常; 9999:表示处理失败,如参数错误,验签失败等 |
0000 |
RetMsg | 返回错误信息 | String | 30 | 是 | 接口调用异常时返回信息 | 验签失败 |
Timestamp | 时间戳 | String | 30 | 是 | 商户业务系统的唯一订单号 | BX20190722902141 |
Data | 业务加密信息 | String | 是 | 业务返回信息 需要使用<Data>业务出参</Data> ,Key 通过des算法解密获取明文信息 |
6n+r9ZMYYTqOO36Y+fhkcbT/dhia57XhikBnmj2uRoTXFMwi4nnZ4oQvaHk…… | |
Signature | 签名 | String | 30 | 是 | 可使用publicKey 通过RSA算法进行验签,确认返回的数据没有被串改 |
BX20190722902141 |
Key | des解密key | String | 30 | 是 | 该key是被des加密后的字符串,需要向平台技术支持人员索要对称密钥来解密该key得到原始值。原始值用于对Data进行解密 |
BX20190722902141 |
- 业务入参:
<Data>
由服务端来组装加签加密
参数 | 名称 | 类型 | 长度 | 必填 | 说明 | 示例 |
---|---|---|---|---|---|---|
order_no | 业务单号 | String | 30 | 是 | 商户业务系统的唯一订单号 | BX20190722902141 |
Name | 支付者姓名 | String | 30 | 是 | 付款者姓名 | 张三 |
Mobile | 手机号码 | String | 15 | 是 | 用户手机号 | 13211112222 |
Amt | 支付金额 | Price | 16.2 | 是 | 以元为单位 | 0.01 |
TransdateTime | 请求支付时间 | String | 16 | 是 | yyyy-MM-dd hh:mm:ss | 2019-07-29 12:23:12 |
paytype | 支付渠道 | String | 2 | 是 | 1=健康钱包;2=支付宝;3=微信 | 2 |
MerchantNo | 收款商户号 | String | 30 | 是 | 创业聚合支付系统为医院分配的平台商户号 | 809900000001 |
MerchName | 收款账户名 | String | 30 | 是 | 商户名称账户名称 | 中山杭创测试商户 |
OrderSubject | 商品标题 | String | 150 | 是 | 如:门诊、住院预交、住院结算、自助缴费等 | 门诊 |
OrderDetail | 商品描述 | String | 300 | 是 | 如:门诊挂号、门诊结算、住院预交、住院结算、自助挂号、自助结算、自助住院预交等 | 门诊挂号 |
PayTimeOut | 订单超时时间 | String | 3 | 否 | 单位是: m (分钟) 如果不填,默认是 6分钟,如果填,必须大于5分钟 | 6 |
Password | 交易密码 | String | 2 | 否 | 当paytype = 1时,必填。设计简单对称加密。网接收后,解密并转成核心系统密文 | 5 |
HealthCardId | 健康e卡号 | String | 30 | 否 | 商户内部区分订单字段 | 001 |
Opt | 操作员 | String | 30 | 否 | 商户内部区分订单字段 | 001 |
remark | 备注 | String | 200 | 否 | 备注 | |
his_charge_no | his收费单号 | String | 300 | 否 | 如果totalFee没有值,那么HIS在窗口通过feeNo进行退款时,只控制每笔feeNo只允许退款一次,而且不管这次金额是否大于或者小于这笔feeNo的原支付金额;当totalFee有值时,HIS在窗口通过feeNo进行退款时,会控制每笔feeNo退款的金额是否大于原支付金额,同时也允许每笔feeNo多次退款,而且累计金额不能大于原支付金额 |
[{"feeNo":"wxdcs001","totalFee":200},{"feeNo":"wxdcs002","totalFee":100}] |
- 业务出参:
<Data>
参数 | 名称 | 类型 | 长度 | 是否必输 | 说明 | 示例 |
---|---|---|---|---|---|---|
TradeNo | 平台订单号 | String | 32 | 是 | 聚合支付平台的唯一订单号 | 54000000 |
PayType | 支付渠道 | number | 1 | 是 | 2=支付宝;3=微信 | 2 |
OrderInfo | 订单信息 | String | 500 | 否 | 支付宝支付请求信息拼接字符串 | 1 |
Appid | 应用ID | String | 32 | 否 | 微信开放平台审核通过的应用APPID | wx8888888888888888 |
Partnerid | 商户号 | String | 32 | 否 | 微信支付分配的商户号 | 1900000109 |
Prepayid | 预支付交易会话标识 | String | 32 | 否 | 微信返回的支付交易会话ID | WX1217752501201407033233368018 |
NonceStr | 随机字符串 | String | 32 | 否 | 随机字符串,不长于32位 | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS |
Timestemp | 时间戳 | String | 10 | 否 | 时间戳 | 1574738745 |
Sign | 签名 | String | 32 | 否 | 签名 | C380BEC2BFD727A4B6845133519F3AD6 |
TradeType | 交易类型 | String | 16 | 否 | 调用接口提交的交易类型 | APP |
客户端请求示例:
<Xml> <MerchantNo>10467</MerchantNo> <FuncId>P2003</FuncId> <Timestamp>1574737510560</Timestamp> <PlatType>1</PlatType> <BundleId>com.hk515.joybao</BundleId> <Signature>OME+Y8tXusMYFdmxpxd6ZUg3OtioZBCZnyaoYNaAlc7z6hw9Ph9iRdovRGtatNAK1wXQNhCEnKJT6g7UZPsuyg==</Signature> <Data>lAKWTa+eweVSoBEWErQEtwdHqDQqCjOg5yvkF0/x/ZntR7nm5nGL+wKbdHMxf/aTfe6SVr4WbP05HdCdmME/zPRkgZbhjOhsk1lYO2CF1dsEDzeScUzb/5UTSpuCR50xYGhshruLP0KXPwdCw6hX+KHdmAYziiy8tvs5Cafwlvl99Fr6k5Qnuoa9OUeLBUNRNvpi4KF/CO7gUXb1+xxys+aGTOWJgjfHvsVr/U6sr/eRaMJg/HXxPDQyWg2ekNa8iX6r6SnRAFBOWPzSn4dkiJeSepez/Z8npu12jhsiRj60rcsjwvS1dbUzSq13XY+pmtspyy90izTwW2sIkeG8nDmmiTCWqOalLHUAVVCGIc6/0AxyDSpIaPS45+f0QErAnZetybb6SDMMQWCUiYf0Vd+nITxSN4oFRSGatBmM75zjDoSbd+ZPs4IBxKk8U7fhpUyQSZsRYV7phGhcy3G8mvi3DxYvWQYHVpddJxlvN3Y7fg+t8RhSA8rIQHqs0NkRUQuZJKWyDgv76l2yyC6k+0bUX+VmZ/c1BxgeZttjte5gpUkYxu0fs4Vq02vD5kOnuZEPKxSymsWmHsOC+V9fg3qeOBElNF9DeuBzRHkAHJScc/mHM/L6Y0mBzEugiykCDlDLMvzTVifo3D76GFN0npXUxS8qruqMpQ4XI5dInJCaaQnc13lQxWZJLgQsvp/MxHWLSk8LyzcPBPpfg9P2Z8DnHF/dqUyWGXAw12ZSESbEdYtKTwvLN6lxZsBnWuS+dQa/z8XNdVM=</Data> </Xml>
客户端响应示例:
<Xml> <RetCode>0000</RetCode> <RetMsg></RetMsg> <Timestamp>1574738745941</Timestamp> <Data>6n+r9ZMYYTqOO36Y+fhkcbT/dhia57XhikBnmj2uRoTXFMwi4nnZ4oQvaHkgpNAmNGOm9tmSr3jkk1OsnxsRR9JKmG3NFBB14zycy478v1uXzn1rxEKrSWmV6dSSVOhEu19Y0lxQXdjlsD6S1KBIdTOlGrfMRoUZEc0R64m/QHjAGH29hbk4Sk7JYBXsq9+0I8M4+4NmmyUV4W0vkwIDER9D9uQv4ooom64Arz2GnkNncmYASuFVqaTaTJKVjgfmfIH+/eV5SVgioRuET1wXjmNFVy48KQZxZ0Olstat12K5yzWUjnwswEJ8IxyG2Y2muxSe4eFLRQK6kRBaWmrfGK5NzTy2j44HOxAnhxWtjoHQ/1rhtmVgSMGy14hA4juV8sOTOUgC/38YN26qF1RcRwV+mRpZzOt7Mm+FusAOmqIu+/xO2APQWBKhE0LrOPFGi2O4ryNNTpxMlW3jKnWvX+3QSzdxgeBwM8Ji3P6UJY+FyvIFsWBlXADxGKap2gnc</Data> <Signature>6bb49128438bd21fb3bce6dfff536293</Signature> <Key>ESG4S0u/KEfwkjSKW5NI+A==</Key> </Xml>
业务入参报文示例:
<Data> <order_no>appTest201911261455746000</order_no> <paytype>3</paytype> <Mobile>13212341234</Mobile> <Amt>0.01</Amt> <TransdateTime>2019-11-26 14:55:37</TransdateTime> <PayTimeOut>6</PayTimeOut> <Opt>小二</Opt> <Remark>我是备注</Remark> <Name>张三</Name> <MerchantNo>809900000001</MerchantNo> <MerchName>杭州聚合支付测试</MerchName> <OrderSubject>预约挂号</OrderSubject> <OrderDetail>耳鼻喉科</OrderDetail> </Data>
业务出参报文示例:
#支付宝: <Data> <TradeNo>9000022441</TradeNo> <OrderInfo>app_id=2017030306032861&biz_content=%7B%22body%22%3A%22%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF%95detail%22%2C%22extend_params%22%3A%22%7B%5C%22sys_service_provider_id%5C%22%3A%5C%222088621455853863%5C%22%7D%22%2C%22out_trade_no%22%3A%229000022441%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22seller_id%22%3A%222088621455853863%22%2C%22subject%22%3A%22%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF%95subject%22%2C%22timeout_express%22%3A%226m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2Fofflinetest.bsoftpay.com%2FgatewayOffline%2Fpay%2Fzfb%2Fcallback&sign=YjWslPBT%2Ftiq6Tgij3rhY4gJDE341w6hL2UvXbScEECnr5Wv22F7mLMQpdWtPeHcvW3gWW%2BsW3DvHBEIH4wS5khg2KLUDjKpe5dR61FhHSLzdqJmO5cBgH4EvZzN8ebvRVtoeIAruaTBEMts%2ByHXirPRdaqHH64sBBnc4O6%2FR4QnovMSVmPtItbwZ2GwjNob2RZZaecgEfhw3ZRIHqx4i92t89aN1bj3ZVFhzWlMms0LAgAGM7Zcy0QOdEAzOCtiRSqK4Zi7LzpQN2FAs2sq4l7l%2F3EnYm7OPSLsJl5ca1%2FV6bk6JDmpu5baflzaqAdhgxSmy58nyzxuqJzZh%2BhBfA%3D%3D&sign_type=RSA2×tamp=2019-11-26+11%3A23%3A45&version=1.0</OrderInfo> <PayType>2</PayType> </Data>
#微信: <Data> <TradeNo>9000022442</TradeNo> <Partnerid>1482325275</Partnerid> <Prepayid>wx2611254591326800c6d11ff11680634500</Prepayid> <Appid>wxe4esaf23321fsa1</Appid> <Sign>BFD72F3C320658580CE3C1C27BDBFF1D</Sign> <NonceStr>0d3d12f927d14be4b9d266aa47b3f9b9</NonceStr> <TradeType>APP</TradeType> <Timestemp>1574738745</Timestemp> <PayType>3</PayType> </Data>
5. 支付全流程了解
- APP支付时序图:
- 外部链接:
微信app支付介绍
支付宝app支付介绍