微信扫码支付手把手教学
专栏: 220908-小班辅导 标签: 微信支付 扫码支付
2022-10-15 08:31:42 983浏览
官网api在线文档
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
1.需要提前准备的几个重要参数
微信支付必须是注册商家才行,得有营业执照。下面的参数登陆你的企业微信公众号后台去获取,
2.新建一个WXPayConfig实现类
由于我们要做的是扫码支付,而扫码支付不需要验证证书,所以下面的方法里getCertStream可以直接返回null,但getWXPayDomain必须自定义写哦。
package com.github.wxpay.sdk; import com.github.wxpay.sdk.config.WXpayConfig; import java.io.*; public class WXPayConfigImpl extends WXPayConfig { private byte[] certData; // public WXPayConfigImpl() throws IOException { // String certPath = "D:/apiclient_cert.p12"; // File file = new File(certPath); // InputStream certStream = new FileInputStream(file); // this.certData = new byte[(int) file.length()]; // certStream.read(this.certData); // certStream.close(); // } @Override public String getAppID() { return WXpayConfig.getProperties("appid"); } @Override public String getMchID() { return WXpayConfig.getProperties("mch_id"); } @Override public String getKey() { return WXpayConfig.getProperties("mchKey"); } public String getTradeType(){ return WXpayConfig.getProperties("trade_type"); } @Override InputStream getCertStream() { /*ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData); return certBis;*/ return null; } @Override IWXPayDomain getWXPayDomain() { IWXPayDomain iwxPayDomain = new IWXPayDomain() { @Override public void report(String domain, long elapsedTimeMillis, Exception ex) { } @Override public DomainInfo getDomain(WXPayConfig config) { return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true); } }; return iwxPayDomain; } }
3. 写一个统一下单接口返回二维码到前端
@WebServlet("/order") public class OrderServlet extends HttpServlet { @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { try { WXPayConfigImpl config = new WXPayConfigImpl(); WXPay wxpay = new WXPay(config); Map<String, String> data = new HashMap<String, String>(); data.put("appid", config.getAppID()); data.put("mch_id", config.getMchID()); data.put("nonce_str", WXPayUtil.generateNonceStr()); data.put("body", req.getParameter("orderName")); data.put("out_trade_no", req.getParameter("orderNo")); data.put("total_fee", "1"); data.put("spbill_create_ip", "123.12.12.123"); data.put("notify_url", "http://tf5i8v.natappfree.cc/wxpay_sdk/OrderNotify"); data.put("trade_type", config.getTradeType());/** wxPay.unifiedOrder 这个方法中调用微信统一下单接口 */ String sign = WXPayUtil.generateSignature(data, config.getKey(), WXPayConstants.SignType.HMACSHA256); /* 签名*/ data.put("sign", sign); Map<String, String> respData = wxpay.unifiedOrder(data); System.out.println("**************wx qr pay***********************************"); System.out.println(respData); if (respData.get("return_code").equals("SUCCESS") && respData.get("return_msg").equals("OK")){ Map<String,String> codeurlMap = new HashMap<>(); codeurlMap.put("code_url",respData.get("code_url")); res.getWriter().write(JSON.toJSONString(codeurlMap));/*返回二维码的支付参数*/ res.getWriter().flush(); res.getWriter().close(); }else{ res.getWriter().write(""); } } catch (Exception e) { e.printStackTrace(); } } }
4.支付回调接口
@WebServlet("/OrderNotify") public class OrderNotify extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream in = req.getInputStream(); BufferedReader br = new BufferedReader( new InputStreamReader( in, "UTF-8" ) ); StringBuffer result = new StringBuffer(); String line = ""; while ( (line = br.readLine())!= null ) { result.append(line); } in.close(); br.close(); try { Map<String, String> map = WXPayUtil.xmlToMap( result.toString() ); System.out.println("===问答=微信扫码支付回调=购买金币====================================="); String mch_id=map.get("mch_id"); String appid=map.get("appid"); boolean flag = WXPayUtil.isSignatureValid(map, WXpayConfig.getProperties("mchKey"),HMACSHA256); if(flag){ if(map.get("result_code").equals("SUCCESS")) { //修改订单状态啥的。 String orderNo = map.get("out_trade_no");//商户订单 String transaction_id = map.get("transaction_id");//交易订单号 //告诉微信这边已经收到通知了' Map<String,String> returnMap = new HashMap<>(); returnMap.put("return_code","SUCCESS"); returnMap.put("return_msg","OK"); String xml = WXPayUtil.generateSignedXml(returnMap, WXpayConfig.getProperties("mchKey"), HMACSHA256); resp.getWriter().write(xml); resp.getWriter().flush(); resp.getWriter().close(); } } } catch (Exception e) { e.printStackTrace(); } } }
5.注意事项
- 注意这个xml安全机制
微信支付的安全机制:所有请求参数通过ASSIC排序后(abcde的顺序),在末尾添加微信支付秘钥(key),然后把封装好的字符串通过MD5或SHA256方式加密。微信接收到请求信息之后会先把你传递过来的参数重新排序,加密,然后拿2个加密后的字符串做对比,如果匹配证明数据无误,此时的秘钥只有你知,微信知,不能透露给其他无关用户。
- 支付回调验签总是失败
原因是:下单的时候默认是用HMACSHA256的加密方式,而验签的时候默认是MD5加密方式,所以我这里的加密方式全部改成了HMACSHA256就可以了。
- 支付回调重复调用的问题
已经告诉微信这边进回调了,但微信还是一直发请求过来,原因是给微信返回的必须是xml格式的数据,而且还必须加签加密后再传。
4,主要的参考文档:
好博客就要一起分享哦!分享海报