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