因業(yè)務(wù)需求,需要在app中打開第三方網(wǎng)頁并在網(wǎng)頁中進行支付,app中使用webview加載網(wǎng)頁。
- 測試時發(fā)現(xiàn)微信支付錯誤,提示“商家參數(shù)格式有誤,請聯(lián)系商家解決”,ios沒有問題。查看微信支付開發(fā)文檔(如下圖)發(fā)現(xiàn),需要在webview中手動設(shè)置referer。

微信支付開發(fā)文檔
在shouldOverrideUrlLoading()方法中攔截url,設(shè)置referer,有的文章說referer需要實時設(shè)置更新,每個頁面都要獲取上一個界面的referer,然后傳遞給下一個頁面,因此把url傳遞給referer,代碼如下:
webview.setWebViewClient(new WebViewClient() {
String referer = "商戶申請H5時提交的授權(quán)域名(例如:http://www.baidu.com)";
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("https://wx.tenpay.com")) {
Map<String, String> extraHeaders = new HashMap<>();
extraHeaders.put("Referer", referer);
view.loadUrl(url, extraHeaders);
referer = url;
return true;
}
view.loadUrl(url);
return true;
}
});
- 設(shè)置完referer后,再次運行微信支付和支付寶支付,均提示錯誤“net::ERR_UNKNOWN_URL_SCHEME”,如下圖。

因為上面兩個url都是自定義scheme開頭的(weixin://和alipays://),而webview只能識別http://或https://開頭的url,因此需要用intent調(diào)起能處理此scheme開頭的url的App,代碼如下:
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try {
if (url.startsWith("weixin://") || url.startsWith("alipays://")) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
}
} catch (Exception e) {
return false;
}
view.loadUrl(url);
return true;
}
});
修改完成后,微信和支付寶都能正常支付。
附上完整代碼:
webview.setWebViewClient(new WebViewClient() {
String referer = "商戶申請H5時提交的授權(quán)域名";
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try {
if (url.startsWith("weixin://") || url.startsWith("alipays://")) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
return true;
}
} catch (Exception e) {
return false;
}
if (url.contains("https://wx.tenpay.com")) {
Map<String, String> extraHeaders = new HashMap<>();
extraHeaders.put("Referer", referer);
view.loadUrl(url, extraHeaders);
referer = url;
return true;
}
view.loadUrl(url);
return true;
}
});