对接农业银行支付(微信和支付宝)的总结(三)

分类: 假的网站365怎么看 时间: 2025-10-17 23:59:01 作者: admin 阅读: 2070

最后总结下农行支付的几个需要注意的地方:

1.退款接口

由于是同步接口,一般返回的状态都是"受理成功",而不是"交易成功"。

农行文档(6.6的第6点)清晰描述道:

"若交易成功,则商户可以取得交易结果对象的其他属性来进行后续的作业。

注意:GetKeyValue("ReturnCode")返回 0000 可能代表退款成功,也可能代表退款受理成功。

还要看GetKeyValue("ErrorMessage")返回的中文信息是“交易成功”还是“受理成功”。"

意味着用户的退款状态需要由业务方主动查询退款结果才更新,对用户而言有一定的延迟。

(钱到帐了,但是订单和支付状态未变)

而且没有第三方退款流水号iRspRef和退款时间HostDate/HostTime等值,这样意味着我们必须轮询农行方才行。

2.查询退款接口

成功的示例见下:只返回了平台退款流水号iRspRef和退款时间OrderDate/OrderTime

,其中状态的判断不是文档里描述的05--已退款。

另外,有些字段名可能前后会携带空格字符。

{

"PayTypeID":"AliRefund",

"OrderNo":"R0621061B0155736016065",

"OrderDate":"2021/06/10",

"OrderTime":"16:07:02",

"RefundAmount":"0.01",

"Status":"04",

"iRspRef":"6AECEP01160423007350",

" MerRefundAccountNo":"19015601040024091",

" MerRefundAccountName":"浙江学海教育科技有限公司",

"SplitAccInfoItems":[

]

}

最大的坑当属PayTypeID了,如果你只操作了支付宝的退款,又怎么能确定微信等退款返回的是何值。

所以我在程序里是根据contains()包含关系来判断是否为退款。

这里的不确定性,也带来了很多未知的bug。

农行文档(附录二-响应码一览表的com.abc.pay.client.ebus.QueryOrderRequest)对PayTypeID写道:

ImmediatePay:直接支付

PreAuthPay:预授权支付

DividedPay:分期支付

AgentPay:授权支付

Refund:退款

DefrayPay:付款

PreAuthed:预授权确认

PreAuthCancel:预授权取消

从初步的联调结果来看,这里的词典遗漏不少。

最后贴出我对接查询交易结果的示例:

/**

* 返回代码.

* 0000-代表成功

*/

String returnCode = json.GetKeyValue(AbcBankConfig.RETURN_CODE);

/**

* 返回信息

*/

String errorMessage = json.GetKeyValue(AbcBankConfig.ERROR_MESSAGE);

if (AbcBankConfig.RC_SUCCESS.equalsIgnoreCase(returnCode)) {

String orderDecodeStr = Base64Code.Decode64(json.GetKeyValue("Order"));

JSONObject orderObject = com.alibaba.fastjson.JSON.parseObject(orderDecodeStr);

//格式: YYYY/MM/DD

String txDate = orderObject.getString("OrderDate").replaceAll("/", "-");

//格式:HH:MM:SS

String txTime = orderObject.getString("OrderTime");

//01-未支付;02-无回应;03-微信和支付宝支付成功;04-农行清算或支付成功;05-已退款;07-授权确认成功;00-授权已取消;99-失败;

String status = orderObject.getString("Status");

String payTypeID = orderObject.getString("PayTypeID");

//PayTypeID 根据交易类型判断是退款还是支付

// AliRefund-支付宝退款

// WeiXinRefund-微信退款

if (payTypeID.contains(AbcBankConfig.PayType.PAY_TYPE_REFUND)) {

//退款处理

} else {

//支付处理

}

}

3.查询退款结果和查询支付结果,是共用一个接口,这里的关键入参OrderNo,前者应该传平台退款流水号,后者应该传入平台支付流水号。

