前言
在iOS里,使用WKWebView加載H5頁(yè)面,進(jìn)行微信支付后,會(huì)跳轉(zhuǎn)不回原來(lái)的App?,F(xiàn)象就是微信內(nèi)點(diǎn)擊 (完成|取消) ,返回的是手機(jī)Safari瀏覽器。針對(duì)這個(gè)問(wèn)題,下面是我總結(jié)的解決方案,推薦使用第三個(gè)方案.
方案一:
在網(wǎng)上搜索時(shí)這類(lèi)答案時(shí),提到解決辦法幾乎全是這個(gè)方案,這個(gè)方案?jìng)€(gè)人覺(jué)得有點(diǎn)麻煩了,如果要適配到iOS9之前可以考慮??偨Y(jié)起來(lái)如下:
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://不能隨便寫(xiě),這個(gè)域名必須和 微信H5商家后臺(tái)提交的授權(quán)域名一致,不然會(huì)報(bào)[商家參數(shù)格式有誤,請(qǐng)聯(lián)系商家解決]
1.5 具體的代碼細(xì)節(jié),網(wǎng)絡(luò)上很多的,比如下面這2個(gè)哥們寫(xiě)的:
點(diǎn)評(píng):感覺(jué)有點(diǎn)麻煩,萬(wàn)一微信改了API,也許就不行了,而且我面臨的需求是多個(gè)App,比如ABCD...等這么多App都接入同一個(gè)H5頁(yè)面支付,怎么保證Schemes不沖突? 二級(jí)域名?怎么讓這么多App的開(kāi)發(fā)者都寫(xiě)這么多代碼呢?
方案二:
之前有說(shuō),H5調(diào)起微信支付,會(huì)返回Safari瀏覽器,那干脆就在Safari瀏覽器所呈現(xiàn)的頁(yè)面,加個(gè)按鈕,點(diǎn)擊返回原App即可。(當(dāng)然,高興的話(huà),你也可以直接執(zhí)行js代碼自動(dòng)跳轉(zhuǎn)回來(lái)),所以這個(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)頁(yè)面,根據(jù)scheme=appScheme,點(diǎn)擊按鈕,跳轉(zhuǎn)回對(duì)應(yīng)的App即可.
2.3 注意:區(qū)分好iOS和Android,Android的H5微信支付是沒(méi)問(wèn)題的。也注意區(qū)分是在手機(jī)的Safari瀏覽器,還是在App內(nèi)的瀏覽器。
點(diǎn)評(píng):需要產(chǎn)品經(jīng)理同意,H5前端開(kāi)發(fā)需要寫(xiě)很多判斷代碼。
方案三:
這個(gè)方案是目前==最優(yōu)的方案==,使用Universal Links!?。?/p>
Universal Link(通用鏈接)是Apple在iOS9推出的一種能夠方便的通過(guò)HTTPS鏈接來(lái)啟動(dòng)App的功能,當(dāng)你的App支持Universal Link后,一個(gè)正確的HTTPS鏈接就可以無(wú)縫重定向到你的App,且不需要通過(guò)Safari瀏覽器,==微信==已全面支持Universal Link.
Universal Link的配置過(guò)程,網(wǎng)上百度一大堆的,蘋(píng)果爸爸在開(kāi)發(fā)者網(wǎng)站也寫(xiě)的很詳細(xì),我這里簡(jiǎn)單過(guò)一下:
3.1 必須有一個(gè)正規(guī)的https域名,并且擁有該域名下的上傳到根目錄的權(quán)限。(阿里云的https就可以)
3.2 蘋(píng)果開(kāi)發(fā)者中心配置:在Identifiers里找到對(duì)應(yīng)的App ID,在Capabilities列表里有Associated Domains,把它變?yōu)?code>Enabled就可以了。

3.3 在Xcode中,配置Associated Domains,注意格式,必須必須以applinks:為前綴,域名當(dāng)然是后臺(tái)或者運(yùn)維給你的。

3.4 配置域名支持Universal Links這塊自己查即可,資料很多的,注意的是apple-app-site-association文件一定要配置對(duì),它決定了能不能正確的跳轉(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)可以打開(kāi)App了,后面跟的returnUrl=是我跟前端的約定,畢竟打開(kāi)App后,我需要加載顯示真正的回調(diào)頁(yè)面.
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):
// 通過(guò)universal link來(lái)喚起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 正如你所看到的,通過(guò)Universal Link實(shí)現(xiàn)跳轉(zhuǎn)回來(lái),代碼量很少,大多都是配置而已,需要注意的是:
- 區(qū)分好Android 和 iOS,比如H5的URL加參數(shù):
&from=ios,安卓就是正?;卣{(diào)地址,iOS就是通過(guò)Universal Links返回。 -
Universal Links這個(gè)域名需要在微信H5商家后臺(tái)提交的授權(quán)域名一致,不然會(huì)報(bào)[商家參數(shù)格式有誤,請(qǐng)聯(lián)系商家解決] - 通過(guò)
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為無(wú)法獲取訂單信息,輸入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ě)了,其中的方案三也是我項(xiàng)目中使用的辦法,不僅解決了跳轉(zhuǎn)回來(lái),還解決了跳轉(zhuǎn)到N多App的問(wèn)題。大家如果遇到什么問(wèn)題,可以直接留言交流。
-- End ---
PS:最近我有跳槽的想法,有工作機(jī)會(huì)的老板,歡迎騷擾哦!北京呦!
END。
我是小侯爺。
在帝都艱苦奮斗,白天是上班族,晚上是知識(shí)服務(wù)工作者。
如果讀完覺(jué)得有收獲的話(huà),記得關(guān)注和點(diǎn)贊哦。
非要打賞的話(huà),我也是不會(huì)拒絕的。