支付二維碼整合 - 三碼合一支持支付寶、QQ、微信
1. 前提:獲取各個二維碼的具體內容
在寫代碼前,我們需要先獲取不同支付方式的二維碼內容。很簡單,只需要打開各個支付碼,截圖,然后隨便找個可以掃碼的工具把各個碼的內容給掃出來,得到文本內容即可。下面是我的內容:
支付寶:
https://qr.alipay.com/tsx108134acakckixsivtd4
微信:
wxp://f2f0kIl6qSrlWNFuIo8t8rXCU7Si7CC7ucQs
QQ:
https://i.qianbao.qq.com/wallet/sqrcode.htm?m=tenpay&f=wallet&a=1&ac=CAEQi5uqmQMY8Y-T_wU%3D_xxx_sign&u=QQ號&n=昵稱
2. 方法一:使用Nginx 分發內容
可以看到各個支付方式都是甚於帶參跳轉協議,所以我們可以用一個固定的網址,讓它去檢測不同的網站進而跳轉不同的鏈接。
這一步可以用后台程序跳轉,也可以用Nginx 這樣的服務器去做,因為只需要能對請求的內容做區分就可以了。
用Nginx 可以這樣寫:
location /pay {
if ( $http_user_agent ~* "AlipayClient" ) { return 302 "https://qr.alipay.com/tsx108134acakckixsivtd4"; }
if ( $http_user_agent ~* "MicroMessenger" ) { return 302 "wxp://f2f0kIl6qSrlWNFuIo8t8rXCU7Si7CC7ucQs"; }
if ( $http_user_agent ~* "QQ" ) { return 302 "https://i.qianbao.qq.com/wallet/sqrcode.htm?m=tenpay&f=wallet&a=1&ac=CAEQi5uqmQMY8Y-T_wU%3D_xxx_sign&u=QQ號&n=昵稱"; }
return 400 "不支持的類型";
}
經測試,發現QQ, 微信不可以用😢 可能是騰訊為了安全規避了由跳轉過來的調用吧。
3. 方法二:使用獨立的二維碼1
由於不能使用跳轉去完全支持三種支付方式了。這里我們小改一下,首先用二維碼生成工具生成樣式統一的二維碼,因為原生那個三家的碼都長得不太一樣會影響美觀。
QQ:

微信:

然后小改一下上面的Nginx 配置,改成如果是這兩個的話跳轉到對應的頁面。
刪減1
上面這個頁面,如果你是從微信瀏覽器打開的應該會看到微信的支付碼,如果是QQ 瀏覽器中打開應該會看到QQ 的支付碼。如果是從其他瀏覽器或者PC 則什么碼都看不到。
此時的Nginx 的配置:
location /donate {
root /www/pages/build/donate;
if ( $http_user_agent ~* "AlipayClient" ) { return 302 "https://qr.alipay.com/tsx108134acakckixsivtd4"; }
if ( $http_user_agent ~* "MicroMessenger" ) { rewrite ^/(.*) /wechat.html break; }
if ( $http_user_agent ~* "QQ" ) { rewrite ^/(.*) /qq.html break; }
return 302 "https://www.pulsgarney.com/";
}
4. 方法三:使用獨立的二維碼2
做到這里了基本能實現功能了。
但如果用戶是直接從手機的客戶端里打開那其實那個體驗還是不太好。因為那樣他們就等於是得掃碼,打開對應的頁面,然后再長按一次掃碼才能看到收銀台。這個步驟體驗也很糟糕。可以怎么優化一下呢?我們把前端頁面的代碼修改一下:如果是在手機客戶端中打開的那我們就直接顯示對應的支付碼就好了,不要再顯示那個中轉頁面的二維碼了。
這部分的改動就看你用的是什么前端程序了,應對改就行了。下面是我這個博客的部分代碼:
const [qrCode, setQrCode] = React.useState('');
React.useEffect(() => {
const ua = window.navigator.userAgent || '';
if (ua.includes('AlipayClient')) {
setQrCode(process.env['REACT_APP_DONATE_ALIPAY'] || '');
} else if (ua.includes('MicroMessenger')) {
setQrCode(process.env['REACT_APP_DONATE_WECHAT'] || '');
} else if (ua.includes('QQ')) {
setQrCode(process.env['REACT_APP_DONATE_QQ'] || '');
} else {
setQrCode(process.env['REACT_APP_DONATE_INDEX'] || '');
}
}, []);
因為我的博客使用了同構的SSR. 所以需要將瀏覽器的代碼用 React.useEffect 給包起來,否則在服務器渲染時會報錯。另外各個不同的二維碼內容用環境變量加載起來,這樣如果需要替換內容可以不動這部分代碼。
經測試,微信正常,但支付寶內好像不讓加載JS 文件?頁面是加載了,但JS 的功能全廢了。。QQ 的二維碼好像太復雜沒識別出來…… 😭😭
5. 總結
折騰的過程很有意思,但沒有和他們合作的能力靠Hack 的方式實現最終的實用性還是槽點滿滿的,所以,要真有剛需的還是接第三方的服務吧~
