公众号支付 微信支付 小程序支付 h5支付开发连载(二):h5页面提交订单

版权声明:本文为博主原创文章,如需转载,敬请注明转载链接 https://blog.csdn.net/guobinhui/article/details/85374806

上一节给大家分享了用户授权公众号获取用户openid的详细教程,本节给大家继续分享用户进入公众号的h5网页提交订单的实现过程

上节教程获取到用户openid后,把这个参数返回到h5页面,用隐藏域接收后再连同这个openid以及订单所有信息提交后台接口,这里以最关键的订单信息:金额为例进行代码实现。

首先在商品页面定义一个表单,里面有商品信息和价格信息,由于这里只做演示,价格暂时写死,再定义一个提交订单的Button

<button id="sub-but"class="weui-btn weui-btn_primary"
    style="width:100%;margin-top:10px;margin-bottom: 30px" onclick="pay()">立即支付
</button>

事件处理函数,拉起微信的h5支付

<script>
    function pay(){
        var payParams = {"totalFee":$("#totalFee").text(),"applyId":$("#applyId").val()};
        $.ajax({
            url: "/submitOrder?time=" + new Date().getTime(),//访问后台地址生成订单
            dataType: "json",//返回json格式的数据
            type: "post",
            data: payParams,//要发送的数据
            success: function (data) {
                //支付回调验证参数
                WeixinJSBridge.invoke('getBrandWCPayRequest', {
                        appId: data.appId,
                        timeStamp: data.timeStamp,
                        nonceStr: data.nonceStr,
                        package: data.package,
                        signType: data.signType,
                        paySign: data.paySign,
                    },
                    //调起微信支付成功
                    function (res) {
                        if (res.err_msg == "get_brand_wcpay_request:ok") {
                             alert("支付成功!");
                        }else {
                            alert(JSON.stringify(res));
                            alert("支付失败!");
                        }
                    });
            },
            error: function () {
                alert("接口访问出现异常");
            }
        });
    }
</script>
    /**
     * 跳转至微信支付
     **/
    @RequestMapping(value = "/submitOrder", method= RequestMethod.POST)
    public void  submitOrder(HttpServletRequest request,HttpServletResponse response) throws Exception{
        String openid = request.getParameter("openid")
        float fee = Float.parseFloat(request.getParameter("totalFee"));
        String totalFee = (new Float(fee * 100)).intValue() + "";//分为单位

        String outTradeNo = Constants.APPID + WxPayUtil.getNonceStr() + Constants.WXPAY;//自定义规则随机生成一个订单号
        String timeStamp = System.currentTimeMillis()+"";

        String spbillCreateIp = WxPayUtil.getIpAdrress(request);
        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", Constants.APPID);
        packageParams.put("mch_id", Constants.MCHID);
        String nonceStr = WxPayUtil.getNonceStr();
        packageParams.put("nonce_str",nonceStr);
        packageParams.put("body", Constants.body);
        packageParams.put("out_trade_no", outTradeNo);
        packageParams.put("total_fee", totalFee);
        packageParams.put("spbill_create_ip", spbillCreateIp);
        packageParams.put("notify_url", Constants.WXPAY_NOYIFY_URL);//公众号支付结果通知
        packageParams.put("trade_type", Constants.tradeType);
        packageParams.put("openid", openid);
        Date payTime = new Date();
        String mapStr = WxPayUtil.createLinkString(packageParams);

        //MD5运算生成签名
        String sign = WxPayUtil.sign(mapStr, WXConfig.key, "utf-8").toUpperCase();
        /**
         * 组装成xml参数,此处偷懒使用手动组装,严格代码可封装一个方法,XML标排序需要注意,ASCII码升序排列
         */

        String xmlTemplate = "<xml> \n" +
                "<appid><![CDATA[%s]]></appid> \n" +
                "<body><![CDATA[%s]]></body> \n" +
                "<mch_id><![CDATA[%s]]></mch_id> \n" +
                "<nonce_str><![CDATA[%s]]></nonce_str> \n" +
                "<notify_url><![CDATA[%s]]></notify_url> \n" +
                "<openid><![CDATA[%s]]></openid> \n" +
                "<out_trade_no><![CDATA[%s]]></out_trade_no> \n" +
                "<spbill_create_ip><![CDATA[%s]]></spbill_create_ip> \n" +
                "<total_fee><![CDATA[%s]]></total_fee> \n" +
                "<trade_type><![CDATA[%s]]></trade_type> \n" +
                "<sign><![CDATA[%s]]></sign> \n" +
                "</xml> \n";
        //方式一:
        String xml = String.format(xmlTemplate,Constants.HQAPPID,Constants.body,Constants.MCHID,nonceStr,Constants.WXPAY_NOYIFY_URL,openid,outTradeNo,spbillCreateIp,totalFee,WXConfig.tradeType,sign,payTime);
        //微信统一下单接口
        String result = WxPayUtil.httpRequest(Constants.ORDER_API, "POST", xml);
        //生成预支付id
        String prepay_id = WxPayUtil.getPayNo(result);
        //...获取到微信返回的预支付id后,此处在数据库里存储订单信息,返回操作记录数num
        if (num != 1) {
            response.getWriter().write(Constants.ORDER_FAIL);
            return;
        }

        //开始第二次签名
        java.lang.String packages = "prepay_id=" + prepay_id;
        java.lang.String nonceStr1 = WxPayUtil.getNonceStr();
        java.lang.String mapStr1 = "appId=" + Constants.APPID + "&nonceStr=" + nonceStr1 + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + timeStamp;
        java.lang.String paySign = WxPayUtil.sign(mapStr1, Constants.key, "utf-8").toUpperCase();
        //拼接支付回调参数
        java.lang.String finalPackage = "{\"appId\":\"" + Constants.HQAPPID  + "\",\"timeStamp\":\"" + timeStamp
                + "\",\"nonceStr\":\"" + nonceStr1 + "\",\"package\":\""
                + packages + "\",\"signType\":\"MD5" + "\",\"paySign\":\""
                + paySign + "\"}";
        response.getWriter().write(finalPackage);
    }

到此,在公众号网页的h5支付过程完成了,一般为了让用户有更好的支付体验,用户得知道自己的哪个订单有付款记录,那么会在我们本节教程中配置的支付回调通知配置回调接口,用于接收微信服务器推送的支付消息通知,在下一节教程中为大家分享。

猜你喜欢

转载自blog.csdn.net/guobinhui/article/details/85374806