本文主要描述工商银行支付的返回示例,入参在接口文档已有较详细的介绍。
但是工行并没有提供响应报文示例以及各字段的说明。
一.微信JSAPI支付请求成功的示例
{
"apiName":"",
"appId":"",
"certID":"13412652941845540388",
"checkValid":true,
"sign":"kfkR3h+l7jA00/wzddiNfHON6RumyTwM04wpwMgnZdSV2mkvPUIE8FJ0igGXF2nEmc6oqhrcivFSAZJAHAvCn6kPSzpn+DZMWcSUDuAUySMNv+5wG33wJgUJV2AAjygjlWgnUGVwc+NmNqzvGGdAENs/IHYHErD/u0Q9c6pAwWWW/4zFqiJ2rtf1nVeazl/SRWHC6u2KQR+xfUNLugR2yNMzSEpt8rZ2Tc3kC6NEB4B/LL+Wcvs6/VrS6OSKHHMw69pRhz/SKlGtXv8H51g+mKauSMrm0pP4ee0xNXSJyU44WYnjePsPv2dUhOhjOAk8lijLvICZzjm5YQhyF2KwAg==",
"signBlock":"{\"invokerCode\":\"SUCCESS\",\"response\":{\"appid\":\"wx63a1482d11b202es\",\"tradeType\":\"JSAPI\",\"prepayId\":\"wx02083623748238d740a35960bd9cc60000\",\"codeUrl\":\"\",\"payInfo\":{\"timeStamp\":\"1630542983\",\"package\":\"prepay_id=wx02083623748238d740a35960bd9cc60000\",\"paySign\":\"Ajw1vyfILfYjMSrDJM+g7oc85qQOpCStAlw6SlzQ6tfUeFpE+Be8nFtbxh7kiU5QAi8GeAfbkmNs3hpPbHyTobh5D1Lu3HDr850gNsSU/kdQA3EiyyT23wCWKRwl/AibL9GfdtcPObiHzZyrJkiPzxOU48/A4AYmmFivibgeIFDlOzqBuIOAoD6uGI3smPaFzabxPqXuMjWnMpc/fPMmjqXaoY1E8swI5S5xAyT6Q84d6PogqgXQgXww+1Ex4gfXSJfCwk02vZ4YvX8XkOKIplfhWqBrvHvO7JcGjJoJ0FWbEeGjGuJvm3EfiIytqfCtgxgC03DcdV6W9rUnQ8apEg==\",\"appId\":\"wxd9a9691ecfa23xxx\",\"signType\":\"RSA\",\"nonceStr\":\"npAvwgnrSsvwby2L6N7bNCstoLxlcPx3\"},\"serialNo\":\"174522800600\"},\"invokerMsg\":\"交易成功\",\"hostRspMsg\":\"交易成功\",\"ICBC_API_TIMESTAMP\":\"2021-09-02 08:36:23\",\"hostRspCode\":\"00000\",\"ICBC_API_RETMSG\":\"success\",\"ICBC_API_RETCODE\":0}",
"timesTamp":""
}
需要抽取的字段是payInfo,下面给出示例代码,用于前端拉起微信支付。
ApiResponse apiResponse = apiClient.execute(req);
String rspCode = apiResponse.getString("hostRspCode");
String rspMsg = apiResponse.getString("hostRspMsg");
if (IcbcConfig.SUCC_CODE.equals(rspCode)) {
// 成功
}
String signBlock = apiResponse.getSignBlock();
JSONObject signBlockJsonObject = com.alibaba.fastjson.JSON.parseObject(signBlock);
JSONObject responseJsonObject = signBlockJsonObject.getJSONObject("response");
JSONObject payInfoJsonObject = responseJsonObject.getJSONObject("payInfo");
JsApiParam jsApiParam = JsApiParam.builder()
.appId(payInfoJsonObject.getString("appId"))
.timeStamp(payInfoJsonObject.getString("timeStamp"))
.nonceStr(payInfoJsonObject.getString("nonceStr"))
.packageValue(payInfoJsonObject.getString("package"))
.signType(payInfoJsonObject.getString("signType"))
.paySign(payInfoJsonObject.getString("paySign"))
.build();
return jsApiParam;
二.主动查询支付结果
{
"apiName":"",
"appId":"",
"certID":"13412652941845540388",
"checkValid":true,
"sign":"sofNa9OLHrTAGjKtTgm2aoVXRZfj8yK0UseWmUOieizkhPy8pVy3JCmmhO/TJY89UrKVU551mLKDmCQJzCDKz5u60PySTwn/hy4g29cn2PnjCoRSZ+dcM1Lq9UJMptBxOx9tOng1/ZhXKkI8qFGeyP147EWwjjlK+5HjnHxFloFhV6K7JPf9lIKOL2oT2CYo29R6+66nRtAFVTcmsDAOaeDhLBxh/z0u1F5oSrKcNrjyxbXOkTJXIstnOvHZwlItgjaNHnBufX84bkMvv+yN9vfzhLJ15zmf8VatTkEmk611jzBje39c5mDWCfLxkcHTWZw5BDJiZ9z4+GK6Mpv2og==",
"signBlock":"{\"invokerCode\":\"SUCCESS\",\"response\":{\"instId\":\"12021000000000000366\",\"subInstId\":\"001\",\"orderNo\":\"0621090B2161503053509\",\"totalAmount\":\"0.01\",\"payAmount\":\"0.01\",\"stlAmt\":\"0.01\",\"tradeStatus\":\"SUCCESS\",\"serialNo\":\"174523624444\",\"payMethod\":\"8\",\"tradeNo\":\"4200001197202109020042222221\",\"tradeType\":\"JSAPI\",\"resultCode\":\"00000\",\"resultMsg\":\"交易成功\",\"doubtf\":\"0\",\"txDate\":\"20210902\",\"txTime\":\"161510\",\"systemDate\":\"20210902\",\"systemTime\":\"161503\",\"deviceInfo\":\"zty2_IcbcBank\",\"txTimeStamp\":\"\",\"alipay\":{\"buyerLogonId\":\"\",\"receiptAmount\":\"\",\"buyerPayAmount\":\"\",\"pointAmount\":\"\",\"invoiceAmount\":\"\",\"storeId\":\"\",\"fundBillList\":\"\",\"storeName\":\"\",\"buyerUserId\":\"\"},\"wxpay\":{\"appid\":\"wx63a1482d11b20e35\",\"openid\":\"oeLK0jgAa0J1GWf5Da2_2B8X7IXE\",\"isSubscribe\":\"\",\"subOpenid\":\"oX0xrsxe8csXcJ_zieYjk5qrAHu8\",\"subIsSubscribe\":\"\",\"bankType\":\"OTHERS\",\"detail\":\"\",\"cashFee\":\"0.01\",\"couponFee\":\"0\",\"couponInfo\":\"\",\"attach\":\"\",\"channelId\":\"27121336\",\"subMctCode\":\"459892488\"},\"esh\":{\"payStatus\":\"\",\"custId\":\"\",\"cardNo\":\"\",\"pointAmt\":\"\",\"ecouponAmt\":\"\",\"couponAmt\":\"\",\"merDiscAmt\":\"\",\"bankDiscAmt\":\"\",\"totalDiscAmt\":\"\",\"paymentAmt\":\"\",\"outTradeNo\":\"\",\"tradeNo\":\"4200001197202109020042222221\",\"channel\":\"\"}},\"invokerMsg\":\"交易成功\",\"hostRspMsg\":\"交易成功\",\"ICBC_API_TIMESTAMP\":\"2021-09-02 17:28:27\",\"hostRspCode\":\"00000\",\"ICBC_API_RETMSG\":\"success\",\"ICBC_API_RETCODE\":0}",
"timesTamp":""
}
当支付回调出现问题时,需要使用本接口进行补偿,关键字段见下:
//交易状态SUCCESS代表成功
String tradeStatus = (String) apiResponse.getMap("response").get("tradeStatus");
//交易金额
String totalAmount = (String) apiResponse.getMap("response").get("totalAmount");
//银行支付流水号
String serialNo = (String) apiResponse.getMap("response").get("serialNo");
//平台支付流水号
String orderNo = (String) apiResponse.getMap("response").get("orderNo");
// 交易日期和交易时间
String txDate = (String) apiResponse.getMap("response").get("txDate");
String txTime = (String) apiResponse.getMap("response").get("txTime");
三.退款
{
"apiName":"",
"appId":"",
"certID":"13412652941845540388",
"checkValid":true,
"sign":"JUEYnmfU1Eu+X5TV94PgTrANSstHWpPT1Z3GlOdpCy1MjApFpkvB7anBDSHauy9YOauyHd4qIVX95GTfaxO98o4VBCP7mmylkp7hBJn4hifIYmbWf69CtrsGUyUsT56IH9SoX0uiXGMgLb8n5P16UDU+H9mqO9UiPOuPSMLMhRHDtI7h+TyOEUzI8qK5sht+vWvkZFe2WpF2qwk5xVsAD99lBFPncBQnAPJ0vf/JVaW/BqgFsWFGPIPwshJmjkokKZJc21S6RL2bSmg/mIFIRSDdh1WiJ86rkuqsMbxU1TF1md+rYgdCSEhlvsV2ZZVqj2gmz9vfIoZhW1cq7SpVkw==",
"signBlock":"{\"invokerCode\":\"SUCCESS\",\"response\":{\"instId\":\"12021000000000000366\",\"subInstId\":\"001\",\"orderNo\":\"R062109021731B26054507\",\"oriOrderNo\":\"0621090B2161503053509\",\"tradeNo\":\"50101409422021090212117793575\",\"refundFee\":\"0.01\",\"deviceInfo\":\"\",\"txDate\":\"20210902\",\"txTime\":\"180930\",\"serialNo\":\"174523808763\",\"alipay\":{\"buyerLogonId\":\"\",\"fundChange\":\"\",\"buyerUserId\":\"\",\"storeName\":\"\"},\"wxpay\":{\"appid\":\"wx63a1482d11b20e35\",\"subAppid\":\"wxd9a9691ecfa23abc\",\"refundChannel\":\"\",\"settleRefundFee\":\"\",\"settlementTotalFee\":\"\",\"cashRefundFee\":\"0.01\",\"couponRefundInfo\":\"\"}},\"invokerMsg\":\"交易成功\",\"hostRspMsg\":\"交易成功\",\"ICBC_API_TIMESTAMP\":\"2021-09-02 18:09:31\",\"hostRspCode\":\"00000\",\"ICBC_API_RETMSG\":\"success\",\"ICBC_API_RETCODE\":0}",
"timesTamp":""
}
这里有个疑问,如果是退款中,返回的hostRspCode会不会等于00000呢。。
//平台退款流水号
(String) apiResponse.getMap("response").get("orderNo")
//银行返回交易流水号
(String) apiResponse.getMap("response").get("serialNo")
//平台支付流水号
(String) apiResponse.getMap("response").get("oriOrderNo")
//退款金额
AmountUtils.changeY2F((String) apiResponse.getMap("response").get("refundFee"))
// 退款成功与否,只管hostRspCode==00000
.status(PayConstants.RefundStatus.SUCCESS)
// 退款日期和时间
(String) apiResponse.getMap("response").get("txDate")
(String) apiResponse.getMap("response").get("txTime")
四.查询退款结果
{
"invokerCode":"SUCCESS",
"response":{
"instId":"12021000000000000366",
"subInstId":"001",
"orderNo":"R0621090218244205550B5",
"oriOrderNo":"0621B0902175029055004",
"amount":"0.01",
"stlAmt":"0.01",
"serialNo":"174523828100",
"payMethod":"8",
"tradeNo":"50101409452021090212114207497",
"tradeType":"JSAPI",
"resultCode":"00000",
"resultMsg":"交易成功",
"doubtf":"0",
"txDate":"20210902",
"txTime":"182442",
"wxpay":{
"appid":"wx63a1482d11b20e35",
"subAppid":"wxd9a9691ecfa23abc"
}
},
"invokerMsg":"交易成功",
"hostRspMsg":"交易成功",
"ICBC_API_TIMESTAMP":"2021-09-03 08:30:24",
"hostRspCode":"00000",
"ICBC_API_RETMSG":"success",
"ICBC_API_RETCODE":0
}
// resultCode==00000表示退款成功
String resultCode = (String) apiResponse.getMap("response").get("resultCode");
//退款金额
String amount = (String) apiResponse.getMap("response").get("amount");
//银行的退款流水号
String serialNo = (String) apiResponse.getMap("response").get("serialNo");
//平台退款流水号
String orderNo = (String) apiResponse.getMap("response").get("orderNo");
//平台支付流水号
String oriOrderNo = (String) apiResponse.getMap("response").get("oriOrderNo");
//退款的日期和时间
String txDate = (String) apiResponse.getMap("response").get("txDate");
String txTime = (String) apiResponse.getMap("response").get("txTime");
五.支付回调报文
{
"wxpay.subIsSubscribe":"",
"esh.channel":"",
"apigw_sign":"S3L+FV6/IUNl+tUv3b5Orrqu1pyhYgQpOy8vCuX8DASYl3XoScBA7YUQhuN+giOPndMQJ3GpsMeCzvsef+sqT6afqM3ZhYcL43TiqEc8bxYqN0/My7W8TaI+i1wT/QdKktVLD9POayhyHuukoGxT+MrvOGHaKsMBDzavbcS9FXEsvKb5NHAe8M7DJ09Nl2HUOT4pC7SG7+XhXrmJ/1QCl8kKNJFeqwP1l0bf159SiLn/ZkH6r9yLcLE0VFMZQ5OFmhV0s/pJojeLM1iqLb995oIi5SWQw3BJuOs4rMxK5u9361tTfqnMuBY1JnKOdE+w+lVwSdF6l3gLX3yn+OlNWA==",
"esh.couponAmt":"",
"esh.paymentAmt":"",
"payMethod":"8",
"alipay.receiptAmount":"",
"orderNo":"0621090310595B8059005",
"tradeNo":"4200001158202109031530806392",
"esh.payStatus":"",
"esh.ecouponAmt":"",
"esh.merDiscAmt":"",
"wxpay.couponInfo":"",
"wxpay.appid":"wx63a1482d11b20e35",
"wxpay.attach":"",
"deviceInfo":"zty2_IcbcBank",
"resultMsg":"交易成功",
"serialNo":"174625524981",
"esh.pointAmt":"",
"totalAmount":"0.01",
"alipay.storeId":"",
"alipay.pointAmount":"",
"esh.bankDiscAmt":"",
"tradeStatus":"SUCCESS",
"systemDate":"20210903",
"merId":"",
"alipay.buyerUserId":"",
"doubtf":"0",
"alipay.fundBillList":"",
"apigw_certid":"13412652941845540388",
"txTime":"110005",
"userNo":"",
"resultCode":"00000",
"systemTime":"105958",
"stlAmt":"0.01",
"alipay.buyerLogonId":"",
"alipay.buyerPayAmount":"",
"wxpay.couponFee":"0",
"wxpay.isSubscribe":"",
"tradeType":"JSAPI",
"alipay.invoiceAmount":"",
"esh.custId":"",
"esh.cardNo":"",
"wxpay.subOpenid":"oX0xrsxe8csXcJ_zieYjk5qrAHu8",
"wxpay.openid":"oeLK0jgAa0J1GWf5Da2_2B8X7IXE",
"wxpay.bankType":"OTHERS",
"instId":"12021000000000000366",
"wxpay.channelId":"27121336",
"esh.totalDiscAmt":"",
"wxpay.detail":"",
"alipay.storeName":"",
"wxpay.subMctCode":"459892488",
"wxpay.cashFee":"0.01",
"subInstId":"001",
"txDate":"20210903"
}
回调除了找对字段外,最容易出错的就是验签了。建议直接使用sdk中的验签方法。
注意:Content-Type:application/x-www-form-urlencoded
/**
* 支付回调的参数
*/
public final static String APIGW_RSPDATA = "apigw_rspdata";
/**
* 支付回调的签名
*/
public final static String APIGW_SIGN = "apigw_sign";
public final static String APIGW_CERTID = "apigw_certid";
// 获取回调的三个字段
String sign = request.getParameter(IcbcConfig.APIGW_SIGN);
String certId = request.getParameter(IcbcConfig.APIGW_CERTID);
String rspData = request.getParameter(IcbcConfig.APIGW_RSPDATA);
//解析报文并放入Map集合
Map<String, Object> resultMap = JSON.parseObject(rspData, HashMap.class);
resultMap.put(IcbcConfig.APIGW_SIGN, sign);
resultMap.put(IcbcConfig.APIGW_CERTID, certId);
resultMap.put(IcbcConfig.APIGW_RSPDATA, rspData);
//调用ApiClient.java中的doVerifyWithExit()验签方法。
apiClient.doVerifyWithExit((String) resultMap.get(IcbcConfig.APIGW_RSPDATA),
(String) resultMap.get(IcbcConfig.APIGW_CERTID),
(String) resultMap.get(IcbcConfig.APIGW_SIGN),
"UTF-8");
/**
* 获取平台支付流水号
*
* @param resultMap
* @return
*/
@Override
protected String getChannelTradeNo(Map<String, Object> resultMap) {
return (String) resultMap.get("orderNo");
}
/**
* 获取第三方支付流水号.
* <p>
* <p>upay流水号</p>
*
* @param resultMap
* @return
*/
@Override
protected String getOutTradeNo(Map<String, Object> resultMap) {
return (String) resultMap.get("serialNo");
}
/**
* 获取支付金额
*
* @param resultMap
* @return
*/
@Override
protected Integer getPayAmt(Map<String, Object> resultMap) {
return AmountUtils.changeY2F((String) resultMap.get("totalAmount"));
}
/**
* 获取支付日期和时间
*
* @param resultMap
* @return
*/
@Override
protected Date getPayOkDate(Map<String, Object> resultMap) {
String txDate = String.valueOf(resultMap.get("txDate"));
String txTime = String.valueOf(resultMap.get("txTime"));
return DateUtils.getDate(txDate + txTime, DateUtils.DATE_FORMAT_1);
}
网友评论