博客> App调起H5微信支付并返回App
App调起H5微信支付并返回App
2019-12-09 16:27 评论:0 阅读:831 kyloMooa
ios H5微信支付
点击微信支付时webView会先加载https://wx.tenpay.com开头的Url,我们需要把Referer修改为与URL scheme相对应的域名,比如Referer为 "www.xxxxx.com ://"那么URL scheme为"www.xxxxx.com"。ww.xxxxx.com需是网站域名或子域名。然后移除Url中的redirect_url,如果不去掉 微信返回时会跳转到Safari)。 具体代码如下
//将要加载Url时进行拦截处理
- (BOOL)webView:(UIWebView * _Nonnull)webView shouldStartLoadWithRequest:(NSURLRequest * _Nonnull)request navigationType:(UIWebViewNavigationType)navigationType
{

    if (![self settingWeiXingPayInvokeApp:request]) {
        return NO;
    }
    if (![self invokeWeiXinPay:request]) {
        return NO;
    }
    return YES;
}
//设置调起微信返回到App
-(BOOL)settingWeiXingPayInvokeApp:(NSURLRequest *)request{
    if ([request.URL.absoluteString hasPrefix:@"https://wx.tenpay.com"]) {
        NSDictionary *headers = [request allHTTPHeaderFields];
        if ([[headers objectForKey:@"Referer"] isEqualToString:@"www.sybercare.com://"]) {
            return YES;
        } else{
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                NSURL *url = [request URL];
                NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:kWebLoadTimeoutInterval];
                [newRequest setHTTPMethod:@"GET"];
                [newRequest setValue:@"www.xxxxx.com://" forHTTPHeaderField:@"Referer"];

                if ([newRequest.URL.absoluteString containsString:@"redirect_url"]) {
                    //转成字典
                    NSDictionary *dict = [self dictionaryFromQuery:newRequest.URL.absoluteString usingEncoding:NSUTF8StringEncoding];

                    //去掉redirect_url(如果不去掉 微信返回时会跳转到Safari)
                    NSMutableArray *array = [NSMutableArray array];
                    [dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL * _Nonnull stop) {
                        if (![key isEqualToString:@"redirect_url"]) {
                            [array addObject:[NSString stringWithFormat:@"%@=%@",key,obj]];
                        }else{
                            self.redirect_url = [obj copy];
                        }
                    }];
                    NSString * newUrl = [array componentsJoinedByString:@"&"];
                    newRequest.URL = [NSURL URLWithString:newUrl];
                }
                //加载新的request
                [self.webView loadRequest:newRequest];
            });
            return NO;
        }
    }
    return YES;
}
把字符串转字典
-(NSMutableDictionary *) dictionaryFromQuery:(NSString *)query usingEncoding:(NSStringEncoding)encoding {

    NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"];
    NSMutableDictionary* pairs = [NSMutableDictionary dictionary];
    NSScanner* scanner = [[NSScanner alloc] initWithString:query];
    while (![scanner isAtEnd]) {
        NSString* pairString = nil;
        [scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];
        [scanner scanCharactersFromSet:delimiterSet intoString:NULL];

        NSRange qRange = [pairString rangeOfString:@"="];

        if (qRange.length > 0) {
            NSString *key = [pairString substringToIndex:qRange.location];
            NSString *value = [pairString substringFromIndex:qRange.location+qRange.length];

            if (key && value) {
                [pairs setObject:value forKey:key];
            }
        }
    }

    return [NSMutableDictionary dictionaryWithDictionary:pairs];
}
//调起微信支付
-(BOOL)invokeWeiXinPay:(NSURLRequest *)request{
    NSString *reqUrl = request.URL.absoluteString;
    if ([reqUrl hasPrefix:@"weixin://wap/pay"] || [reqUrl hasPrefix:@"weixins://wap/pay"]) {
        BOOL bSucc = [[UIApplication sharedApplication]openURL:request.URL]; //bSucc是否成功调起微信
        if (!bSucc) {
            [self showHint:@"请先安装微信"];
            return NO;
        }
    }
    return YES;
}
支付完成后或者取消,H5需要刷新支付页面,此时在App进入前台时发送一个通知,让webView加载刚才保存的redirect_url
//微信返回App后刷新H5
-(void)reloadPaymentPage{
    if (self.redirect_url.length != 0) {
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[self URLDecodedString:self.redirect_url]]];
        [self.webView loadRequest:request];
    }
    self.redirect_url = @"";
}

//URL需做转码处理,防止url编码格式不对
-(NSString *)URLDecodedString:(NSString *)str
{
    NSString *decodedString=(__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)str, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));

    return decodedString;
}
相关参考:
微信H5支付官方开发文档:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1
iOS实现微信外部H5支付完成后返回原APP(多APP也可实现):http://www.cnblogs.com/Life-Record/p/8472319.html
iOS 解决微信h5支付无法直接返回APP的问题https://www.jianshu.com/p/90db7dfb075c
收藏
0
sina weixin mail 回到顶部