交易类¶
快捷支付统合版短信发送 T01¶
功能说明¶
个人用户使用快捷支付时商户需要调用本接口。接口返回成功后,会向个人用户银行预留手机上发送验证码,将获取到的短信验证码,通过调用【快捷支付统合版支付】接口,完成整个快捷支付流程。
调用方式:系统调用
校验逻辑¶
- 用户若首次使用快捷,交易成功时快捷卡绑定+支付一次操作完成。用户再次使用快捷不会重复绑卡。
- 银行预留手机号必须与银行卡号对应,且银行卡持有人必须与个人用户一致。
- 调用本接口成功后,若需要更改用户银行卡号对应的银行预留手机号时,需要调用【银行卡解绑】接口。
- 交易类型为充值时,只支持借记卡充值,用户客户号字段必输,记入用户虚拟账户可用余额。
- 交易类型为其它时,分账串和入账客户号两者必填其一,记入用户虚拟账户可用余额。
- 交易类型为担保时,入账客户号必填,记入商户中间担保过渡户,当调用【订单确认】接口时,从商户中间担保过渡户转入入账方虚拟账户可用余额。
- 若分账串不为空时,分账串总金额必须等于交易金额;分账客户号必须为当前商户或商户下的用户;分账客户号不能与用户客户号相同;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大仅支持5个分账客户号。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T01 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 必须 | 由汇付生成,用户的唯一性标识 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
交易金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
银行卡号 | card_no | 变长32位String | 必须 | 本次快捷绑卡待绑定的银行卡号 |
银行预留手机号 | card_ mobile | 变长11位String | 必须 | 本次快捷绑卡待绑定的银行卡,在银行开户时的预留手机号 |
银行卡开户省份 | card_prov | 定长4位String | 可输 | 本次快捷绑卡待绑定的银行卡开户省份 |
银行卡开户地区 | card_area | 定长4位String | 可输 | 本次快捷绑卡待绑定的银行卡开户地区 |
入账用户号 | in_cust_id | 定长16位String | 可选 | 交易类型为充值时,必须为空; 其它时,入账客户号与分账串必填一个。 |
入账子账户号 | in_acct_id | 变长9位String | 可选 | 交易类型为充值时,必须为空; 其它时,入账子账户号与分账串不能同时存在。 |
分账串 | div_detail | 变长String | 可选 | 交易类型为充值或担保时,必须为空; 其它时,入账客户号与分账串必填一个;分账串最多5个: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; recharge-充值; other-其它; 默认other。 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
付款方交易终端类型 | payer_term_type | 定长2位String | 可选 | 01-电脑; 02-手机; 03-平板设备; 04-可穿戴设备; 05-数字电视; 06-条码支付受理终端; 99-其他。 |
付款方交易终端编码 | payer_term_no | 变长32位String | 可选 | 请参考《网络支付报文结构及要素技术规范(V1.0)》(银办发[2016] 222号) |
收款方交易终端类型 | payee_term_type | 定长2位String | 可选 | 01-电脑; 02-手机; 03-平板设备; 04-可穿戴设备; 05-数字电视; 06-条码支付受理终端; 99-其他。 |
收款方交易终端编码 | payee_term_no | 变长32位String | 可选 | 请参考《网络支付报文结构及要素技术规范(V1.0)》(银办发[2016] 222号) |
商品简称 | goods_short_name | 变长40位String | 可选 | 不能包含特殊字符:<>&’”|%#\^- |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
分账类型 | div_type | 定长2位String | 可选 | 01: 延时分账 |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 变长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T01 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 必须 | 由汇付生成,用户的唯一性标识 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
交易金额 | trans_amt | 变长14位String | 必须 | |
入账用户号 | in_cust_id | 定长16位String | 可选 | |
分账串 | div_detail | 变长String | 可选 | |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; recharge-充值; other-其它; 默认other。 |
银行卡号 | card_no | 变长32位String | 必须 | 本次快捷绑卡待绑定的银行卡号 |
银行预留手机号 | card_ mobile | 变长11位String | 必须 | 本次快捷绑卡待绑定的银行卡,在银行开户时的预留手机号 |
银行卡开户省份 | card_prov | 定长4位String | 可输 | 本次快捷绑卡待绑定的银行卡开户省份 |
银行卡开户地区 | card_area | 定长4位String | 可输 | 本次快捷绑卡待绑定的银行卡开户地区 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T01");
map.put("mer_cust_id", "6666000000118348");
map.put("user_cust_id", " 6666000000134045");
map.put("order_date", "20181018");
map.put("order_id", "20181018000001");
map.put("trans_amt", "0.01");
map.put("card_no", " 6232510000000002");
map.put("card_mobile", " 131566800000");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("trans_type", " recharge");
map.put("mer_priv", "mer_priv");
map.put("extension", "extension");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T01"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"card_area":"",
"extension":"",
"return_code": "90000",
"return_desc": "交易成功",
"payer_term_no":"",
"trans_amt":"0.01",
"payee_term_type":"",
"order_date":"20181018",
"bg_ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"card_no":"6232510000000002",
"payee_term_no":"",
"payer_term_type":"",
"div_detail":"",
"mer_priv":"",
"user_cust_id":"6666000000134045",
"card_prov":"",
"goods_short_name":"",
"in_cust_id":"",
"order_id":"20181018000001",
"cmd_id":"T01",
"card_mobile":"13156680000",
"mer_cust_id":"6666000000118348",
"trans_type":"recharge"
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"card_area":"",
"extension":"extension",
"payer_term_no":"",
"trans_amt":"0.01",
"payee_term_type":"",
"order_date":"20181018",
"bg_ret_url":" http://192.168.0.200:8008/hftest/common/commonResult.jsp ",
"card_no":"6232510000000002",
"payee_term_no":"",
"payer_term_type":"",
"div_detail":"",
"mer_priv":"mer_priv",
"user_cust_id":"6666000000134045",
"card_prov":"",
"goods_short_name":"",
"in_cust_id":"",
"order_id":"20181018000001",
"cmd_id":"T01",
"card_mobile":"13156680000",
"mer_cust_id":"6666000000118348",
"trans_type":"recharge"
}
快捷支付统合版支付 T02¶
功能说明¶
本接口调用之前先要调用【快捷支付统合版短信发送】接口完成短信验证码的发送。用户进行快捷支付的短信验证码确认阶段。如果是第一次支付,会弹出快捷卡支付协议页面(可以配置不弹出);如果是贷记卡,会弹出cvv2有效期输入页面。 用户付款银行卡需要预先在银行网银或柜面开通在线支付功能才可进行支付。
调用方式:页面调用
校验逻辑¶
- 原请求订单号、原请求订单日期为【快捷支付统合版短信发送】的请求订单号,请确认已调用成功,且收到短信验证码。
- 【快捷支付统合版短信发送】的【用户客户号】必须与本接口【用户客户号】保持一致。
- 短信验证码设有默认过期时间,请尽快输入并完成支付。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T02 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 必须 | 由汇付生成,用户的唯一性标识 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为 YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
原请求订单号 | ori_order_id | 变长20位String | 必须 | 快捷支付短信发送的请求订单号 |
原请求订单日期 | ori_order_date | 定长8位String | 必须 | 快捷支付短信发送的请求订单日期 |
短信验证码 | sms_code | 定长6位String | 必须 | |
页面返回URL | ret_url | 变长128位String | 可选 | 交易完成后,本平台系统把交易结果通过页面方式,发送到该地址上 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果 注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
请求类型 | request_type | 定长2位String | 必须 | 00 : PC端; 01 : 移动端。 |
二级商户号 | secondary_mer_id | 定长10位String | 可选 | 对于开启二级商户模式的商户,必须输入其配下的二级商户号 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 变长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T02 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 必须 | 由汇付生成,用户的唯一性标识 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
原请求订单号 | ori_order_id | 变长20位String | 必须 | 快捷支付短信发送的请求订单号 |
原请求订单日期 | ori_order_date | 定长8位String | 必须 | 快捷支付短信发送的请求订单日期 |
本平台交易唯一标识号 | platform_seq_id | 定长18位String | 必须 | 组成规则:8位本平台日期+ 10位系统流水号 |
短信验证码 | sms_code | 定长6位String | 必须 | |
绑卡id | bind_card_id | 变长20位String | 必须 | 本次快捷绑卡的ID |
开户银行代号 | bank_id | 变长8位String | 可选 | 具体见附件:开户银行代号 |
银行卡号 | card_no | 变长32位String | 可选 | 返回银行卡号 |
交易金额 | trans_amt | 变长14位String | 必须 | |
页面返回URL | ret_url | 变长128位String | 可选 | 交易完成后,本平台系统把交易结果通过页面方式,发送到该地址上 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果 注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
手续费金额 | fee_amt | 变长14位String | 可选 | |
手续费客户号 | fee_cust_id | 定长16位String | 可选 | |
手续费账户号 | fee_acct_id | 变长9位String | 可选 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T02");
map.put("mer_cust_id", "6666000000118348");
map.put("user_cust_id", " 6666000000134045");
map.put("order_date", "20181018");
map.put("order_id", "20181018000002");
map.put("sms_code", "111111");
map.put("ori_order_id", "20181018000001");
map.put("ori_order_date", "20181018");
map.put("request_type", "00");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "mer_priv");
map.put("extension", "extension");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T02"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"return_code": "90000",
"return_desc": "交易成功",
"card_area":"",
"extension":"",
"bind_card_id":"1000009940",
"request_type":"",
"sms_code":"111111",
"trans_amt":"0.01",
"secondary_mer_id":"",
"ori_order_id":"20181018000001",
"card_no":"6232510000000002",
"payee_term_no":"",
"bank_id":"01050000",
"div_detail":"",
"mer_priv":"",
"card_prov":"",
"goods_short_name":"",
"cmd_id":"T02",
"fee_amt":"0.00",
"card_mobile":"13156680000",
"trans_type":"recharge",
"payer_term_no":"",
"fee_cust_id":"6666000000118348",
"payee_term_type":"",
"order_date":"20181018",
"bg_ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"fee_acct_id":"216548",
"ori_order_date":"20181018",
"payer_term_type":"",
"user_cust_id":"6666000000134045",
"in_cust_id":"",
"order_id":"20181018000002",
"ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_cust_id":"6666000000118348"
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"bank_id": "",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"cash_bind_card_id": "69273",
"cash_type": "T0",
"cmd_id": "T07",
"extension": "extension",
"fee_acct_id": "",
"fee_amt": "",
"fee_cust_id": "",
"mer_cust_id": "6666000000118348",
"mer_priv": "mer_priv",
"order_date": "20181018",
"order_id": "20181018000001",
"real_trans_amt": "",
"ret_url": "",
"trans_amt": "0.01",
"trans_stat": "F",
"user_cust_id": "6666000000136008"
}
网银支付 T03¶
校验逻辑¶
- 【交易类型】为充值时,用户必须注册,只支持借记卡充值,【用户客户号】字段必输,记入用户虚拟账户可用余额。
- 【交易类型】为其它时,用户可以未注册,【分账串】和【入账客户号】两者必填其一,记入用户虚拟账户可用余额。
- 【交易类型】为担保时,记入商户中间担保过渡户,当调用【订单确认】接口时,从商户中间担保过渡户转入入账方虚拟账户可用余额。
- 若分账串不为空时,分账串总金额必须等于交易金额;分账客户号必须为当前商户或商户下的用户;分账客户号不能与用户客户号相同;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大仅支持5个分账客户号。
- 如果输入【支付网关号】参数,会直接跳转到指定银行的网银页面;若未输入,则会弹出如下页面供用户选择:

