前言
在iOS里,使用WKWebView
加載H5頁面,進行微信支付后,會跳轉不回原來的App。現象就是微信內點擊 (完成|取消) ,返回的是手機Safari
瀏覽器。針對這個問題,下面是我總結的解決方案,推薦使用第三個方案.
方案一:
在網上搜索時這類答案時,提到解決辦法幾乎全是這個方案,這個方案個人覺得有點麻煩了,如果要適配到iOS9之前可以考慮。總結起來如下:
1.1 在H5微信支付時,攔截Request Header
里面的Referer
字段,設置為能調起自己App的scheme
鏈接,比如shop.demo.com://
1.2 攔截微信支付統一下單鏈接,修改鏈接中的redirect_url=
字段,比如改為:shop.demo.com://
,注意要跟Request Header
里面的Referer
字段是一致的。
1.3 設置App項目的URL Types
,增加一個URL Schemes
,內容就是上面的shop.demo.com
,注意白名單的添加.
1.4 注意,上面的shop.demo.com://
不能隨便寫,這個域名必須和 微信H5商家后臺提交的授權域名一致,不然會報[商家參數格式有誤,請聯系商家解決]
1.5 具體的代碼細節,網絡上很多的,比如下面這2個哥們寫的:
點評:感覺有點麻煩,萬一微信改了API,也許就不行了,而且我面臨的需求是多個App,比如ABCD...等這么多App都接入同一個H5頁面支付,怎么保證Schemes
不沖突? 二級域名?怎么讓這么多App的開發者都寫這么多代碼呢?
方案二:
之前有說,H5調起微信支付,會返回Safari
瀏覽器,那干脆就在Safari
瀏覽器所呈現的頁面,加個按鈕,點擊返回原App即可。(當然,高興的話,你也可以直接執行js代碼自動跳轉回來),所以這個方案需要產品經理能同意!!
2.1 App內的H5鏈接地址,多加個query
參數,比如https://shop.demo.com/index?scheme=appScheme
2.2 H5的回調頁面,根據scheme=appScheme
,點擊按鈕,跳轉回對應的App即可.
2.3 注意:區分好iOS和Android,Android的H5微信支付是沒問題的。也注意區分是在手機的Safari
瀏覽器,還是在App內的瀏覽器。
點評:需要產品經理同意,H5前端開發需要寫很多判斷代碼。
方案三:
這個方案是目前==最優的方案==,使用Universal Links
!!!
Universal Link
(通用鏈接)是Apple在iOS9推出的一種能夠方便的通過HTTPS鏈接來啟動App的功能,當你的App支持Universal Link
后,一個正確的HTTPS鏈接就可以無縫重定向到你的App,且不需要通過Safari
瀏覽器,==微信==已全面支持Universal Link
.
Universal Link
的配置過程,網上百度一大堆的,蘋果爸爸在開發者網站也寫的很詳細,我這里簡單過一下:
3.1 必須有一個正規的https
域名,并且擁有該域名下的上傳到根目錄的權限。(阿里云的https就可以)
3.2 蘋果開發者中心配置:在Identifiers
里找到對應的App ID,在Capabilities
列表里有Associated Domains
,把它變為Enabled
就可以了。
3.3 在Xcode中,配置Associated Domains
,注意格式,必須必須以applinks:
為前綴,域名當然是后臺或者運維給你的。
3.4 配置域名支持Universal Links
這塊自己查即可,資料很多的,注意的是apple-app-site-association
文件一定要配置對,它決定了能不能正確的跳轉到App。
3.5 上面都搞定后,前端H5需要做的就是處理iOS特殊的回調地址,這個地址是跟apple-app-site-association
文件里面配置的PATHS
一致的,比如:
redirect_url=https://www.shop.demo.com/apppath?returnUrl=https://www.shop.demo.com/result/123123
其實redirect_url=https://www.shop.demo.com/apppath/
已經可以打開App了,后面跟的returnUrl=
是我跟前端的約定,畢竟打開App后,我需要加載顯示真正的回調頁面.
3.5 其實代碼很少的,比如App內的H5支付攔截,以WKWebView
為例:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([navigationAction.request.URL.scheme isEqualToString:@"weixin"]) {
// 2.微信支付
[[UIApplication sharedApplication] openURL:navigationAction.request.URL options:@{} completionHandler:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
3.6 Appdelegate.m
文件里面處理支付回調:
// 通過universal link來喚起app API_AVAILABLE(ios(8.0))
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * restorableObjects))restorationHandler
{
// 檢查是否是H5商城的支付回調喚起
if ([userActivity.webpageURL.host isEqualToString:@"shop.demo.com"]) {
// 1.獲得真正的回調地址
NSArray *array = [userActivity.webpageURL.query componentsSeparatedByString:@"returnUrl="];
NSURL *url = [NSURL URLWithString:array.lastObject];
YouMallWebController *mallVC = [xx xxx]; // H5的控制器,看你的項目里怎么獲取到了
[mallVC loadURL:url]; // 加載顯示真正的回調地址
}
return YES;
}
3.7 正如你所看到的,通過Universal Link
實現跳轉回來,代碼量很少,大多都是配置而已,需要注意的是:
- 區分好Android 和 iOS,比如H5的URL加參數:
&from=ios
,安卓就是正常回調地址,iOS就是通過Universal Links
返回。 -
Universal Links
這個域名需要在微信H5商家后臺提交的授權域名一致,不然會報[商家參數格式有誤,請聯系商家解決] - 通過
Universal Links
這樣的回調地址,是可以調到不同的App,僅靠PATHS
區分即可。
3.8 Universal Link
的配置參考鏈接:
支付寶H5支付:
在這方面,支付寶的確比微信好多了,直接提供了h5攔截支付入口方法,在AlipaySDK.h
里面:
/**
* h5 攔截支付入口
* 從h5鏈接中獲取訂單串并支付接口(自版本15.4.0起,推薦使用該接口)
* @param urlStr 攔截的 url string
* @return YES為成功獲取訂單信息并發起支付流程;NO為無法獲取訂單信息,輸入url是普通url
*/
- (BOOL)payInterceptorWithUrl:(NSString *)urlStr
fromScheme:(NSString *)schemeStr
callback:(CompletionBlock)completionBlock;
所以,在WKWebView
里面,攔截支付寶的H5支付就很方便了:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([navigationAction.request.URL.host isEqualToString:@"mclient.alipay.com"]) {
// 1.支付寶支付
[[AlipaySDK defaultService] payInterceptorWithUrl:navigationAction.request.URL fromScheme:@"You Scheme" callback:^(NSDictionary *resultDic) {
// 支付成功或者失敗的 回調處理
}];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
附: 支付寶官方的文檔講解
最后:
思路就如上面所寫了,其中的方案三也是我項目中使用的辦法,不僅解決了跳轉回來,還解決了跳轉到N多App的問題。大家如果遇到什么問題,可以直接留言交流。
-- End ---
PS:最近我有跳槽的想法,有工作機會的老板,歡迎騷擾哦!北京呦!
END。
我是小侯爺。
在帝都艱苦奮斗,白天是上班族,晚上是知識服務工作者。
如果讀完覺得有收獲的話,記得關注和點贊哦。
非要打賞的話,我也是不會拒絕的。