微信小程序支付 簽名

當(dāng)時(shí)做微信小程序支付真的是炸毛了?舅汀!
特此立貼爹土,記錄一下,避免再次采坑


先把流程圖放著


image.png

商戶系統(tǒng)和微信支付系統(tǒng)主要交互:

1踩身、小程序內(nèi)調(diào)用登錄接口胀茵,獲取到用戶的openid,api參見公共api【小程序登錄API

2、商戶server調(diào)用支付統(tǒng)一下單挟阻,api參見公共api【統(tǒng)一下單API

3琼娘、商戶server調(diào)用再次簽名,api參見公共api【再次簽名

4附鸽、商戶server接收支付通知脱拼,api參見公共api【支付結(jié)果通知API

5、商戶server查詢支付結(jié)果坷备,api參見公共api【查詢訂單API

這是微信官方給出的


1.獲取用戶openid
前端代碼

image.png

重要的步驟圈起來(lái)了

  1. wx.login
    2.進(jìn)行登錄向后端發(fā)送請(qǐng)求

后端代碼


    @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是調(diào)用wx.login返回的code調(diào)用https://api.weixin.qq.com/sns/jscode2session接口獲取openid或者sessionkey

image.png

3.獲取到openid后向后端發(fā)送請(qǐng)求熄浓,讓后端請(qǐng)求微信統(tǒng)一下單

參見 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)) {

            //創(chuàng)建一個(gè)map盛放微信生成的相關(guān)信息
            Map map = new HashMap();
            WeixinPay weixinPay = new WeixinPay();
            //生成訂單號(hào)
            String outTradeNo = WXPayUtil.generateNonceStr();
            String sceneInfo = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"填寫你的url\",\"wap_name\": \"填寫你的名稱\"}}";
            WeixinResult result = null;

            String ip = "";
            //獲得到用戶的真實(shí)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 {

                //發(fā)起微信的統(tǒng)一下單
//              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("返回的結(jié)果:" + 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;
                }


                //封裝數(shù)據(jù)就行了
                map.put("outTradeNo", outTradeNo);
                //將CodeUrl重新進(jìn)行拼接
                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); // 有 商戶號(hào)
            String nonceStr = WXPayUtil.generateNonceStr();
            data.put("nonce_str", nonceStr);  //有 隨機(jī)字符串
//        data.put("signType", "MD5");
//        data.put("packageValue","Sign=WXPay");

            if ("JSAPI".equals(payScene)) {
                data.put("openid", openId);
                //加入我需要傳輸?shù)男畔?                data.put("attach", "{'userId':'" + user.getPkId() + "','payType':'SP'}");
            } else if ("APP".equals(payScene)) {
                //加入我需要傳輸?shù)男畔?                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 {
                //請(qǐng)求訂單
                resp = wxpay.unifiedOrder(data);

                System.out.println("請(qǐng)求訂單信息" + 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;

    }

返回的訂單信息再返回給前臺(tái)
讓他拉起微信支付

// 僅作為示例,非真實(shí)參數(shù)信息击你。
                        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));
                            }
                        });
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末玉组,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子丁侄,更是在濱河造成了極大的恐慌惯雳,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸿摇,死亡現(xiàn)場(chǎng)離奇詭異石景,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門潮孽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)揪荣,“玉大人,你說(shuō)我怎么就攤上這事往史≌叹保” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵椎例,是天一觀的道長(zhǎng)挨决。 經(jīng)常有香客問我,道長(zhǎng)订歪,這世上最難降的妖魔是什么脖祈? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮刷晋,結(jié)果婚禮上盖高,老公的妹妹穿的比我還像新娘。我一直安慰自己眼虱,他們只是感情好喻奥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捏悬,像睡著了一般映凳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上邮破,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音仆救,去河邊找鬼抒和。 笑死,一個(gè)胖子當(dāng)著我的面吹牛彤蔽,可吹牛的內(nèi)容都是我干的摧莽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼顿痪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼镊辕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蚁袭,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤征懈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后揩悄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卖哎,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亏娜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焕窝。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖维贺,靈堂內(nèi)的尸體忽然破棺而出它掂,到底是詐尸還是另有隱情,我是刑警寧澤溯泣,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布虐秋,位于F島的核電站,受9級(jí)特大地震影響发乔,放射性物質(zhì)發(fā)生泄漏熟妓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一栏尚、第九天 我趴在偏房一處隱蔽的房頂上張望起愈。 院中可真熱鬧,春花似錦译仗、人聲如沸抬虽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阐污。三九已至,卻和暖如春咱圆,著一層夾襖步出監(jiān)牢的瞬間笛辟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工序苏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留手幢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓忱详,卻偏偏與公主長(zhǎng)得像围来,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匈睁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355