[轉]將微信和支付寶支付的個二維碼合二爲一

本文轉自:http://www.javashuo.com/article/p-sisebraj-o.htmlhtml

因公司須要將支付寶和微信的二維碼合成一個,無論用戶用支付寶掃仍是微信掃都能打開對應的支付頁面,在網上找了一些文章,很感謝各位大神的經驗,我也記錄下我是如何將兩個二維碼合二爲一的~。java

原理:支付寶或微信生成的二維碼中本質都內嵌了一個url,在掃碼時實際是定向去訪問二維碼中內嵌的url,這樣我就能夠將這個url指定到個人一個控制器,在控制器中判斷是微信仍是支付寶軟件掃的,而後去喚醒各自的支付便可。web

 

1.首先生成二維碼:ajax

folderName:存儲二維碼圖片的文件夾名json

imageName:二維碼圖片名稱api

content:是在二維碼中寫入的內容,這裏我傳入的是URL:指定我判斷軟件類型的控制器微信

 

[java]  view plain  copy
 
  1. public static String genQRImage(String folderName, String imageName, String content) {  
  2.         //String filePath = System.getProperty("twtwebapp.root");  
  3.         String fileName = imageName + ".png";  
  4.   
  5.         try {  
  6.   
  7.             // 檢查是否存在imageQR目錄,不存在則先建立  
  8.             File file = new File(folderName);  
  9.             if (!file.exists() && !file.isDirectory()) {  
  10.                 file.mkdir();  
  11.             }  
  12.             folderName = file.getAbsolutePath();  
  13.   
  14.             int width = 200; // 圖像寬度  
  15.             int height = 200; // 圖像高度  
  16.             String format = "png";// 圖像類型  
  17.   
  18.             Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();  
  19.             hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
  20.             hints.put(EncodeHintType.MARGIN, 1);  
  21.             BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);// 生成矩陣  
  22.             Path path = FileSystems.getDefault().getPath(folderName, fileName);  
  23.             MatrixToImageWriter.writeToPath(bitMatrix, format, path);// 輸出圖像  
  24.             log.info("二維碼已經生成," + path);  
  25.             fileName = path.toString();  
  26.   
  27.         } catch (Exception e) {  
  28.             log.error(e.getMessage(), e);  
  29.             fileName = null;  
  30.         }  
  31.         return fileName;  
  32.     }  

 

 

2.定義類型控制器:app

你們必定都想問是如何判斷打開軟件的類型,把Request Header Cookie 都看看就明白了,掃碼二維碼時不會傳入任何參數,webapp

但會有一個請求頭,就是這個請求頭告知了我打開軟件的類型。微信支付

使用request獲取名爲User-Agent的請求頭,

支付寶的請求頭:ucbrowser/1.0.0.100 u3/0.8.0 mobile safari/534.30 alipaydefined(nt:wifi,ws:360|604|3.0) aliapp(ap/9.9.7.112401) alipayclient/9.9.7.112401 language/zh-hans usestatusbar/true

微信的請求頭: mqqbrowser/6.8 tbs/036887 safari/537.36 micromessenger/6.3.31.940 nettype/wifi language/zh_cn

就是根據這兩個請求頭去判斷對應的軟件類型,根據不一樣的軟件類型去喚醒不一樣的支付。

 

