微信小程序支付 签名

当时做微信小程序支付真的是炸毛了!!
特此立贴,记录一下,避免再次采坑


先把流程图放着


image.png

商户系统和微信支付系统主要交互:

1、小程序内调用登录接口,获取到用户的openid,api参见公共api【小程序登录API

2、商户server调用支付统一下单,api参见公共api【统一下单API

3、商户server调用再次签名,api参见公共api【再次签名

4、商户server接收支付通知,api参见公共api【支付结果通知API

5、商户server查询支付结果,api参见公共api【查询订单API

这是微信官方给出的


1.获取用户openid
前端代码

image.png

重要的步骤圈起来了

  1. wx.login
    2.进行登录向后端发送请求

后端代码


    @GetMapping("/getOpenId.json")
    public PageResult getOpenId(String code) {

        String sendGet = HttpUtils.sendGet("https://api.weixin.qq.com/sns/jscode2session", "appid=" + WXPayConstants.SMALL_APP_ID + "&secret=" + WXPayConstants.SMALL_APPSECRET + "&js_code=" + code + "&grant_type=authorization_code");

        System.out.println("sendGet = " + sendGet);
        Map<String, String> map = JSONObject.parseObject(sendGet, HashMap.class);

        return new PageResult(map);
    }

此处的code是调用wx.login返回的code调用https://api.weixin.qq.com/sns/jscode2session接口获取openid或者sessionkey

image.png

3.获取到openid后向后端发送请求,让后端请求微信统一下单

参见 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1&index=1

4.后端代码

