React Native 0.44.3 ----------微信h5支付

本篇记录ios使用ReactNative完成微信h5支付的一些注意事项。

     a. 支付完成或者取消微信h5支付,会跳转到手机默认的浏览器中(safari),无法回到原App.

     b. 如何获得支付状态???


1. 微信sdk与微信h5支付链接的不同

微信sdk:

{"package":"Sign=WXPay","appid":"wx41647c3ca4a4c6de","sign":"735D651D1BA5733EC12AC2B9218CC6DA","prepayid":"wx19105425889487ab4f70f0d5ec60920000","partnerid":"1500210432","noncestr":"s8tqy0wTNBA8p7nk","timestamp":"1597805512"}

微信h5支付:( A链接

https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx1716451470364793c6d22eeee8f3040000&package=602473332&redirect_url=https%3A%2F%2Fmp.weixin.qq.com/intp/nontax%2Fmwebpay%3Faction%3Dpage%26order_id%3DZWJoYW5EcW8rTWYyNW1vWEIyNkUnXyMwQWBIJ3lRMGZRZnZgVSE-WVYoaEJ3RmdQdUglZDkqXzh1OzN5KkxdeXcoRCwkKngtSyhRIldOVw%26from_mwebpay%3D1%26auto_call_pay%3D0%26auto_jump_result_page%3D0

 2. React Native微信h5支付流程:

    通过React Native 的WebView加载 A链接,微信会返回给我门一个调起微信支付的链接(B链接),然后通过React Native 桥接的方法Linking.openURL(B链接),调起微信支付。

B链接如下:

weixin://wap/pay?prepayid%3Dwx24143958550903678a2224c0957e420000&package=1666328792&noncestr=1598251198&sign=1933725ad49c94e84c52703b436fb857

 3. 微信h5支付需要解决的问题(只针对ios)

     a. 支付完成或者取消微信h5支付,会跳转到手机默认的浏览器中(safari),无法回到原App.

     b. 如何获得支付状态???

 

解决a: 

       参考文档https://www.jianshu.com/p/90db7dfb075c

     在网上找了一堆关于a问题的博客,基本上都和上面的参考文档一样,只给出了原生ios UIWebView或者WKWebView的解决方法。很少有React Native的WebView的解决方法,但是我都试过,没用。

例如添加WebView 添加请求头:

source={{
 uri:this.url+'&redirect_url=https%3A%2F%2Fapi.jingtaomall.cn%2Fhtml%2Fwxpay.html',
 headers: {Referer:'https://api.jingtaomall.cn' }
}}

经过多次实验:React Native层的WebView貌似修改链接中的redirect_url和请求头中的Referer不起作用。

最终的解决思路:

        还是的参照参考文档,修改React Native(版本0.44.3)的源码-------RCTWebView.m。            

        一、在React Native的源码-------RCTWebView.m中,拦截 A链接,修改链接中的redirect_url和请求头中的Referer。

               由于React Native 0.44.3使用的还是iOS UIWebView, 所以在RCTWebView.m中的shouldStartLoadWithRequest方法中添  加了如下内容

  //拦截微信h5支付
  if ([[request.URL absoluteString] hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"]) {

        NSDictionary *headers = [request allHTTPHeaderFields];    
        NSString *newUrl = nil;
        NSString *absoluteString = [request.URL absoluteString];
        //两种方法:
        //1.将链接中的redirect_url替换为自己定义的URL Schemes,
        //2.直接将redirect_url去掉,系统会用Referer填充redirect_url
        if ([absoluteString containsString:@"redirect_url="]) {
            NSRange redirectRange = [absoluteString rangeOfString:@"redirect_url"];
            newUrl = [[absoluteString substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=a1.mp.weixin.qq.com://wxpayh5/"]];
        } else {
            newUrl = [absoluteString stringByAppendingString:[NSString stringWithFormat:@"redirect_url=a1.mp.weixin.qq.com://wxpayh5/"]];
        }

        //如果Referer不是自己定义的URL Schemes,则替换,其中wxpayh5为回传参数
        if (![[headers objectForKey:@"Referer"] isEqualToString:@"a1.mp.weixin.qq.com://wxpayh5/"]) {
            //拦截该请求,创建一个新的请求,将Referer设置为定义的URL Schemes,在重新加载新的请求
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                dispatch_async(dispatch_get_main_queue(), ^{
                    // NSURL *url = [request URL];
                    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:newUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
                    [request setHTTPMethod:@"POST"];
                    //修改Referer,当作告诉浏览器,跳回我的app
                    [request setValue:@"a1.mp.weixin.qq.com://wxpayh5/" forHTTPHeaderField: @"Referer"];
                    [_webView loadRequest:request];
                });
            });
            return NO;
        }
    }

二、 创建info---->URL Types

      

    

到这里我们已经将问题a解决了。 


下面解决问题b:由于没法知道微信h5的支付状态。我的解决方法是:在每次调起微信支付回到原app之后,调一下自己的订单查询接口,来判断订单状态。

三、在AppDelegate.m的openURL方法中通过回传参数--wxpayh5,处理微信支付回到原app的逻辑。

 if([url.host isEqualToString:@"wxpayh5"]){
      //微信h5支付,发起广播,通知React Native层处理相应逻辑
      [[NSNotificationCenter defaultCenter] postNotificationName:@"WxPayBoardcast" object:@"1"];
    return YES;
  }

 

最后再给一个React Native 的微信支付的封装:

//直接调起微信h5支付
export function DIRECT_NATIVE_WX(payInfo) {

	if (payInfo.indexOf("weixin://wap/pay?") != -1) {
		Linking.canOpenURL(payInfo).then(supported => {
			if (!supported) {
				TOAST_SHOW_FAIL("未检查到微信客户端,请确认是否安装???");
			} else {
				// let url = payInfo.replace("alipays", "jszk");
				return Linking.openURL(payInfo);
			}
		}).catch(err => {
			console.log('微信支付错误');
		});
		return true;
	}
	return false;
}

//桥接原生微信支付
export function BRIDGE_NATIVE_WXPAY(object, payInfo) {

	console.log('开启微信支付');
	//创建监听器监听native端的广播
	object.wxay_subscription = global.NativeBoardcastEmitter.addListener(
		'Native_PushTo_RN_WxPayBoardcast', //广播名称
		(result) => {

			if (object._handleWxPayComplete) {
				object._handleWxPayComplete();
			}

			if (result == 1) {
				console.log('微信SDK支付成功,或者h5支付返回')
				if (object._handleWxPaySuccess) {
					object._handleWxPaySuccess();
				}
			} else {
				console.log('微信支付失败')
				if (object._handleWxPayFailed) {
					object._handleWxPayFailed();
				}
			}
			//删除监听
			// global.NativeBoardcastEmitter.removeAllListeners('Native_PushTo_RN_WxPayBoardcast')
			//删除监听
			if (object.wxay_subscription) {
				object.wxay_subscription.remove();
				object.wxay_subscription = null;
			}
		}
	);

	// 判断是否是微信h5支付
	if (!DIRECT_NATIVE_WX(payInfo)) {
		// 调起微信SDK支付
		global.NativeBridge.NATIVE_wxPay(payInfo);
	}
}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值