[java]  view plain  copy
 
  1. @RequestMapping("qrcallback")  
  2.     public void qrcallback(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {  
  3.               
  4.         String agent = request.getHeader("User-Agent").toLowerCase();  
  5.         System.out.println("響應頭的類型:"+agent);  
  6.         if (agent.indexOf("micromessenger") > 0) {  
  7.             System.out.println("微信支付");           
  8.         } else if (agent.indexOf("alipayclient") > 0) {  
  9.             System.out.println("阿里支付");  
  10.               
  11.             String form = testService.aliPay();  
  12.             response.setContentType("text/html;charset=UTF-8");  
  13.             response.getWriter().write(form);//直接將完整的表單html輸出到頁面  
  14.             response.getWriter().flush();  
  15. //          response.sendRedirect("/ali.html");  
  16.         }         
  17.     }  

 

 

3.先說簡單的,喚醒支付寶支付,其實使用的是 支付寶手機網站支付:這個須要簽約噢~

https://b.alipay.com/signing/productDetail.htm?productId=I1011000290000001001

這個喚起支付能夠看看官網是怎麼寫的:https://doc.open.alipay.com/docs/doc.htm?treeId=203&articleId=105285&docType=1

有兩種方式:一種是頁面喚醒,本身構建請求form參數而後請求支付寶喚醒支付操做,另外一種是服務端調用支付寶的SDK去生

成form參數而後去請求支付寶,我使用的是第二種。

步驟:{

1.首先引入pom.xml依賴

 

[html]  view plain  copy
 
  1. <span style="white-space:pre;">     </span><!-- alipay-sdk -->  
  2.         <dependency>  
  3.             <groupId>com.twt.charge</groupId>  
  4.             <artifactId>alipay-sdk-java</artifactId>  
  5.             <version>20160519120058</version>  
  6.         </dependency>  


2.生成form參數:

 

裏面的參數本身填寫從支付寶獲取的那些參數,copy個人確定出錯哈

 

[java]  view plain  copy
 
  1. public String aliPay() throws AlipayApiException {  
  2.         AlipayClient alipayClient = new DefaultAlipayClient(openapi, SecurityUtil.decodeBase64(appid),  
  3.                 SecurityUtil.decodeBase64(rsa_private_key), "json", "utf-8", SecurityUtil.decodeBase64(alipay_pub_key));  
  4.         AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();// 建立API對應的request  
  5.         alipayRequest.setReturnUrl("http://192.168.1.219:22222/ali.html");  
  6.         alipayRequest.setNotifyUrl("http://192.168.1.219:22222/callback");// 在公共參數中設置回跳和通知地址  
  7.         alipayRequest.setBizContent("{" + "    \"out_trade_no\":\"20160320020192222\"," + "    \"total_amount\":66.66,"  
  8.                 + "    \"subject\":\"主題\"," + "    \"seller_id\":\"213215dsa\"," +  
  9.                 // " \"product_code\":\"QUICK_WAP_PAY\"" +  
  10.                 "  }");// 填充業務參數  
  11.         String form = alipayClient.pageExecute(alipayRequest).getBody(); // 調用SDK生成表單  
  12.   
  13.         return form;  
  14.     }  

將這個form以流的形式輸出便可。

 

如:

 

[java]  view plain  copy
 
  1. <span style="white-space:pre;">     </span>response.setContentType("text/html;charset=UTF-8");  
  2.         response.getWriter().write(form);//直接將完整的表單html輸出到頁面  
  3.         response.getWriter().flush();  

 

 

喚起支付寶支付就這麼簡單,但要注意參數中的帳單號要是商戶系統中惟一的帳單號。

 

4.喚起微信支付:喚起的實際上是微信公衆號支付,作過公衆號支付的同窗都知道,調用微信公衆號的統一下單API時

須要傳入openID,即用戶在該公衆號的下的惟一標識,這個過程須要用於受權登陸該公衆號,這個過程是一個缺點,

用戶僅僅只是微信的掃碼支付,但你中間不是黑箱子的形式展現,而是在支付中多出了一個受權登陸的頁面,而且

也比較繁瑣,在喚醒微信支付的過程當中請求次數較多,因此微信支付會比正在的掃碼支付會慢不少。

 

喚起微信公衆號支付:{

步驟:

 

 

1.首先拼裝好你的受權登陸url。在類型控制中判斷若是是微信支付則重定向到微信受權登陸頁面,微信會重定向到

你在受權登陸url中設置重定向url參數的頁面,

2.跳轉到這個頁面後,先獲取到用戶code而後利用ajax訪問服務端,

3.服務端使用code去獲取用戶的openID,

4.根據openID去調用微信公衆號的統一下單API生成參數,而後返回給頁面喚醒支付,這就是整個微信的流程,

中間訪問了3次微信獲取數據,整個流程共6次請求,須要將微信跳轉的頁面放到官網的微信目錄下。

在寫這篇博文的時候由於支付寶我尚未簽約,因此沒有調通,而微信也只成功了一次,但第二次什麼都沒改的狀況

下就不行了,寫這篇博文順便捋捋思路,怎麼更簡單。

 

注:訪問微信受權頁面中的redirect_url參數能夠添加請求參數。

相關文章
相關標籤/搜索