IOS WKWebView H5支付打開支付寶/微信客戶端

近期公司項(xiàng)目中的App使用WKWebView封裝作為一個殼,加載web的網(wǎng)頁,其中的支付使用的是H5支付,在APP中需要調(diào)起微信和支付客戶端進(jìn)行支付晦攒,過程中遇到了一些問題,好在通過查找資料找到了以下解決方案得哆,這里來記錄下
一、支付寶
找了下支付寶的開發(fā)文檔哟旗,發(fā)現(xiàn)支付寶自己其實(shí)已經(jīng)做了手機(jī)網(wǎng)站支付轉(zhuǎn)Native支付的接口贩据,使用很方便,直接按照開發(fā)文檔接入即可闸餐,這里是開發(fā)文檔的連接 手機(jī)網(wǎng)站支付轉(zhuǎn)Native支付(下面我大概引用下集成流程)
iOS接入說明(先下載支付的SDK下載Demo)
配置
步驟1:啟動Xcode饱亮,把iOS包中的壓縮文件中以下文件拷貝到項(xiàng)目文件夾下,并導(dǎo)入到項(xiàng)目工程中舍沙。
AlipaySDK.bundle
AlipaySDK.framework
在Build Phases選項(xiàng)卡的Link Binary With Libraries中近上,增加以下依賴:
其中,需要注意的是:
如果是Xcode 7.0之后的版本拂铡,需要添加libc++.tbd壹无、libz.tbd;
如果是Xcode 7.0之前的版本感帅,需要添加libc++.dylib斗锭、libz.dylib(如下圖)。

步驟2:在需要調(diào)用AlipaySDK的文件中失球,增加頭文件引用岖是。

import

步驟3:配置支付寶客戶端返回url處理方法。
(外部存在支付包錢包实苞,支付寶錢包將處理結(jié)果通過url返回豺撑。)
如示例AliSDKDemo\APAppDelegate.m文件中,增加引用代碼:

import

在@implementation AppDelegate中增加如下代碼:

-  (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
//如果極簡開發(fā)包不可用黔牵,會跳轉(zhuǎn)支付寶錢包進(jìn)行支付聪轿,需要將支付寶錢包的支付結(jié)果回傳給開發(fā)包
if ([url.host isEqualToString:@"safepay"]) {
    [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
//【由于在跳轉(zhuǎn)支付寶客戶端支付的過程中,商戶app在后臺很可能被系統(tǒng)kill了荧止,所以pay接口的callback就會失效屹电,請商戶對standbyCallback返回的回調(diào)結(jié)果進(jìn)行處理,就是在這個方法里面處理跟callback一樣的邏輯】
        NSLog(@"result = %@",resultDic);
    }];
}
if ([url.host isEqualToString:@"platformapi"]){//支付寶錢包快登授權(quán)返回authCode
    [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
        //【由于在跳轉(zhuǎn)支付寶客戶端支付的過程中,商戶app在后臺很可能被系統(tǒng)kill了跃巡,所以pay接口的callback就會失效危号,請商戶對standbyCallback返回的回調(diào)結(jié)果進(jìn)行處理,就是在這個方法里面處理跟callback一樣的邏輯】
        NSLog(@"result = %@",resultDic);
    }];
}
return YES;
}

接口調(diào)用說明

本SDK提供的所有接口均定義在AlipaySDK.h中。

SDK中提供了若干接口素邪,手機(jī)網(wǎng)站轉(zhuǎn)Native支付只用到其中一部分外莲,本文未提到的接口無需關(guān)注。

如何調(diào)用提供的接口?
APP支付最新版本 15.4.0 新增攔截+支付二合一接口(payInterceptorWithUrl...)偷线,該接口將原來的獲取H5支付訂單信息接口和支付接口進(jìn)行了合并磨确。
接口的調(diào)用方式是先調(diào)用defaultService獲取SDK的實(shí)例,然后再調(diào)用單獨(dú)提供的功能接口声邦,以payInterceptorWithUrl為例:
[[AlipaySDK defaultService] payInterceptorWithUrl:url fromScheme:scheme callback:^(NSDictionary result) {
// 處理支付結(jié)果
NSLog(@"%@", result);
}];
如何實(shí)現(xiàn)手機(jī)網(wǎng)站轉(zhuǎn)APP支付乏奥?
步驟一: 實(shí)現(xiàn)UIWebViewDelegate協(xié)議,攔截H5的URL亥曹;
步驟二: 調(diào)用新增攔截+支付二合一接口(payInterceptorWithUrl...)進(jìn)行URL攔截及支付轉(zhuǎn)化邓了;具體參照如下接口說明。
攔截+支付二合一接口
接口原型
/
*

  • 支付寶H5支付URL攔截器媳瞪,完成攔截及支付方式轉(zhuǎn)化
  • @param urlStr 待過濾攔截的 url string
  • @param schemeStr 調(diào)用支付的app注冊在info.plist中的scheme
  • @param compltionBlock 支付結(jié)果回調(diào)Block
  • @return YES:表示URL為支付寶支付URL骗炉,URL已經(jīng)被攔截轉(zhuǎn)化;NO:表示URL非支付寶支付URL蛇受;
    */
  • (BOOL)payInterceptorWithUrl:(NSString *)urlStr
    fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;

