电商收付通系列⑧,合单下单之支付通知
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了电商收付通系列⑧,合单下单之支付通知相关的知识,希望对你有一定的参考价值。
大家好,我是小悟
1、介绍
用户支付完成后,微信会把相关支付结果和用户信息发送给清算机构,清算机构需要接收处理后返回应答成功,然后继续给异步通知到下游从业机构。
对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。
2、对通知数据进行解密
系统对于开启结果通知的内容一定要做签名验证,并校验通知的信息是否与我们的信息一致,防止数据泄露导致出现“假通知”,造成资金损失。
支付通知和获取微信支付平台证书一样,需要对获取到的内容进行解密,解密规则一样,AesUtils这个解密工具类参考官方文档给的demo。
String result = new String(outSteam.toByteArray(), StandardCharsets.UTF_8);// 获取微信调用我们notify_url的返回信息
System.out.println("微信支付回调返回参数result:=====" + result);
JSONObject json = JSONObject.parseObject(result);
System.out.println("微信支付回调返回参数json:=====" + json);
JSONObject resourceRes = json.getJSONObject("resource");
System.out.println("微信支付回调返回参数resourceRes:=====" + resourceRes);
AesUtils aesUtil = new AesUtils("APIv3密钥".getBytes(StandardCharsets.UTF_8));
String resourceStr = aesUtil.decryptToString(resourceRes.getString("associated_data").getBytes(StandardCharsets.UTF_8),
resourceRes.getString("nonce").getBytes(StandardCharsets.UTF_8),
resourceRes.getString("ciphertext"));
JSONObject resourceJson = JSONObject.parseObject(resourceStr);
System.out.println("微信支付回调返回参数resourceJson明文:=====" + resourceJson);
3、避免重复下发通知
同样的通知可能会多次发送给我们自身系统,所以我们需要做好正确处理重复通知的逻辑。当自身系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理,如果已处理,则直接返回结果成功。
为尽可能提高通知的成功率,微信侧会重复发起通知,为了避免这样的结果影响到处理业务逻辑,我们需要返回一定格式的响应数据给微信,如下,亲测有效。
Map<String,Object> res = new HashMap<String, Object> ();
res.put("code","SUCCESS");
res.put("message","OK");
res.put("code","ERROR_NAME");
res.put("message",e.getMessage());
4、支付通知接口
在合单支付的notify_url参数字段传入" https://xxx/combineNotify"即可
@RequestMapping(value = "/combineNotify", method = RequestMethod.POST)
public Map<String,Object> combineNotify(HttpServletRequest request)
Map<String,Object> res = new HashMap<String, Object> ();
try
// 创建支付应答对象
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1)
outSteam.write(buffer, 0, len);
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray(), StandardCharsets.UTF_8);
System.out.println("微信支付回调返回参数result:=====" + result);
JSONObject json = JSONObject.parseObject(result);
System.out.println("微信支付回调返回参数json:=====" + json);
JSONObject resourceRes = json.getJSONObject("resource");
System.out.println("微信支付回调返回参数resourceRes:=====" + resourceRes);
AesUtils aesUtil = new AesUtils("APIv3密钥".getBytes(StandardCharsets.UTF_8));
String resourceStr = aesUtil.decryptToString(resourceRes.getString("associated_data").getBytes(StandardCharsets.UTF_8),
resourceRes.getString("nonce").getBytes(StandardCharsets.UTF_8),
resourceRes.getString("ciphertext"));
JSONObject resourceJson = JSONObject.parseObject(resourceStr);
System.out.println("微信支付回调返回参数resourceJson明文:=====" + resourceJson);
//验证微信支付返回签名
String Wtimestamp = request.getHeader("Wechatpay-Timestamp");
String Wnonce = request.getHeader("Wechatpay-Nonce");
String Wsign = request.getHeader("Wechatpay-Signature");
System.out.println("Wtimestamp:"+Wtimestamp+",Wnonce:"+Wnonce+",Wsign:"+Wsign);
//拼装待签名串
StringBuffer ss =new StringBuffer();
ss.append(Wtimestamp).append("\\n");
ss.append(Wnonce).append("\\n");
ss.append(result).append("\\n");
//验证签名
if(SignUtils.v3VerifyRSA(ss.toString(), Base64.decodeBase64(Wsign.getBytes()), "/data/tomcat/webapps/ROOT/wechat_pay_platform_4927801AFE1D0A15A2E4491C9C13E6414B17AFCC.pem"))
System.out.println("微信支付回调签名验证成功");
else
System.out.println("微信支付回调签名验证失败");
res.put("code","SUCCESS");
res.put("message","OK");
catch (GeneralSecurityException e)
e.printStackTrace();
res.put("code","ERROR_NAME");
res.put("message",e.getMessage());
catch (IOException e)
e.printStackTrace();
res.put("code","ERROR_NAME");
res.put("message",e.getMessage());
catch (Exception e)
e.printStackTrace();
res.put("code","ERROR_NAME");
res.put("message",e.getMessage());
return res;
5、结果
微信支付回调返回参数json:====="summary":"支付成功","event_type":"TRANSACTION.SUCCESS","create_time":"2020-03-24T18:07:42+08:00","resource":"associated_data":"transaction","ciphertext":"6XMaa17DRH9uKYuRJneC3wy6ihGiPquKGaCsCScBtxxMY5PLHEeLPl3kBgH/Yes+FOrLh92zsbQa85OIAtnc7eqlLpWb1uiP3jJhglmjzul35WK+naUsxzKLDgUFnUcyfV1PTM287QEFRIC+jvbwHK82lpELOEUCnBx0/ompQM3fzxWQczlw3CvPWTciSgy8XUqui5owvXxkbrKwruIEfigY/LOByXW0w26jX7hEKLjAghdD1NvIgFhkKf3MkbGduNiDsTn1V5z9hzoWR2MwJI/NZFRpsdr9QmxkSiGwf0FzqnOhCLsjntXAKru89CsdWyfznl2BRdbBYF+4ZRqRgbMr+sROQ9TNXVMYjNFeeyXdnpM0BNAdOIKCMI7eBkHsyARgKkXVVlAUkInatbkO/IyIUyJ4PaUJJAYkbxsgIrh1XXpDMfmR8lVpDT8FfumNebL4cILpcOCTfJ+4mn8Es8xKdOiGgEH6ZVqYrjWVkUwBwAHel4xGdat8i80wlIUh2q1z9IN0QggIHp4lCbnSeyeqiTh3WwFiM6Yv/1pHaYde/JSRo0fmdIhFrPGR383GXWqCkQK7yoUydu8e5Dq4qY1GPI9VcaAkMG68sVl762w3Us5/VvO41+nX1BlhFWNsg0VqDLHRvWL+I/gsbXHffub34Je2UF1e0mL7ghmFEXT6k6fQ4FYvSEPQ8CI3KaxMW1RJfUBRqpzKfrzkfi6EgVDAKXQvJc4HvwSmdix8UkRXysger/yfzugVAqwUV2SC6qm+m29MOHGgb37fCaL5fJOnXkvBeb7suYsT2RbyIvoA","original_type":"transaction","nonce":"qyzVVgtmQ0fk","algorithm":"AEAD_AES_256_GCM","resource_type":"encrypt-resource","id":"7b3b0fa6-a627-59c1-0733-2606ec31153c"
微信支付回调返回参数resourceJson明文:====="combine_appid":"wxd352ef315ac365bd","sub_orders":["transaction_id":"4323220200001484847904033204","amount":"payer_amount":1,"total_amount":1,"currency":"CNY","payer_currency":"CNY","mchid":"1915696108","trade_state":"SUCCESS","out_trade_no":"out_trade_no2_1585030201441","bank_type":"OTHERS","trade_type":"JSAPI","attach":"123&456&789","success_time":"2020-03-24T18:07:43+08:00","sub_mchid":"1564468071"],"combine_payer_info":"openid":"ofMy16jrqy7Z8pS23M5JI4SkKvwc","combine_out_trade_no":"out_trade_no1_1504430158999","combine_mchid":"1811569960","scene_info":"device_id":"POS1:12"
Wtimestamp:1546844504,Wnonce:jXQ70fE0SepL62SNpUhduNCooXF2RseC,Wsign:m2QZupx0hp3fPmfAfYD35FoYK+o1DOzWQs8vkeGTiFY68JHkIlx1cx825sPbW/AHu5xsQ4nlOt4BZZ0Q4Z6szqYgxJUZe/JR0OXNtoG0yHq0m5teVLoFY5eEAuY3szAPC5RIsUOs0ByXP62KEiNNiw7sYbdVXDar4MkKLho7NY6sjaigRQZeSGvsV0q0TIy1HTQTR9otAJ5lnibwbheecXaCLvvkvHGr/kDPHkvnP1fIzVzeIM32VDTf9L4/k7vN4zdgd4R73Y/6hmk8vyTsB+VfciqUpDUQ0rC0SigGzaLukawRK+S3r4XBe1nNiM0jVTKIe5l7s8BO9THd+gwI6A==
微信支付回调签名验证成功
您的一键三连,是我更新的最大动力,谢谢
山水有相逢,来日皆可期,谢谢阅读,我们再会
我手中的金箍棒,上能通天,下能探海
以上是关于电商收付通系列⑧,合单下单之支付通知的主要内容,如果未能解决你的问题,请参考以下文章
01 场景:一个真实电商订单系统的整体架构业务流程及负载情况
Material Design系列,Behavior之BottomSheetBehavior与BottomSheetDialog