微信支付采坑记录 (java后端二:普通商户模式下APP支付统一下单后的回调通知)
2021/9/12 11:34:51
本文主要是介绍微信支付采坑记录 (java后端二:普通商户模式下APP支付统一下单后的回调通知),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
普通商户模式App支付统一下单接口调用成功之后,进入微信回调支付结果通知接口。
先来看看微信支付开发文档里面怎么描述的支付结果通知的应用场景:
应用场景:支付完成后,微信会把相关支付结果及用户信息通过数据流的形式发送给商户,商户需要接收处理,并按文档规范返回应答。
首先说明一点:要成功进入微信回调支付结果通知必须注意的一点是要在app支付统一下单接口的参数中加入自己系统设置的回调路径;
如下图:
注意:
1、同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
2、后台通知交互时,如果微信收到商户的应答不符合规范或超时,微信会判定本次通知失败,重新发送通知,直到成功为止(在通知一直不成功的情况下,微信总共会发起多次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m),但微信不保证通知最终一定能成功。
3、在订单状态不明或者没有收到微信支付结果通知的情况下,建议商户主动调用微信支付【查询订单API】确认订单状态。
话不多说了,直接上代码说明:
// controller层代码接口,此处的接口路径则为统一下单接口回调字段的参数 @RequestMapping(value = "/wxPayNotifyOfCoupon",method = RequestMethod.POST) public void wxPayNotifyOfCoupon(HttpServletRequest request,HttpServletResponse response){ try { wxPayService.wxPayNotify(request, response); } catch (Exception e) { log.error("微信支付回调处理出错!"); e.printStackTrace(); } } //微信支付统一下单之后的回调通知方法service层 public JSONObject wxPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { //解析结果存储在HashMap() Map<String, String> map = new HashMap<String, String>(); //获取微信返回的数据 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) { map.put(e.getName(), e.getText()); } // 释放资源 inputStream.close(); //返回code String return_code = map.get("return_code"); String result_code = map.get("result_code"); String out_trade_no = map.get("out_trade_no");//商户订单号号 String transaction_id = map.get("transaction_id");//微信订单号 String total_fee = map.get("total_fee"); //订单金额 String payAttach = map.get("attach");//附加数据,现在只有sessionId log.info("进入微信回调成功"+out_trade_no); //返回给微信结果,xml格式返回给微信服务成功或者失败 String xml = ""; //校验签名和订单金额,这里最好做一下安全校验,PaymentKit是微信sdk提供的工具类方法 if (PaymentKit.codeIsOK(return_code) && PaymentKit.codeIsOK(result_code)) { ResBean<?> resBean = orderQuery(transaction_id); // 此处调用了一个查询订单的方法,用于验证这一笔支付订单是否成功,具体方法的代码在下面 if (PaymentKit.verifyNotify(map,mchSecret)){ // 此处校验签名 if ("SUCCESS".equals(resBean.getRes_content())) { // 查询订单结果返回SUCCESS则进行自己系统的相关订单的业务处理,比如修改订单状态等操作 log.info("微信支付成功,现在进行业务处理"); ReqUserGetBean reqUserGetBean = new ReqUserGetBean(); reqUserGetBean.setG_order_no(out_trade_no); reqUserGetBean.setSession_id(payAttach); reqUserGetBean.setG_pay_type(6); reqUserGetBean.setG_u_payNum(BigDecimal.valueOf(Long.parseLong(total_fee))); reqUserGetBean.setTransaction_id(transaction_id); ResBean<Object> js = HttpTooler.httpsInvoke(javaUrl, "/userGetGoldInfo/finishPayFunction", reqUserGetBean); if ("0000".equals(js.getRes_code())){ // 自己系统的业务处理成功之后,则给微信服务那边响应一个成功 log.info("微信支付回调业务处理数据成功!"+js.getRes_code()); xml = "<xml>\n" + "<return_code><![CDATA[SUCCESS]]></return_code>\n" + "<return_msg><![CDATA[OK]]></return_msg>\n" + "</xml>"; } else { // 失败则响应失败 log.error("修改订单状态出错"+js.getRes_desc()); log.error(js.getRes_content()); xml = "<xml>\n" + "<return_code><![CDATA[FAIL]]></return_code>\n" + "<return_msg><![CDATA[ERROR]]></return_msg>\n" + "</xml>"; } response.getWriter().write(xml); xml = "<xml>\n" + "<return_code><![CDATA[SUCCESS]]></return_code>\n" + "<return_msg><![CDATA[OK]]></return_msg>\n" + "</xml>"; }else { log.info("支付失败!"); xml = "<xml>\n" + "<return_code><![CDATA[FAIL]]></return_code>\n" + "<return_msg><![CDATA[ERROR]]></return_msg>\n" + "</xml>"; } response.getWriter().write(xml); } } else { log.info("支付失败!"); xml = "<xml>\n" + "<return_code><![CDATA[FAIL]]></return_code>\n" + "<return_msg><![CDATA[ERROR]]></return_msg>\n" + "</xml>"; response.getWriter().write(xml); } JSONObject jsonObject = new JSONObject(); jsonObject.put("out_trade_no",out_trade_no); jsonObject.put("transaction_id",transaction_id); return jsonObject; } //查询微信订单,普通商户查询 public ResBean<?> orderQueryOfCoupon(String transaction_id){ Map<String, String> mapSign = new LinkedHashMap<>(); mapSign.put("appid",appId); mapSign.put("mch_id",mchId); mapSign.put("nonce_str",Long.toString(System.currentTimeMillis() / 1000)); mapSign.put("transaction_id",transaction_id); mapSign.put("sign",PayUtils.getSign(mapSign,mchSecret)); String post = HttpUtils.post("https://api.mch.weixin.qq.com/pay/orderquery", PaymentKit.toXml(mapSign)); Map<String, String> result = PaymentKit.xmlToMap(post); String return_code = result.get("return_code"); String result_code = result.get("result_code"); String err_code = result.get("err_code"); String err_code_des = result.get("err_code_des"); ResBean<Object> resBean = new ResBean<>(); if (PaymentKit.codeIsOK(return_code)){ if (PaymentKit.codeIsOK(result_code)){ resBean.setRes_code("0000"); resBean.setRes_desc(result.get("trade_state_desc")); resBean.setRes_content(result.get("trade_state")); }else { resBean.setRes_code("9999"); resBean.setRes_desc(err_code_des); resBean.setRes_content(err_code); } }else { resBean.setRes_code("9999"); resBean.setRes_desc(err_code_des); resBean.setRes_content(err_code); } return resBean; }
到此处微信支付统一下单之后的回调就完成了,接下来就是微信支付的退款操作了,下一篇踩坑记录继续讲解!
这篇关于微信支付采坑记录 (java后端二:普通商户模式下APP支付统一下单后的回调通知)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南