最近碰到一個需要用H5支付的商城,痛苦了一整天,查找了N多的資料,終于還是苦盡甘來了。話不多說,干貨來了。我用的是WKWebView,套路是一樣的。
1.首先,設置白名單,確保你能順利跳轉微信。
2.在webView的代理中,截獲跳轉微信的HTTP(下面的所有代碼都是在這個方法中實現)
- (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler;
代碼如下:
? ? NSURL*url = navigationAction.request.URL;
? ? NSString*urlString = url.absoluteString;
? ? //調用微信
? ? if([urlStringrangeOfString:@"weixin://wap/pay"].location!=NSNotFound) {
? ? //阻止跳轉
? ? ? ? decisionHandler(WKNavigationActionPolicyCancel);
? ? ? ? BOOLcanOpen = [[UIApplicationsharedApplication]canOpenURL:url];
? ? ? ? if(canOpen) {
? ? ? ? ? ? [[UIApplication sharedApplication] openURL:url];
? ? ? ? }
? ? ? ? return;
? ? }
OK這兩步是讓跳轉到微信的,但是支付完成或者取消支付之后會跳到瀏覽器!!!很無語。SO,請接著看。
3.設置schemes,讓程序外能回到APP
4.更改參數redirect_url,實現回到APP
調用支付的時候一定會有一條URL:https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb&redirect_url =**********,通過測試得出支付返回的時候會加載redirect_url,當你的redirect_url是網址的時候,必定會跳轉到瀏覽器.瀏覽器有個特性就是當你的URL是****://的時候,會查找你的schemes,(iOS系統應該在跳轉瀏覽器之前自己有了判斷是網址才進瀏覽器,****://直接會調用APP),從而可以跳轉到APP,SO,只要更改這個redirect_url的值等于你的schemes的值加上://,就可以實現跳轉回APP.
static const NSString*schemeString =@"sale.eutrun.com";
? ? static const NSString*redirectString =@"redirect_url";
? ? NSString *jumpString = @"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb";
? ? NSString*changeredirectString =[NSStringstringWithFormat:@"%@=%@://",redirectString,schemeString];
//更改微信參數redirect_url 只要把redirect_url改成scheme的地址加上://就能跳轉回APP
? ? if([urlString hasPrefix:jumpString] && ![urlString containsString:changeredirectString]) {
? ? ? ? decisionHandler(WKNavigationActionPolicyCancel);
? ? ? ? dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{
? ? ? ? ? ? ? ? NSRange redirectRange = [urlString rangeOfString:@"redirect_url"];
? ? ? ? ? ? ? ? //更改redirect_url 為scheme的地址
? ? ? ? ? ? ? ? NSString*redirectUrl = [[urlString substringToIndex:redirectRange.location]stringByAppendingString:changeredirectString];
? ? ? ? ? ? ? ? //記錄本來跳轉的地址,用于APP回來之后的刷新
? ? ? ? ? ? ? ? NSArray*reloadArray = [urlString componentsSeparatedByString:@"redirect_url="];
? ? ? ? ? ? ? ? if(reloadArray.count>1) {
? ? ? ? ? ? ? ? ? ? self.reloadURL= [[reloadArray lastObject]stringByRemovingPercentEncoding];
? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ? self.reloadURL=[NSString stringWithFormat:@"https:%@",schemeString] ;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //發送請求
? ? ? ? ? ? ? ? NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
? ? ? ? ? ? ? ? [request setHTTPMethod:@"GET"];
? ? ? ? ? ? ? ? //referer為空會提示"出現商家參數格式有誤,請聯系商家解決"
? ? ? ? ? ? ? ? //設置Referer 此地址必須注冊到商戶后臺
? ? ? ? ? ? ? ? [requestsetValue:@"sale.eutrun.com://"forHTTPHeaderField:@"Referer"];
? ? ? ? ? ? ? ? [self.webViewloadRequest:request];
? ? ? ? ? ? });
? ? ? ? });
? ? ? ? return;
? ? }
然而,這樣子仍然不夠好,回來的時候,是個白屏,因為你的URL是錯誤的,H5也不能識別,SO,最后一步。
5.重新加載正確的URL
if([urlString isEqualToString:[NSStringstringWithFormat:@"%@://",schemeString]]) {
? ? ? ? decisionHandler(WKNavigationActionPolicyCancel);
? ? ? ? dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{
? ? ? ? ? ? ? ? NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.reloadURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
? ? ? ? ? ? ? ? [self.webView loadRequest:request];
? ? ? ? ? ? });
? ? ? ? });
? ? ? ? return;
? ? }
這個有兩個方法,直接寫在webView的代理中,或者監聽APP的生命周期都可以。綜上所訴,可以完美的在支付完成跳回APP.
最后 加上decisionHandler(WKNavigationActionPolicyAllow);作為正確的H5跳轉。
有什么問題請直接提問,看到的話會立刻回復的,有更好的方式方法麻煩大佬們不吝賜教,謝謝。