国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java實現微信H5支付方法詳解

java實現微信H5支付方法詳解

2020-09-09 13:33李小拐 Java教程

本篇文章主要介紹了java實現微信H5支付方法詳解,非常具有實用價值,需要的朋友可以參考下

前面做了app微信支付的回調處理,現在需要做微信公眾號的支付,花了一天多時間,終于折騰出來了!鑒于坑爹的微信官方沒有提供Java版的demo,所以全靠自己按照同樣坑爹的文檔敲敲敲,所以記錄下來,以供自己及后來人參考,不足之處,還請指正。

首先,我們貼出調用支付接口的H5頁面,當然,在這個頁面之前,還需要做很多其他的操作,我們一步一步的來。

坑爹的官方文檔給了兩個不同的支付接口,在微信公眾平臺開發中文檔的“微信JS-SDK說明文檔”中,給出的支付方式是下面被屏蔽的那一部分,而在商戶平臺的“H5調起支付API”中,又給了一份不同的接口,即下面未屏蔽正常使用的接口。關于坑爹的微信提供了兩個不同的支付接口,網上搜索結果也是眾說紛紛,所以,只有自己試了。當然,為了簡單,我直接試了下面這一種,然后奇跡般的成功了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
 <!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>微信網頁支付</title>
    <!-- <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> -->
    <!-- <script type="text/javascript" src=" https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> -->
    <script type="text/javascript">
      /* wx.config({
        debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。
        appId: appid, // 必填,公眾號的唯一標識
        timestamp: timestamp, // 必填,生成簽名的時間戳
        nonceStr: nonceStr, // 必填,生成簽名的隨機串
        signature: '',// 必填,簽名,見附錄1
        jsApiList: [chooseWXPay] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
      }); */
     
      // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作
      //所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行
      //wx.ready(function(){
        //參數是后臺傳過來的,簽名加密,隨機數,時間戳等全部后臺處理好
        var appId="${appId}";
        var timeStamp="${timeStamp}";
        var nonceStr="${nonceStr}";
        var prepay_id="${prepay_id}";//之前參數名叫package,對應api接口,因為package是關鍵字,被坑了一次
        var sign="${paySign}";
        //支付接口
        function onBridgeReady(){
            WeixinJSBridge.invoke(
              'getBrandWCPayRequest', {
                "appId" : appId,   //公眾號名稱,由商戶傳入 
                "timeStamp" : timeStamp, //時間戳,自1970年以來的秒數 (java需要處理成10位才行,又一坑)
                "nonceStr" : nonceStr, //隨機串
                "package" : prepay_id, //拼裝好的預支付標示
                "signType" : "MD5",//微信簽名方式
                "paySign" : sign //微信簽名
              },
              function(res){
                //使用以下方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回  ok,但并不保證它絕對可靠。
                if(res.err_msg == "get_brand_wcpay_request:ok" ) {   
                  alert("支付成功");       
                }else{
                  alert("支付失敗");
                }
              }
            ); 
        }
        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();
        }
      //});
      //究竟哪個是支付接口
      /* wx.chooseWXPay({
        timestamp: timestamp, // 支付簽名時間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。但最新版的支付后臺生成簽名使用的timeStamp字段名需大寫其中的S字符
        nonceStr: nonceStr, // 支付簽名隨機串,不長于 32 位
        package: 'prepay_id', // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=***)
        signType: 'MD5', // 簽名方式,默認為'SHA1',使用新版支付需傳入'MD5'
        paySign: sign, // 支付簽名
        success: function (res) {
          // 支付成功后的回調函數
          //使用以下方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回  ok,但并不保證它絕對可靠。
          if(res.err_msg == "get_brand_wcpay_request:ok" ) {   
                       
          
        }
      }); */
    </script>
  </head>
  <body>
     
  </body>
</html>

上面h5頁面中,支付接口所需的參數都是由后臺傳過來的,除此之外,在進行上面一步之前,我們還需要獲取一個預支付標識,下面貼上后臺傳參,及獲取預支付標識和參數加密等方法(獲取預支付標識之前需要網頁授權獲取用戶openid,鑒于這個比較簡單,所以不貼代碼了)

