iOS支付功能篇:原生WebView調起支付寶客戶端支付方案
阿新 • • 發佈:2019-01-28
產品需求:
使用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);
}