iOS集成H5微信支付實(shí)現(xiàn)跳轉(zhuǎn)與回調(diào)的解決方案

由于不能在iOS客戶端內(nèi)集成支付寶和微信的App支付SDK(為了防蘋果審核檢測SDK)舆驶,因此使用H5支付往史,雖然微信和支付寶的H5支付文檔都說不要在App內(nèi)使用H5支付而是使用App支付嫉沽,但辦法總是有的糕再。

這篇講的是微信H5支付如何從App跳轉(zhuǎn)微信以及如何從微信跳轉(zhuǎn)回App锨能,支付寶支付的見這篇:

iOS集成支付寶H5支付實(shí)現(xiàn)跳轉(zhuǎn)與回調(diào)的解決方案

實(shí)現(xiàn)的效果是:App→微信→支付(成功失敗或取消)→App

前置準(zhǔn)備

準(zhǔn)備時(shí)大家需要看下官方文檔: 微信H5支付開發(fā)文檔

本項(xiàng)目使用WKWebView丑罪,前置動(dòng)作是后端小伙伴已經(jīng)處理好支付寶H5支付下單流程,客戶端接收到下單鏈接后的操作鬓长。

下單鏈接即為微信支付文檔-統(tǒng)一下單API中返回的 mweb_url谒拴,格式為 https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx2016121516420242444321ca0631331346&package=1405458241

下單鏈接

操作步驟

1. 添加 URL Scheme 并把微信加入白名單

添加 URL Scheme

添加 URL Scheme涉波。在 xcodeproj文件Info 選項(xiàng)卡最下面的 URL Types內(nèi)設(shè)置英上。 注意此URL的一級(jí)域名需要與微信商戶后臺(tái)(微信商戶平臺(tái)-產(chǎn)品中心-開發(fā)配置-H5支付)設(shè)置的的一級(jí)域名一致炭序,比如微信商戶里設(shè)置的是company.com,那 URL Schemes 可以設(shè)為 a1.company.com苍日,此特性使得一套H5支付可以方便得集成到多個(gè)App惭聂。只有一個(gè)App需要H5支付的話也可以直接填與微信后臺(tái)的一致的 company.com

如果像上圖那樣填的是 www.company.com相恃,那URL Scheme 只能設(shè)為其三級(jí)域名如 a2.www.company.com 或同樣的 www.company.com

白名單

把微信的URL Scheme weixinwechat填入項(xiàng)目的白名單辜纲。在 xcodeproj 文件 Info 選項(xiàng)卡內(nèi)的 Custom iOS Target PropertiesLSApplicationQueriesSchemes 里添加上述兩個(gè)字符串,若沒有 LSApplicationQueriesSchemes 就手動(dòng)輸入添加拦耐,類型為數(shù)組 Array耕腾。

2. WKWebView加載鏈接

添加協(xié)議 WKNavigationDelegateWKUIDelegate

創(chuàng)建一個(gè)WKWebView杀糯,并加載統(tǒng)一下單鏈接扫俺。

- (void)buildWKWebView {
    WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    [self.view addSubview:webView];
    webView.navigationDelegate = self;
    webView.UIDelegate = self;
    NSURL *payURL = [NSURL URLWithString:self.payString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:payURL];
    [request setValue:@"a1.company.com://wxpaycallback/" forHTTPHeaderField:@"Referer"];
    [webView loadRequest:request];
}

此處self.payString就是后臺(tái)傳來的微信H5支付統(tǒng)一下單鏈接,格式為 https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx2016121516420242444321ca0631331346&package=1405458041固翰。

我們需要做的處理是根據(jù)文檔給這個(gè)請求添加請求頭Referer狼纬,關(guān)鍵在于這個(gè) a1.company.com://wxpaycallback/既滿足了微信檢測到有商戶后臺(tái)設(shè)置好的一級(jí)域名,同時(shí)把這個(gè)鏈接做成了 URL Scheme 使得可以在跳轉(zhuǎn)微信客戶端后(不管支付成功還是失斅罴省)能順利跳轉(zhuǎn)回自己的App疗琉。其中的 host wxpaycallback/可以任意設(shè)置,方便在 AppDelegate 里處理跳轉(zhuǎn)回來后部署業(yè)務(wù)邏輯歉铝。當(dāng)然如果你不需要在 AppDelegate里接收動(dòng)作而是直接跳回支付界面自行后續(xù)處理的話就只用設(shè)為前一步在 URL Scheme a1.company.com://即可盈简。

經(jīng)過測試,對于App 內(nèi)的H5 支付而言太示,實(shí)際上是下面步驟里
@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"
后接的參數(shù) redirect_url 對支付后跳回App起作用送火,Referer 只起到給微信校驗(yàn)的作用。

所以Referer 只需要設(shè)置成微信H5 支付登記的域名的子域名即可先匪,如
[request setValue:@"a1.company.com" forHTTPHeaderField:@"Referer"];

