微信支付之公众号支付

参考文档:微信公众号支付

微信公众号支付,最为麻烦的是需要获取支付者的openid,这就需要用户在查看商品时,就要提前获取到用户的openid,注意:尽量在支付之前就获取到openid,保存在session中,以方便接下来的调用。

下面是具体开发步骤:

1.登陆微信公众平台,查看“开发”-->“接口权限”,如下图

 

2.如未获取网页授权权限,需要先申请,接下来需要配置授权域名,点击修改,打开如下页面

 

3.点击设置,配置授权域名如图,这里需要注意的时,回调域名说明中的3,首先按照说明,下载文件,打开文件

MP_verify_suf8fVQzCk0Mh42y.txt,把文件中的内容复制出来。接下里在项目中配置一个供直接访问的文件路径。
@RequestMapping("/MP_verify_suf8fVQzCk0Mh42y.txt")
    public ResponseEntity<String> checkWX(){
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json;charset=UTF-8");
        return new ResponseEntity<String>("XXXXXXXXXXX",responseHeaders, HttpStatus.OK);
    }

  

4.配置成功后,查看公众号中的开发者id,打开“开发”-->“基本配置”。接下来把微信支付配置也顺便处理了,打开“微信支付”-->“开发配置”,配置支付授权目录(注意,目录至少配置到二级或三级,如www.baidu.com/wx/pay/,通知以“/”结尾,这个域名需要和网页授权域名相同,这个很容易忽略!

 

 

5.获取用户openid,一般通过静默授权,打开链接 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx00000000000&redirect_uri=http%3A%2F%2Fwww.baidu.com%2Fwx?response_type=code&scope=snsapi_base&state=dac24d03f848ce899f28ad787eba74e2&connect_redirect=1#wechat_redirect。红色标识为需要根据自己公众号改变的,得到code。

6.拦截到5中配置的回调链接,拿到code,再去获取用户的openid。代码如下

public static User getUserWXOpenid(String code){
        //1.得到access_token

        String jsonUrl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx000000000000&secret=5652222222222200000&code="+code+"&grant_type=authorization_code"; //appid和secret根据上述在基本配置中查看

        String jsonResponse=sendGet(jsonUrl);
        //2.对json数据进行解析
        JSONObject jsonObject=JSONObject.parseObject(jsonResponse);
        String access_token=jsonObject.getString("access_token");
        String openid=jsonObject.getString("openid");
       
         User user=new User();
         user.setOpenid(openid);
         return user;
    }  

@RequestMapping("/wx")
public String wx_open(HttpServletRequest request, Model model) {
    System.out.println("得到code");
    String code = request.getParameter("code");
    System.out.println("code:"+code);
    User user = getUserWXOpenid(code);

    System.out.println("openId:"+user.getOpenid());

    request.getSession().setAttribute("openId",user.getOpenid());
    request.getSession().setAttribute("is_got_auth",true);
    return "redirect:/index";
}

  

7.下面就是吊起微信公众号支付的核心代码

String subject="商品";
       String openid=request.getSsion.getAttribute("openid");//得到之前存在session中的openid //微信支付 Utils.getIP(request) String now_ip= "192.168.1.3"; String nonce_str=Utils.getCharAndNum(32); String total_fee="1";//注意:微信支付单位为分 String prepay_id=null; Map<String,String> paraMap=new HashMap<>(); paraMap.put("appid", PayConfigUtils.getWx_app_id());//appid paraMap.put("attach", subject); paraMap.put("body", subject); paraMap.put("mch_id", PayConfigUtils.getWx_mch_id()); //商户id,登陆微信商户平台查看 paraMap.put("nonce_str", nonce_str); paraMap.put("notify_url", PayConfigUtils.getWebUrl()+"wx_pay/notify");//微信支付回执链接,用于回馈支付结果 paraMap.put("openid", openId); paraMap.put("out_trade_no", "5225555111"); paraMap.put("spbill_create_ip", now_ip); paraMap.put("total_fee", total_fee); paraMap.put("trade_type", "JSAPI"); List<String> keys =new ArrayList<>(paraMap.keySet()); Collections.sort(keys); StringBuilder authInfo = new StringBuilder(); for (int i=0;i<keys.size()-1; i++) { String value = paraMap.get(keys.get(i)); authInfo.append(keys.get(i)+"="+value+"&"); } authInfo.append(keys.get(keys.size()-1)+"="+paraMap.get(keys.get(keys.size()-1))); String stringA=authInfo.toString()+"&key="+PayConfigUtils.getWx_app_secret_key(); String sign=Utils.encode("MD5",stringA).toUpperCase(); //封装xml String paras="<xml>\n" + " <appid>"+PayConfigUtils.getWx_app_id()+"</appid>\n" + " <attach>"+subject+"</attach>\n" + " <body>"+subject+"</body>\n" + " <mch_id>"+PayConfigUtils.getWx_mch_id()+"</mch_id>\n" + " <nonce_str>"+nonce_str+"</nonce_str>\n" + " <notify_url>"+paraMap.get("notify_url")+"</notify_url>\n" + " <out_trade_no>"+order.getPay_number()+"</out_trade_no>\n" + " <spbill_create_ip>"+now_ip+"</spbill_create_ip>\n" + " <total_fee>"+total_fee+"</total_fee>\n" + " <openid>"+openId+"</openid>\n" + " <trade_type>JSAPI</trade_type>\n" + " <sign>"+sign+"</sign>\n" + "</xml>"; try { String content=senPost(paras); if(content!=null){ prepay_id=Utils.readStringXml(content); } if(prepay_id!=null){ String current_noncestr=Utils.getCharAndNum(32); String current_sign=null; long current_timestamp=System.currentTimeMillis()/1000; result.put("appid",PayConfigUtils.getWx_app_id()); result.put("signType","MD5"); result.put("package","prepay_id="+prepay_id); //a,n,p,s,t result.put("noncestr",current_noncestr); result.put("timestamp",current_timestamp); //加密算法 String nowStringA="appId="+PayConfigUtils.getWx_app_id()+"&nonceStr="+current_noncestr+"&package=prepay_id="+prepay_id+"&signType=MD5&timeStamp="+current_timestamp+"&key="+PayConfigUtils.getWx_app_secret_key(); System.out.println(nowStringA); current_sign=Utils.encode("MD5",nowStringA).toUpperCase(); System.out.println(current_sign); result.put("paySign",current_sign); } } catch (Exception e) { e.printStackTrace(); } System.out.println(result.toString());

  

//发送post请求,得到微信预支付id
public static String senPost(String paras) throws IOException {
    boolean is_success=true;
    int i=0;
    String  result="";
    while (is_success){
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost post = new HttpPost(url);
        StringEntity postingString = new StringEntity(paras,"utf-8");// xml传递
        post.setEntity(postingString);
        post.setHeader("Content-type", "text/html; charset=UTF-8");
        HttpResponse response = httpClient.execute(post);
        result = EntityUtils.toString(response.getEntity());

        if(result==null||result.isEmpty()){
            i++;
        }else {
            break;
        }
        if(i>2){
            break;
        }
    }
    return result;
}
8.至此,微信公众号支付的参数已准备完毕,最后是前台的js吊起微信支付,具体代码如下:

function onBridgeReady(){
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', {
           "appId" : "wx2421b1c4370ec43b",     //公众号名称,由商户传入     
           "timeStamp":" 1395712654",         //时间戳,自1970年以来的秒数     
           "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串     
           "package" : "prepay_id=u802345jgfjsdfgsdg888",     
           "signType" : "MD5",         //微信签名方式:     
           "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
       },
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
       }
   ); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}

  

 

 9.微信公众支付过程比较繁琐,细节要注意好!

posted @ 2017-02-23 15:06  流年飞逝  阅读(928)  评论(0编辑  收藏  举报