接口功能
本接口首先是個攔截器句葵,攔截支付寶H5支付URL;其次是個支付方式轉(zhuǎn)化器兢仰,將手機(jī)網(wǎng)站支付方式轉(zhuǎn)化為APP支付方式乍丈。
參數(shù)說明
參數(shù)名稱類型說明
urlStrNSString *手機(jī)網(wǎng)站支付的請求URL
schemeStrNSString *接入方App注冊的URL scheme,供支付完成后跳回接入方App
completionBlockobjc(^CompletionBlock)(NSDictionary *resultDic)支付結(jié)束之后的回調(diào)其中CompletionBlock定義如下:objctypedef void(^CompletionBlock)(NSDictionary *resultDic);

同步攔截結(jié)果返回值說明
返回值類型說明
BOOL1.如果urlStr是有效的支付寶H5支付URL旨别,則說明攔截轉(zhuǎn)化成功诗赌,返回YES,商戶容器無需再加載該URL秸弛;
2.如果是無效的铭若,則返回NO,商戶容器需要繼續(xù)加載該URL递览。

異步支付結(jié)果返回值說明
支付結(jié)束后SDK將回調(diào)completionBlock叼屠,并將支付結(jié)果resultDic(NSDictionary *類型)作為參數(shù)傳入該Block。resultDic中主要包含兩個字段绞铃,如下所示:

參數(shù)名稱類型說明
resultCodeNSString *返回碼镜雨,標(biāo)識支付狀態(tài),含義如下:
9000——訂單支付成功
8000——正在處理中
4000——訂單支付失敗
5000——重復(fù)請求
6001——用戶中途取消
6002——網(wǎng)絡(luò)連接出錯
returnUrlNSString *支付結(jié)束后應(yīng)當(dāng)跳轉(zhuǎn)的url地址

接口使用方式
調(diào)用本接口對支付寶支付URL進(jìn)行攔截和支付轉(zhuǎn)化儿捧。
當(dāng)接口調(diào)用完成后荚坞,該接口會返回一個BOOL類型的同步攔截結(jié)果,如果同步結(jié)果返回值為YES菲盾,說明傳入的URL為支付寶支付URL颓影,支付寶SDK已經(jīng)成功攔截該URL,并轉(zhuǎn)化為APP支付方式懒鉴,商戶容器無需再加載該URL诡挂;如果返回值為NO碎浇,說明傳入的URL并非支付寶支付URL,商戶容器需要繼續(xù)加載該URL璃俗;

當(dāng)支付結(jié)束后奴璃,會通過回調(diào)的方式返回異步支付結(jié)果,如果返回的支付結(jié)果中的resultCode為9000城豁,則表示支付成功苟穆,接入方可以提示用戶支付成功;如果返回結(jié)果不是9000钮蛛,無需做任何處理鞭缭。當(dāng)返回的returnUrl不為空,建議接入方跳轉(zhuǎn)到該returnUrl魏颓。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{ 
__weak APWebViewController* wself = self;
BOOL isIntercepted = [[AlipaySDK defaultService] payInterceptorWithUrl:[request.URL absoluteString] fromScheme:@"alisdkdemo" callback:^(NSDictionary *result) {
    // 處理支付結(jié)果
    NSLog(@"%@", result);
    // isProcessUrlPay 代表 支付寶已經(jīng)處理該URL
    if ([result[@"isProcessUrlPay"] boolValue]) {
        // returnUrl 代表 第三方App需要跳轉(zhuǎn)的成功頁URL
        NSString* urlStr = result[@"returnUrl"];
        [wself loadWithUrlStr:urlStr];
    }
}];
if (isIntercepted) {
    return NO;
}
return YES;
}