请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T03 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 可选 | 由汇付生成,用户的唯一性标识 |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为 YYYYMMDD |
入账客户号 | in_cust_id | 定长16位String | 可选 | 交易类型为充值时,必须为空; 分账类型为延时分账时,可为空。其它时,入账客户号与分账串必填一个。 |
入账子账户号 | in_acct_id | 变长9位String | 可选 | 交易类型为充值时,必须为空;分账类型为延时分账时,可为空。其它时,入账子账户号与分账串必填一个。 |
分账串 | div_detail | 变长String | 可选 | 交易类型为充值或担保时,必须为空;分账类型为延时分账时,可为空。 其它时,入账客户号与分账串必填一个;分账串最多5个: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; recharge-充值; other-其它; 默认other。 |
支付网关号 | gate_id | 定长2位String | 可选 | 网关号 |
交易金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
页面返回URL | ret_url | 变长128位String | 可选 | 前台异步通知商户网银支付结果,前台页面返回 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
二级商户号 | secondary_mer_id | 定长10位String | 可选 | 对于开启二级商户模式的商户,必须输入其配下的二级商户号 |
商品名称 | goods_desc | 变长12位String | 可选 | 默认:通用型产品 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
分账类型 | div_type | 定长2位String | 可选 | 01: 延时分账 |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T03 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_Id | 定长16位String | 可选 | 由汇付生成,用户的唯一性标识 |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
入账客户号 | in_cust_id | 定长16位String | 可选 | |
分账串 | div_detail | 变长String | 可选 | 分账串最多5个: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; recharge-充值; other-其它; 默认other。 |
交易金额 | trans_amt | 变长14位String | 必须 | |
本平台交易唯一标识号 | platform_seq_id | 定长18位String | 必须 | 组成规则:8位本平台日期+ 10位系统流水号 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
页面返回URL | ret_url | 变长128位String | 可选 | 前台异步通知商户网银支付结果,前台页面返回 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
手续费金额 | fee_amt | 变长14位String | 可选 | |
手续费客户号 | fee_cust_id | 定长16位String | 可选 | |
手续费账户号 | fee_acct_id | 变长9位String | 可选 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T03");
map.put("mer_cust_id", " 6666000000043640");
map.put("user_cust_id", " 6666000000053384");
map.put("in_cust_id", " 6666000000053385");
map.put("order_date", "20181018");
map.put("order_id", "20181018000001");
map.put("trans_amt", "0.01");
map.put("trans_type", " other");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "mer_priv");
map.put("extension", "extension");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T03"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"return_code": "90000",
"return_desc": "交易成功",
"extension":"",
"trans_amt":"0.01",
"goods_desc":"",
"fee_cust_id":"",
"secondary_mer_id":"",
"order_date":"20181018",
"bg_ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"fee_acct_id":"",
"gate_id":"",
"div_detail":"",
"mer_priv":"",
"user_cust_Id":"6666000000053384",
"in_cust_id":"6666000000053385",
"order_id":"20181018000001",
"cmd_id":"T03",
"fee_amt":"",
"ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_cust_id":"6666000000043640",
"trans_type":"other"
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"extension":"",
"trans_amt":"0.01",
"goods_desc":"",
"fee_cust_id":"",
"secondary_mer_id":"",
"order_date":"20181018",
"bg_ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"fee_acct_id":"",
"gate_id":"",
"div_detail":"",
"mer_priv":"",
"user_cust_Id":"6666000000053384",
"in_cust_id":"6666000000053385",
"order_id":"20181018000001",
"cmd_id":"T03",
"fee_amt":"",
"ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_cust_id":"6666000000043640",
"trans_type":"other"
}
扫码支付 T04¶
功能说明¶
- 商户调用该接口生成订单二维码,并展示在PC或手机上,用户使用微信、支付宝APP扫描二维码并完成支付。
- 自2019年5月5日起上线的新商户,完成入驻后商户需继续完成自身微信官方实名认证后才能进行交易,实名认证流程请 下载指引手册。
调用方式:页面调用
校验逻辑¶
- 交易类型为充值时,用户必须注册,只支持借记卡充值,用户客户号字段必输,记入用户虚拟账户可用余额。
- 交易类型为其它时,用户可以未注册,分账串和入账客户号两者必填其一,记入用户虚拟账户可用余额。
- 交易类型为担保时,记入商户中间担保过渡户,当调用【订单确认】接口时,从商户中间担保过渡户转入入账方虚拟账户可用余额。
- 若分账串不为空时,分账串总金额必须等于交易金额;分账客户号必须为当前商户或商户下的用户;分账客户号不能与用户客户号相同;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大仅支持5个分账客户号。
- 需要商户提供更多材料做入驻后才能使用本接口。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T04 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 可选 | 由汇付生成,用户的唯一性标识 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
入账客户号 | in_cust_id | 定长16位String | 可选 | 交易类型为充值时,必须为空; 分账类型为延时分账时,可为空。其它时,入账客户号与分账串必填一个。 |
入账子账户号 | in_acct_id | 变长9位String | 可选 | 交易类型为充值时,必须为空;分账类型为延时分账时,可为空。其它时,入账子账户号与分账串必填一个。 |
分账串 | div_detail | 变长String | 可选 | 交易类型为充值或担保时,必须为空;分账类型为延时分账时,可为空。 其它时,入账客户号与分账串必填一个;分账串最多5个: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; recharge-充值; other-其它; 默认other。 |
商品描述 | goods_desc | 变长127位String | 必须 | |
二维码支付类型 | qr_type | 定长2位String | 必须 | 04 : 微信; 05 : 支付宝。 |
请求类型 | request_type | 定长2位String | 必须 | 00 : PC端(汇付页面显示二维码); 01 : 移动端(汇付页面显示二维码)。 |
交易金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
操作员 | oper_user_Id | 变长32位String | 可选 | |
商品类型 | goods_type | 变长32位String | 可选 | |
订单超时时间 | order_expire_time | 定长14位String | 可选 | 单位秒 格式为YYYYMMDDHHmmss |
设备号 | device_info | 变长32位String | 可选 | |
商户前台应答地址 | ret_url | 变长128位String | 可选 | 请求类型为后端时,必须输入 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
二级商户号 | secondary_mer_id | 定长10位String | 可选 | 对于开启二级商户模式的商户,必须输入其配下的二级商户号 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
分账类型 | div_type | 定长2位String | 可选 | 01: 延时分账 |
入驻客户号 | sign_cust_id | 定长16位String | 可选 | 支付宝微信支付时填写的用户的入驻客户号,交易时在微信支付宝支付页面显示该用户的企业信息 |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T04 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 可选 | 由汇付生成,用户的唯一性标识 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
入账客户号 | in_cust_id | 定长16位String | 可选 | |
分账串 | div_detail | 变长String | 可选 | 分账串最多5个: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; recharge-充值; other-其它; 默认other。 |
商品描述 | goods_desc | 变长1024位String | 必须 | |
二维码支付类型 | qr_type | 定长2位String | 必须 | 04 : 微信; 05 : 支付宝。 |
请求类型 | request_type | 定长2位String | 必须 | 00 : PC端(汇付页面显示二维码); 01 : 移动端(汇付页面显示二维码)。 |
交易金额 | trans_amt | 变长14位String | 必须 | |
二维码链接 | qrcode_url | 变长128位String | 可选 | |
操作员 | oper_user_id | 变长32位String | 可选 | |
商品类型 | goods_type | 变长32位String | 可选 | |
订单超时时间 | order_expire_time | 变长12位String | 可选 | 单位秒 |
设备号 | device_info | 变长32位String | 可选 | |
外部订单流水号 | out_trans_id | 变长64位String | 可选 | 外部订单流水号,指支付宝、微信、银联流水号 |
商户前台应答地址 | ret_url | 变长128位String | 可选 | 请求类型为后端时,必须输入 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
二级商户号 | secondary_mer_id | 定长10位String | 可选 | 对于开启二级商户模式的商户,必须输入其配下的二级商户号 |
手续费金额 | fee_amt | 变长14位String | 可选 | |
手续费客户号 | fee_cust_id | 定长16位String | 可选 | |
手续费账户号 | fee_acct_id | 变长9位String | 可选 | |
内外扣标志 | fee_flag | 定长1位String | 可选 | 0 : 内扣; 1 : 外扣 |
入驻客户号 | sign_cust_id | 定长16位String | 可选 | 支付宝微信支付时用户的入驻客户号,交易时在微信支付宝支付页面显示该用户的企业信息(仅同步返回) |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T04");
map.put("mer_cust_id", "6666000000118348");
map.put("user_cust_id", " 6666000000118473");
map.put("order_date", "20181018");
map.put("order_id", "20181018000001");
map.put("trans_amt", "0.01");
map.put("goods_desc", "扫码测试");
map.put("qr_type", "05");
map.put("request_type", "00");
map.put("trans_type", " recharge");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "mer_priv");
map.put("extension", "extension");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T04"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"cmd_id": "T04",
"goods_desc": "扫码测试",
"mer_cust_id": "6666000000118348",
"order_date": "20181018",
"order_id": "20181018000001",
"qr_type": "05",
"request_type": "00",
"return_code": "90000",
"return_desc": "交易成功",
"ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"secondary_mer_id": "",
"trans_amt": "0.01",
"trans_type": "recharge",
"user_cust_id": "6666000000118473"
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"bg_ret_url": "http://172.31.19.97:8081/eacloud",
"cmd_id": "T04",
"goods_desc": "扫码测试",
"mer_cust_id": "6666000000118348",
"order_date": "20181018",
"order_id": "20181018000001",
"qr_type": "05",
"request_type": "00",
"ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"secondary_mer_id": "",
"trans_amt": "0.01",
"trans_type": "guarantee",
"user_cust_id": "6666000000118473"
}
用户提现 T07¶
校验逻辑¶
- 用户已绑定提现银行卡,若未绑定提现银行卡,请调用【绑定提现卡】接口。
- 用户账户可用余额充足,调用【余额查询】接口,可查看用户可用余额。
- 若商户账户安全措施选择短信验证时,需先调用【短信发送】接口,两个接口的订单号和订单日期必须一致,将用户收到的短信验证码上送【短信验证码】字段中,系统会验证短信验证码的正确性。短信验证码的时效为10分钟,且同一笔订单号的短信验证码验证失败总次数不得超过5次,若过期或验证失败次数超限,请重新调用【短信发送】接口。
- 提现方式为T1时,同步返回处理中,银行T+1日处理完成后,通过商户后台应答地址发送异步通知给商户,商户需要处理该异步通知。
- 提现方式为T0时,同步返回处理中,通过商户后台应答地址发送异步通知给商户,商户需要处理该异步通知。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位的String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T07 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 必须 | 用户的唯一性标识 |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
交易金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
提现绑定银行卡ID | cash_bind_card_id | 变长20位String | 必须 | |
提现方式 | cash_type | 定长2位String | 必须 | T0:T+0提现; T1:T+1提现。 |
手续费收取对象 | fee_obj | 定长8位String | 可选 | 商户指定提现手续费的收取对象,优先级别高于商户配置的收取对象:M:向商户收取;U:向用户收取。 |
手续费收取子账户 | fee_acct_id | 变长9位String | 可选 | 向商户收取时,必填 |
短信验证码 | sms_code | 定长6位String | 可选 | 商户支付安全配置短信验证时必输 |
商户前台返回地址 | ret_url | 变长128位String | 可选 | 通过前台通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
出款账户号 | out_acct_id | 变长9位String | 可选 | 指定取现出款账户号,为空,默认获取用户基本账户出款 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T07 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 变长16位String | 必须 | |
用户客户号 | user_cust_id | 变长16位String | 必须 | |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一 |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
交易金额 | trans_amt | 变长14位String | 必须 | |
实际到账金额 | real_trans_amt | 变长14位String | 可选 | 提现成功实际到账金额 |
提现绑定银行卡ID | cash_bind_card_id | 变长20位String | 必须 | |
提现方式 | cash_type | 定长2位String | 必须 | T0:T+0提现; T1:T+1提现。 |
开户银行代号 | bank_id | 变长8位String | 可选 | 具体见附件:开户银行代号 |
手续费金额 | fee_amt | 变长14位String | 可选 | |
手续费扣款客户号 | fee_cust_id | 变长16位String | 可选 | |
手续费扣款子账户号 | fee_acct_id | 变长9位String | 可选 | |
交易状态 | trans_stat | 变长8位String | 必须 | S-成功; F-失败; I-初始; P-处理中。 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | |
出款账户号 | out_acct_id | 变长9位String | 可选 | 指定取现出款账户号,为空,默认获取用户基本账户出款 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T07");
map.put("mer_cust_id", "6666000000118348");
map.put("user_cust_id", "6666000000136008");
map.put("order_date", "20181018");
map.put("order_id", "20181018000001");
map.put("trans_amt", "0.01");
map.put("cash_bind_card_id", "69273");
map.put("cash_type", "T0");
map.put("sms_code", "666666");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "mer_priv");
map.put("extension", "extension");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T07"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"bank_id": "",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"cash_bind_card_id": "69273",
"cash_type": "T0",
"cmd_id": "T07",
"extension": "extension",
"fee_acct_id": "216548",
"fee_amt": "0",
"fee_cust_id": "6666000000118348",
"mer_cust_id": "6666000000118348",
"mer_priv": "mer_priv",
"order_date": "20181018",
"order_id": "20181018000001",
"real_trans_amt": "",
"return_code": "90000",
"return_desc": "交易成功",
"ret_url": "",
"trans_amt": "0.01",
"trans_stat": "S",
"user_cust_id": "6666000000136008"
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"bank_id": "",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"cash_bind_card_id": "69273",
"cash_type": "T0",
"cmd_id": "T07",
"extension": "extension",
"fee_acct_id": "",
"fee_amt": "",
"fee_cust_id": "",
"mer_cust_id": "6666000000118348",
"mer_priv": "mer_priv",
"order_date": "20181018",
"order_id": "20181018000001",
"real_trans_amt": "",
"ret_url": "",
"trans_amt": "0.01",
"trans_stat": "F",
"user_cust_id": "6666000000136008"
}
APP支付 T09¶
功能说明¶
- 支持支付宝正扫、微信正扫、银联正扫、微信APP支付、微信公众号支付、支付宝统一下单和微信小程序支付功能。
- 自2019年5月5日起上线的新商户,完成入驻后商户需继续完成自身微信官方实名认证后才能进行交易,实名认证流程请 下载指引手册。
调用方式:系统调用
校验逻辑¶
- 交易类型为其它时,用户可以未注册,【分账串】和【入账客户号】两者必填其一,记入用户虚拟账户可用余额。
- 交易类型为担保时,记入商户中间担保过渡户,当调用【订单确认】接口时,从商户中间担保过渡户转入入账方虚拟账户可用余额。
- 若分账串不为空时,分账串总金额必须等于交易金额;分账客户号必须为当前商户或商户下的用户;分账客户号不能与用户客户号相同;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大仅支持5个分账客户号。
- 支付类型为微信APP支付、微信公众号支付、微信小程序支付时,商户需先在微信官方申请APPID。
- 支付类型为微信公众号、微信小程序时,商户需先调用微信官方接口获取用户登录产生的operid,对应到本接口参数buyer_id, 详见微信官方文档 。
- 需要商户提供更多材料做入驻后才能使用本接口。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T09 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 可选 | 付款人客户号 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为 YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
支付类型 | pay_type | 定长2位String | 必须 | 04:微信正扫; 05:支付宝正扫; 10 : 微信APP支付; 12:支付宝统一下单; 13:微信公众号; 18:银联正扫; 19:微信小程序。 |
交易金额 | trans_amt | 变长14位String | 必须 | 金额格式是###.00 |
入账客户号 | in_cust_id | 定长16位String | 可选 | 交易类型为充值时,必须为空; 分账类型为延时分账时,可为空。其它时,入账客户号与分账串必填一个。 |
入账子账户号 | in_acct_id | 变长9位String | 可选 | 交易类型为充值时,必须为空;分账类型为延时分账时,可为空。其它时,入账子账户号与分账串必填一个。 |
分账串 | div_detail | 变长String | 可选 | 交易类型为担保时,必须为空;分账类型为延时分账时,可为空。 其它时,入账客户号与分账串必填一个;分账串最多5个: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “dvCustId”:”6666000000118348”}] |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; other-其它; 默认other。 |
是否原生态 | is_raw | 定长1位String | 可选 | 微信公众号支付支持的参数, 是否原生态: 1-是; 0-否; 为空时,默认1。 |
APPID | app_id | 变长32位String | 可选 | 支付类型为微信APP支付、微信公众号、微信小程序时不能为空,商户在微信申请的APPID。 |
买家用户ID | buyer_id | 变长100位String | 可选 | 微信公众号支付和小程序支付时,不能为空。 |
商品描述 | goods_desc | 变长127位String | 必须 | |
商品类型 | goods_type | 定长4位String | 可选 | |
附加信可选息 | attach_info | 变长128位String | 可选 | 微信公众号支付的可选参数 |
商品标记 | good_tag | 变长32位String | 可选 | 微信公众号支付的可选参数 |
支付返回地址 | ret_url | 变长128位的String | 可选 | 微信公众号支付、支付宝统一下单时,必须输入 |
商户后台应答地址 | bg_ret_url | 变长128位的String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位的String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位的String | 可选 | 用于扩展请求参数 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
分账类型 | div_type | 定长2位String | 可选 | 01: 延时分账 |
入驻客户号 | sign_cust_id | 定长16位String | 可选 | 支付宝微信支付时填写的用户的入驻客户号,交易时在微信支付宝支付页面显示该用户的企业信息 |
订单超时时间 | order_expire_time | 定长14位String | 可选 | 单位秒 格式为YYYYMMDDHHmmss |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
同步返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T09 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
银行返回码 | bg_bank_code | 变长32位String | 可选 | |
银行返回描述 | bg_bank_message | 变长200位String | 可选 | |
订单日期 | order_date | 定长8位String | 必须 | |
订单号 | order_id | 变长20位String | 必须 | |
商户客户号 | mer_cust_id | 定长16位String | 必须 | |
支付地址 | pay_url | 变长64位String | 可选 | 支付宝统一下单返回参数; 支付宝浏览器下直接用此链接请求支付宝支付; 微信公众号也有可能返回支付地址,在未返回支付信息时,使用支付地址。 注:目前部分通道不支持返回支付地址。 |
动态口令 | token_id | 变长64位String | 可选 | 微信公众号非原生态时返回参数 |
支付信息 | pay_info | 变长String | 可选 | |
内外扣标志 | fee_flag | 定长1位String | 可选 | 0 : 内扣; 1 : 外扣 |
入驻客户号 | sign_cust_id | 定长16位String | 可选 | 支付宝微信支付时填写的用户的入驻客户号,交易时在微信支付宝支付页面显示该用户的企业信息 |
异步返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T09 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为 YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
用户客户号 | user_cust_id | 定长16位String | 可选 | 付款人客户号 |
支付类型 | pay_type | 定长2位String | 必须 | 04:微信正扫; 05:支付宝正扫; 10 : 微信APP支付; 12:支付宝统一下单; 13:微信公众号; 18:银联正扫; 19:微信小程序。 |
交易金额 | trans_amt | 变长14位String | 必须 | 金额格式是###.00 |
入账客户号 | in_cust_id | 定长16位String | 可选 | |
分账账户串 | div_detail | 变长String | 可选 | 分账串最多5个: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}]。 |
交易类型 | trans_type | 变长Stirng | 可选 | guarantee-担保; other-其它; 默认other。 |
是否原生态 | is_raw | 定长1位String | 可选 | 微信公众号支付支持的参数, 是否原生态: 1-是; 0-否; 为空时,默认1。 |
APPID | app_id | 变长32位String | 可选 | 支付类型为微信APP支付时不能为空,商户在微信申请的APPID。 |
买家用户ID | buyer_id | 变长100位String | 可选 | 微信公众号支付和小程序支付时,不能为空。 |
商品描述 | goods_desc | 变长127位String | 必须 | |
商品类型 | goods_type | 定长4位String | 可选 | |
附加信可选息 | attach_info | 变长128位String | 可选 | 微信公众号支付的可选参数 |
商品标记 | good_tag | 变长32位String | 可选 | 微信公众号支付的可选参数 |
外部订单流水号 | out_trans_id | 变长64位String | 可选 | 外部订单流水号,指支付宝、微信、银联流水号 |
支付返回地址 | ret_url | 变长128位的String | 可选 | 微信公众号支付、支付宝统一下单时,必须输入 |
商户后台应答地址 | bg_ret_url | 变长128位的String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文 2) 必须是外网地址 |
商户私有域 | mer_priv | 变长120位的String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位的String | 可选 | 用于扩展请求参数 |
手续费客户号 | fee_cust_id | 定长16位String | 可选 | |
手续费账户号 | fee_acct_id | 变长16位String | 可选 | |
手续费金额 | fee_amt | 变长14位String | 可选 | |
内外扣标志 | fee_flag | 定长1位String | 可选 | 0 : 内扣; 1 : 外扣 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T09");
map.put("mer_cust_id", "6666000000118348");
map.put("user_cust_id", " 6666000000134045");
map.put("user_cust_id", " 6666000000136507");
map.put("order_date", "20181018");
map.put("order_id", "20181018000001");
map.put("trans_amt", "0.01");
map.put("pay_type", "04");
map.put("goods_desc", "微信正扫测试");
map.put("trans_type", " other");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "mer_priv");
map.put("extension", "extension");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T09"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
同步成功响应示例
200
{
"bg_bank_code":"",
"bg_bank_message":"",
"cmd_id":"T09",
"mer_cust_id":"6666000000118348",
"order_date": "20181018",
"order_id": "20181018000001",
"pay_info":"",
"pay_url":"weixin://wxpay/bizpayurl?pr=IZOr2UZ",
"return_code": "90000",
"return_desc": "交易成功",
"token_id":""
}
异步成功响应示例
200
{
"bg_ret_url":" http://192.168.0.200:8008/hftest/common/commonResult.jsp ",
"cmd_id":"T09",
"fee_acct_id":"216548",
"fee_amt":"0.10",
"fee_cust_id":"6666000000118348",
"goods_desc":"微信正扫测试",
"in_cust_id":"6666000000136507",
"mer_cust_id":"6666000000118348",
"order_date":"20181018",
"order_id":"20181018000001",
"pay_type":"04",
"return_code": "90000",
"return_desc": "交易成功",
"ret_url":"http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"trans_amt":"0.01",
"trans_type":"other",
"user_cust_id":"6666000000134045"
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"cmd_id":"T09",
"goods_desc": "扫码测试",
"mer_cust_id": "6666000000118348",
"order_date": "20181018",
"order_id": "20181018000001",
}
微信APP支付商户端开发示例¶
同步pay_info字段,返回用于唤起微信APP支付的参数,数据格式如下:
{
"sign": "F21465FEAE87F4C02E639D846B2CFCC2",
"timestamp": "1504863344",
"noncestr": "1504863344725",
"partnerid": "12723495",
"prepayid": "wx20170908173544b0662982990254372413",
"package": "Sign=WXPay",
"appid": "324125"
}
ios调起支付主要方法
// 注册APPID
// 商户APP工程中引入微信lib库和头文件,调用API前,需要先向微信注册您的APPID,代码如下:
[WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"demo 2.0"];
// 唤起微信APP
PayReq *request = [[[PayReq alloc] init] autorelease];
request.partnerId = @"10000100";
request.prepayId= @"1101000000140415649af9fc314aa427";
request.package = @"Sign=WXPay";
request.nonceStr= @"a462b76e7436e98e0ed6e13c64b4fd1c";
request.timeStamp= @"1397527777";
request.sign= @"582282D72DD2B03AD892830965F428CB16E7A256";
[WXApi sendReq:request];
Android调起支付主要方法
// 注册APPID
// 商户APP工程中引入微信JAR包,调用API前,需要先向微信注册您的APPID,代码如下:
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
// 将该app注册到微信
msgApi.registerApp("wxd930ea5d5a258f4f");
// 唤起微信APP
IWXAPI api;
PayReq request = new PayReq();
request.appId = "wxd930ea5d5a258f4f";
request.partnerId = "1900000109";
request.prepayId= "1101000000140415649af9fc314aa427",;
request.packageValue = "Sign=WXPay";
request.nonceStr= "1101000000140429eb40476f8896f4c9";
request.timeStamp= "1398746574";
request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";
api.sendReq(request);
详细内容请参照微信官网: APP支付
微信公众号支付开发示例¶
公众号原生态js支付接口(推荐使用)
同步pay_info字段,用于唤起微信公众号支付的参数,数据格式如下:
{
"appId": "wx1f87d44db95cba7a",
"timeStamp": "1514459875237",
"status": "0",
"signType": "MD5",
"package": "prepay_id = wx20171228191755dff683fea20032942684",
"callback_url": "https://www.baidu.com",
"nonceStr": "1514459875237",
"paySign": "5DEE76A6C0CB7BE924BDB11945D591CA"
}
ios调起支付主要方法
使用示例
需要注意: 所有传入参数都是字符串类型! 使用 JavaScript、 PHP 等弱类型语言需要关注一下。示例代码如下:
WeixinJSBridge.invoke('getBrandWCPayRequest',{
//公众号名称, 由商户传入
"appId" : "wx2421b1c4370ec43b",
//时间戳, 自 1970 年以来的秒数
"timeStamp":" 1395712654",
//随机串
"nonceStr" : "e61463f8efa94090b1f366cccfbbb444",
"package" : "prepay_id=u802345jgfjsdfgsdg888",
//微信签名方式:
"signType" : "MD5",
//微信签名
"paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89"
},function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
// 使用以上方式判断前端返回,微信团队郑重提示: res.err_msg 将在用户支付成功后返回 ok, 但并不保证它绝对可靠。
}
}
);
如有疑惑请参照微信官网 微信官网公众号支付
返回结果
返回值 | 说明 |
---|---|
err_msg | get_brand_wcpay_request:ok 支付成功 |
get_brand_wcpay_request:cancel 支付过程中用户取消 | |
get_brand_wcpay_request:fail 支付失败 |
注:JS API 的返回结果 get_brand_wcpay_request:ok 仅在用户成功完成支付时返回。 由于前端交互复杂, get_brand_wcpay_request:cancel 或者get_brand_wcpay_request:fail 可以统一处理为用户遇到错误或者主动放弃, 不必细化区分。
获取当前微信版本号
由于微信 5.0 版本后才加入微信支付模块, 低版本用户调用微信支付功能将无效。 因此,建议商户通过 user agent 来确定用户当前的版本号后再调用支付接口。 以 iPhone 版本为例,可以通过 user agent 可获取如下微信版本示例信息:
"Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS X)
AppleWebKit/534.46(KHTML,likeGeocko) Mobile/9B206 MicroMessenger/5.0"
其中 5.0 为用户安装的微信版本号, 商户可以判定版本号是否高于或者等于5.0。
公众号非原生支付
接口功能
初始化 JSAPI 请求, 通过生成 token_id 来进行交互验证。如调用时是用的原生态 js 支付, 此接口可以忽略。
显示微信安全支付标题
对于商户具有支付权限且需要调用微信支付的页面,为了让用户增加购买信心,确认交易环境安全, 微信强烈建议商户使用“微信安全支付”标题。安全支付标题的如下图。

