本文记录React Native 实现的iOS App,如何用iOS调起支付宝App???
两种方法:
方法一:使用支付宝sdk方法:payOrder;
方法二:使用React Native 提供的Linking.openURL(url)方法。
方法一:
iOS集成支付宝 https://opendocs.alipay.com/open/204/105295/
然后React Native通过桥接方法调用原生iOS支付宝sdk;
请求支付宝的url格式:这种格式ios和Android sdk 都能调起支付宝App
alipay_sdk=alipay-sdk-java-
dynamicVersionNo&app_id=2018012302041306&biz_content=%7B%22out_trade_no%22%3A%22200
410ZpAKFY5852%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3
A%22%E9%87%91%E6%A6%9C%E9%A2%98%E5%90%8D%E5%A4%A7%E7%A4%BC%E5%8C%85%22%2C%22timeout
_express%22%3A%2230m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=UTF-
8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2F221.226.157.194%3
A18011%2Forder%2Falipay%2FasynCallback&sign=B4bXla2KNpa9hVMM0ByujPHsKITuV6Cy8hZ%2Bc
YaoDjgUrtb8CZjSFEOZB1wYBAVICIfYwlKxfCiq%2FeuanElO7O7p9FaP1BGSfO3UkVV%2FACXAFc2aQS64
Xeppx88yZalegLZiFRRpzdxZ6Nx5vQYwfu1LaUr46Hmz2KzyAolQZt4Ogwx90r4S3M4PYtNQgJ30Iv8NFzw
emfaoljyVGsJAMjIdjRPCDYyw6as7lj7gjCfGhYmk9S%2BUwYAH72d3ImG9uPrIjTdvoprKbbFIi34pXqQ%
2Fb1TOcz2%2BF%2Fqhhuq917ZhQZbXRHeeiNbDod49gz4LlF1CUhczKucSA%2FFMB3u7Cw%3D%3D&sign_t
ype=RSA2×tamp=2020-04-17+15%3A11%3A07&version=1.0
方法二:
基本上面的方法已经可以完成所用的支付了,但是有需求要在webview中调起原生支付宝这种情况。
下图:支付宝H5页面:https://mclient.alipay.com/cashier/mobilepay.htm。。。。。
在webview加载支付宝H5页面的时候
会给你发送下面支付信息
"alipay://alipayclient/?%7B%22requestType%22%3A%22SafePay%22%2C%22fromAppUrlScheme%22%3A%22alipays%22%2C%22
dataString%22%3A%22h5_route_token%3D%5C%22RZ54yFXFqXTIiVTyBnFDk4YFvhngbimobilecashierRZ54%5C%22%26is_h5_route%3D%5C%22true%5C%22%22%7D"
解码后格式:(方便查看,使用时不用解码)
"alipay://alipayclient/?{"requestType":"SafePay","fromAppUrlScheme":"alipays","
dataString":"h5_route_token=\"RZ54yFXFqXTIiVTyBnFDk4YFvhngbimobilecashierRZ54\"&is_h5_route=\"true\""}"
注意其中的"fromAppUrlScheme":"alipays"
首先重写React Native webview的 onShouldStartLoadWithRequest 方法:拦截支付信息
onShouldStartLoadWithRequest(req) {
var url=req.url
if(url.indexOf("alipay://alipayclient")!=-1 || url.indexOf("alipays://alipayclient")!=-1){
//去支付宝
this.goAlipay(url)
}
//一定要拦截非http链接,否则会有警告
if(url.indexOf("http")!=-1||url.indexOf("https")!=-1){
return true;
}
//不加载该请求
return false;
}
goAlipay(payInfo){
Linking.canOpenURL(payInfo).then(supported => {
if (!supported) {
TOAST_SHOW_FAIL("请检查手机是否安装了支付宝App");
} else {
let url = payInfo.replace("alipays", "jszk");//这里面的xxx是你在iOS原生配置的urlScheme,用来返回你的app的一个标志
return Linking.openURL(url);
}
}).catch(err => console.error('An error occurred', err));
}
上面goAlipay方法中先调用canOpenURL检测手机是否安装支付宝App,但是需要注意:如果你确认手机有支付宝App,但是该方法还是为false,检查iOS项目下的info.plist文件是否设置了应用访问白名单:alipay和alipayshare
如果canOpenURL 为true
在调用openURL前一定要替换fromAppUrlScheme的值为自己定义的值 ,否则支付完成后,没法返回自己的App.
自定义Scheme值: 还是在info.plist文件中的URL types创建一个自己的值
但是这种方法有的问题-------没有支付的状态返回,所以没法做一些善后工作。
这里提供一种方法:
前面讲过用webview加载支付宝H5页面的时候,会返回支付信息-------未支付的支付信息(上面提道的)和支付完成的支付信息(支付宝支付成功后,会回调我们服务给它暴露的支付成功接口--------我们项目给的是一个html页面,展示支付成功)。
可以通过这个页面返回的信息判断是否支付成功。
这里也要分两种情况:
情况一:
在支付宝H5页面6s倒计前,调起原生支付宝app支付,这个页面就不会在读秒了,会等待支付结果。如果支付失败,继续读秒。如果支付成功,会回调我们服务给它暴露的支付成功接口。
情况二:
在支付宝H5页面6s倒计后,会自动跳转到https://mclient.alipay.com/h5Continue.htm。。。。这个页面,再原生支付宝app支付,支付失败,页面不变,支付成功。也会回调我们服务给它暴露的支付成功接口。但是如果我们服务器回传给支付宝的是一个页面,会被https://mclient.alipay.com/h5Continue.htm。。。。遮挡。解决办法:再用户调用原生时。调用webview的回退方法:this.refs.webview.goBack(null);