微信公众号支付

一、准备工作

公共号支付需要提前在微信公共平台进行业务配置,包括设置支付授权目录、测试支付目录和白名单、设置JS接口安全域名以及设置授权回调页面域名。

1.进行微信公众支付之前,我们需要申请个公众号,以及申请微信支付的功能。

这里写图片描述
基本参数获取:
APPID 和Appsecret
微信公众平台基本配置里面可以看到
这里写图片描述

商户号mch_id在微信商户平台里面
这里写图片描述

API密钥也在商户平台里面
这里写图片描述

2.支付授权目录:

位置:商户平台–>产品中心–>开发配置

1) 所有使用公众号支付方式发起支付请求的链接地址,都必须在支付授权目录之下;

2) 正式支付授权目录最多设置5个,且域名必须通过ICP备案;

这里写图片描述

目录示例:
url路径为:http://hbdtty.com/BeautyApp/oauth2controller/oauth2
那么我们需要配置的是:http://hbdtty.com/BeautyApp/oauth2controller/

如果后面带参数的话,省略参数;这个我们不需要考虑参数
url路径为:http://hbdtty.com/BeautyApp/oauth2controller/oauth2 ?user=1
那么我们需要配置的是:http://hbdtty.com/BeautyApp/oauth2controller/

假如没有配对,调用会提示当前url未注册的错误

3.支付类型我们选择jsapi支付

具体的就不多说了,配置的时候百度就可以了记住支付目录配置就可以,我是springmvc项目亲测的。

4、信息填写页面会有防欺诈提示,如何去掉就是在公众号设置里面的功能设置里面设置网页授权域名

这里写图片描述

二、上面的配置好以后说一下开发代码流程

1.获取授权。获取用户的openid

// oauth2授权时回调controller
    public final static String  REDIRECT_URI_BASE       = "http://www.hbdtty.com/BeautyApp/oauth2controller/oauth2_Base";
// oauth2授权(第一步获取code用到的地址)
    public final static String  OAUTH2_BASE         = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                                                        + APPID
                                                        + "&redirect_uri="
                                                        + CommonUtil.urlEncodeUTF8(REDIRECT_URI_BASE)
                                                        + "&response_type=code&scope=snsapi_base&state=pay#wechat_redirect";
// oauth2授权接口(GET)
    public final static String  OAUTH2_URL          = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

我们在授权书回调的controller里面获取返回来的openid

@RequestMapping("/oauth2_Base")
    public String oauth2_Base(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        code = request.getParameter("code");
        System.out.println(code+"第一次获取的code");
        StringBuffer weiXinOauth2TokenJson = new StringBuffer();
        if (!"authdeny".equals(code)) {
            weiXinOauth2Token = Oauth2Util.getOauth2AccessToken(code, weiXinOauth2TokenJson);
            System.out.println(weiXinOauth2Token.getOpenId());
            if(weiXinOauth2Token!=null){
                request.getSession().setAttribute("openId", weiXinOauth2Token.getOpenId());//将获取的openid存到缓存,统一下单时要用到
            }
        }

        return "wxpay/pay";
    }

2.调统一下单接口

