整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          一文快速實現(xiàn)微信公眾號支付功能(詳細版,建議收藏備用)

          階架構精品專題

          • Mysql優(yōu)化專題(★★★★)
          • 網(wǎng)絡協(xié)議專題(★★★★)
          • 其余18大專題,請在主頁菜單欄查看
          • 后臺回復【加群】,獲取BAT真實面經(jīng)




          微信支付類型

          微信支付實際上有很多種不同的類型,具體要使用哪一種就需要根據(jù)不同的應用場景來選擇,官方給出的參考例子:

          刷卡支付:用戶打開微信錢包的刷卡的界面,商戶掃碼后提交完成支付。

          公眾號支付:用戶在微信內(nèi)進入商家H5頁面,頁面內(nèi)調(diào)用JSSDK完成支付

          掃碼支付:用戶打開"微信掃一掃“,掃描商戶的二維碼后完成支付

          APP支付:商戶APP中集成微信SDK,用戶點擊后跳轉(zhuǎn)到微信內(nèi)完成支付

          H5支付:用戶在微信以外的手機瀏覽器請求微信支付的場景喚起微信支付

          小程序支付:用戶在微信小程序中使用微信支付的場景

          本篇文章實現(xiàn)的是公眾號支付,會使用到網(wǎng)頁授權及微信JS-SDK相關知識,但不再詳細介紹

          建議大家先閱讀以下文章了解相關內(nèi)容:

          網(wǎng)頁授權:https://www.jianshu.com/p/94b0e53cccc3

          微信JS-SDK:https://www.jianshu.com/p/b3c4450f845e

          實現(xiàn)效果如下動圖:


          公眾號支付相關配置

          本篇文章中實現(xiàn)的是公眾號支付,實現(xiàn)條件如下:

          1.需要一個已經(jīng)進行微信認證的公眾號


          2.該公眾號需要開通微信支付功能


          3.到微信商戶平臺https://pay.weixin.qq.com 注冊一個商戶賬號,并關聯(lián)你的公眾號,如果需要實現(xiàn)小程序支付的,需要關聯(lián)小程序。


          4.擁有一個正式的應用服務器,并且注冊域名

          微信支付涉及的私密數(shù)據(jù)比較多,不允許使用natapp,花生殼之類的內(nèi)網(wǎng)穿透工具實現(xiàn),需要有正式的服務器環(huán)境,并且要注冊域名,不能使用IP。

          比如:http://www.baidu.com

          5.相關配置

          5.1 配置支付授權目錄,登錄商戶平臺——>產(chǎn)品中心——>開發(fā)配置

          圖中配置的例子,代表在項目根路徑下,以及web目錄下的頁面都有支付權限,如果不在該路徑的頁面,則無法調(diào)用支付功能。

          若頁面地址為:http://mywexx.xxxx.com/web/pay.html

          則需要配置為:http://mywexx.xxxx.com/web/


          5.2 設置API密鑰,登錄商戶平臺——>賬戶中心——>API安全——>API密鑰

          該密鑰在后面的代碼中計算支付簽名的時候需要使用到。


          5.3 配置JS接口安全域名與網(wǎng)頁授權域名,登錄公眾平臺——>公眾號設置——>功能設置

          配置網(wǎng)頁授權域名:主要用于獲取用戶的openId,需要識別這是哪個人。

          若對openID不了解的同學可先參考微信公眾號開發(fā)文檔:https://mp.weixin.qq.com/wiki

          配置JS接口安全域名:要讓我們的頁面中彈出輸入密碼的窗口,需要使用微信提供的JS-SDK工具,如果不配置JS接口安全域名,你的頁面無法使用JS-SDK。


          公眾號支付實現(xiàn)流程

          大致流程參考官方提供的時序圖:


          流程有很多,不一一演示,我們選取核心部分來實現(xiàn)。

          1.提供商城主頁,用戶進入后通過網(wǎng)頁授權獲取openid


          如果對網(wǎng)頁授權不熟悉的同學先參考這篇文章:

          https://www.jianshu.com/p/94b0e53cccc3

          訪問主頁的地址:http://www.wolfcode.cn/index.do

          當用戶第一次打開主頁,默認沒有code參數(shù),此時會先重定向到獲取授權的地址

          (如果只需要獲取openid,可以使用scope為snsapi_base靜默授權的方式)

          經(jīng)過授權地址再重定向到我們的index.do時,會帶上code參數(shù),此時即可通過接口獲取用戶的openid

          @Controllerpublic class IndexController { @RequestMapping("index") public void index(String code, Model model, HttpServletResponse response,HttpServletRequest request) { //如果有code就可以去獲取用戶的openid
           if(code!=null) { //通過code來換取access_token
           JSONObject json = WeChatUtil.getWebAccessToken(code); //獲取用戶openid
           String openid = json.getString("openid"); //設置到會話中
           request.getSession().setAttribute("openid",openid); //重定向到主頁
           response.sendRedirect("/index.html");
           }else{ //重定向到授權頁面
           response.sendRedirect(WeChatUtil.WEB_REDIRECT_URL.replace("APPID",WeChatUtil.APPID)
           .replace("REDIRECT_URI", RequestUtil.getUrl(request)));
           }
           }
          }
          注意: 1. WeChatUtil.getWebAccessToken 方法在網(wǎng)頁授權的文章中有介紹。 
          2. WEB_REDIRECT_URL 是網(wǎng)頁授權的地址常量:
          public static final String WEB_REDIRECT_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
           "appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base#wechat_redirect";
          

          2.點擊商品后跳轉(zhuǎn)到商品詳細頁面

          具體頁面根據(jù)自己的項目添加,主要是頁面需要提供一個可以馬上下訂單的按鈕即可。(這里不演示加入購物車功能)


          點擊立即購買按鈕跳轉(zhuǎn)到后臺下單地址,并帶上當前商品的id。

          <script>
           $(function () { //立即購買按鈕
           $("#orderBtn").click(function(){ //獲取商品id
           var id = $("#productId").val(); //提交到下單
           window.location.href = "/order.do?productId="+id;
           })
           })</script>
          

          3.接收商品參數(shù)并調(diào)用微信支付統(tǒng)一下單接口

          正常的業(yè)務流程是在該方法中,獲取商品id,再通過id去查詢數(shù)據(jù)庫該商品的相關屬性,比如名稱,價格等等,然后再創(chuàng)建業(yè)務訂單,再去調(diào)用微信支付的統(tǒng)一下單接口(讓微信生成預支付單,后續(xù)才可以進行支付)。

          但此處重點在支付流程,商品的屬性值和訂單相關值,暫且先使用假數(shù)據(jù)。

          接口以及參數(shù)可參考微信官方提供的統(tǒng)一下單文檔:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

          根據(jù)文檔介紹,我們調(diào)用統(tǒng)一下單接口時需要帶上相關必填的參數(shù)如下:


          1.PNG

          把必填的參數(shù)封裝成對應的實體類:



          調(diào)用接口成功后返回的結果也封裝成實體類:



          該結果中最重要的是prepay_id參數(shù),在頁面中彈出支付窗口時需要用到。


          注意:下單的業(yè)務邏輯,正常是需要抽取到業(yè)務層的,但是此處為了方便閱讀代碼,直接寫到了控制器上。

          @Controllerpublic class OrderController { @RequestMapping("order") public String save(Long productId,Model model,HttpServletRequest request) throws Exception { //根據(jù)商品id查詢商品詳細信息(假數(shù)據(jù))
           //productService.getProductById(productId)
           double price = 0.01;//(0.01元)
           String productName = "SweetCity"; //生成訂單編號
           int number = (int)((Math.random()*9)*1000);//隨機數(shù)
           DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");//時間
           String orderNumber = dateFormat.format(new Date()) + number; //獲取openId
           String openId = (String) request.getSession().getAttribute("openid"); //準備調(diào)用接口需要的參數(shù)
           WxOrderEntity order = new WxOrderEntity(); //公眾號appid
           order.setAppid(WeChatUtil.APPID); //商戶號
           order.setMch_id(WeChatUtil.MCH_ID); //商品描述
           order.setBody(productName); //設備號,公眾號支付直接填WEB
           order.setDevice_info("WEB"); //交易類型
           order.setTrade_type("JSAPI"); //商戶訂單號
           order.setOut_trade_no(orderNumber); //支付金額(單位:分)
           order.setTotal_fee((int)(price*100)); //用戶ip地址
           order.setSpbill_create_ip(RequestUtil.getIPAddress(request)); //用戶openid
           order.setOpenid(openId); //接收支付結果的地址
           order.setNotify_url("http://www.wolfcode.com/receive.do"); //32位隨機數(shù)(UUID去掉-就是32位的)
           String uuid = UUID.randomUUID().toString().replace("-", "");
           order.setNonce_str(uuid); //生成簽名
           String sign = WeChatUtil.getPaySign(order);
           order.setSign(sign); //調(diào)用微信支付統(tǒng)一下單接口,讓微信也生成一個預支付訂單
           String xmlResult = HttpUtil.post(GET_PAY_URL,XMLUtil.toXmlString(order)); //把返回的xml字符串轉(zhuǎn)成對象
           WxOrderResultEntity entity = XMLUtil.toObject(xmlResult,WxOrderResultEntity.class); //如果微信預支付單成功創(chuàng)建,就跳轉(zhuǎn)到支付訂單頁進行支付
           if(entity.getReturn_code().equals("SUCCESS")&&entity.getResult_code().equals("SUCCESS")){ //jssdk權限驗證參數(shù)
           TreeMap<Object, Object> map = new TreeMap<>();
           map.put("appId",WeChatUtil.APPID); long timestamp = new Date().getTime();
           map.put("timestamp",timestamp);//全小寫
           map.put("nonceStr",uuid);
           map.put("signature",WeChatUtil.getSignature(timestamp,uuid,RequestUtil.getUrl(request)));
           model.addAttribute("configMap",map); //微信支付權限驗證參數(shù)
           String prepayId = entity.getPrepay_id();
           TreeMap<Object, Object> payMap = new TreeMap<>();
           payMap.put("appId",WeChatUtil.APPID);
           payMap.put("timeStamp",timestamp);//駝峰
           payMap.put("nonceStr",uuid);
           payMap.put("package","prepay_id="+prepayId);
           payMap.put("signType","MD5");
           payMap.put("paySign",WeChatUtil.getPaySign(payMap));
           payMap.put("packageStr","prepay_id="+prepayId);
           model.addAttribute("payMap",payMap);
           } //跳轉(zhuǎn)到查看訂單頁面
           return "order";
           }
          }
          

          下面是jssdk中config權限使用到的的簽名,以及微信支付使用的簽名的算法代碼。

          官方文檔參考:

          config簽名:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

          pay簽名:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

          /**
           * 計算jssdk-config的簽名
           * @param timestamp
           * @param noncestr
           * @param url
           * @return
           */
           public static String getSignature(Long timestamp,String noncestr,String url ){ //對所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)
           Map<String,Object> map = new TreeMap<>();
           map.put("jsapi_ticket",getTicket());
           map.put("timestamp",timestamp);
           map.put("noncestr",noncestr);
           map.put("url",url); //使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1
           StringBuilder sb = new StringBuilder();
           Set<String> set = map.keySet(); for (String key : set) {
           sb.append(key+"="+map.get(key)).append("&");
           } //去掉最后一個&符號
           String temp = sb.substring(0,sb.length()-1); //使用sha1加密
           return SecurityUtil.SHA1(temp);
           } /**
           * 計算微信支付的簽名
           * @param obj
           * @return
           * @throws IllegalAccessException
           */
           public static String getPaySign(Object obj) throws IllegalAccessException, IOException {
           StringBuilder sb = new StringBuilder(); //把對象轉(zhuǎn)為TreeMap集合(按照key的ASCII 碼從小到大排序)
           TreeMap<String, Object> map; if(!(obj instanceof Map)) {
           map = ObjectUtils.objectToMap(obj);
           }else{
           map = (TreeMap)obj;
           }
           Set<Map.Entry<String, Object>> entrySet = map.entrySet(); //遍歷鍵值對
           for (Map.Entry<String, Object> entry : entrySet) { //如果值為空,不參與簽名
           if(entry.getValue()!=null) { //格式key1=value1&key2=value2…
           sb.append(entry.getKey() + "=" + entry.getValue() + "&");
           }
           } //最后拼接商戶的API密鑰
           String stringSignTemp = sb.toString()+"key="+WeChatUtil.KEY; //進行md5加密并轉(zhuǎn)為大寫
           return SecurityUtil.MD5(stringSignTemp).toUpperCase();
           }
          

          4.提供訂單展示頁面


          若對微信JS-SDK不了解的同學可先參考該文章:

          https://www.jianshu.com/p/b3c4450f845e

          在頁面中調(diào)用微信JS-SDK,通過config接口注入權限驗證配置,并且添加支付功能。

          <!--jquery-->
           <script src="/js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
           <!--微信的JSSDK-->
           <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
           <script>
           $(function() {
           <!--通過config接口注入權限驗證配置-->
           wx.config({ debug: true, // 開啟調(diào)試模式
           appId: '${configMap.appId}', // 公眾號的唯一標識
           timestamp: '${configMap.timestamp}', // 生成簽名的時間戳
           nonceStr: '${configMap.nonceStr}', // 生成簽名的隨機串
           signature: '${configMap.signature}',// 簽名
           jsApiList: ['chooseWXPay'] // 填入需要使用的JS接口列表,這里是先聲明我們要用到支付的JS接口
           }); <!-- config驗證成功后會調(diào)用ready中的代碼 -->
           wx.ready(function(){
           //點擊馬上付款按鈕
           $("#payBtn").click(function(){
           //彈出支付窗口
           wx.chooseWXPay({
           timestamp: '${payMap.timeStamp}', // 支付簽名時間戳,
           nonceStr: '${payMap.nonceStr}', // 支付簽名隨機串,不長于 32 位
           package: '${payMap.packageStr}', // 統(tǒng)一支付接口返回的prepay_id參數(shù)值,提交格式如:prepay_id=xxxx)
           signType: '${payMap.signType}', // 簽名方式,默認為'SHA1',使用新版支付需傳入'MD5'
           paySign: '${payMap.paySign}', // 支付簽名
           success: function (res) {
           // 支付成功后的回調(diào)函數(shù)
           alert("支付成功!");
           }
           });
           })
           });
           }); </script>
          

          點擊馬上付款后可彈出支付窗口:


          支付完成:


          5.支付結果的處理

          當用戶支付后,微信會把支付結果發(fā)送到我們前面指定的notify_url地址,我們可以根據(jù)支付結果的參數(shù)來做相關的業(yè)務邏輯,但這里暫不實現(xiàn),具體支付通知結果的參數(shù)可參考官方文章:

          https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7&index=8

          作者:陳惠

          鏈接:https://www.jianshu.com/p/9c322b1a5274

          國黨建網(wǎng) https://www.ahdj.gov.cn/por/login_psw.csp?rnd=0.1195575743615227#https%3A%2F%2Fwww.ahdj.gov.cn%2F

          共產(chǎn)黨員網(wǎng) http://www.12371.cn/

          189郵箱 https://webmail30.189.cn/w2/

          交黨費 https://partyfee.bestpay.com.cn/sys/index

          安徽本地發(fā)票驗證 https://etax.anhui.chinatax.gov.cn/fpbl/view/fpxxCx

          發(fā)票真?zhèn)尾樵?https://inv-veri.chinatax.gov.cn/

          中共中央紀律檢查委員會 http://www.ccdi.gov.cn/


          共產(chǎn)黨員網(wǎng) http://www.12371.cn/

          鐵塔監(jiān)控 http://180.153.49.130:9000/baf/jsp/uiframe/login.jsp

          鐵塔四費 http://120.52.120.164:8080/ahttreportweb/finedo/auth/loginindex

          發(fā)票查驗系統(tǒng) https://www.51fapiao.cn/

          天翼云省公司門戶登錄系統(tǒng) https://cmp.ctyun.cn/cas/login

          安徽電信官方招聘網(wǎng)址 http://www.zhaopin.ahtelecom.com.cn/

          穩(wěn)崗補貼 http://61.190.31.165:7006/index.html

          養(yǎng)老網(wǎng)址 http://61.190.31.167:9009/volanst/logonDialog_267.jsp

          統(tǒng)一社會信用代碼查詢 https://www.cods.org.cn/

          智能廣播管理平臺 http://60.173.83.175:8090/ts/login.do

          中國電信精品門店銷售系統(tǒng) https://jpqd.crm.189.cn/psm/

          稅務發(fā)票查驗網(wǎng)址 https://etax.anhui.chinatax.gov.cn/fpbl/view/fpxxCx

          陽光采購 https://caigou.chinatelecom.com.cn/MSS-PORTAL/account/login.do


          全國黨建網(wǎng) https://www.ahdj.gov.cn/por/login_psw.csp?rnd=0.1195575743615227#https%3A%2F%2Fwww.ahdj.gov.cn%2F

          國家稅務總局全國增值稅發(fā)票查驗平臺 https://inv-veri.chinatax.gov.cn/#

          安徽省就業(yè)失業(yè)動態(tài)監(jiān)測網(wǎng)上直報系統(tǒng) http://124.127.118.122/anhuiss/

          銅陵社保網(wǎng)上服務大廳 http://218.23.50.229:8015/index/index.html

          安徽省陽光就業(yè)網(wǎng) http://61.190.31.165:7006/

          電商采購平臺 https://www.ztf58.cn/login

          安徽省招生考試院 https://www.ahzsks.cn/index.htm

          安徽政務服務網(wǎng) https://www.ahzwfw.gov.cn/

          國家企業(yè)信用信息公示系統(tǒng) http://www.gsxt.gov.cn/corp-query-homepage.html

          安徽省應急管理廳 http://yjt.ah.gov.cn/

          省消防救援總隊 http://www.ah119.cn/ 51發(fā)票 https://www.51fapiao.cn/

          翼支付繳黨費系統(tǒng) https://partyfee.bestpay.com.cn/sys/login

          網(wǎng)廳代客下單 http://ah.189.cn/netup/bootkds/login?

          安徽電信網(wǎng)上營業(yè)廳 http://www.189.cn/ah/

          天翼積分商城 http://y.jf.189.cn/home/index.html

          網(wǎng)廳電子發(fā)票打印頁面 http://ah.189.cn/cms/r/cms/ah/default/v2016/electronicInvoice/elecInv.html 全國黨員管理信息系統(tǒng) https://ahdj.gov.cn/por/service.csp#


          美橙域名查詢(whois) https://whois.cndns.com/

          社會組織代碼證查詢 https://www.cods.org.cn/


          目中遇到一個需要微信獲取code支付,其中遇到很多問題,現(xiàn)在做一下總結。


          一、進入頁面獲取code:



          二、截取code:


          ?


          主站蜘蛛池模板: 亚洲伦理一区二区| 91精品一区国产高清在线| 色欲AV无码一区二区三区| 国产伦精品一区二区三区精品| 亚洲爆乳无码一区二区三区| 国产成人一区在线不卡| 免费日本一区二区| 亚洲AV香蕉一区区二区三区| 综合人妻久久一区二区精品 | 亚洲一区二区三区高清| 亚洲日韩AV一区二区三区四区| 精品国产一区二区三区香蕉| 精品人妻一区二区三区四区在线 | 伊人色综合一区二区三区影院视频| 学生妹亚洲一区二区| 精品视频午夜一区二区| 亚洲一区二区三区夜色| 国产精品一区二区在线观看| 成人无码一区二区三区| 亚洲日本va一区二区三区| 亚洲AV无码一区二三区| 精品国产一区二区三区麻豆| 日本韩国黄色一区二区三区| 久久伊人精品一区二区三区| 欧洲精品一区二区三区在线观看 | 香蕉免费一区二区三区| 怡红院美国分院一区二区 | 精品一区二区三区色花堂| 国产福利一区二区三区视频在线| 国产成人精品无码一区二区老年人| 亚洲线精品一区二区三区影音先锋| 亚洲日韩精品国产一区二区三区| 久久AAAA片一区二区| 国产微拍精品一区二区| 九九久久99综合一区二区| 日本韩国黄色一区二区三区| 亚洲视频一区二区三区四区| 国产一区二区精品久久岳| 无码国产精品一区二区高潮| 少妇人妻精品一区二区三区| 精品成人一区二区三区四区|