显示支付安全标题,需将原始链接添加上”showwxpaytitle=1”的尾串。
- 通过这种方式,商户的页面将出现微信安全支付的标识。例如,原始URL为: htp://weixin.qq.com,显示安全支付标题的 URL 为: htp://weixin.qq.com?showwxpaytitle=1。
- 当用户在微信里打开 http://weixin.qq.com 不会直接出现微信安全支付的标题,而打开htp://weixin.qq.com?showwxpaytitle=1后将出现微信安全支付标题。
请求参数列表
- 请求 url: https://pay.swiftpass.cn/pay/jspay
- 该请求参数为 http queryString,即: https://pay.swiftpass.cn/pay/jspay?token_id=xxx,如https://pay.swiftpass.cn/pay/jspay?token_id=9a0610bc519e782e6275e8c7dd94a445&showwxtitle=1
在服务号中点击这个链接就可调起支付(用户点击页面中的微信支付按钮时实际上就是点击的这个链接,此种方式无需配置支付授权目录,也不用像原生态jsapi 支付那样获取那些参数后续的操作,测试时可以将组装好的这个链接放到手机微信端文件传输助手点击调起支付界面)
参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|
token_id | VARCHAR(64) | 是 | 动态口令 |
showwxpaytitle | CHAR(1) | 是 | 取值1或0,请填写: 1,用于页面显示微信安全支付 |
退货 T10¶
校验逻辑¶
- 若原交易为余额支付时,从原交易的入款方回退到原交易的出款方;若原交易的出款方为个人用户支付账户时,系统会同时回退个人用户支付账户限额。
- 若原交易为快捷支付、网银支付、扫码支付等支付场景,退货遵循原路退回原则,退回用户原交易发起时的银行账户,因涉及到外部银行处理,通常3~5个工作日资金会到账。
- 若原交易的分账串不为空时,调用该接口时,分账串也必须上送,且校验在原交易分账串的范围内。
- 若分账串不为空时,须注意分账串合计金额必须等于交易金额; 分账客户号必须为当前商户或商户下的用户;分账客户号不能与出款客户号相同;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大仅支持5个分账客户号。
- 对于担保类型、以及延时分账交易,可进行一次全部、或多次部分退货,传入的原订单号须是订单确认接口传入的订单号、或延时分账交易的订单号,不是原支付交易订单号。
- 对于不带分账的担保类型交易(未传分账串),可对担保确认订单的进行一次全部、或多次部分退货。
- 对于带分账的担保交易、或延时分账,可对担保确认或延时分账的订单进行一次全部或多次部分退货。
- 多次部分退款,时可对原分账串中部分分账子账户资金进行退款,也可对分账子账户的资金进行部分金额退款。
- 备注:例如原交易为手续费内扣且延时分账,其中交易金额1000.00元,手续费2.00元,延时分账时分账串为:[{“divAmt”:”990.00”, “divAcctId”:”216000”, “divCustId”:”6666000000118000”},{“divAmt”:”8.00”, “divAcctId”:”216001”, “divCustId”:”6666000000118001”}],当发生全额退货且退手续费时,退货订单交易金额1000,手续费添加在分账串的第一个账户的金额中,此时分账串如下:[{“divAmt”:”992.00”, “divAcctId”:”216000”, “divCustId”:”6666000000118000”},{“divAmt”:”8.00”, “divAcctId”:”216001”, “divCustId”:”6666000000118001”}]
- 分账子账户部分金额退款示例,退货订单交易金额1000,不退缓手续费,客户6666000000118000分账990元,只退500元,此时退货分账串如下:[{“divAmt”:”500.00”, “divAcctId”:”216000”, “divCustId”:”6666000000118000”},{“divAmt”:”8.00”, “divAcctId”:”216001”, “divCustId”:”6666000000118001”}]
- 退货订单中的分账串必须在对应的担保确认、或延时分账订单分账串范围内。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T10 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
用户客户号 | user_cust_id | 定长16位String | 可选 | 由汇付生成,用户的唯一性标识 对原交易为网银支付、扫码支付、APP支付时可选;其余原交易时必须 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一;对于退货失败的,支持同订单号同金额的重复请求;新订单号认为是新的退货交易 |
退款金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
原订单号 | org_order_id | 定长18位String | 必须 | 原交易订单号,如使用多次分账及多次退款,传入确认订单号,或延时分账订单号 |
原订单日期 | org_order_date | 定长8位String | 必须 | 原交易订单日期 |
分账串 | div_detail | 变长String | 可选 | 分账串最多5个,示例如: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
同步返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T10 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 变长16位String | 必须 | 原样返回 |
用户客户号 | user_cust_id | 变长16位String | 可选 | 原样返回 |
订单日期 | order_date | 定长8位String | 必须 | 原样返回 |
订单号 | order_id | 变长20位String | 必须 | 原样返回 |
原订单号 | org_ order_id | 定长18位String | 必须 | 原样返回 |
原订单日期 | org_order_date | 定长8位String | 必须 | 原样返回 |
退款金额 | trans_amt | 变长14位String | 必须 | 原样返回 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 原样返回 |
商户私有域 | mer_priv | 变长120位String | 可选 | 原样返回 |
扩展域 | extension | 变长512位String | 可选 | 原样返回 |
异步返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T10 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 变长16位String | 必须 | 原样返回 |
用户客户号 | user_cust_id | 变长16位String | 可选 | 原样返回 |
订单日期 | order_date | 定长8位String | 必须 | 原样返回 |
订单号 | order_id | 变长20位String | 必须 | 原样返回 |
原订单号 | org_ order_id | 定长18位String | 必须 | 原样返回 |
原订单日期 | org_order_date | 定长8位String | 必须 | 原样返回 |
退款金额 | trans_amt | 变长14位String | 必须 | 原样返回 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 原样返回 |
商户私有域 | mer_priv | 变长120位String | 可选 | 原样返回 |
扩展域 | extension | 变长512位String | 可选 | 原样返回 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T10");
map.put("mer_cust_id", "6666000000118348");
map.put("user_cust_id", "6666000000118473");
map.put("order_id", DateUtils.getCurrentDateTime());
map.put("order_date", DateUtils.getCurrentDate());
map.put("trans_amt", "25.00");
map.put("org_order_id", "1539169979291");
map.put("org_order_date", "20181010");
map.put("bg_ret_url", "http://tech.chinapnr.com/hftest/page/test7943_3.jsp");
map.put("mer_priv", "fhertfygwer");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T10"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"org_order_id": "20181018000002",
"cmd_id": "T10",
"extension": "extension",
"org_order_date": "20181017",
"mer_cust_id": "6666000000118348",
"mer_priv": "mer_priv",
"order_date": "20181018",
"order_id": "20181018000001",
"return_code": "90000",
"return_desc": "交易成功",
"trans_amt": "0.01",
"user_cust_id": "6666000000136008"
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"org_order_id": "20181018000002",
"cmd_id": "T10",
"extension": "extension",
"org_order_date": "20181017",
"mer_cust_id": "6666000000118348",
"mer_priv": "mer_priv",
"order_date": "20181018",
"order_id": "20181018000001",
"trans_amt": "0.01",
"user_cust_id": "6666000000136008"
}
余额支付 T11¶
校验逻辑¶
- 用户虚拟账户必须是支付账户类型才可以余额支付。
- 不支持不同商户下用户之间的余额支付,不支持商户向其下用户进行余额支付。
- 支付账户按I/II/III类支付账户管理办法规定有年累计限额限制。超过限额支付失败,请改用快捷、网银等其它支付方式。
- 用户支付账户可用余额充足,调用【余额查询】接口,可查看用户可用余额。
- 若商户账户安全措施选择短信验证时,需先调用【短信发送】接口,两个接口的订单号和订单日期必须一致,将用户收到的短信验证码上送【短信验证码】字段中,系统会验证短信验证码的正确性。短信验证码的时效为10分钟,且同一笔订单号的短信验证码验证失败总次数不得超过5次,若过期或验证失败次数超限,请重新调用【短信发送】接口。
- 交易类型为非担保时,支持分账,入账客户号和分账串两者必选其一。
- 若分账串不为空时,分账串总金额必须等于交易金额;分账客户号必须为当前商户或商户下的用户;分账客户号不能与出款客户号相同;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大仅支持5个分账客户号。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T11 |
出账客户号 | out_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
入账客户号 | in_cust_id | 定长16位String | 可选 | 交易类型为担保时,必填; 交易类型为非担保时,入账客户号与分账串两者必填其一。 |
交易金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
短信验证码 | sms_code | 定长6位String | 可选 | 商户支付安全配置短信验证时必输 |
交易类型 | trans_type | 定长1位String | 必须 | 1担保; 2非担保。 |
分账串 | div_detail | 变长String | 可选 | 分账串最多5个,示例如: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
前台返回地址 | ret_url | 变长128位String | 可选 | |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
分账类型 | div_type | 定长2位String | 可选 | 01: 延时分账 |
入账子账户号 | in_acct_id | 变长9位String | 可选 | 分账串存在时入账子账户号为分账串内账户号,无分账串时该值存在取该值,分账串和该值均不存在取默认账户 |
出账子账户号 | out_acct_id | 变长9位String | 可选 | 无值时出账子账户号为默认账户 |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T11 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
买家客户号 | out_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
卖家客户号 | in_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
消费金额 | trans_amt | 变长14位String | 必须 | |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
短信验证码 | sms_code | 定长6位String | 可选 | 商户支付安全配置短信验证时必输 |
交易类型 | trans_type | 定长1位String | 必须 | 1担保; 2非担保。 |
前台返回地址 | ret_url | 变长128位String | 可选 | |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
入账子账户号 | in_acct_id | 变长9位String | 可选 | |
出账子账户号 | out_acct_id | 变长9位String | 可选 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T11");
map.put("mer_cust_id", "6666000000118348");
map.put("out_cust_id", "6666000000122259");
map.put("in_cust_id", "6666000000118473");
map.put("trans_amt", "0.01");
map.put("order_id", "12345678912345679018");
map.put("order_date", "20181019");
map.put("trans_type", "1");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "");
map.put("extension", "");
map.put("sms_code", "");
map.put("ret_url", "");
map.put("in_acct_id", "");
map.put("out_acct_id", "");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T07"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"cmd_id": "T11",
"return_code": "90000",
"return_desc": "交易成功",
"out_cust_id": "6666000000122259",
"mer_cust_id": "6666000000118348",
"in_cust_id": "6666000000118473" ,
"trans_amt": "0.01",
"order_id": "12345678912345679018",
"order_date": "20181019",
"sms_code": "",
"trans_type": "1",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_priv" : "",
"extension " : "",
"ret_url" : "",
"in_acct_id " : "",
"out_acct_id" : ""
}
失败响应示例
200
{
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"cmd_id": "T11",
"out_cust_id": "6666000000122259",
"mer_cust_id": "6666000000118348",
"in_cust_id": "6666000000118473",
"trans_amt": "0.01",
"order_id": "12345678912345679018",
"order_date": "20181019",
"sms_code": "",
"trans_type": "1",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_priv":"",
"extension": "",
"ret_url":"",
"in_acct_id " : "",
"out_acct_id" : ""
}
订单确认 T12¶
校验逻辑¶
- 原交易必须为担保交易。
- 订单确认后视为交易结束,后续只能调用【退货】接口。
- 入账客户号和分账串两者必填其一。
- 若分账串不为空时,分账串总金额必须等于交易金额;分账客户号必须为当前商户或商户下的用户;分账客户号不能与出款客户号相同;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大长度仅支持5个分账客户号。
- 原交易为快捷支付、网银支付、以及扫码支付、APP支付、余额支付等的担保交易时,可进行一次全额或多次部分确认。
- 多次部分确认,如果不带分账,可使用入账客户号+入账子账户号参数对同一收款人进行多次确认付款,入账客户号必须与原支付交易相同,入账子账户号不强制与原交易相同,但必须隶属于收款人;如果带分账,则可使用分账串进行确认付款,可每次确认分账串内容不同。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T12 |
原订单号 | old_order_id | 变长20位String | 必须 | 担保交易订单号 |
原订单日期 | old_order_date | 定长8位String | 必须 | 担保交易订单日期YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
交易金额 | trans_amt | 变长14 位String | 必须 | 金额格式是 ###.00,本次确认金额,应小于或等于原订单交易金额 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
入账客户号 | in_cust_id | 定长16 位String | 可选 | 入账客户号和分账串两者必填其一 |
入账子账户号 | in_acct_id | 变长9位String | 可选 | 入账子账户号与分账串不能同时存在。 |
出账客户号 | out_cust_id | 定长16 位String | 可选 | 由汇付生成,商户的唯一性标识 |
分账串 | div_detail | 变长String | 可选 | 分账串最多5个,示例如: [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T12 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
原订单号 | old_order_id | 变长20位String | 必须 | 担保交易订单号 |
原订单日期 | old_order_date | 定长8位String | 必须 | 担保交易订单日期YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为YYYYMMDD |
交易金额 | trans_amt | 变长14 位String | 必须 | |
剩余担保金额 | remain_amt | 变长14 位String | 必须 | |
商户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
卖家编号 | in_cust_id | 定长16位String | 必须 | 由汇付生成,商户的唯一性标识 |
买家编号 | out_cust_id | 定长16 位String | 必须 | 由汇付生成,商户的唯一性标识 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T12");
map.put("old_order_id", " 12345678912345679018");
map.put("old_order_date", " 20181019");
map.put("mer_cust_id", "6666000000118348");
map.put("out_cust_id", "6666000000122259");
map.put("in_cust_id", "6666000000118473");
map.put("trans_amt", "0.01");
map.put("order_id", "12345678912345679018");
map.put("order_date", "20181019");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "");
map.put("extension", "");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T07"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"cmd_id": "T12",
"return_code": "90000",
"return_desc": "交易成功",
"out_cust_id": "6666000000122259",
"mer_cust_id": "6666000000118348",
"in_cust_id": "6666000000118473",
"trans_amt": "0.01",
"order_id": "12345678912345679018",
"order_date": "20181019",
"old_order_id": "12345678912345679018",
"old_order_date": "20181019",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_priv" : "",
"extension " : ""
}
失败响应示例
200
{
"cmd_id": "T12",
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"out_cust_id": "6666000000122259",
"mer_cust_id": "6666000000118348",
"in_cust_id": "6666000000118473",
"trans_amt": "0.01",
"order_id": "12345678912345679018",
"order_date": "20181019",
"old_order_id": "12345678912345679018",
"old_order_date": "20181019 ",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp ",
"mer_priv":"",
"extension":""
}
订单撤销 T13¶
功能说明¶
对于快捷、网银、扫码、APP支付、余额支付的担保交易,如使用担保交易类型、或延时分账方式,在未调用【订单确认】接口、或者延时分账接口(延时分账方式)前,可以对原交易进行全部、或部分金额的撤销操作,操作完成后,资金返回付款人的原付款账户,如果是余额支付则恢复出账客户支付账户扣减的年已使用限额。
调用方式:系统调用
校验逻辑¶
- 只可撤销原订单还留存在担保过渡账户中的,未进行确认或延时分账的订单金额,已进行担保确认或延时分账的金额只可通过退货接口进行退款。比如原支付订单金额100元,已调用担保确认接口支付了50元,那么只可再撤销50元。
- 可对原支付订单进行一次全部、或多次部分确认,前提是撤销交易金额需小于或等于原订单在中间担保过渡账户的剩余金额。
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T13 |
原订单号 | old_order_id | 变长20位String | 必须 | 担保交易订单号 |
原订单日期 | old_order_date | 定长8位String | 必须 | 担保交易订单日期 YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为 YYYYMMDD |
交易金额 | trans_amt | 变长14 位String | 必须 | 金额格式是 ###.00 |
商户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
卖家编号 | in_cust_id | 定长16 位String | 必须 | 由汇付生成,商户的唯一性标识 |
买家编号 | out_cust_id | 定长16 位String | 可选 | 由汇付生成,商户的唯一性标识 对原交易为网银支付、扫码支付、APP支付时可选;其余原交易时必须 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见 设备静态信息 。 |
同步返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T13 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
原订单号 | old_order_id | 变长20位String | 必须 | 担保交易订单号 |
原订单日期 | old_order_date | 定长8位String | 必须 | 担保交易订单日期 YYYYMMDD |
订单号 | order_id | 变长20位String | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 保证订单号和订单日期唯一,格式为 YYYYMMDD |
交易金额 | trans_amt | 变长14 位String | 必须 | |
商户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
卖家编号 | in_cust_id | 定长16 位String | 必须 | 由汇付生成,商户的唯一性标识 |
买家编号 | out_cust_id | 定长16 位String | 必须 | 由汇付生成,商户的唯一性标识 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户结果,注意: 1) 使用时不要包含中文; 2) 必须是外网地址。 |
商户私有域 | mer_priv | 变长120位String | 可选 | 为商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于扩展请求参数 |
异步返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T13 |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
商户客户号 | mer_cust_id | 变长16位String | 必须 | 原样返回 |
订单日期 | order_date | 定长8位String | 必须 | 原样返回 |
订单号 | order_id | 变长20位String | 必须 | 原样返回 |
退款金额 | trans_amt | 变长14位String | 必须 | 原样返回 |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 原样返回 |
商户私有域 | mer_priv | 变长120位String | 可选 | 原样返回 |
扩展域 | extension | 变长512位String | 可选 | 原样返回 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T13");
map.put("old_order_id", "12345678912345679018");
map.put("old_order_date", "20181019");
map.put("mer_cust_id", "6666000000118348");
map.put("out_cust_id", "6666000000122259");
map.put("in_cust_id", "6666000000118473");
map.put("trans_amt", "0.01");
map.put("order_id", "12345678912345679018");
map.put("order_date", "20181019");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/common/commonResult.jsp");
map.put("mer_priv", "");
map.put("extension", "");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T07"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"cmd_id": "T13",
"return_code": "90000",
"return_desc": "交易成功",
"out_cust_id": "6666000000122259",
"mer_cust_id": "6666000000118348",
"in_cust_id": "6666000000118473",
"trans_amt": "0.01",
"order_id": "12345678912345679018",
"order_date": "20181019",
"old_order_id": "12345678912345679018",
"old_order_date": "20181019",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_priv" : "",
"extension" : ""
}
失败响应示例
200
{
"cmd_id": "T13",
"return_code": "10099",
"return_desc": "交易处理失败",
"error_code": "100001",
"error_desc": "请求订单号重复",
"out_cust_id": "6666000000122259",
"mer_cust_id": "6666000000118348",
"in_cust_id": "6666000000118473",
"trans_amt": "0.01",
"order_id": "12345678912345679018",
"order_date": "20181019",
"old_order_id": "12345678912345679018",
"old_order_date": "20181019",
"bg_ret_url": "http://192.168.0.200:8008/hftest/common/commonResult.jsp",
"mer_priv":"",
"extension":""
}
延时分账 T14¶
功能说明¶
- 当原交易为【快捷支付统合版一阶段】、【网银支付】、【扫码支付】、【余额支付】、【APP支付】且原交易中的分账类型为“延时分账”时,调用此接口做延时分账;调用延时分账接口后,资金将从商户过渡户解冻并转入分账方入账账户的可用余额。
- 可支持对原订单进行多次延时分账。
调用方式:系统调用
校验逻辑¶
- 原交易分账类型必须打上“延时分账”标记。
- 原交易为扫码支付和 APP 支付支持手续费内扣和外扣;原交易为快捷、网银目前仅支持手续费外扣;原交易为余额支付的不涉及手续费问题。
- 若原交易为手续费内扣,则分账串总金额=原交易交易金额-原交易商户手续费;若原交易为手续费外扣,则分账串总金额=原交易交易金额(原交易商户手续费金额可从原交易返参字段中获取)。
- 分账客户号必须为当前商户或商户下的用户;分账客户号不能重复;分账账户号必须为分账客户号的子账户号;分账串最大长度仅支持 5 个分账客户号(最小长度为 2 个分账客户号)。
- 备注:例如原交易为手续费内扣,其中交易金额1000.00元,手续费2.00元,则分账串总金额为998.00元,分账串为:[{“divAmt”:”990.00”, “divAcctId”:”216000”, “divCustId”:”6666000000118000”},{“divAmt”:”8.00”, “divAcctId”:”216001”, “divCustId”:”6666000000118001”}]
请求参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
版本号 | version | 定长2位String | 必须 | 固定为10,如版本升级,能向前兼容 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T14 |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
订单号 | order_id | 变长20位纯数字 | 必须 | 保证订单号和订单日期唯一 |
订单日期 | order_date | 定长8位String | 必须 | 格式为YYYYMMDD |
分账金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
原订单号 | org_order_id | 变长20位纯数字 | 必须 | 原交易订单号 |
原订单日期 | org_order_date | 定长8位String | 必须 | 原交易订单日期 |
分账串 | div_detail | 变长512位String | 必须 | 最多5个,格式如下 [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户退款结果 注意: 1) 使用时不要包含中文 2) 必须是外网地址 |
商户私有域 | mer_priv | 变长128位String | 可选 | 商户的自定义字段,该字段在交易完成后由本平台原样返回 |
扩展域 | extension | 变长512位String | 可选 | 用于拓展请求参数 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见设备静态信息 |
分账串div_detail说明:
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
分账客户号 | divCustId | 定长16位String | 必须 | 用户客户号 |
分账账户号 | divAcctId | 变长9位String | 必须 | 用户子账户号 |
分账金额 | divAmt | 变长14位String | 必须 | 分账金额,金额格式是 ###.00 |
返回参数¶
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
商户后台应答地址 | bg_ret_url | 变长128位String | 必须 | 通过后台异步通知商户退款结果 注意: 1) 使用时不要包含中文 2) 必须是外网地址 |
消息类型 | cmd_id | 定长3位String | 必须 | 每一种消息类型代表一种交易,此处为 T14 |
设备静态信息 | dev_info | 变长512位String | 必须 | 参见设备静态信息 |
分账串 | div_detail | 变长512位String | 必须 | 最多5个,格式如下 [{“divAmt”:”0.05”, “divAcctId”:”216548”, “divCustId”:”6666000000118348”}] |
错误码 | error_code | 定长6位String | 可选 | 参见 错误码 |
错误描述 | error_desc | 变长String | 可选 | |
扩展域 | extension | 变长512位String | 可选 | |
商户客户号 | mer_cust_id | 定长16位String | 必须 | 商户的唯一标识 |
商户私有域 | mer_priv | 变长128位String | 可选 | 商户的自定义字段,该字段在交易完成后由本平台原样返回 |
订单日期 | order_date | 定长8位String | 必须 | 格式为YYYYMMDD |
订单号 | order_id | 变长20位纯数字 | 必须 | 商户号+订单号+订单日期唯一 |
原订单日期 | org_order_date | 定长8位String | 必须 | 原交易订单日期 |
原订单号 | org_order_id | 变长20位纯数字 | 必须 | 原交易订单号 |
状态码 | resp_code | 变长8位String | 必须 | T14000–交易成功,其他见状态码表 |
状态描述 | resp_desc | 变长128位String | 必须 | |
返回码 | return_code | 定长5位String | 必须 | 参见 返回码 |
返回描述 | return_desc | 变长String | 必须 | |
分账金额 | trans_amt | 变长14位String | 必须 | 金额格式是 ###.00 |
代码示例¶
JAVA
请求示例
// 测试环境请求地址
String requestUrl = "https://eacloud.testpnr.com/api/publicRequests";
Map<String, String> map = new HashMap<>();
map.put("version", "10");
map.put("cmd_id", "T14");
map.put("mer_cust_id", "6666000000118348");
map.put("order_id", "2018122896938642251");
map.put("order_date", "20181019");
map.put("org_order_id", "201810317020839");
map.put("org_order_date", "20181031");
map.put("trans_amt", "100.00");
map.put("div_detail", "[{\"divCustId\":\"6666000000532325\",\"divAcctId\":\"656359\",\"divAmt\":\"45.00\"},{\"divCustId\":\"6666000000134045\",\"divAcctId\":\"237603\",\"divAmt\":\"55.00\"}]");
map.put("bg_ret_url", "http://192.168.0.200:8008/hftest/page/test7906_5.jsp");
map.put("mer_priv", "");
map.put("extension", "");
map.put("dev_info", "");
// 将请求参数转换为json字符串
String jsonStr = JSON.toJSONString(map);
// 将json字符串使用CFCA加签
String chkValue = cfcaSEncrypt(jsonStr);
// 组装接口调用参数
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("mer_cust_id", "6666000000118348"));
nameValuePairs.add(new BasicNameValuePair("cmd_id", "T14"));
nameValuePairs.add(new BasicNameValuePair("version", "10"));
nameValuePairs.add(new BasicNameValuePair("check_value", chkValue));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8);
// 创建httpPost
HttpPost httpPost = new HttpPost(requestUrl);
httpPost.setEntity(uefEntity);
InputStreamReader isr;
BufferedReader br;
String line;
try {
// 使用HttpClient发送请求
CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost);
isr = new InputStreamReader(response.getEntity().getContent(), Consts.UTF_8);
StringBuffer resultString = new StringBuffer();
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
resultString.append(line);
}
// 返回结果解签
String resultJson = cfcaSDncrypt(resultString.toString());
} catch (Exception e) {
// 处理异常
}
成功响应示例
200
{
"bg_ret_url":"http://192.168.0.200:8008/hftest/page/test7906_5.jsp",
"cmd_id":"T14",
"dev_info":"",
"div_detail":"[{"divCustId":"6666000000056576","divAcctId":"68040","divAmt":"0.01"},{"divCustId":"6666000000056577","divAcctId":"68042","divAmt":"0.01"}]",
"error_code":"",
"error_desc":"",
"extension":"",
"mer_cust_id":"6666000000055892",
"mer_priv":"",
"order_date":"20181228",
"order_id":"2018122896938642268",
"org_order_date":"20181228",
"org_order_id":"201812283173148606",
"resp_code":"T14000",
"resp_desc":"交易成功",
"return_code":"90000",
"return_desc":"交易成功",
"trans_amt":"0.02"
}
失败响应示例
200
{
"bg_ret_url":"http://192.168.0.200:8008/hftest/page/test7906_5.jsp",
"cmd_id":"T14",
"dev_info":"",
"div_detail":"[{"divCustId":"6666000000532325","divAcctId":"656359","divAmt":"0.01"},{"divCustId":"6666000000134045","divAcctId":"237603","divAmt":"0.01"}]",
"error_code":"100235",
"error_desc":"原交易不支持延时分账",
"extension":"",
"mer_cust_id":"6666000000118348",
"mer_priv":"",
"order_date":"20181227",
"order_id":"2018122796938642250",
"org_order_date":"20181015",
"org_order_id":"201803032600509",
"resp_code":"T14235",
"resp_desc":"原交易不支持延时分账",
"return_code":"10099",
"return_desc":"交易处理失败",
"trans_amt":"0.02"
}
状态码¶
状态码 | 状态描述 |
---|---|
T14000 | 交易成功 |
T14001 | 请求订单号重复 |
T14100 | 请求参数非法 |
T14106 | 商户不存在或未配置 |
T14107 | 商户状态异常 |
T14111 | 用户账户信息状态异常 |
T14119 | 原订单交易未成功 |
T14121 | 原交易不存在 |
T14232 | 延时分账的分账串个数至少为两个 |
T14233 | 分账账户号不属于分账用户 |
T14234 | 商户不支持延时分账 |
T14235 | 原交易不支持延时分账 |
T14236 | 原交易分账已完成 |
T14237 | 商户上送分账金额不等于可分账金额 |
T14238 | 原交易已退货或正在退货中,不支持延时分账 |
T14999 | 系统异常 |
T14991 | 内部接口调用异常 |
T14R00 | 风控拦截 |