微信小程序支付 签名

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


先把流程图放着


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));
                            }
                        });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354