1.文档说明
1.1文档目的
本文档的目的是为宝付商户退款API定义一个接口规范,以帮助商户技术人员快速接入宝付认证网关,并快速掌握其相关功能,便于尽快的投入使用。
1.2阅读对象
- 商户开发人员、维护人员和管理人员
- 宝付相关的技术人员
1.3技术支持
在开发或使用退款API接口时,如果您有任何技术上的疑问,请按如下方式寻求帮助,宝付技术支持人员会及时处理,给予您答复:
- 技术支持热线:021-68819999
- 技术支持Email:support@baofoo.com
- 技术支持QQ:800066689
1.4术语与定义
1.4.1符号含义
序号 | 符号缩写 | 符号性质 | 符号说明 |
---|---|---|---|
1 | M | 强制域(Mandatory) | 必须填写的属性,否则会被认为格式错误 |
2 | C | 条件域(Conditional) | 某条件成立时必须填写的属性 |
3 | O | 选用域(Optional) | 选填属性 |
4 | R | 原样返回域(Returned) | 必须与先前报文中对应域的值相同的域 |
1.4.2术语含义
- 商户号:宝付提供给商户的唯一编号,是商户在宝付的唯一标识;
- 终端号:商户在与宝付签订某项具体产品功能的合作协议自动分配的会员属性,将用于进行具体交易的必要参数。
- 原商户订单号:原先支付时商户请求提交的支付订单号。
- 退款商户订单号:商户退款时请求宝付提交的退款订单号,当天请求不可重复。
- 退款商户流水号:商户请求宝付退款时提交的流水号,每次请求均不可重复;
- 退款宝付业务流水号:宝付返回给商户的唯一退款订单号,是宝付记录一笔退款订单的唯一标识。
1.5 报文说明
1.5.1 请求报文
请求报文格式
格式:key1=value1&key2=value2&key3=value3…
例如:send_time=2018-01-24 13:25:33&msg_id=456795112&version=4.0.0.0&terminal_id=100000949&txn_type=03&member_id=100000749&dgtl_envlp=5a9c3ac419735d249e319727c89cfc0ce4a80d6a954980eaf3ea934316a56a121c758b0d13bf3302b877a8dd68619db72b2bd588ccdc9eb7fdb455705be1909df96540009146d7d81c96c0b90578f9344bd3fc00ded94d27c0c8040a83c02114b7a3a4698f830b7d0db60f230a5c3a4b38e7104088f2ee0139a4e765a9d79255&user_id=123&signature=7ca60bdea1f253b1a09588f7e4f0d455d984eaad0a446e61044c1527ea19fbdd70d690cc627327955b7a01a58acbc11cad6a26f8086c1bf23126da36832be59c46bc20e942bcae7614fcd9ba4dc7eec4c5e17024fb04fe5e63f2d137a3517a1e0c7bdea6d4ae33dbab7d20543e474a4bd790f7ba42cacaef45730623482a70ac
将除签名字段之外的不为空的字段按key-value的形式构建TreeMap<String, String>对象,按key1=value1&key2=value2…模式将TreeMap对象转换为字符串,UTF-8编码格式下转换为字节数组,用终端号作为ID,用商户SM2签名私钥证书使用SM2withiSM3算法签名后转16大写进制。
生成SM4密钥,按照如下拼装:
格式:02|对称密钥,02代表SM4_ECB算法
加密方式:用宝付SM2加密证书公钥加密后转16进制大写
加密方式:UTF-8编码格式下转字节数组,使用数字信封指定的方式和密钥加密后转16进制大写
商户订单号格式
商户订单号为8位系统当前日期+1-42位随机数
1.5.2 返回报文
返回报文格式
格式:key1=value1&key2=value2&key3=value3…
例如:
biz_resp_code=0000&biz_resp_msg=交易成功&dgtl_envlp=74652829c07a71983c0da582321818aec41364528626e0f90eac1c633755b9dab84593695f5a101401052e9c64d457a881e442206330215de2281d2a3ea15d79e6732e296fdc36c6e0c76d17376cf6b9fc978b50bc747a9536d93226a69aba587f9fa5227a9b2cb915d1b822753f4a86a9fa1d81bf4d106723d927cf0f6365fb&member_id=100000749&msg_id=4a3f0b1862b94b6f853c1d28f9913f82&protocols=f222d7fe76b7c8ea7e22f3ee315e579a4263d697b12de605c287018e15cd530358dd8f638e4211b09e4e250d6b352304e0b454332aa0efda6977d435cf911dbc3943615ae31752e9a87c6e4b69dfc9e3af6be7a9a6e3f6a92a63e65b59936beb&resp_code=S&send_time=2018-01-25 09:53:01&signature=8ab74c7869632dc395cc945adcc388e6afceb759e4d406c3bb6e0e8002ec422f1615f2a43966d7337dcc57963f18877a959fe9f67b082da2cd95217ba003cc81f07962d665f576509ebc1a38f7ddf2a423775a794b262b7ffc4af615da3ba6bd05d0672c004d7cf80be3ed236f268078bb5c700d4b0a6ae9a0e58f2c782bd6ef&terminal_id=100000949&txn_type=03&version=4.0.0.0
将宝付返回的除签名字段之外的不为空的字段按key-value的形式构建TreeMap<String, String>对象,按key1=value1&key2=value2…模式将TreeMap对象转换为字符串,UTF-8编码格式下转换字节数组。将宝付返回的签名字段转大写后转16进制字节数组,用终端号作为ID,用宝付SM2签名证书公钥使用SM2withiSM3算法验签。
解密方式:将数字信转16进制字节数组,使用商户的加密证书私钥解密
解密后格式:02|对称密钥,02代表SM4_ECB算法
解密方式:将敏感字段转大写后转16进制字节数组后,使用数字信封指定的方式和密钥解密
2.业务方案说明
2.1应用场景
退款API产品是宝付为满足商户在与宝付发生交易后需发起退款,以非页面手动点击,而是以纯后台的模式发起退款。
2.2业务流程
流程说明:
1、持卡人在支付成功后,发起退款;
2、商户向宝付发送退款请求;
3、宝付进行信息审核,通知商户是否受理;
4、退款结果无论成功或失败都会通知商户;
5、商户可以向宝付发起退款查询;
6、宝付返回查询结果详情。
3.业务接口说明
测试信息:
商户号:100000178
终端号:100000972
商户测试私钥:bfkey100000178@@100000972.pfx
商户测试私钥密码:100000178296251
商户测试公钥:bfkey_100000178@@100000972.cer
3.1退款请求接口
3.1.1交易URL
测试环境地址:https://vgw.baofoo.com/cutpayment/api/backTransRequest
正式环境地址:https://public.baofoo.com/cutpayment/api/backTransRequest
3.1.2请求报文
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 验签方式 | verify_type | M | 取值:10 |
2. | 数据类型 | data_type | M | data_type=xml或json |
3. | 签名信息 | verify_string | M | 交易签名 |
4. | 业务数据 | data_content | M | 具体参数如下 |
业务数据
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 报文发送时间 | send_time | M | 发送方发出本报文时的机器日期时间,如 2017-12-19 20:19:19 5分钟容错 |
2. | 终端号 | terminal_id | M | |
3. | 版本号 | version | M | 4.0.0.0 |
4. | 交易类型 | txn_type | M | 331 |
5. | 商户号 | member_id | M | 宝付提供给商户的唯一编号 |
6. | 交易子类 | txn_sub_type | M | 09 |
7. | 退款类型 | refund_type | M | 取值 1:宝付收银台 2:认证支付、代扣、快捷支付 3:微信支付 5:支付宝支付 8:协议支付 18:转账支付 |
8. | 原商户订单号 | trans_id | M | 原商户发起的支付订单号 |
9. | 退款商户订单号 | refund_order_no | M | 退款时商户端生成的订单号 |
10. | 退款商户流水号 | trans_serial_no | M | 每次发起退款的流水不能重复 |
11. | 退款原因 | refund_reason | M | |
12. | 退款金额 | refund_amt | M | 单位:分 例:1元则提交100 |
13. | 退款发起时间 | refund_time | M | 14 位定长。 格式:年年年年月月日日时时分分秒秒 |
14. | 附加字段 | additional_info | O | 长度不超过 128 位 |
15. | 请求方保留域 | req_reserved | O | |
16. | 服务器通知商户地址 | notice_url | O | 结果成功或者失败通知商户地址 |
17. | 营销退款信息 | union_refund_info | O | 单位(分) 格式 商户1,金额1;商户2,金额2… 例如 100000363,10;100000364,90; |
18. | 已分账退款信息 | part_share_refund_info | O | 单位(分) 格式 商户1,金额1;商户2,金额2… 例如 CM100000363,10;100000364,90; |
19. | 分账退款是否垫资 | share_refund_advance_flag | O | 传1:是 不传或传0:否 如果垫资,part_share_refund_info字段传:垫资商户号,垫资金额; 目前只支持主商户垫资。 |
20. | 退款分账信息 | share_refund_info | O | 单位(分) 格式 商户1,金额1;商户2,金额2… 例如 100000363,10;100000364,90; |
20. | 加密证书序列号 | ncrptn_sn | M | 宝付公钥证书序列号,用于选择解密证书 |
21. | 签名证书序列号 | sign_sn | M | 商户公钥证书序列号,用于选择验签证书 |
22. | 风险控制参数 | risk_item | O | 风控预留字段 |
3.1.3应答报文
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 签名 | signature | M | 交易签名 |
2. | 业务数据 | data_content | M | 具体参数如下 |
业务数据
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 应答码 | resp_code | M | 具体参照错误码表 |
2. | 应答消息 | resp_msg | M | 具体参照错误码表 |
3. | 退款宝付业务流水号 | refund_business_no | M | 宝付返回给商户的唯一退款订单号 |
4. | 退款商户订单号 | refund_order_no | R | |
5. | 退款金额 | refund_amt | R | 单位:分 |
6. | 终端号 | terminal_id | R | |
7. | 商户号 | member_id | R | |
8. | 数据类型 | data_type | R | xml/json |
9. | 交易类型 | txn_type | R | |
10. | 交易子类 | txn_sub_type | R | |
11. | 版本号 | version | O | |
12. | 附加字段 | additional_info | O | |
13. | 预留字段 | req_reserved | O | |
14. | 加密证书序列号 | ncrptn_sn | M | 商户公钥证书序列号,用于选择解密证书 |
15. | 签名证书序列号 | sign_sn | M | 宝付公钥证书序列号,用于选择验签证书 |
3.1.4范例
3.1.4.1请求范例
请求密文组装:
- xml格式:
<?xml version="1.0" encoding="UTF-8" ?> <data_content> <terminal_id>123456</terminal_id> <member_id>123564</member_id> <txn_sub_type>09</txn_sub_type> <trans_id>123456</trans_id> <refund_order_no>4509883</refund_order_no> <refund_reason>需要退款<refund_reason> <refund_amt>100</refund_amt> <refund_time>20160119111112</refund_time> <refund_type>2</refund_type> <notice_url>http://www.example.com/page_url</notice_url> <trans_serial_no>1234567890</trans_serial_no> <additional_info>附加字段</additional_info> <req_reserved>请求方保留域</req_reserved> </data_content>
- json格式:
{ "terminal_id":123456, "member_id":123564, "txn_sub_type:09, "trans_id":"123456", "refund_order_no":"14509883", "refund_reason":"需要退款", "refund_amt":"100", "refund_time":"20160119111112", "refund_type":"2", "notice_url":"http://www.example.com/page_url", "trans_serial_no":"1234567890", "additional_info":"附加字段", "req_reserved":"请求方保留域" }
备注:如果明文参数中data_type的值为xml,这里组装密文则使用xml格式,反之为json。将以上组装的字符串先进行base64进行加密,然后使用商户私钥进行证书加密,生成的密文则对应为data_content的值。
3.1.4.2应答范例
应答密文解析:
- Xml格式:
<?xmlversion="1.0"encoding="UTF-8" ?> <result> <refund_amt></refund_amt> <refund_order_no>20160119123456</refund_order_no> <refund_business_no></refund_business_no> <version>4.0.0.1</version> <member_id>123456</member_id> <terminal_id>456789</terminal_id> <resp_code>0000</resp_code> <resp_msg>退款交易已受理</resp_msg> <req_reserved>预留字段</req_reserved> <additional_info></additional_info> <txn_sub_type>09</txn_sub_type> <txn_type>331</txn_type> <data_type>xml</data_type> </result>
- Json格式:
{ "data_type":"json", "member_id":"123456", "terminal_id":"456789", "refund_order_no":"20160119123456", "req_reserved":"预留字段", "resp_code":"0000", "resp_msg":"退款交易已受理", "txn_sub_type":"09", "txn_type":"331", "version":"4.0.0.1" }
备注:resp_code返回0000是表示此次受理交易已成功,并不代表退款成功。
3.2退款状态查询
3.2.1交易URL
测试环境地址:https://vgw.baofoo.com/cutpayment/api/backTransRequest
正式环境地址:https://public.baofoo.com/cutpayment/api/backTransRequest
3.2.2请求报文
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 验签方式 | verify_type | M | 取值:10 |
2. | 数据类型 | data_type | M | data_type=xml或json |
3. | 签名信息 | verify_string | M | 交易签名 |
4. | 业务数据 | data_content | M | 具体参数如下 |
业务数据
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 报文发送时间 | send_time | M | 发送方发出本报文时的机器日期时间,如 2017-12-19 20:19:19 5分钟容错 |
2. | 交易子类 | txn_sub_type | M | 10 |
3. | 版本号 | version | M | 4.0.0.0 |
4. | 交易类型 | txn_type | M | 331 |
5. | 商户号 | member_id | M | 宝付提供给商户的唯一编号 |
6. | 终端号 | terminal_id | M | |
7. | 退款商户订单号 | refund_order_no | M | 退款时商户端生成的订单号 |
8. | 商户流水号 | trans_serial_no | M | 每次发起退款不能重复 |
9. | 附加字段 | additional_info | O | 长度不超过 128 位 |
10. | 请求方保留域 | req_reserved | O | |
11. | 加密证书序列号 | ncrptn_sn | M | 宝付公钥证书序列号,用于选择解密证书 |
12. | 签名证书序列号 | sign_sn | M | 商户公钥证书序列号,用于选择验签证书 |
3.2.3应答报文
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 签名 | signature | M | 交易签名 |
2. | 业务数据 | data_content | M | 具体参数如下 |
业务数据
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 应答码 | resp_code | M | 具体参见附录:应答码 |
2. | 应答信息 | resp_msg | M | 填写具体的应答信息 |
3. | 退款商户订单号 | refund_order_no | R | |
4. | 成功退款金额 | refund_amt | M | 交易成功后返回的金额;单位:分 |
5. | 商户号 | member_id | R | |
6. | 终端号 | terminal_id | R | |
7. | 交易类型 | txn_type | R | |
8. | 交易子类 | txn_sub_type | R | |
9. | 签名数据类型 | data_type | R | |
10. | 版本号 | version | O | |
11. | 附加字段 | additional_info | O | |
12. | 预留字段 | req_reserved | O | |
13. | 加密证书序列号 | ncrptn_sn | M | 商户公钥证书序列号,用于选择解密证书 |
14. | 签名证书序列号 | sign_sn | M | 宝付公钥证书序列号,用于选择验签证书 |
3.2.4范例
3.2.4.1请求范例
请求密文组装:
- xml格式:
<?xml version="1.0" encoding="UTF-8" ?> <data_content> <terminal_id>123456</terminal_id> <member_id>123564</member_id> <txn_sub_type>10</txn_sub_type> <refund_order_no>4985612</refund_order_no> <trans_serial_no>1234567890</trans_serial_no> <additional_info>附加字段</additional_info> <req_reserved>请求方保留域</req_reserved> </data_content>
- json格式:
{ "terminal_id":123456, "member_id":123564, "txn_sub_type":10, "refund_order_no":"4985612", "trans_serial_no":"1234567890", "additional_info":"附件字段", "req_reserved":"请求方保留域" }
备注:如果明文参数中data_type的值为xml,这里组装密文则使用xml格式,反之为json。将以上组装的字符串先进行base64加密,然后使用商户私钥进行证书加密,生成的密文则对应为data_content的值。
3.2.4.2应答范例
应答密文解析:
- Xml 格式:
<?xml version="1.0" encoding="UTF-8" ?> <result> <refund_amt></refund_amt> <refund_order_no>20160119123456</refund_order_no> <version>4.0.0.1</version> <member_id>123456</member_id> <resp_code>BF00128</resp_code> <resp_msg>该笔订单不存在</resp_msg> <terminal_id>456789</terminal_id> <req_reserved>预留字段</req_reserved> <additional_info>附加字段</additional_info> <txn_sub_type>10</txn_sub_type> <txn_type></txn_type> <data_type>xml</data_type> </result>
- Json 格式:
{ "additional_info":"附加字段", "data_type":"json", "member_id":"123456", "refund_order_no":"20160119123456", "req_reserved":"预留字段", "resp_code":"BF00128", "resp_msg":"该笔订单不存在", "terminal_id":"456789", "txn_sub_type":"10", "version":"4.0.0.1" }
备注:resp_code返回0000是表示退款成功。
3.3通知商户退款结果
3.3.1异步通知报文
异步通知,商户接收到通知后,需在notice_url
页面上输出 OK
字符,表示接收成功<除了 OK
无其他内容>,若不返回则20分钟通知一次,一共通知5次结束。商户还可通过退款状态查询接口
查询退款订单的状态。
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 签名 | signature | M | 交易签名 |
2. | 业务数据 | data_content | M | 具体参数如下 |
业务数据
序号 | 域名 | 变量名 | 必填 | 备注 |
---|---|---|---|---|
1. | 商户号 | member_id | R | |
2. | 退款商户订单号 | refund_order_no | R | |
3. | 退款成功金额 | refund_amt | M | |
4. | 退款宝付业务流水号 | refund_business_no | M | |
5. | 返回码 | resp_code | M | 参照错误码 |
6. | 应答消息 | resp_msg | M | 应答消息 |
7. | 加密证书序列号 | ncrptn_sn | M | 商户公钥证书序列号,用于选择解密证书 |
8. | 签名证书序列号 | sign_sn | M | 宝付公钥证书序列号,用于选择验签证书 |
3.3.2异步通知范例
- xml格式:
data_content = <result> <terminal_id>10001</terminal_id> <member_id>100000362</member_id> <trans_id>1236546587</trans_id> <trade_date>20160425181400</trade_date> <succ_amt>1</succ_amt> <resp_code>0000</resp_code> <resp_msg>交易成功</resp_msg> <trans_no>201508060110000524183254</trans_no> <ncrptn_sn>4026170977</ncrptn_sn> <sign_sn>1387287898</sign_sn> </ result> signature=3046022100A16E88164336F9870C917364EAEA11346104E43C66B3F78CD0A37E480D4C0B85022100EACEB82F34FDFDFAD8B1716B2ACF4A5B7A9666C82D2DAB48F81F3FDA53EDC2B8
- json格式:
data_content={ "terminal_id":"10001", "member_id":"100000362", "trans_id":"1236546587", "trade_date":"20160425181400", "succ_amt":"1", "resp_code":"0000", "resp_msg":"交易成功", "trans_no":"201508060110000524183254", "ncrptn_sn":"4026170970", "sign_sn":"1387287808" } signature=3046022100A16E88164336F9870C917364EAEA11346104E43C66B3F78CD0A37E480D4C0B85022100EACEB82F34FDFDFAD8B1716B2ACF4A5B7A9666C82D2DAB48F81F3FDA53EDC2B8
备注:退款成功或者失败均会通知商户。验签响应报文时,先将16进制签名转字节数组,再使用SM2宝付签名公钥证书验签。
附录:
1.应答码
1)成功类
错误码 | 含义 |
---|---|
0000 | 交易成功,已退款成功金额为准(退款请求接口返回0000表示退款受理;退款状态查询接口返回0000表示退款成功) |
2)交易处理中或未知,需要后续查询
错误码 | 含义 |
---|---|
BF00100 | 系统异常,请联系宝付 |
BF00112 | 系统繁忙,请稍后再试 |
BF00113 | 交易结果未知,请稍后查询 |
BF00115 | 交易处理中,请稍后查询 |
BF00307 | 退款处理中 |
BF00384 | 银行处理中 |
BF00203 | 退款交易已受理 |
3)交易失败
错误码 | 含义 |
---|---|
BF00308 | 交易失败:%具体失败原因% |
BF00101 | 持卡人信息有误 |
BF00116 | 该终端号不存在 |
BF00118 | 报文中密文解析失败 |
BF00119 | 短信验证超时,请稍后再试 |
BF00120 | 报文交易要素缺失 |
BF00121 | 报文交易要素格式错误 |
BF00123 | 商户不存在或状态不正常,请联系宝付 |
BF00124 | 商户与终端号不匹配 |
BF00125 | 商户该终端下未开通此类型交易 |
BF00126 | 该笔订单已存在 |
BF00128 | 该笔订单不存在 |
BF00129 | 密文和明文中参数值【%s】不一致,请确认是否被篡改 |
BF00135 | 交易金额不正确 |
BF00170 | 未开通该产品,请联系宝付 |
BF00172 | 报文中密文解析失败,请确认密文格式是否正确 |
BF00173 | 绑定关系不存在或状态不正常 |
BF00177 | 非法的交易 |
BF00179 | 交易存在风险,交易中止 |
BF00190 | 商户流水号不能重复 |
BF00300 | 退款金额超出原订单支付金额 |
BF00301 | 商户号和终端号与原订单不匹配 |
BF00302 | 原订单拒绝退款 |
BF00303 | 退款订单已存在,请勿重复提交 |
BF00304 | 退款金额超出可退款金额 |
BF00305 | 退款订单信息不存在 |
BF00306 | 原交易订单未支付成功,无法退款 |
2.交易子类
取值 | 交易子类 |
---|---|
09 | 退款 |
10 | 退款订单查询 |
3.订单重复性校验
宝付为了确保交易能够准确的通知到商户,有可能会重复发送通知消息,为此宝付提醒商户,采取正确的防重复校验。
大多数校验通知都采取先查询后更新的方式,这种方式存在一个很大的漏洞,当多个通 知请求在很短的一个时间内达到时,查询数据有可能是脏数据,导致订单重复更新,后续工 作重复执行。
对于此种情况,宝付结合自身校验情况,分享两个校验方式。
1) 如果是单线程或者订单资源在一个共享区域,那么可以采取锁定资源的方式,每次 调用加锁,每次调用完毕解锁。
2) 大部分数据都存在数据库,宝付绝大多数都是这种情况,利用数据库的特性来控制, 在我们调用数据库更新信息时,数据库会返回给我们更新条目数,我们利用这个特性,这样 操作,当我们更新订单时,把这个订单的原始状态作为条件进行更新,当我们短时间内操作 更新时,第二次更新必然不成功,因为条件不满足了,状态变了,那么数据库在第二次就会 返回更新数量为0,这样我们就发现问题了,这就是熟称的“乐观锁”。
最后编辑:xiaofeng 更新时间:2025-01-09 17:41