微信支付H5調用支付詳解(java版)_java

來源:互聯網
上載者:User

最近項目需要微信支付,然後看了下微信公眾號支付,,雖然不難,但是細節還是需要注意的,用了大半天時間寫了個demo,並且完整的測試了一下支付流程,下面分享一下微信公眾號支付的經驗。

一、配置公眾號微信支付 

需要我們配置微信公眾號支付地址和測試白名單。

比如:支付JS頁面的地址為 http://www.xxx.com/shop/pay/

那此處配置www.xxx.com/shop/pay/

二、開發流程

借用微信公眾號支付api(地址 http://pay.weixin.qq.com/wiki/doc/api/index.PHP?chapter=7_4),我們需要開發的為紅色標記出的。如下:

三、向微信伺服器端下訂單

調用統一下單介面,這樣就能擷取微信支付的prepay_id(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1)。

在調用該介面前有幾個欄位是H5支付必須填寫的openid

3.1 擷取openid

可以通過網頁授權形式(http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)

在微信中發送如下連結
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=要跳轉的下訂單的url&response_type=code&scope=snsapi_base&state=123#wechat_redirect

3.2 下訂單擷取prepay_id

代碼如下,實際上是通過post發送一個xml 檔案,擷取微信伺服器端發送過來的prepay_id。

import java.io.ByteArrayInputStream; import javaioIOException; import javaioInputStream; import javaioUnsupportedEncodingException; import javautilDate; import javautilHashMap; import javautilIterator; import javautilMap; import javautilMapEntry; import javautilRandom;  import javaxservlethttpHttpServletRequest; import javaxservlethttpHttpServletResponse;  import orgapachecommonscodecdigestDigestUtils; import orgspringframeworkstereotypeController; import orgspringframeworkwebbindannotationRequestMapping; import orgxmlpullvXmlPullParser; import orgxmlpullvXmlPullParserException; import orgxmlpullvXmlPullParserFactory;  import comfasterxmljacksondatabindJsonNode; import comgsonoauthOauth; import comgsonoauthPay; import comgsonutilHttpKit; import comsyutilDatetimeUtil; import comsyutilJsonUtil;  @Controller @RequestMapping("/pay") public class WXPayController {    @RequestMapping(value = "wxprepaydo")   public void jspay(HttpServletRequest request, HttpServletResponse response, String callback) throws Exception {     // 擷取openid     String openId = SessionUtilgetAtt(request, "openId");     if (openId == null) {       openId = getUserOpenId(request);     }      String appid = "wx16691fcb0523c1a4";     String paternerKey = "ININGFENG1234567fdfwfdfd1ss234567";          String out_trade_no = getTradeNo();     Map<String, String> paraMap = new HashMap<String, String>();     paraMapput("appid", appid);     paraMapput("attach", "測試");     paraMapput("body", "測試購買支付");     paraMapput("mch_id", "10283271");     paraMapput("nonce_str", create_nonce_str());     paraMapput("openid", openId);     paraMapput("out_trade_no", out_trade_no);     paraMapput("spbill_create_ip", getAddrIp(request));     paraMapput("total_fee", "1");     paraMapput("trade_type", "JSAPI");     paraMapput("notify_url", "http://wwwxxxco/bank/page/wxnotify");     String sign = getSign(paraMap, paternerKey);     paraMapput("sign", sign);      // 統一下單 https://apimchweixinqqcom/pay/unifiedorder     String url = "https://apimchweixinqqcom/pay/unifiedorder";      String xml = ArrayToXml(paraMap);      String xmlStr = HttpKitpost(url, xml);      // 預付商品id     String prepay_id = "";      if (xmlStrindexOf("SUCCESS") != -1) {       Map<String, String> map = doXMLParse(xmlStr);       prepay_id = (String) mapget("prepay_id");     }      Map<String, String> payMap = new HashMap<String, String>();     payMapput("appId", appid);     payMapput("timeStamp", create_timestamp());     payMapput("nonceStr", create_nonce_str());     payMapput("signType", "MD5");     payMapput("package", "prepay_id=" + prepay_id);     String paySign = getSign(payMap, paternerKey);          payMapput("pg", prepay_id);     payMapput("paySign", paySign);               WebUtilresponse(response, WebUtilpackJsonp(callback, JsonUtilwarpJsonNodeResponse(JsonUtilobjectToJsonNode(payMap))toString()));   }    /**    * map轉成xml    *    * @param arr    * @return    */   public String ArrayToXml(Map<String, String> arr) {     String xml = "<xml>";      Iterator<Entry<String, String>> iter = arrentrySet()iterator();     while (iterhasNext()) {       Entry<String, String> entry = iternext();       String key = entrygetKey();       String val = entrygetValue();       xml += "<" + key + ">" + val + "</" + key + ">";     }      xml += "</xml>";     return xml;   }    // 擷取openId   private String getUserOpenId(HttpServletRequest request) throws Exception {     String code = requestgetParameter("code");     if (code == null) {       String openId = requestgetParameter("openId");       return openId;     }     Oauth o = new Oauth();     String token = ogetToken(code);     JsonNode node = JsonUtilStringToJsonNode(token);     String openId = nodeget("openid")asText();     return openId;   }    private String create_nonce_str() {       String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";       String res = "";       for (int i = 0; i < 16; i++) {         Random rd = new Random();         res += charscharAt(rdnextInt(charslength() - 1));       }       return res;   }      private String getAddrIp(HttpServletRequest request){     return requestgetRemoteAddr();   }    private String create_timestamp() {     return LongtoString(SystemcurrentTimeMillis() / 1000);   }      private String getTradeNo(){     String timestamp = DatetimeUtilformatDate(new Date(), DatetimeUtilDATETIME_PATTERN);     return "HZNO" + timestamp;   }      private String getSign(Map<String, String> params, String paternerKey )       throws UnsupportedEncodingException {     String string1 = PaycreateSign(params, false);     String stringSignTemp = string1 + "&key=" + paternerKey;     String signValue = DigestUtilsmd5Hex(stringSignTemp)toUpperCase();     return signValue;   }    private Map<String, String> doXMLParse(String xml)       throws XmlPullParserException, IOException {      InputStream inputStream = new ByteArrayInputStream(xmlgetBytes());      Map<String, String> map = null;      XmlPullParser pullParser = XmlPullParserFactorynewInstance()         newPullParser();      pullParsersetInput(inputStream, "UTF-8"); // 為xml設定要解析的xml資料      int eventType = pullParsergetEventType();      while (eventType != XmlPullParserEND_DOCUMENT) {       switch (eventType) {       case XmlPullParserSTART_DOCUMENT:         map = new HashMap<String, String>();         break;        case XmlPullParserSTART_TAG:         String key = pullParsergetName();         if (keyequals("xml"))           break;          String value = pullParsernextText();         mapput(key, value);          break;        case XmlPullParserEND_TAG:         break;        }        eventType = pullParsernext();      }      return map;   }  } 

四、H5支付

H5支付其實很簡單,只需要調用微信內嵌瀏覽器的js方法就行(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=7_7)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="spring" uri="http://wwwspringframeworkorg/tags" %> <%   String path = requestgetContextPath();   String basePath = requestgetScheme() + "://" + requestgetServerName() + ":" + requestgetServerPort() + path + "/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 01 Transitional//EN" "http://wwwworg/TR/html4/loosedtd"> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=0, maximum-scale=0, user-scalable=0" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="format-detection" content="telephone=no" /> <title>測試支付</title> <link href="/css/csscss?v=0" rel="stylesheet" type="text/css"> </head>  <body>   <div class="index_box">     <div class="apply_name">微信js支付測試</div>               <div class="branch_con">       <ul>         <li><span class="name">測試支付資訊</span></li>       </ul>       <p class="cz_btn"><a href="javascript:pay();" class="btn_1">立即支付</a></p>     </div>   </div>    <script type="text/javascript" src="/js/zeptominjs"></script>   <script type="text/javascript" src="/js/commonjs"></script>   <script type="text/javascript">       var appId = urlparameter("appId");   var timeStamp = urlparameter("timeStamp");   var nonceStr = urlparameter("nonceStr");   var pg = urlparameter("pg");   var signType = urlparameter("signType");   var paySign = urlparameter("paySign");          function onBridgeReady(){             WeixinJSBridgeinvoke(         'getBrandWCPayRequest', {           "appId" : appId,   //公眾號名稱,由商戶傳入              "timeStamp": timeStamp,     //時間戳記,自1970年以來的秒數              "nonceStr" : nonceStr, //隨機串              "package" : "prepay_id=" + pg,              "signType" : signType,     //微信簽名方式:              "paySign" : paySign  //微信簽名          },                  function(res){              if(reserr_msg == "get_brand_wcpay_request:ok" ) {                          alert("支付成功");           }   // 使用以上方式判斷前端返回,微信團隊鄭重提示:reserr_msg將在使用者支付成功後返回  ok,但並不保證它絕對可靠。          }       );      }             function pay(){              if (typeof WeixinJSBridge == "undefined"){         if( documentaddEventListener ){           documentaddEventListener('WeixinJSBridgeReady', onBridgeReady, false);         }else if (documentattachEvent){           documentattachEvent('WeixinJSBridgeReady', onBridgeReady);            documentattachEvent('onWeixinJSBridgeReady', onBridgeReady);         }       }else{         onBridgeReady();       }             }   </script> </body> </html> 

效果如下

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.