1. 程式人生 > >iOS支付功能篇:原生WebView調起支付寶客戶端支付方案

iOS支付功能篇:原生WebView調起支付寶客戶端支付方案

產品需求:

使用iOS原生WKWebView載入H5調起支付寶客戶端進行支付的功能實現。

資源

開發歷程

1. 安卓直接webView載入上面的URL直接可完成跳轉支付寶彈出支付介面;

2. iOS WKWebView載入這個URL,只是單純載入,無法實現跳轉;

3. 使用Safari瀏覽器載入該URL,直接提示開啟,如下圖(這裡由於一個訂單隻有一個小時的待付款時間限制,否則會失效,如果這裡沒有失效,會開啟讓您支付的頁面):

這裡寫圖片描述這裡寫圖片描述

4. 第三步說明這個地址是OK的,使用原生webView為什麼不能實現跳轉呢?

初步思路這樣的:dataStr就是伺服器響應後的支付寶需要的引數,我想,帶上引數跳轉過去應該問題不大吧?跳轉是成功的但是還是無法彈出支付的頁面(這裡理解成識別結果頁面就可,未識別)

// 在收到響應開始載入後,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"alipay://alipayclient/?%@",navigationResponse.response.URL.absoluteString]]
options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) { }]; WKNavigationResponsePolicy actionPolicy = WKNavigationResponsePolicyAllow; //這句是必須加上的,不然會異常 decisionHandler(actionPolicy); }

5. 很是糾結,我試著複製出來Safari瀏覽器的內容看看什麼樣的格式。

一頓分析後,我試著直接用這個地址跳轉:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"alipay://alipayclient/?%@", @"https://ds.alipay.com/?from=mobilecodec&scheme=alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-othe"]] options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {

    }];   

以上想法也是夠傻的,再仔細看看,像下面這樣就成功了。

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-othe"] options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {

    }];   

6.斷點除錯,列印伺服器返回的資訊

我列印了一下 navigationResponse.response.URL.absoluteString 這個東西是什麼玩意?好吧,是經過URLEncode的。如下:

https%3a%2f%2fds.alipay.com%2f%3ffrom%3dmobilecodec%26scheme%3dalipays%3a%2f%2fplatformapi%2fstartapp%3fsaId%3d10000007%26clientVersion%3d3.7.0.0718%26qrcode%3dhttps%25253A%25252F%25252Fqr.alipay.com%25252Fbax041244dd0qf8n6ras805b%25253F_s%25253Dweb-other

解碼後:

完結。

成功實現程式碼

載入URL程式碼

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://qr.alipay.com/bax06385q32ssucugqxm00f1"]];
    NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
    //Cookies陣列轉換為requestHeaderFields
    NSDictionary *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
    //設定請求頭
    request.allHTTPHeaderFields = requestHeaderFields;
    [self.payWebView loadRequest:request];
// 在收到響應開始載入後,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    //返回支付寶的資訊字串,alipays:// 以後的為支付資訊,這個資訊後臺是經過 URLEncode 後的,前端需要進行解碼後才能跳轉支付寶支付(坑點)

    //https://ds.alipay.com/?from=mobilecodec&scheme=alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-other

    NSString *urlStr = [navigationResponse.response.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    if ([urlStr containsString:@"alipays://"]) {

        NSRange range = [urlStr rangeOfString:@"alipays://"]; //擷取的字串起始位置
        NSString * resultStr = [urlStr substringFromIndex:range.location]; //擷取字串

        NSURL *alipayURL = [NSURL URLWithString:resultStr];

        [[UIApplication sharedApplication] openURL:alipayURL options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {

        }];
    }
    WKNavigationResponsePolicy actionPolicy = WKNavigationResponsePolicyAllow;
    //這句是必須加上的,不然會異常
    decisionHandler(actionPolicy);
}

總結

這種方案就是相當於一個掃描二維碼支付的方案,我們後臺提供的URL資訊裡面包含了一個二維碼資訊,iOS使用WKWebView載入後得到相應的的二維碼資訊,我們按照指定格式跳轉到支付寶客戶端,帶著資訊過去,可能支付寶內部做了識別吧,直接就能彈出識別結果:是支付呢?還是該二維碼已失效。

後續的難點就是支付成功後的iOS原生處理了,這裡的邏輯可以發揮想象,該如何實現比較適合使用者習慣吧。

iOS實現起來比安卓麻煩一點吧!不過這很iOS對吧。呵呵!