iOS H5微信支付

前言

踩了很多坑,记录下吧

  • 这里使用的webView,wk的话类似
  • H5微信支付可以在网页监听到订单的生成地址和微信的scheme跳转,从而我们可以拦截实现自己的需求

流程

1.添加自定义请求头参数

使用自定义NSURLProtocol,中拦截后加入自己的请求头

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{

    //添加 shop.immouo.com
    //只处理http和https请求
    NSString *scheme = [[request URL] scheme];
    if ( (([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame))
        && ([[request.URL absoluteString] hasSuffix:@"webp"] || [[request.URL absoluteString] containsString:@"shop.immouo.com"]))
    {
        // 看看是否已经处理过了,防止无限循环
        if ([NSURLProtocol propertyForKey:URLProtocolHandledKey inRequest:request]) {
            return NO;
        }
        return YES;
    }
    return NO;
}

在startLoading中拼接

- (void)startLoading
{
    //Mozilla/5.0 (iPhone; CPU iPhone OS 11_2 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Mobile/15C114
    NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
    NSLog(@"---请求打印:%@",mutableReqeust.allHTTPHeaderFields);
    //
    NSLog(@"%@",mutableReqeust.URL.absoluteString);
    if ([mutableReqeust.URL.absoluteString containsString:@"shop.immouo.com"]) {
        [mutableReqeust setValue:@"Mozilla/5.0 (iPhone; CPU iPhone OS 11_2 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Mobile/15C114,immouoapp" forHTTPHeaderField:@"User-Agent"];
        [mutableReqeust setValue:@"shop.immouo.com://" forHTTPHeaderField:@"Referer"];
    }
    
    //在这里该改?
    [NSURLProtocol setProperty:@YES forKey:URLProtocolHandledKey inRequest:mutableReqeust];
    
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue currentQueue]];
    [[self.session dataTaskWithRequest:mutableReqeust] resume];
    
}

2.拦截订单生成的url

UIWebViewDelegate的方法

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    //拦截订单
    NSString *url = request.URL.absoluteString;
    if ([url rangeOfString:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?"].location != NSNotFound && ![url containsString:@"shop.immouo.com://"]) {
        NSString *urlnew = url;
        //拼接回调地址
        urlnew = [NSString stringWithFormat:@"%@&redirect_url=%@",urlnew,@"shop.immouo.com://"];
        NSURL *url = [NSURL URLWithString:urlnew];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
        //设置授权域名
        [request setValue:@"shop.immouo.com://" forHTTPHeaderField: @"Referer"];
        [self.webView loadRequest:request];
        return NO;
    }
    return YES;
    
}

其中shop.immouo.com://自己配置自己的scheme
redirect_url是需要你到微信商户平台配置的域名
微信H5支付(https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4)
网页打开App(https://www.jianshu.com/p/a111c05ad73f)

3.回调加载页面

AppDelegate中判断是自己的scheme,如shop.immouo.com发送通知

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
if ([url.scheme isEqualToString:@"shop.immouo.com"]) {
        NSNotification *notification = [NSNotification notificationWithName:@"wxPaidNotification" object:nil userInfo:nil];
        [[NSNotificationCenter defaultCenter] postNotification:notification];
    }

网页控制器中接受通知,刷新或者重新加载新页面

- (void)wxPaidNotification {
    NSLog(@"刷新网页");
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.webView goBack];
        NSURL *url = [NSURL URLWithString:@"http://shop.immouo.com/member"];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
        [self.webView loadRequest:request];
    });
}

参考链接

https://www.jianshu.com/p/c1973aacc774
https://blog.csdn.net/qq_34873211/article/details/80095573
https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4

你可能感兴趣的:(iOS H5微信支付)