@GetMapping("/createOrder.json")
    public PageResult createOrder(String money, String payScene, @RequestParam(required = false) String openId, HttpServletRequest request) throws Exception {

        AppUser user = ThreadLocalUtil.getUser();

        if ("MWEB".equals(payScene)) {

            //创建一个map盛放微信生成的相关信息
            Map map = new HashMap();
            WeixinPay weixinPay = new WeixinPay();
            //生成订单号
            String outTradeNo = WXPayUtil.generateNonceStr();
            String sceneInfo = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"填写你的url\",\"wap_name\": \"填写你的名称\"}}";
            WeixinResult result = null;

            String ip = "";
            //获得到用户的真实ip地址
            if (request.getHeader("x-forwarded-for") == null) {
                ip = request.getRemoteAddr();
            } else {
                ip = request.getHeader("x-forwarded-for");
                String[] ips = StringUtils.split(ip, ",");
                if (ips.length > 0) {
                    ip = ips[0];
                }
            }

            try {

                //发起微信的统一下单
//              result = weixinPay.createNative(outTradeNo, money, sceneInfo, payScene, com.sdworan.weChat.WXPayUtil.getIpAddr(request),"http://m.qiuxuemao.cn/handleWeixin.do",null);

                Map param = new HashMap();
                param.put("appid", "填写你的appid");
                param.put("mch_id", "填写的你商户id");
                param.put("nonce_str", com.github.wxpay.sdk.WXPayUtil.generateNonceStr());
                param.put("body", "填写你的body主体");
                param.put("out_trade_no", outTradeNo);
                param.put("total_fee", money);
                String ipAddr = WXPayUtil.getIpAddress(request);
                System.out.println("ip是 = " + ipAddr);
                if (org.apache.commons.lang.StringUtils.isNotBlank(ipAddr)) {
                    System.out.println("ipAddr="+ipAddr);
                    param.put("spbill_create_ip", ipAddr);
                }
                param.put("notify_url", "填写的你的通知地址");
                param.put("trade_type", payScene);
                if (org.apache.commons.lang.StringUtils.equals("MWEB", payScene)) {
                    param.put("scene_info", sceneInfo);
                }
                param.put("attach", "{'userId':'" + user.getPkId() + "','payType':'H5'}");

                try {
                    String xmlParam = com.github.wxpay.sdk.WXPayUtil.generateSignedXml(param, "WAWW4mogbeBFat0jxPKcczJ3V5d3vr9t");
                    this.logger.info("生成的xml:" + xmlParam);
                    com.sdworan.weixinPay.HttpClientUtils httpClient = new HttpClientUtils("https://api.mch.weixin.qq.com/pay/unifiedorder");
                    httpClient.setHttps(true);
                    httpClient.setXmlParam(xmlParam);
                    httpClient.post();
                    String xmlResult = httpClient.getContent();
                    this.logger.info("返回的结果:" + xmlResult);
                    Map<String, String> mapResult = com.github.wxpay.sdk.WXPayUtil.xmlToMap(xmlResult);
                    String codeUrl = "";
                    if (org.apache.commons.lang.StringUtils.equals("MWEB", payScene)) {
                        codeUrl = (String) mapResult.get("mweb_url");
                    } else if (org.apache.commons.lang.StringUtils.equals("NATIVE", payScene)) {
                        codeUrl = (String) mapResult.get("code_url");
                    }

                    result = new WeixinResult(codeUrl, outTradeNo, money);
                } catch (Exception var14) {
                    var14.printStackTrace();
                    throw var14;
                }


                //封装数据就行了
                map.put("outTradeNo", outTradeNo);
                //将CodeUrl重新进行拼接
                String codeUrl = result.getCodeUrl();
                codeUrl = codeUrl + "&redirect_url="+ URLEncoder.encode("替换为你的返回地址","UTF-8");
                map.put("codeUrl", codeUrl);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new PageResult(map);

        } else if ("APP".equals(payScene) || "JSAPI".equals(payScene)) {
            //        payScene = "APP";
//        payScene = "JSAPI";

            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);

            SortedMap<String, String> data = new TreeMap<>();
            if ("JSAPI".equals(payScene)) {
                data.put("appid", WXPayConstants.SMALL_APP_ID);   // 有  小程序id
            } else if ("APP".equals(payScene)) {
                data.put("appid", WXPayConstants.SMALL_APP_ID);   // 有  app的id
            }
            data.put("body", "填写你的body主体");
            String outTradeNo = WXPayUtil.generateNonceStr();
            data.put("out_trade_no", outTradeNo);
            data.put("device_info", "WEB");
            data.put("fee_type", "CNY");
            data.put("total_fee", "1");
            data.put("spbill_create_ip", com.sdworan.weChat.WXPayUtil.getIpAddr(request));  //有 终端ip
            data.put("notify_url", "替换为你的通知地址");  //有
            data.put("trade_type", payScene);  // 此处指定为扫码支付
            String productId = WXPayUtil.generateNonceStr();
            data.put("product_id", productId);

            data.put("mch_id", WXPayConstants.MCH_ID); // 有 商户号
            String nonceStr = WXPayUtil.generateNonceStr();
            data.put("nonce_str", nonceStr);  //有 随机字符串
//        data.put("signType", "MD5");
//        data.put("packageValue","Sign=WXPay");

            if ("JSAPI".equals(payScene)) {
                data.put("openid", openId);
                //加入我需要传输的信息
                data.put("attach", "{'userId':'" + user.getPkId() + "','payType':'SP'}");
            } else if ("APP".equals(payScene)) {
                //加入我需要传输的信息
                data.put("attach", "{'userId':'" + user.getPkId() + "','payType':'APP'}");
            }

            System.out.println("data = " + data);

            //签名
            String sign = WXPayUtil.generateSignature(data, WXPayConstants.KEY);
            //加入签名
            data.put("sign", sign);

//        data.put("out_trade_no", outTradeNo);
//        data.put("product_id", productId);
//        data.put("nonce_str", nonceStr);
            System.out.println("data1111111111111111 = " + data);

            SortedMap<String, String> map = new TreeMap<>();
            Map<String, String> resp = null;
            try {
                //请求订单
                resp = wxpay.unifiedOrder(data);

                System.out.println("请求订单信息" + resp);

//            map.put("prepayId", resp.get("prepay_id"));
                Map<String, String> mapReturn = new HashMap<>();


                if ("JSAPI".equals(payScene)) {
                    map.put("appId", WXPayConstants.SMALL_APP_ID);
                    map.put("timeStamp", (System.currentTimeMillis() / 1000) + "");
                    map.put("nonceStr", resp.get("nonce_str"));
                    String packag = "prepay_id=" + resp.get("prepay_id");
                    map.put("package", packag);
                    map.put("signType", "MD5");

                } else if ("APP".equals(payScene)) {
                    map.put("appid", resp.get("appid"));
                    map.put("partnerid", resp.get("mch_id"));
                    map.put("prepayid", resp.get("prepay_id"));
                    map.put("noncestr", resp.get("nonce_str"));
                    map.put("timestamp", (System.currentTimeMillis() / 1000) + "");
                    map.put("package", "Sign=WXPay");
                }

                System.out.println("map = " + map);
                String generateSignature = WXPayUtil.generateSignature(map, WXPayConstants.KEY);

                map.put("sign", generateSignature);
//                map.put("timestamp",map.get("timestamp"));
//                map.put("package","Sign=WXPay");
//            map.put("sign", generateSignature);
                System.out.println("generateSignature = " + generateSignature);
                System.out.println("签名是否正确 = " + WXPayUtil.isSignatureValid(map, WXPayConstants.KEY));
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("map = " + map);

            return new PageResult(map);
        }


        return null;

    }

返回的订单信息再返回给前台
让他拉起微信支付

// 仅作为示例,非真实参数信息。
                        uni.requestPayment({
                            provider: 'wxpay',
                            orderInfo:orderInfo.data.obj,
                            timeStamp: orderInfo.data.obj.timeStamp,
                            nonceStr: orderInfo.data.obj.nonceStr,
                            package: orderInfo.data.obj.package,
                            signType: orderInfo.data.obj.signType,
                            paySign: orderInfo.data.obj.sign,
                            success: function (res) {
                                console.log('success:' + JSON.stringify(res));
                            },
                            fail: function (err) {
                                console.log('fail:' + JSON.stringify(err));
                            }
                        });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。