当回调出现故障时,我们必须调用主动查询接口来更新支付状态,所以我们需要知道第三方支付流水号,

也就是说,查询字段QueryDetail必须是1,不能填写0(不会返回第三方支付流水号)。等于0的场景是用不上的,不明白农行的设计意图何在?

4.退款接口的入参,OrderNo是平台支付流水号,NewOrderNo是平台退款流水号。

如果OrderNo传值错误,会报错说“无此账单”。

{

"TrxResponse":{

"ReturnCode":"2307",

"ErrorMessage":"无此账单!",

"TrxType":"Refund",

"OrderNo":"006210B6101501522608N",

"NewOrderNo":"R0621061B0155736016065",

"TrxAmount":"0.01",

"BatchNo":"",

"VoucherNo":"",

"HostDate":"",

"HostTime":"",

"iRspRef":""

}

}

这里,特别指出,不是放在第一点一起说,是因为字段的命名让我们容易差生错觉。

5.支付回调接口

HTTP的POST方式,这里获取入参的方式比较特别,放着请求体不用,

偏偏要通过表单和链接传递参数,让你程序必须使用getParameter来接收报文。

public class Notify{

public String abcRefundNotifyRes(HttpServletRequest request, HttpServletResponse response) {

String msg = request.getParameter("MSG");

//而我们一般对接微信和其他银行的接收入参是如下写法

String xmlResult = IOUtils.toString(request.getInputStream(),

request.getCharacterEncoding());

}

}

6.农行对接文档的吐槽

有一个不足之处是,缺少请求和响应的示例报文。导致我们写程序只能走一步调试一步。

还有就是在总体设计的时候,不去注重描述协议的规范和格式,甚至把他们自认为有用的UML贴出来给你看。

有这个功夫,不是应该提供一个SDK,让接入方直接引入,然后Builder模式一把就可以发送报文,

易于接入才是王道,偏要让接入方去反编译他的class文件。

然后你提出不要jar中的固化打印一些无用的调试日志,他们会跟你说,那是你自己的个性化需求,需要自己实现。

我想去掉不打印日志,都没得开关,让接入方如何不去“个性化”实现。。。(日志不是slf4j打印,

且是自己单独写服务器的某文件中,不携带任何业务信息,就算采集到ELK,也根本不能帮助排查问题。)

7.最后想要吐嘈的是他们的验签方法。

有两个地方需要尤为注意:

第一、编码格式,并不全是utf-8;

发送json格式请求的时候是utf-8,验证签名却应该是gbk。支付回调报文的验签却又不同,应该是gb2312.

第二、支付回调的报文必须采用他们给的XMLDocument.java才验证通过。

这一块,如果不给出示例代码,对接的过程中会踩不少坑!!

8.最后梳理下他们的报文协议

https+证书,发http采用HttpClient框架,读取证书文件在应用启动后,

保存在应用内存缓存起来,后期只需要根据account账户来缓存里取即可。

既然要使用https,就必须初始化农行的根证书abc.truststore,取得javax.net.ssl.SSLContext后赋值给HttpClient的http连接池。

发送报文前,必须要使用商户私钥(使用密码读取pfx文件,取出私钥内容)加密,计算出签名。

接收报文的时候,使用农行的支付平台证书TrustPay.cer进行加密,对比两者的签名是否一致。

9.没有SDK的痛苦!!

写道这里,有没有一种感觉,需要理解透这些协议,以及字段的含义,才能够开始接入联调。农行给你整一堆的jsp和html页面,以及jar包等着你去反编译呢~~

提供一个官网可下载的sdk,以及spring boot版本的sample,就是那么难~~

相关文章

假的网站365怎么看

Curic Measure++

假的网站365怎么看

《Google Android 编程权威指南.pdf》清晰中文完整版:权威、全面的Android学习资源...

mobile365立即加入

父母去世戴孝多久(给父母戴孝要多长时间才能取下来)