你的位置:首页 > Java教程

[Java教程]微信公众号支付(三):页面调用微信支付JS并完成支付


一、调用微信的JS文件

1.首先要绑定【JS接口安全域名】,“公众号设置”的“功能设置”中

2.引入JS文件

 备注:支持使用 AMD/CMD 标准模块加载方法加载

1 <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

3.通过config接口注入权限验证配置

1 wx.config({2   debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。3   appId: '', // 必填,公众号的唯一标识4   timestamp: , // 必填,生成签名的时间戳5   nonceStr: '', // 必填,生成签名的随机串6   signature: '',// 必填,签名,见附录17   jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,这里只写支付的8 });

4.通过ready接口处理成功验证

1 wx.ready(function(){2   wx.hideOptionMenu();//隐藏右边的一些菜单3 });

 

二、wx.config中的签名

1.首先要获取到access token:公众号的全局唯一票据 。然后根据access token获取到jsapi_ticket:公众号用于调用微信JS接口的临时票据。再用jsapi_ticket获取到签名。

2.获取access token:文档:url:http://mp.weixin.qq.com/wiki/15/54ce45d8d30b6bf6758f68d2e95bc627.html

 1   public static Token getToken(String appid, String appsecret) { 2     Token token = null; 3     String requestUrl = Constants.token_url.replace("APPID", appid).replace("APPSECRET", appsecret); 4     // 发起GET请求获取凭证 5     JSONObject jsonObject = CommonUtil.httpsRequestToJsonObject(requestUrl, "GET", null); 6  7     if (null != jsonObject) { 8       try { 9         token = new Token();10         token.setAccessToken(jsonObject.getString("access_token"));11         token.setExpiresIn(jsonObject.getInt("expires_in"));12       } catch (JSONException e) {13         token = null;14         // 获取token失败15         log.error("获取token失败 "+jsonObject.getInt("errcode")+","+jsonObject.getString("errmsg"));16       }17     }18     return token;19   }

有些方法在前两篇中。

3.获取jsapi_ticket

 1   public static Ticket getTicket() { 2     //Constants.ticket_url = https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi 3     String requestUrl = Constants.ticket_url.replace("ACCESS_TOKEN", TokenThread.accessToken.getAccessToken()); 4     // 发起GET请求获取凭证 5     JSONObject jsonObject = CommonUtil.httpsRequestToJsonObject(requestUrl, "GET", null); 6     Ticket ticket = null; 7     String jsapi_ticket = ""; 8     int expires_in = 0; 9     if (null != jsonObject) {10       try {11         jsapi_ticket = jsonObject.getString("ticket");12         expires_in = jsonObject.getInt("expires_in");13         ticket = new Ticket();14         ticket.setTicket(jsapi_ticket);15         ticket.setExpiresIn(expires_in);16       } catch (JSONException e) {17         // 获取失败18         log.error("获取jsapi_ticket失败"+jsonObject.getInt("errcode")+","+jsonObject.getString("errmsg"));19       }20     }21     return ticket;22   }

注意:jsapi_ticket和access token为7200的有效时间。7200后要重新获取,我是放在线程里面死循环的。

4.算签名

 1 /** 2  * 签名实体类 3  * @author rory.wu 4  * 5 */ 6 public class Signature implements Serializable { 7   private static final long serialVersionUID = -7799030247222127708L; 8    9   private String url;10   private String jsapi_ticket;11   private String nonceStr;12   private String timestamp;13   private String signature;14    15  //下面是getset方法    16 }

 1  /** 2    * 算出签名 3    * @param jsapi_ticket  4    * @param url 业务中调用微信js的地址 5    * @return 6   */ 7   public static Signature sign(String jsapi_ticket, String url) { 8     String nonce_str = CommonUtil.create_nonce_str(); 9     String timestamp = CommonUtil.create_timestamp();10     String string1;11     String signature = "";12 13     //注意这里参数名必须全部小写,且必须有序14     string1 = "jsapi_ticket=" + jsapi_ticket +15          "&noncestr=" + nonce_str +16          "&timestamp=" + timestamp +17          "&url=" + url;18     try19     {20       MessageDigest crypt = MessageDigest.getInstance("SHA-1");21       crypt.reset();22       crypt.update(string1.getBytes("UTF-8"));23       signature = CommonUtil.byteToStr(crypt.digest());24     }25     catch (NoSuchAlgorithmException e)26     {27       e.printStackTrace();28     }29     catch (UnsupportedEncodingException e)30     {31       e.printStackTrace();32     }33     34     Signature result = new Signature();35     result.setUrl(url);36     result.setJsapi_ticket(jsapi_ticket);37     result.setNonceStr(nonce_str);38     result.setTimestamp(timestamp);39     result.setSignature(signature);40 41     return result;42   }

注意:有些方法在前两篇中

这样就算出签名了。

5.传递到前端页面

把随机字符串:nonce_str,timestamp时间戳,appId,签名,包装为prepay_id=prepay_id的预支付ID传递到前端。

1 wx.config({2   appId: '${appId}', // 必填,公众号的唯一标识3   timestamp: ${timestamp}, // 必填,生成签名的时间戳4   nonceStr: '${nonceStr}', // 必填,生成签名的随机串5   signature: '${signature}',// 必填,签名,见附录16   jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录27 });

6.现在就可以使用微信JS了。

 三、调用微信支付

在前一篇中已经获取到了预支付订单的ID,prepay_id,

 1 /** 2  * 微信支付对象 3  * @author rory.wu 4  * 5 */ 6 public class WxPay implements Serializable { 7   private static final long serialVersionUID = 3843862351717555525L; 8   private String paySign; 9   private String prepay_id;10   private String nonce_str;11   private String timeStamp;12   13   //get,set方法14 }

 1  /** 2    * 获取页面上weixin支付JS所需的参数 3    * @param map 4    * @return 5   */ 6   private WxPay getWxPayInfo(String prepay_id) { 7     String nonce = CommonUtil.create_nonce_str().replace("-", ""); 8     String timeStamp = CommonUtil.create_timestamp(); 9     //再算签名10     String newPrepay_id = "prepay_id="+prepay_id;11     String args = "appId="+Constants.appid12            +"&nonceStr="+nonce13            +"&package="+newPrepay_id14            +"&signType=MD5"15            +"&timeStamp="+timeStamp16            +"&key=7e6niG6sdotSuH79KnRqV8LvdrhUDgR0";17     String paySign = SignUtil.getSign(args, "MD5");18     WxPay wxPay = new WxPay();19     wxPay.setNonce_str(nonce);20     wxPay.setPaySign(paySign);21     wxPay.setPrepay_id(newPrepay_id);22     wxPay.setTimeStamp(timeStamp);23     return wxPay;24   }25   

注意:有些方法在前2篇中。

微信支付的最后一步:js调用

 1 wx.chooseWXPay({ 2   timestamp: json.timeStamp, 3   nonceStr: json.nonce_str,  4   package: json.prepay_id, 5   signType: 'MD5', 6   paySign: json.paySign,  7   success: function (res) { 8     alert("支付成功"); 9   }10 });


结束,微信支付全部结束啦,有问题可以留言找我哦,只会java的,88