上面是使用UIWebView的回調(diào)寫法,下面是我使用的WKWebView的代碼:

-   (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler{
    __weakWebViewController* wself = self;
    BOOL isIntercepted = [[AlipaySDK defaultService] payInterceptorWithUrl:[navigationAction.request.URL absoluteString] fromScheme:@"PuHuiAlipay" callback:^(NSDictionary *result) {
      // 處理支付結(jié)果
      NSLog(@"%@", result);
      // isProcessUrlPay 代表 支付寶已經(jīng)處理該URL
      if ([result[@"isProcessUrlPay"]boolValue]) {
          NSString*resultCode = result[@"resultCode"];
          // returnUrl 代表 第三方App需要跳轉(zhuǎn)的成功頁URL
          NSString* urlStr = result[@"returnUrl"];
          if ([resultCodeisEqual:@"6001"]) {//當(dāng)不是取消支付的時候吱晒,重新加載支付前的頁面
              urlStr = self.URLString;
              [wself toast:@"取消支付了"];
          }else {
              if (urlStr.length==0) {
                  urlStr = [NSString stringWithFormat:@"http://huigong.jmzgo.com/weibojie/payResult.aspx?OrderID=%@",_wbjOrderID];
             }
          }
          [wselfloadWithUrlStr:urlStr];
      }
    }];
    if (isIntercepted) {
       actionPolicy =WKNavigationActionPolicyCancel;
  }
    decisionHandler(actionPolicy);
}

二甸饱、微信支付

微信支付目前使用的下面的方法跳轉(zhuǎn)到微信客戶端進(jìn)行支付,做法在WKWebView的回調(diào)中攔截URL仑濒,然后使用openURL的方式叹话,代碼如下:

- (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler{

WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow; NSString*urlString = [[navigationAction.requestURL]absoluteString];

urlString = [urlStringstringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];    if ([urlStringcontainsString:@"weixin://wap/pay?"]) {
    actionPolicy =WKNavigationActionPolicyCancel;
    //解決wkwebview weixin://無法打開微信客戶端的處理
    NSURL*url = [NSURLURLWithString:urlString];
    if ([[UIApplicationsharedApplication]respondsToSelector:@selector(openURL:options:completionHandler:)]) {
        [[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {   }];
    } else {
        [[UIApplicationsharedApplication]openURL:webView.URL];
    }
}
}
//這句是必須加上的,不然會異常
decisionHandler(actionPolicy);
}

上面的方法有個問題墩瞳,微信支付完或者取消的時候會跳轉(zhuǎn)是Safari瀏覽器驼壶,沒辦法直接返回到APP端,這個問題一直沒辦法很好的解決喉酌,所以我的做法是在我們的支付結(jié)果頁中加了一個返回APP的按鈕热凹,這樣在Safari中加載支付結(jié)果頁的時候,在頁面中通過Scheme可以打開我們的APP

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泪电,一起剝皮案震驚了整個濱河市般妙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌相速,老刑警劉巖碟渺,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異突诬,居然都是意外死亡苫拍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門旺隙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绒极,“玉大人,你說我怎么就攤上這事催束〖停” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長塔淤。 經(jīng)常有香客問我摘昌,道長,這世上最難降的妖魔是什么高蜂? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任聪黎,我火速辦了婚禮,結(jié)果婚禮上备恤,老公的妹妹穿的比我還像新娘稿饰。我一直安慰自己,他們只是感情好露泊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布喉镰。 她就那樣靜靜地躺著,像睡著了一般惭笑。 火紅的嫁衣襯著肌膚如雪侣姆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天沉噩,我揣著相機(jī)與錄音捺宗,去河邊找鬼。 笑死川蒙,一個胖子當(dāng)著我的面吹牛蚜厉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播畜眨,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼昼牛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胶果?” 一聲冷哼從身側(cè)響起匾嘱,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎早抠,沒想到半個月后霎烙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蕊连,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年悬垃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甘苍。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡尝蠕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出载庭,到底是詐尸還是另有隱情看彼,我是刑警寧澤廊佩,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站靖榕,受9級特大地震影響标锄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜茁计,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一料皇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧星压,春花似錦践剂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至竣贪,卻和暖如春男窟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贾富。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牺六,地道東北人颤枪。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像淑际,于是被迫代替她去往敵國和親畏纲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容