一. 微信支付配置
如下圖,找到微信支付“開發配置”:
- http://htyundai.com/jfinal-weixin-demo/pay/對應後臺處理微信支付邏輯的路徑,前臺js主要代碼如下:
個人覺得如果條件允許,不必使用測試授權目錄和測試白名單,因爲以後移植的時候可能導致錯誤。//微信支付 $("#li_wepay").click(function(){ var expense = 10; var url = contextPath + "/pay"; $.post(url, { expense : expense, },function(result){ WeixinJSBridge.invoke('getBrandWCPayRequest', { "appId":result.appId, "timeStamp":result.timeStamp, "nonceStr":result.nonceStr, //隨機串 "package":result.package, "signType":result.signType, //微信簽名方式: "paySign":result.paySign //微信簽名 }, function(res){ //getProes(res); //支付成功或失敗前臺判斷 if(res.err_msg=='get_brand_wcpay_request:ok'){ window.location.href = contextPath+"/pay_finish.jsp"; } }); },'json'); });
- 值得注意的是,由於android機微信開發,錯誤提示得非常不明顯,筆者建議直接獲取支付返回的“res”對象,將裏面的屬性全部彈出,就知道哪裏出錯了!
- 二. 微信支付主要後臺代碼
- 2.1 微信支付後臺主接口
- 調用微信支付方法:
封裝的WxPayDto類:/** * 微信支付配置 * @param money * @param orderid * @return */ public String handleWePay(String money,String orderid) { //微信支付jsApi WxPayDto tpWxPay = new WxPayDto(); tpWxPay.setOpenId(CookieUtils.getCookieByName(getRequest(), "openid")); tpWxPay.setBody("商品信息"); //訂單號 tpWxPay.setOrderId(orderid); tpWxPay.setSpbillCreateIp("127.0.0.1"); //TODO 暫時設爲1分方便測試 money tpWxPay.setTotalFee("0.01"); //tpWxPay.setTotalFee(money); return "{"+PayUtils.getPackage(tpWxPay)+"}"; }
PayUtils中的getPackage方法:package com.cbj.entity; public class WxPayDto { private String orderId;//訂單號 private String totalFee;//金額 private String spbillCreateIp;//訂單生成的機器 IP private String notifyUrl;//這裏notify_url是 支付完成後微信發給該鏈接信息,可以判斷會員是否支付成功,改變訂單狀態等 private String body;// 商品描述根據情況修改 private String openId;//微信用戶對一個公衆號唯一 /** * @return the orderId */ public String getOrderId() { return orderId; } /** * @param orderId the orderId to set */ public void setOrderId(String orderId) { this.orderId = orderId; } /** * @return the totalFee */ public String getTotalFee() { return totalFee; } /** * @param totalFee the totalFee to set */ public void setTotalFee(String totalFee) { this.totalFee = totalFee; } /** * @return the spbillCreateIp */ public String getSpbillCreateIp() { return spbillCreateIp; } /** * @param spbillCreateIp the spbillCreateIp to set */ public void setSpbillCreateIp(String spbillCreateIp) { this.spbillCreateIp = spbillCreateIp; } /** * @return the notifyUrl */ public String getNotifyUrl() { return notifyUrl; } /** * @param notifyUrl the notifyUrl to set */ public void setNotifyUrl(String notifyUrl) { this.notifyUrl = notifyUrl; } /** * @return the body */ public String getBody() { return body; } /** * @param body the body to set */ public void setBody(String body) { this.body = body; } /** * @return the openId */ public String getOpenId() { return openId; } /** * @param openId the openId to set */ public void setOpenId(String openId) { this.openId = openId; } }
/** * 獲取請求預支付id報文 * @return */ @SuppressWarnings("static-access") public static String getPackage(WxPayDto tpWxPayDto) { String openId = tpWxPayDto.getOpenId(); // 1 參數 // 訂單號 String orderId = tpWxPayDto.getOrderId(); // 附加數據 原樣返回 String attach = ""; // 總金額以分爲單位,不帶小數點 String totalFee = getMoney(tpWxPayDto.getTotalFee()); // 訂單生成的機器 IP String spbill_create_ip = tpWxPayDto.getSpbillCreateIp(); // 這裏notify_url是 支付完成後微信發給該鏈接信息,可以判斷會員是否支付成功,改變訂單狀態等。 String trade_type = "JSAPI"; // ---必須參數 // 商戶號 String mch_id = PropKit.get("mch_id"); // 隨機字符串 String nonce_str = SignUtil.getNonceStr(); // 商品描述根據情況修改 String body = tpWxPayDto.getBody(); // 商戶訂單號 String out_trade_no = orderId; String appid = PropKit.get("appId"); SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", appid); packageParams.put("mch_id", mch_id); packageParams.put("nonce_str", nonce_str); packageParams.put("body", body); packageParams.put("attach", attach); packageParams.put("out_trade_no", out_trade_no); packageParams.put("total_fee", totalFee); packageParams.put("spbill_create_ip", spbill_create_ip); packageParams.put("notify_url", notify_url); packageParams.put("trade_type", trade_type); packageParams.put("openid", openId); RequestHandler reqHandler = new RequestHandler(null, null); reqHandler.init(appid, PropKit.get("appSecret"), PropKit.get("paternerKey")); String sign = reqHandler.createSign(packageParams); String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>" + "<nonce_str>" + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>" + "<body><![CDATA[" + body + "]]></body>" + "<out_trade_no>" + out_trade_no + "</out_trade_no>" + "<attach>" + attach + "</attach>" + "<total_fee>" + totalFee + "</total_fee>" + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" + "<notify_url>" + notify_url + "</notify_url>" + "<trade_type>" + trade_type + "</trade_type>" + "<openid>" + openId + "</openid>" + "</xml>"; String prepay_id = ""; String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml); System.out.println("獲取到的預支付ID:" + prepay_id); //獲取prepay_id後,拼接最後請求支付所需要的package SortedMap<String, String> finalpackage = new TreeMap<String, String>(); String timestamp = Sha1Util.getTimeStamp(); String packages = "prepay_id="+prepay_id; finalpackage.put("appId", appid); finalpackage.put("timeStamp", timestamp); finalpackage.put("nonceStr", nonce_str); finalpackage.put("package", packages); finalpackage.put("signType", "MD5"); //要簽名 String finalsign = reqHandler.createSign(finalpackage); String finaPackage = "\"appId\":\"" + appid + "\",\"timeStamp\":\"" + timestamp + "\",\"nonceStr\":\"" + nonce_str + "\",\"package\":\"" + packages + "\",\"signType\" : \"MD5" + "\",\"paySign\":\"" + finalsign + "\""; System.out.println("V3 jsApi package:"+finaPackage); return finaPackage; }
- 轉換金額的getMoney方法:
未完待續。。。/** * 元轉換成分 * @param money * @return */ public static String getMoney(String amount) { if(amount==null){ return ""; } // 金額轉化爲分爲單位 String currency = amount.replaceAll("\\$|\\¥|\\,", ""); //處理包含, ¥ 或者$的金額 int index = currency.indexOf("."); int length = currency.length(); int amLong = 0; if(index == -1){ amLong = Integer.valueOf(currency+"00"); }else if(length - index >= 3){ amLong = Integer.valueOf((currency.substring(0, index+3)).replace(".", "")); }else if(length - index == 2){ amLong = Integer.valueOf((currency.substring(0, index+2)).replace(".", "")+0); }else{ amLong = Integer.valueOf((currency.substring(0, index+1)).replace(".", "")+"00"); } System.out.println("預支付金額:"+amLong); return amLong+""; }