參考文檔:微信公衆號支付php
微信公衆號支付,最爲麻煩的是須要獲取支付者的openid,這就須要用戶在查看商品時,就要提早獲取到用戶的openid,注意:儘可能在支付以前就獲取到openid,保存在session中,以方便接下來的調用。html
下面是具體開發步驟:前端
1.登錄微信公衆平臺,查看「開發」-->「接口權限」,以下圖java
2.如未獲取網頁受權權限,須要先申請,接下來須要配置受權域名,點擊修改,打開以下頁面算法
3.點擊設置,配置受權域名如圖,這裏須要注意的時,回調域名說明中的3,首先按照說明,下載文件,打開文件json
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/,通知以「/」結尾,這個域名須要和網頁受權域名相同,這個很容易忽略!)api
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。代碼以下session
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.下面就是吊起微信公衆號支付的核心代碼app
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.微信公衆支付過程比較繁瑣,細節要注意好!