首先是后臺參數封裝并對其簽名(關鍵部分代碼):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
if(payway.equals("1")){
      System.out.println("----------支付寶支付-------------");
      request.setAttribute("WIDout_trade_no", WIDout_trade_no);//訂單號
      request.setAttribute("WIDsubject", WIDsubject);//訂單名稱
      request.setAttribute("WIDtotal_fee", WIDtotal_fee);//付款金額
      request.setAttribute("WIDshow_url", WIDshow_url);//商品鏈接
      request.setAttribute("WIDbody", "");//商品描述,可空
      return "alipayapi";
    }else if(payway.equals("2")){
      System.out.println("----------微信支付-------------");
      //1、通過網頁授權接口,獲取到的openid
      String openid=request.getSession().getAttribute("openid")+"";
      //處理價格單位為:分(請自行處理)
      WIDtotal_fee="1";
      String preid=getPrepayid(WIDout_trade_no, WIDtotal_fee, openid);//獲取預支付標示
      System.out.println("預支付標示:----------------"+preid);
      //APPID
      String appId=Common.appid;
      request.setAttribute("appId", appId);
      //時間戳
      String timeStamp=(System.currentTimeMillis()/1000)+"";
      request.setAttribute("timeStamp", timeStamp);
      //隨機字符串
      String nonceStr=Common.randString(16).toString();
      request.setAttribute("nonceStr", nonceStr);
      //預支付標識
      request.setAttribute("prepay_id", "prepay_id="+preid);
      //加密方式
      request.setAttribute("signType", "MD5");
       
      //組裝map用于生成sign
      Map<String, String> map=new HashMap<String, String>();
      map.put("appId", appId);
      map.put("timeStamp", timeStamp);
      map.put("nonceStr", nonceStr);
      map.put("package", "prepay_id="+preid);
      map.put("signType", "MD5");
       
      request.setAttribute("paySign", Common.sign(map, Common.MchSecret));//簽名
      return "weixinpay";
    }else {
      return "error";
    }

接下是獲取預支付標識的方法getPrepayid:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
   * 微信統一下單接口,獲取預支付標示prepay_id
   * @param out_trade_no1 商戶訂單號
   * @param total_fee1 訂單金額(單位:分)
   * @param openid1 網頁授權取到的openid
   * @return
   */
  @ResponseBody
  public String getPrepayid(String out_trade_no1,String total_fee1,String openid1){
     
    String result = "";
     
    String appid = Common.appid;
    String mch_id = Common.mch_id;
    String nonce_str = Common.randString(16);//生成隨機數,可直接用系統提供的方法
    String body = "E光學-商品訂單";
    String out_trade_no = out_trade_no1;
    String total_fee = total_fee1;
    String spbill_create_ip = "xxx.xxx.38.47";//用戶端ip,這里隨意輸入的
    String notify_url = "http://www.xxxxxxx.cn/egxwx/wxpay_notify_url.jsp";//支付回調地址
    String trade_type = "JSAPI";
    String openid = openid1;
     
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("appid", appid);
    map.put("mch_id", mch_id);
    map.put("attach", "支付測試");
    map.put("device_info", "WEB");
    map.put("nonce_str", nonce_str);
    map.put("body", body);
    map.put("out_trade_no", out_trade_no);
    map.put("total_fee", total_fee);
    map.put("spbill_create_ip", spbill_create_ip);
    map.put("trade_type", trade_type);
    map.put("notify_url", notify_url);
    map.put("openid", openid);
    String sign = Common.sign(map, Common.MchSecret);//參數加密
    System.out.println("sign秘鑰:-----------"+sign);
    map.put("sign", sign);
    //組裝xml(wx就這么變態,非得加點xml在里面)
    String content=Common.MapToXml(map);
    //System.out.println(content);
    String PostResult=HttpClient.HttpsPost("https://api.mch.weixin.qq.com/pay/unifiedorder", content);
    JSONObject jsonObject=XmlUtil.XmlToJson(PostResult);//返回的的結果
    if(jsonObject.getString("return_code").equals("SUCCESS")&&jsonObject.getString("result_code").equals("SUCCESS")){
      result=jsonObject.get("prepay_id")+"";//這就是預支付id
    }
    return result;
  }

