美文网首页IOS
WebView内部发起微信H5支付-IOS

WebView内部发起微信H5支付-IOS

作者: lenka01 | 来源:发表于2019-05-13 18:03 被阅读0次

    前言

    对于微信支付的这块,我们原生App一般处理都是集成微信SDK来完成,这样不仅安全可靠,app之间的跳转也显得比较容易。然而在原生app内部的webView是否也可以做到类似效果呢,答案是可以的。
    优点:可以实现像集成SDK样效果,支付完成可以跳转回来。
    缺点:支付完成后无法立即确认支付完成结果,需要等待服务端支付完成回调确认。

    1.通过跳转WebApi发起支付

    首先准备设置scheme

    • scheme为在微信平台上注册的后端服务域名.例如:注册的是:https://www.baidu.com。那么scheme则为www.baidu.com://。(解决微信支付完成返回app问题)
      这个配置项很关键,还有这个scheme在下面配置的Referer中也使用到。
      如果不配置Referer那么会报错,如下:
      未配置Referer发起支付报错.jpeg

    捕获下单接口

      //MARK: 微信h5支付处理
        if ([urlString rangeOfString:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?"].location != NSNotFound) {
            TBOpenLinkWebController *tbLinkWEbControl = [TBOpenLinkWebController new];
            tbLinkWEbControl.requestUrl = urlString;
            [self.navigationController pushViewController:tbLinkWEbControl animated:YES];
            return YES;
        }
    

    2.检测回调redirect_url

    • 检测下单url中是否包含redirect_url字段。若有,则需要截取掉,否则支付完成后会强制打开系统浏览器Safari加载。
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        NSString *urlString = request.URL.absoluteString;
        //MARK: 微信h5支付处理
        if ([urlString rangeOfString:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?"].location != NSNotFound) {
            DLog(@"---支付---");
            NSRange range = [urlString rangeOfString:@"&redirect_url="];
            
            NSString *subUrl = urlString;
            
            if (range.location != NSNotFound) {
                
                self.redirect_url = [urlString substringFromIndex:range.location+range.length];
                //去百分号
                self.redirect_url = [self.redirect_url stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                
                subUrl = [subUrl substringToIndex:range.location];
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:subUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
                    [request setHTTPMethod:@"GET"];
                    [request setValue:@"www.baidu.com://" forHTTPHeaderField:@"Referer"];//相当于告知微信我们的app的scheme
                    [self.swebView loadRequest:request];
                    
                });
                return NO;
            }
        }
        
        DLog(@"urlString---:%@",urlString);
        return YES;
    }
    

    在AppDelagate中编写openURL处理

    • 在- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options 中处理逻辑
      if ([url.scheme isEqualToString:@"www.baidu.com"]) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"WeChatH5PayNotification" object:url.absoluteString];
            return YES;
        }
    
    • 在新WebView中接收监听
        //MARK: 微信支付完成回调
    - (void)wechatPayCallback:(NSNotification *)notification
    {
        DLog(@"notification-----:%@",notification.object);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            self.navigationItem.title = @"支付完成";
            if (self.redirect_url) {
                NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.redirect_url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
                [self.swebView loadRequest:request];
                DLog(@"redirect_url:%@",self.redirect_url);
            }
        });
    }
    

    到此,可以愉快的发起支付了。

    相关文章

      网友评论

        本文标题:WebView内部发起微信H5支付-IOS

        本文链接:https://www.haomeiwen.com/subject/nasugqtx.html