iOS集成第三方H5 調(diào)起微信支付和支付寶支付

今天公司產(chǎn)品過來交了個需求南捂,App內(nèi)部加載第三方的H5頁面需要調(diào)起微信和支付寶進行支付吴裤,但是不是調(diào)起原生中集成的旧找,而是H5內(nèi)部調(diào)起。
現(xiàn)在遇到問題是可以打開微信麦牺,但是支付完成之后不會回到app钮蛛,并且取消之后之后會跳轉(zhuǎn)到Safari瀏覽器加載一個第三方的支付完成的網(wǎng)址。
這并不符合預(yù)期剖膳,期待的效果是加載H5頁面調(diào)起微信或者支付寶App進行支付魏颓,取消或者支付成功之后跳轉(zhuǎn) 回到原來的App,并且加載第三方的支付完成的網(wǎng)址甸饱。

無法調(diào)起微信或者調(diào)起微信之后無法返回

無法調(diào)起微信的原因是沒有正確的設(shè)置正確的Referer或者沒有含有一級域名的redirect_url

微信官方文檔中關(guān)于“回調(diào)頁面”有這么一段話:

正常流程用戶支付完成后會返回至發(fā)起支付的頁面,如需返回至指定頁面仑濒,則可以在MWEB_URL后拼接上redirect_url參數(shù)叹话,來指定回調(diào)頁面。
如墩瞳,您希望用戶支付完成后跳轉(zhuǎn)至https://www.wechatpay.com.cn驼壶,則可以做如下處理:
假設(shè)您通過統(tǒng)一下單接口獲到的
MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096
則拼接后的地址為
MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn

微信H5支付,在中間頁面的URL上提供了一個redirect_url參數(shù)喉酌,用于指定支付結(jié)束后的回調(diào)頁面(默認是沒有redirect_url參數(shù)的热凹,微信會取請求頭中referer參數(shù)的值作為回調(diào)頁)泵喘。微信客戶端會通過[[UIApplication sharedApplication] openURL:url]方法來返回回調(diào)頁。如果我們把redirect_ur設(shè)置成我們App的URLSchemes是不是就可以返回我們的App了般妙?

解決方式

1.在微信商戶后臺(微信商戶平臺-產(chǎn)品中心-開發(fā)配置-H5支付(最下面那個))注冊一級域名纪铺,比如 company.com。
2.這里的company.com請和你微信下單時的一級域名保持一致股冗,即與微信中間頁https://wx.tenpay.com請求頭中的Referer字段對應(yīng)的值一致霹陡。因為在微信中間頁會去校驗Referer和redirect_url的值是否在微信后臺注冊過。
3.在APP工程配置中設(shè)置URL Scheme止状,比如 A.company.com(A你可以隨便寫烹棉,后面的域名得和1.中一致)
在webView代理方法中攔截微信中間頁請求(注意是請求不是返回結(jié)果),在這個請求的基礎(chǔ)上新建一個請求怯疤,追加參數(shù)redirect_url=URLEncode(A.company.com://)浆洗,cancel掉原來的請求,webView重新加載這個新的請求集峦。
代碼:

//以WKWebView為例(下面的代碼可能不嚴謹伏社,只是表達一個思路,請根據(jù)自己實際情況調(diào)整)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSURLRequest *request = navigationAction.request;
    //下面這個這個字符串不要直接寫在代碼中塔淤,否則會被蘋果機審掃描到pay字段摘昌,導(dǎo)致被拒絕「叻洌可以自行加密處理或讓后臺返回
    NSString *wxPre = @"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb";
    if ([request.URL.absoluteString hasPrefix:wxPre] && [request.URL.absoluteString rangeOfString:@"redirect_url"].length==0) {
        //開始微信支付會走這里
        //將要請求微信中間頁,且中間頁沒有追加過redirect_url參數(shù),追加redirect_url
        NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] init];
        newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
        NSString *newURLStr = nil;
        //TODO: 對newURLStr追加參數(shù)redirect_url=URLEncode(@"A.company.com://")
        newRequest.URL = [NSURL URLWithString:newURLStr];
        [webView loadRequest:newRequest];
        decisionHandler(WKNavigationActionPolicyCancel);
    }
    else if ([request.URL.scheme rangeOfString:@"company.com"].length!=0) {
        //微信支付結(jié)束(完成\取消\超時)后會走這里
        //TODO: 關(guān)閉微信中間頁,比如dismiss webViewController,或[webView goBack]
    }
    else {
      decisionHandler(WKNavigationActionPolicyAllow);
    }
}