3. 實(shí)現(xiàn)代理方法攔截鏈接并跳轉(zhuǎn)微信

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
    NSURLRequest *request = navigationAction.request;
    NSString *absoluteString = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    
    // 攔截WKWebView加載的微信支付統(tǒng)一下單鏈接, 將redirect_url參數(shù)修改為喚起自己App的URLScheme
    if ([absoluteString hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && ![absoluteString hasSuffix:[NSString stringWithFormat:@"redirect_url=a1.company.com://wxpaycallback/"]]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        NSString *redirectUrl = nil;
        if ([absoluteString containsString:@"redirect_url="]) {
            NSRange redirectRange = [absoluteString rangeOfString:@"redirect_url"];
            redirectUrl = [[absoluteString substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=a1.company.com://wxpaycallback/"]];
        } else {
            redirectUrl = [absoluteString stringByAppendingString:[NSString stringWithFormat:@"redirect_url=a1.company.com://wxpaycallback/"]];
        }
        NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
        newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
        newRequest.URL = [NSURL URLWithString:redirectUrl];
        [webView loadRequest:newRequest];
        return;
    }
    
    //攔截重定向的跳轉(zhuǎn)微信的 URL Scheme, 打開微信
    if ([absoluteString hasPrefix:@"weixin://"]) {
        decisionHandler(WKNavigationActionPolicyAllow);
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if ([[UIApplication sharedApplication] canOpenURL:navigationAction.request.URL]) {
                [[UIApplication sharedApplication] openURL:navigationAction.request.URL];
            } else {
                //未安裝微信, 自行處理
            }
        });
        return;
    }
    
    decisionHandler(WKNavigationActionPolicyAllow);
    return;
}

4. AppDelegate 中接收跳轉(zhuǎn)動(dòng)作

當(dāng)然你也不一定需要在AppDelegate里接收返回動(dòng)作种吸,也可以直接返回支付界面,自行操作后續(xù)邏輯呀非。

以下是AppDelegate接收返回動(dòng)作的示例坚俗。

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    //safepay是支付寶H5支付的回調(diào)host
    if ([url.host isEqualToString:@"wxpaycallback"] ) {
        // 自行操作業(yè)務(wù)邏輯
       
    }
}

5. 關(guān)于微信H5支付域名設(shè)置

這里額外提一下,截止到2019年4月岸裙,微信支付設(shè)置頁面明確說了


域名設(shè)置

添加域名后猖败,其所屬的子域名將都有權(quán)限

也就是說只需要填一個(gè)一級(jí)域名比如 company.com ,就可以有無限多個(gè)二級(jí)域名可供不同App使用降允,繞過微信H5支付只能添加5個(gè)域名的限制恩闻。如果填的是二級(jí)域名比如 www.company.com,那么只能往下使用三級(jí)域名比如a1.www.company.com

以微信H5支付域名填了 company.com為例剧董,那可以這樣操作

App Alpha Beta-A1 Beta-A2 Gamma
添加的Referer alpha.company.com a1.beta.company.com a2.beta.company.com gamma.company.com
要替換的redirect_url alpha.company.com://optional a1.beta.company.com:// a2.beta.company.com://optional gamma.company.com://
URL Scheme alpha.company.com a1.beta.company.com a2.beta.company.com gamma.company.com

參考:
https://paaatrick.com/2019-03-22-ios-wxpay-h5-solution/
https://www.cnblogs.com/Life-Record/p/8472319.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幢尚,一起剝皮案震驚了整個(gè)濱河市破停,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尉剩,老刑警劉巖真慢,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異理茎,居然都是意外死亡黑界,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門皂林,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朗鸠,“玉大人,你說我怎么就攤上這事础倍⊥纾” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵著隆,是天一觀的道長。 經(jīng)常有香客問我呀癣,道長美浦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任项栏,我火速辦了婚禮浦辨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沼沈。我一直安慰自己流酬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布列另。 她就那樣靜靜地躺著芽腾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪页衙。 梳的紋絲不亂的頭發(fā)上摊滔,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機(jī)與錄音店乐,去河邊找鬼艰躺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛眨八,可吹牛的內(nèi)容都是我干的腺兴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼廉侧,長吁一口氣:“原來是場噩夢啊……” “哼页响!你這毒婦竟也來了篓足?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤拘泞,失蹤者是張志新(化名)和其女友劉穎纷纫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陪腌,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辱魁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诗鸭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片染簇。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖强岸,靈堂內(nèi)的尸體忽然破棺而出锻弓,到底是詐尸還是另有隱情,我是刑警寧澤蝌箍,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布青灼,位于F島的核電站,受9級(jí)特大地震影響妓盲,放射性物質(zhì)發(fā)生泄漏杂拨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一悯衬、第九天 我趴在偏房一處隱蔽的房頂上張望弹沽。 院中可真熱鬧,春花似錦筋粗、人聲如沸策橘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丽已。三九已至,卻和暖如春买决,著一層夾襖步出監(jiān)牢的瞬間促脉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工策州, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘸味,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓够挂,卻偏偏與公主長得像旁仿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348