Java將微信和支付寶支付的個二維碼合二為一的方法
因公司需要將支付寶和微信的二維碼合成一個,不管用戶用支付寶掃還是微信掃都能打開對應的支付頁面,在網(wǎng)上找了一些文章,很感謝各位大神的經(jīng)驗,我也記錄下我是如何將兩個二維碼合二為一的~。
原理:支付寶或微信生成的二維碼中本質(zhì)都內(nèi)嵌了一個url,在掃碼時實際是定向去訪問二維碼中內(nèi)嵌的url,這樣我就可以將這個url指定到我的一個控制器,在控制器中判斷是微信還是支付寶軟件掃的,然后去喚醒各自的支付即可。
1.首先生成二維碼:
folderName:存儲二維碼圖片的文件夾名
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ù),
但會有一個請求頭,就是這個請求頭告知了我打開軟件的類型。
使用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
就是根據(jù)這兩個請求頭去判斷對應的軟件類型,根據(jù)不同的軟件類型去喚醒不同的支付。
@RequestMapping("qrcallback")
public void qrcallback(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
String agent = request.getHeader("User-Agent").toLowerCase();
System.out.println("響應頭的類型:"+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輸出到頁面
response.getWriter().flush();
// response.sendRedirect("/ali.html");
}
}
3.先說簡單的,喚醒支付寶支付,其實使用的是 支付寶手機網(wǎng)站支付:這個需要簽約噢~
https://b.alipay.com/signing/productDetail.htm?productId=I1011000290000001001
這個喚起支付可以看看官網(wǎng)是怎么寫的:https://doc.open.alipay.com/docs/doc.htm?treeId=203&articleId=105285&docType=1
有兩種方式:一種是頁面喚醒,自己構(gòu)建請求form參數(shù)然后請求支付寶喚醒支付操作,另一種是服務端調(diào)用支付寶的SDK去生
成form參數(shù)然后去請求支付寶,我使用的是第二種。
步驟:
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我的肯定出錯哈
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對應的request
alipayRequest.setReturnUrl("http://192.168.1.219:22222/ali.html");
alipayRequest.setNotifyUrl("http://192.168.1.219:22222/callback");// 在公共參數(shù)中設置回跳和通知地址
alipayRequest.setBizContent("{" + " \"out_trade_no\":\"20160320020192222\"," + " \"total_amount\":66.66,"
+ " \"subject\":\"主題\"," + " \"seller_id\":\"213215dsa\"," +
// " \"product_code\":\"QUICK_WAP_PAY\"" +
" }");// 填充業(yè)務參數(shù)
String form = alipayClient.pageExecute(alipayRequest).getBody(); // 調(diào)用SDK生成表單
return form;
}
將這個form以流的形式輸出即可。
如:
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(form);//直接將完整的表單html輸出到頁面
response.getWriter().flush();
喚起支付寶支付就這么簡單,但要注意參數(shù)中的賬單號要是商戶系統(tǒng)中唯一的賬單號。
4.喚起微信支付:喚起的其實是微信公眾號支付,做過公眾號支付的同學都知道,調(diào)用微信公眾號的統(tǒng)一下單API時
需要傳入openID,即用戶在該公眾號的下的唯一標識,這個過程需要用于授權(quán)登錄該公眾號,這個過程是一個缺點,
用戶僅僅只是微信的掃碼支付,但你中間不是黑箱子的形式展示,而是在支付中多出了一個授權(quán)登錄的頁面,并且
也比較繁瑣,在喚醒微信支付的過程中請求次數(shù)較多,所以微信支付會比正在的掃碼支付會慢很多。
喚起微信公眾號支付:
步驟:
1.首先拼裝好你的授權(quán)登錄url。在類型控制中判斷如果是微信支付則重定向到微信授權(quán)登錄頁面,微信會重定向到
你在授權(quán)登錄url中設置重定向url參數(shù)的頁面,
2.跳轉(zhuǎn)到這個頁面后,先獲取到用戶code然后利用ajax訪問服務端,
3.服務端使用code去獲取用戶的openID,
4.根據(jù)openID去調(diào)用微信公眾號的統(tǒng)一下單API生成參數(shù),然后返回給頁面喚醒支付,這就是整個微信的流程,
中間訪問了3次微信獲取數(shù)據(jù),整個流程共6次請求,需要將微信跳轉(zhuǎn)的頁面放到官網(wǎng)的微信目錄下。
在寫這篇博文的時候因為支付寶我還沒有簽約,所以沒有調(diào)通,而微信也只成功了一次,但第二次什么都沒改的情況
下就不行了,寫這篇博文順便捋捋思路,怎么更簡單。
注:訪問微信授權(quán)頁面中的redirect_url參數(shù)可以添加請求參數(shù)。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot使用編程方式配置DataSource的方法
這篇文章主要介紹了SpringBoot使用編程方式配置DataSource的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
Spring使用AspectJ的注解式實現(xiàn)AOP面向切面編程
這篇文章主要介紹了Spring使用AspectJ的注解式實現(xiàn)AOP面向切面編程的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
解決日期轉(zhuǎn)化Json異常- Date JSON parse error
這篇文章主要介紹了解決日期轉(zhuǎn)化Json異常- Date JSON parse error問題。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06