4.微信支付結(jié)束后聪黎,你的webView會發(fā)起重定向到redirect_url的請求,即會請求"company.com://"备恤,攔截這個請求關(guān)閉微信中間頁稿饰。(后文會細說)

微信支付返回后白屏問題

白屏問題我以前也沒搞清楚原因,只知道怎么規(guī)避露泊,這次整理這篇博客時又好好研究了一下喉镰,終于弄清除原因了。
現(xiàn)象:
首先惭笑,不使用這篇文章中的方法時侣姆,微信支付結(jié)束后,手動回到App沉噩,不會有白屏的問題捺宗。
其次,如果使用了這篇文章中的方法屁擅,有些讀者反映偿凭,雖然微信支付結(jié)束后能夠自動跳回App,但是App會整個白屏派歌,無法繼續(xù)操作弯囊。
白屏原因總結(jié):
發(fā)起微信支付時痰哨,會把頁面重定向到中間頁,也可以理解為校驗頁匾嘱,有錯誤提示錯誤原因(如下圖)斤斧,沒錯誤就是純白色頁面同時拉起微信客戶端支付,中間頁的js代碼里面會判斷是否有redirect_url的值霎烙,如果沒有則5s后返回上一頁window.history.back()撬讽,也就返回支付前的H5頁面了;如果redirect_url有值悬垃,則重定向到redirect_url頁面游昼,而redirect_url=“A.company.com://“,重定向會失敗尝蠕,就停留在微信中間頁了烘豌,這就是白屏的原因。
白屏問題如何解決

在支付結(jié)束后關(guān)閉微信中間頁即可解決白屏問題看彼。
有兩個點廊佩,一個是支付結(jié)束的時機,一個是關(guān)閉微信中間頁靖榕。

支付結(jié)束的時機标锄,我上文提到過

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSURLRequest *request = navigationAction.request;
    if ([request.URL.scheme rangeOfString:@"company.com"].length!=0) {
        //微信支付結(jié)束(完成\取消\超時)后會走這里
        //TODO: 關(guān)閉微信中間頁,比如dismiss webViewController,或[webView goBack]
    }
    ...
}
復(fù)制代碼

關(guān)閉微信中間頁,我這里提供兩種思路:

  1. 新開一個原生的webViewController來加載你的收銀臺頁面(選擇微信茁计、支付寶那個頁面)料皇,在支付結(jié)束后dismiss這個webViewController。
  2. 借鑒微信的思路簸淀,在支付結(jié)束后瓶蝴,[webView goBack]來返回原來的頁面毒返。

常見問題自查

1.按文章步驟操作后租幕,App跳轉(zhuǎn)微信后,支付或取消沒有返回App而是跳轉(zhuǎn)到Safari

  1. 檢查redirect_url中的域名(有冒號反斜杠)拧簸、App URLScheme(沒有冒號反斜杠)劲绪,是否填寫正確,是否一致盆赤,微信商戶后臺是否注冊了對應(yīng)的域名贾富。
  2. 檢查是否是URLEncode(redirect_url)的過程出現(xiàn)了問題,如果你URLEncode后仍然有 :// 牺六,這是不對的颤枪,你可以拿你URLEncode后的值和在線URLEncode網(wǎng)站對比差異。

下面貼出來部分代碼

#pragma mark - ToolFunction
- (NSString *)WK_URLDecodedString:(NSString *)urlString {
    NSString *string = urlString;
    NSString *decodedString=(__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)string, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    return decodedString;
}

- (NSString *)WK_URLEncodedString:(NSString *)urlString {
    NSString *string = urlString;
    NSString *encodedString = (NSString *) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8));
    return encodedString;
}
//防止被蘋果抓到pay字段 需要下面的編碼
- (NSString *)encode:(NSString *)str
{
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    NSString *string = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    return string;
}

