微信支付說明
1.統一下單接口
統一支付接口:
url: https://api.mch.weixin.qq.com/pay/unifiedorder
目的:經過此接口來建立預支付訂單,獲取訂單支付須要的prepay_id
過程:
1.對全部的支付中使用到的參數以字典序排序,而後使用商戶的key進行MD5加密,得到加密字符串sign,
2.而後將sign加入以上信息中將其轉化爲xml,調用統一下單接口,獲取prepay_id。
代碼說明:
php
1.構建支付參數
//寫購買商品的詳情 JSONObject object = new JSONObject(); JSONArray array = new JSONArray(); JSONObject object1 = new JSONObject(); object1.put("goods_id","購買商品id"); object1.put("goods_name","購買商品名稱"); object1.put("quantity","購買商品數量"); object1.put("price","商品單價"); array.add(object1); object.put("goods_detail",array); //構建統一下單須要的參數 Map<String,String> map = new HashMap<>(); map.put('appid',"支付的微信公衆號的appid"); map.put("mch_id","支付的商戶號"); map.put("device_info","設備編號"); map.put("sign_type","加密類型,通常使用MD5"); map.put("body","商品描述"); map.put("out_trade_no","商戶訂單號"); map.put("total_url","購買總金額"); map.put("notify_url","支付成功後微信的回掉地址,地址不準帶參數"); map.put("trade_type","交易類型"); map.put("nonce_str","隨機字符串"); map.put("detail","商品詳情"); map.put("openid","支付人的openid"); map.put("spbill_create_ip","支付人ip地址");
//將統一下單參數進行字典序排序,進行簽名 /** * 微信支付簽名算法(詳見:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3). * * @param params 參數信息 * @param signType 簽名類型,若是爲空,則默認爲MD5 * @param signKey 簽名Key * @param ignoreSignType 簽名時,是否忽略signType * @return 簽名字符串 */ public static String createSign(Map<String, String> params, String signType, String signKey, boolean ignoreSignType) { SortedMap<String, String> sortedMap = new TreeMap<>(params); StringBuilder toSign = new StringBuilder(); for (String key : sortedMap.keySet()) { String value = params.get(key); boolean shouldSign = false; if (ignoreSignType && "sign_type".equals(key)) { shouldSign = false; } else if (StringUtils.isNotEmpty(value) && !Lists.newArrayList("sign", "key", "xmlString", "xmlDoc", "couponList").contains(key)) { shouldSign = true; } if (shouldSign) { toSign.append(key).append("=").append(value).append("&"); } } toSign.append("key=").append(signKey); if ("HMAC_SHA256".equals(signType)) { return createHmacSha256Sign(toSign.toString(), signKey); } else { return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); } } //將上一步獲得的簽名加入上一個支付參數中,轉爲xml請求統一支付下單接口,獲取訂單支付須要的prepay_id map.put("sign","上一步獲得的簽名"); //將map轉爲xml public static String map2XmlString(Map<String, String> map) { String xmlResult = ""; StringBuffer sb = new StringBuffer(); sb.append("<xml>"); for (String key : map.keySet()) { String value = "<![CDATA[" + map.get(key) + "]]>"; sb.append("<" + key + ">" + value + "</" + key + ">"); } sb.append("</xml>"); xmlResult = sb.toString(); return xmlResult; } //進行網絡請求 public static String httpPostWithXml(String xml, String url){ StringBuffer stringBuffer = new StringBuffer(); HttpPost post = null; try { HttpClient httpClient = new DefaultHttpClient(); // 設置超時時間 //httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000); //httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000); post = new HttpPost(url); // 構造消息頭 post.setHeader("Content-type", "application/json; charset=utf-8"); post.setHeader("Connection", "Close"); // 構建消息實體 StringEntity entity = new StringEntity(xml,"UTF-8"); entity.setContentEncoding("UTF-8"); // 發送Json格式的數據請求 entity.setContentType("application/json"); post.setEntity(entity); HttpResponse response = httpClient.execute(post); // 檢驗返回碼 int statusCode = response.getStatusLine().getStatusCode(); if(statusCode != HttpStatus.SC_OK){ LogUtil.info("請求出錯: "+statusCode); }else{ InputStream inputStream = response.getEntity().getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream,"utf-8")); String str= ""; while((str = br.readLine()) != null){ stringBuffer .append(str ); } } } catch (Exception e) { e.printStackTrace(); } return stringBuffer.toString(); } //獲得了prepay_id,獲取支付的簽名 Map<String,String> map = new HashMap<>(); map.put('appId',"支付的微信公衆號的appid"); map.put("signType","加密類型"); map.put("nonceStr","隨機字符串"); map.put("package","固定格式: prepay_id=上一步得到的prepay_id"); map.put("timeStamp","當前時間戳"); //將上面的參數使用商戶key進行簽名,獲得paysign,將paySign加入上面的參數之中,發給h5頁面調起支付。 map.put(paySign,"獲得的簽名"); //h5頁面調起支付 WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":rs.appId, //公衆號名稱,由商戶傳入 "timeStamp":rs.timeStamp, //時間戳,自1970年以來的秒數 "nonceStr":rs.nonceStr, //隨機串 "package":rs.package, "signType":"MD5", //微信簽名方式: "paySign":rs.paySign //微信簽名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ) { //支付成功 }else if(res.err_msg =="get_brand_wcpay_request:fail"){ //支付失敗 }else if(res.err_msg == "get_brand_wcpay_request:cancel"){ //取消支付 }else { //其餘狀況 } } );