Java將微信和支付寶支付的個(gè)二維碼合二為一的方法
因公司需要將支付寶和微信的二維碼合成一個(gè),不管用戶用支付寶掃還是微信掃都能打開對(duì)應(yīng)的支付頁(yè)面,在網(wǎng)上找了一些文章,很感謝各位大神的經(jīng)驗(yàn),我也記錄下我是如何將兩個(gè)二維碼合二為一的~。
原理:支付寶或微信生成的二維碼中本質(zhì)都內(nèi)嵌了一個(gè)url,在掃碼時(shí)實(shí)際是定向去訪問二維碼中內(nèi)嵌的url,這樣我就可以將這個(gè)url指定到我的一個(gè)控制器,在控制器中判斷是微信還是支付寶軟件掃的,然后去喚醒各自的支付即可。
1.首先生成二維碼:
folderName:存儲(chǔ)二維碼圖片的文件夾名
imageName:二維碼圖片名稱
content:是在二維碼中寫入的內(nèi)容,這里我傳入的是URL:指定我判斷軟件類型的控制器
public static String genQRImage(String folderName, String imageName, String content) { //String filePath = System.getProperty("twtwebapp.root"); String fileName = imageName + ".png"; try { // 檢查是否存在imageQR目錄,不存在則先創(chuàng)建 File file = new File(folderName); if (!file.exists() && !file.isDirectory()) { file.mkdir(); } folderName = file.getAbsolutePath(); int width = 200; // 圖像寬度 int height = 200; // 圖像高度 String format = "png";// 圖像類型 Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);// 生成矩陣 Path path = FileSystems.getDefault().getPath(folderName, fileName); MatrixToImageWriter.writeToPath(bitMatrix, format, path);// 輸出圖像 log.info("二維碼已經(jīng)生成," + path); fileName = path.toString(); } catch (Exception e) { log.error(e.getMessage(), e); fileName = null; } return fileName; }
2.定義類型控制器:
大家一定都想問是如何判斷打開軟件的類型,把Request Header Cookie 都看看就明白了,掃碼二維碼時(shí)不會(huì)傳入任何參數(shù),
但會(huì)有一個(gè)請(qǐng)求頭,就是這個(gè)請(qǐng)求頭告知了我打開軟件的類型。
使用request獲取名為User-Agent的請(qǐng)求頭,
支付寶的請(qǐng)求頭: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
微信的請(qǐng)求頭: mqqbrowser/6.8 tbs/036887 safari/537.36 micromessenger/6.3.31.940 nettype/wifi language/zh_cn
就是根據(jù)這兩個(gè)請(qǐng)求頭去判斷對(duì)應(yīng)的軟件類型,根據(jù)不同的軟件類型去喚醒不同的支付。
@RequestMapping("qrcallback") public void qrcallback(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException { String agent = request.getHeader("User-Agent").toLowerCase(); System.out.println("響應(yīng)頭的類型:"+agent); if (agent.indexOf("micromessenger") > 0) { System.out.println("微信支付"); } else if (agent.indexOf("alipayclient") > 0) { System.out.println("阿里支付"); String form = testService.aliPay(); response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(form);//直接將完整的表單html輸出到頁(yè)面 response.getWriter().flush(); // response.sendRedirect("/ali.html"); } }
3.先說簡(jiǎn)單的,喚醒支付寶支付,其實(shí)使用的是 支付寶手機(jī)網(wǎng)站支付:這個(gè)需要簽約噢~
https://b.alipay.com/signing/productDetail.htm?productId=I1011000290000001001
這個(gè)喚起支付可以看看官網(wǎng)是怎么寫的:https://doc.open.alipay.com/docs/doc.htm?treeId=203&articleId=105285&docType=1
有兩種方式:一種是頁(yè)面喚醒,自己構(gòu)建請(qǐng)求form參數(shù)然后請(qǐng)求支付寶喚醒支付操作,另一種是服務(wù)端調(diào)用支付寶的SDK去生
成form參數(shù)然后去請(qǐng)求支付寶,我使用的是第二種。
步驟:
1.首先引入pom.xml依賴
<!-- alipay-sdk --> <dependency> <groupId>com.twt.charge</groupId> <artifactId>alipay-sdk-java</artifactId> <version>20160519120058</version> </dependency>
2.生成form參數(shù):
里面的參數(shù)自己填寫從支付寶獲取的那些參數(shù),copy我的肯定出錯(cuò)哈
public String aliPay() throws AlipayApiException { AlipayClient alipayClient = new DefaultAlipayClient(openapi, SecurityUtil.decodeBase64(appid), SecurityUtil.decodeBase64(rsa_private_key), "json", "utf-8", SecurityUtil.decodeBase64(alipay_pub_key)); AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();// 創(chuàng)建API對(duì)應(yīng)的request alipayRequest.setReturnUrl("http://192.168.1.219:22222/ali.html"); alipayRequest.setNotifyUrl("http://192.168.1.219:22222/callback");// 在公共參數(shù)中設(shè)置回跳和通知地址 alipayRequest.setBizContent("{" + " \"out_trade_no\":\"20160320020192222\"," + " \"total_amount\":66.66," + " \"subject\":\"主題\"," + " \"seller_id\":\"213215dsa\"," + // " \"product_code\":\"QUICK_WAP_PAY\"" + " }");// 填充業(yè)務(wù)參數(shù) String form = alipayClient.pageExecute(alipayRequest).getBody(); // 調(diào)用SDK生成表單 return form; }
將這個(gè)form以流的形式輸出即可。
如:
response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(form);//直接將完整的表單html輸出到頁(yè)面 response.getWriter().flush();
喚起支付寶支付就這么簡(jiǎn)單,但要注意參數(shù)中的賬單號(hào)要是商戶系統(tǒng)中唯一的賬單號(hào)。
4.喚起微信支付:?jiǎn)酒鸬钠鋵?shí)是微信公眾號(hào)支付,做過公眾號(hào)支付的同學(xué)都知道,調(diào)用微信公眾號(hào)的統(tǒng)一下單API時(shí)
需要傳入openID,即用戶在該公眾號(hào)的下的唯一標(biāo)識(shí),這個(gè)過程需要用于授權(quán)登錄該公眾號(hào),這個(gè)過程是一個(gè)缺點(diǎn),
用戶僅僅只是微信的掃碼支付,但你中間不是黑箱子的形式展示,而是在支付中多出了一個(gè)授權(quán)登錄的頁(yè)面,并且
也比較繁瑣,在喚醒微信支付的過程中請(qǐng)求次數(shù)較多,所以微信支付會(huì)比正在的掃碼支付會(huì)慢很多。
喚起微信公眾號(hào)支付:
步驟:
1.首先拼裝好你的授權(quán)登錄url。在類型控制中判斷如果是微信支付則重定向到微信授權(quán)登錄頁(yè)面,微信會(huì)重定向到
你在授權(quán)登錄url中設(shè)置重定向url參數(shù)的頁(yè)面,
2.跳轉(zhuǎn)到這個(gè)頁(yè)面后,先獲取到用戶code然后利用ajax訪問服務(wù)端,
3.服務(wù)端使用code去獲取用戶的openID,
4.根據(jù)openID去調(diào)用微信公眾號(hào)的統(tǒng)一下單API生成參數(shù),然后返回給頁(yè)面喚醒支付,這就是整個(gè)微信的流程,
中間訪問了3次微信獲取數(shù)據(jù),整個(gè)流程共6次請(qǐng)求,需要將微信跳轉(zhuǎn)的頁(yè)面放到官網(wǎng)的微信目錄下。
在寫這篇博文的時(shí)候因?yàn)橹Ц秾毼疫€沒有簽約,所以沒有調(diào)通,而微信也只成功了一次,但第二次什么都沒改的情況
下就不行了,寫這篇博文順便捋捋思路,怎么更簡(jiǎn)單。
注:訪問微信授權(quán)頁(yè)面中的redirect_url參數(shù)可以添加請(qǐng)求參數(shù)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- js中調(diào)用微信的掃描二維碼功能的實(shí)現(xiàn)代碼
- 微信小程序?qū)崿F(xiàn)二維碼簽到考勤系統(tǒng)
- 微信小程序 生成攜帶參數(shù)的二維碼
- 微信小程序點(diǎn)擊圖片實(shí)現(xiàn)長(zhǎng)按預(yù)覽、保存、識(shí)別帶參數(shù)二維碼、轉(zhuǎn)發(fā)等功能
- 微信小程序掃描二維碼獲取信息實(shí)例詳解
- 微信小程序生成二維碼的示例代碼
- Python提取支付寶和微信支付二維碼的示例代碼
- 微信小程序webview實(shí)現(xiàn)長(zhǎng)按點(diǎn)擊識(shí)別二維碼功能示例
- 基于binarywang封裝的微信工具包生成二維碼
相關(guān)文章
Java使用Lettuce客戶端在Redis在主從復(fù)制模式下命令執(zhí)行的操作
這篇文章主要介紹了Java使用Lettuce客戶端在Redis在主從復(fù)制模式下命令執(zhí)行的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04詳解Java動(dòng)態(tài)加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)
本篇文章主要介紹了詳解Java動(dòng)態(tài)加載數(shù)據(jù)庫(kù)驅(qū)動(dòng),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05java實(shí)現(xiàn)在SSM下使用支付寶掃碼支付功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)在SSM下使用支付寶掃碼支付功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02如何修改FeginCilent定義的服務(wù)名到指定服務(wù)
這篇文章主要介紹了修改FeginCilent定義的服務(wù)名到指定服務(wù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java利用HttpClient模擬POST表單操作應(yīng)用及注意事項(xiàng)
本文主要介紹JAVA中利用HttpClient模擬POST表單操作,希望對(duì)大家有所幫助。2016-04-04java全角、半角字符的關(guān)系以及轉(zhuǎn)換詳解
這篇文章主要介紹了2013-11-11