- (NSString *)decode:(NSString *)str
{
    NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return string;
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler方法中攔截支付

if ([requestString hasPrefix:[self decode:@"YWxpcGF5czovLw=="]] || [requestString hasPrefix:[self decode:@"YWxpcGF5Oi8v"]]) {支付寶需要添加返回的schme
        NSString *urlString = [[self WK_URLDecodedString:requestString] stringByReplacingOccurrencesOfString:[self decode:@"YWxpcGF5cw=="] withString:@"your schme"];
        NSString *prefixString = @"YWxpcGF5Oi8vYWxpcGF5Y2xpZW50Lz8=";
        NSURL *openedURL = navigationAction.request.URL;
        if ([urlString hasPrefix:[self decode:prefixString]]) {
            NSRange rang = [urlString rangeOfString:[self decode:prefixString]];
            NSString *subString = [urlString substringFromIndex:rang.length];
            NSString *encodedString = [[self decode:prefixString] stringByAppendingString:[self WK_URLEncodedString:subString]];
            openedURL = [NSURL URLWithString:encodedString];
        }
        if (![[UIApplication sharedApplication] openURL:openedURL]) {
            [CCHUDTool showTipWithText:[self decode:@"5pyq5a6J6KOF5pSv5LuY5a6d5a6i5oi356uv"]];
        }
         allowJumpToUrl = NO;
    }
    if ([requestString hasPrefix:[self decode:@"aHR0cHM6Ly93eC50ZW5wYXkuY29tL2NnaS1iaW4vbW1wYXl3ZWItYmluL2NoZWNrbXdlYg=="]] &&(![[self WK_URLDecodedString:requestString] containsString:@"redirect_url=your schme"] && ![[self WK_URLDecodedString:requestString] containsString:@"redirect_url=your another schme"] &&![[self WK_URLDecodedString:requestString] containsString:@"redirect_url=your another schme2"])) {
        NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] init];
        newRequest.allHTTPHeaderFields = navigationAction.request.allHTTPHeaderFields;
        newRequest.URL = [NSURL URLWithString:[self handleRedirectUrl:requestString]];
        [webView loadRequest:newRequest];
        allowJumpToUrl = NO;
    }else if ([requestString isEqualToString:@"your schme://"] || [requestString isEqualToString:@"your schme://"]|| [requestString isEqualToString:@"your schme://"]) {
        allowJumpToUrl = NO;  
        [webView goBack];
        NSURL *url = [NSURL URLWithString:_redirect_url];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
        [webView loadRequest:request];
    }

支付寶更簡單了,只需要替換鏈接中的alipays字段為你的schme就可以了,上面的代碼有.

參考地址 :https://bbm.loovee.com/pay/weixin
http://www.reibang.com/p/6d4cccba1288

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淑际,一起剝皮案震驚了整個濱河市畏纲,隨后出現(xiàn)的幾起案子扇住,更是在濱河造成了極大的恐慌,老刑警劉巖盗胀,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艘蹋,死亡現(xiàn)場離奇詭異,居然都是意外死亡票灰,警方通過查閱死者的電腦和手機女阀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屑迂,“玉大人浸策,你說我怎么就攤上這事∪桥危” “怎么了的榛?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逻锐。 經(jīng)常有香客問我夫晌,道長,這世上最難降的妖魔是什么昧诱? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任晓淀,我火速辦了婚禮,結(jié)果婚禮上盏档,老公的妹妹穿的比我還像新娘凶掰。我一直安慰自己,他們只是感情好蜈亩,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布懦窘。 她就那樣靜靜地躺著,像睡著了一般稚配。 火紅的嫁衣襯著肌膚如雪畅涂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天道川,我揣著相機與錄音午衰,去河邊找鬼。 笑死冒萄,一個胖子當著我的面吹牛臊岸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播尊流,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼帅戒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了崖技?” 一聲冷哼從身側(cè)響起逻住,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤施流,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鄙信,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞪醋,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年装诡,在試婚紗的時候發(fā)現(xiàn)自己被綠了银受。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸦采,死狀恐怖宾巍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情渔伯,我是刑警寧澤顶霞,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站锣吼,受9級特大地震影響选浑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜玄叠,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一古徒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧读恃,春花似錦隧膘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至西雀,卻和暖如春萨驶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蒋搜。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工篡撵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留判莉,地道東北人豆挽。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像券盅,于是被迫代替她去往敵國和親帮哈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

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