接下是簽名的方法(MD5加密是調用微信一個jar里面的,你也可以自己寫一個,網上很多參考):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
   * 生成簽名sign
   * 第一步:非空參數值的參數按照參數名ASCII碼從小到大排序,按照鍵值對的形式。生成字符串StringA
   * stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
   * 第二部:拼接API密鑰,這里的秘鑰是微信商戶平臺的秘鑰,是自己設置的,不是公眾號的秘鑰
   * stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d"
   * 第三部:MD5加密
   * sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7"
   *
   * @param map 不包含空字符串的map
   * @return
   */
  public static String sign(Map<String, String> map,String key) {
    //排序
    String sort=sortParameters(map);
    //拼接API秘鑰
    sort=sort+"&key="+key;
    //System.out.println(sort);
    //MD5加密
    String sign=MD5.MD5Encode(sort).toUpperCase();
    return sign;
  }
   
  /**
   * 對參數列表進行排序,并拼接key=value&key=value形式
   * @param map
   * @return
   */
  private static String sortParameters(Map<String, String> map) {
    Set<String> keys = map.keySet();
    List<String> paramsBuf = new ArrayList<String>();
    for (String k : keys) {
      paramsBuf.add((k + "=" + getParamString(map, k)));
    }
    // 對參數排序
    Collections.sort(paramsBuf);
    String result="";
    int count=paramsBuf.size();
    for(int i=0;i<count;i++){
      if(i<(count-1)){
        result+=paramsBuf.get(i)+"&";
      }else {
        result+=paramsBuf.get(i);
      }
    }
    return result;
  }
  /**
   * 返回key的值
   * @param map
   * @param key
   * @return
   */
  private static String getParamString(Map map, String key) {
    String buf = "";
    if (map.get(key) instanceof String[]) {
      buf = ((String[]) map.get(key))[0];
    } else {
      buf = (String) map.get(key);
    }
    return buf;
  }
  /**
   * 字符串列表從大到小排序
   * @param data
   * @return
   */
  private static List<String> sort(List<String> data) {
    Collections.sort(data, new Comparator<String>() {
      public int compare(String obj1, String obj2) {
        return obj1.compareTo(obj2);
      }
    });
    return data;
  }

Map轉XML的方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
   * Map轉Xml
   * @param arr
   * @return
   */
  public static String MapToXml(Map<String, String> arr) {
    String xml = "<xml>";
    Iterator<Entry<String, String>> iter = arr.entrySet().iterator();
    while (iter.hasNext()) {
      Entry<String, String> entry = iter.next();
      String key = entry.getKey();
      String val = entry.getValue();
      if (IsNumeric(val)) {
        xml += "<" + key + ">" + val + "</" + key + ">";
      } else
        xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">";
    }
    xml += "</xml>";
    return xml;
  }
  private static boolean IsNumeric(String str) {
    if (str.matches("\\d *")) {
      return true;
    } else {
      return false;
    }
  }

以上就是java實現微信H5支付的主要代碼了,大部分都有注釋,也沒有什么好解釋的了。希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/yttea/article/details/51954194

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 福利黄色| 国产一区网站 | 中文一区| 日本视频中文字幕 | 国产日韩欧美一区二区 | 国产精品视频久久久 | 97色伦97色伦国产欧美空 | 久久奸| 川上优av中文字幕一区二区 | 日韩在线色 | 欧美一级免费看 | 午夜视频 | 一区二区在线免费观看 | 韩日av在线免费观看 | 久久亚洲精品综合 | 亚洲一区在线视频 | 成年网站视频 | 狠狠干2024 | 丁香婷婷综合激情五月色 | 日韩精品欧美 | 日韩精品一区二 | 国产精选一区二区三区不卡催乳 | 国产激情在线视频 | 亚洲国产精品一区 | 亚洲精品永久免费 | 欧美影院| 免费污片网站 | 91在线看| 一区福利 | 天天射天天干 | 成年人激情视频 | 亚洲视频在线看 | 在线日本视频 | 免费成人福利视频 | 国产视频精品免费 | 欧美区在线 | 欧美福利视频 | 国产亚洲精品久久久久动 | 黄色在线 | 97国产超碰| 成人欧美一区二区三区在线播放 |