@RequestMapping("/pay")
    @ResponseBody
    public String pay(HttpServletRequest request,HttpServletResponse response,String total_fee) {
        String out_trade_no=CommonUtil.getUUID();
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        parameters.put("appid", ConfigUtil.APPID);
        parameters.put("mch_id", ConfigUtil.MCH_ID);
        parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());
        parameters.put("body", "商品");
        parameters.put("out_trade_no", out_trade_no);// 订单号,每次都不能一样
        parameters.put("total_fee","1");
        parameters.put("spbill_create_ip", IpUtil.getIpAddrByRequest(request));
        parameters.put("notify_url", ConfigUtil.NOTIFY_URL);
        parameters.put("trade_type", "JSAPI");
        parameters.put("openid", request.getSession().getAttribute("openId"));
        // 必填————签名
        String sign = PayCommonUtil.createSign("UTF-8", parameters);
        parameters.put("sign", sign);
        String requestXML = PayCommonUtil.getRequestXml(parameters);
        String result = CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);
        System.out.println("同一订单接口返回数据:" + result);
        String json="";
        try {
            @SuppressWarnings("unchecked")
            Map<String, String> map = XMLUtil.doXMLParse(result);
            SortedMap<Object, Object> params = new TreeMap<Object, Object>();
            params.put("appId", ConfigUtil.APPID);
            params.put("timeStamp", Long.toString(new Date().getTime()));
            params.put("nonceStr", PayCommonUtil.CreateNoncestr());
            params.put("package", "prepay_id=" + map.get("prepay_id"));
            params.put("signType", ConfigUtil.SIGN_TYPE);
            String paySign = PayCommonUtil.createSign("UTF-8", params);
            params.put("packageValue", "prepay_id=" + map.get("prepay_id")); // 这里用packageValue是预防package是关键字在js获取值出错
            params.put("paySign", paySign); // paySign的生成规则和Sign的生成规则一致
            params.put("sendUrl", ConfigUtil.SUCCESS_URL); // 付款成功后跳转的页面
            System.out.println();
    //      String userAgent = request.getHeader("user-agent");
    //      char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger") + 15);
        //  params.put("agent", new String(new char[] { agent }));// 微信版本号,用于前面提到的判断用户手机微信的版本是否是5.0以上版本。
            json = JSONObject.fromObject(params).toString();

        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }// 解析微信返回的信息,以Map形式存储便于取值
        return json;
    }

付款成功后的方法:

@RequestMapping("/paySuccess")
    public void paySuccess(HttpServletRequest request,HttpServletResponse response) throws Exception {
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        System.out.println("~~~~~~~~~~~~~~~~付款成功~~~~~~~~~");
        outSteam.close();
        inStream.close();
        String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
        @SuppressWarnings("unchecked")
        Map<Object, Object> map = XMLUtil.doXMLParse(result);
        String orderId = "";
        String transactionId = "";
        for (Object keyValue : map.keySet()) {
            if (keyValue.equals("out_trade_no")) {
                orderId = (String) map.get(keyValue);
                System.out.println("orderId=--------------"+orderId);
            }
            if (keyValue.equals("transaction_id")) {
                transactionId = (String) map.get(keyValue);
                System.out.println("transactionId=--------------"+transactionId);
            }
            System.out.println(keyValue + "=" + map.get(keyValue));
        }
        if (map.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {

            // TODO 对数据库的操作
            response.getWriter().write(PayCommonUtil.setXML("SUCCESS", "")); // 告诉微信服务器,我收到信息了,不要在调用回调action了
            System.out.println("-------------" + PayCommonUtil.setXML("SUCCESS", ""));
        }
    }

3、h5页面根据返回的信息调取支付

<script type="text/javascript">
                    $("#test").one("click",function(){
                        $.ajax({
                            url:"${pageContext.request.contextPath}/wxpay/pay" ,
                            data:{"total_fee":$("#orderId").val(),
                                  "storename":$("#storename").val(),
                                  "name":$("name").val(),
                                  "phone":$("phone").val()
                                }           //<span style="font-family:微软雅黑;">ajax调用微信统一接口获取prepayId</span>
                        }).done(function(data){
                            //alert(data);
                            var obj = eval('(' + data + ')');
                            if(parseInt(obj.agent)<5){
                                alert("您的微信版本低于5.0无法使用微信支付");
                                return;
                            }
                            WeixinJSBridge.invoke('getBrandWCPayRequest',{
                                "appId" : obj.appId,                  //公众号名称,由商户传入
                                "timeStamp":obj.timeStamp,          //时间戳,自 1970 年以来的秒数
                                "nonceStr" : obj.nonceStr,         //随机串
                                "package" : obj.packageValue,      //<span style="font-family:微软雅黑;">商品包信息</span>
                                "signType" : obj.signType,        //微信签名方式:
                                "paySign" : obj.paySign           //微信签名
                                },function(res){    
                                    alert(res.err_msg);
                                if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                                    window.location.href=obj.sendUrl;
                                    //window.location.href="www.baidu.com";
                                }else{
                                    alert("fail");
                                    window.location.href="http://www.hbdtty.com/BeautyApp/oauth2controller/oauth2";

                                }
                            });

                        });
                    });
            </script>

上面只是代码片段,大概就这么一个流程,下面附上一个能使用的例子 把ConfigUtil里面配置上自己的东西就可以直接测试了,下载地址 https://download.csdn.net/download/qq_33866778/10341970

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值