uniapp H5支付宝支付

uniapp没有对H5的支付进行封装   uni.requestPayment(OBJECT) | uni-app官网 (dcloud.net.cn)

本次先说支付宝的H5支付,微信后面有时间再说。

H5调支付宝支付,目前项目主要是通过后端接口返回的的form表单进行的,后端会生成form表单并编译成字符串返回给前端,前端要做的就是将返回的form表单渲染到页面上,通过提交form表单调起支付宝支付。

form表单大致是这样的,这里我从别处找到

<form name="punchout_form" method="post" action="https://openapi.alipay.com/gateway.do?charset=UTF-8&method=alipay.trade.wap.pay&sign=DEpMkI**********************eWUs6EW3QKlt9OHYv%2FqkporO8Sr5%2Bay5VA9dpx3pAbIiPPajQ2gEcWHvz5bm*******kxH8ZvHUXahQL9S69p9wKNXpXOxYadlsxE8QKGUc4cO5rrgGq08%2BpiOq%2FOz4fLogEBWANXILUMWXNzJn8YryNifZ416Pd%2BxkKgXs%2Fo%2FQDcqEUg*********VXXPRq7IGRGQg%2FpZkOhxCH%2Fq%2B9hnWEncAfQLlAXfPqjdcQTNJ0TJdVr1X1ENOdAr5LQkydWw2EQ8g%3D%3D&return_url=+https%3A%2F%2**********&notify_url=+https%3A%2F%*********Fpub%2Fapi%2Fv1%2F********allback1&version=1.0&app_id=20********57&sign_type=R***&timestamp=2019-0******55&alipay_sdk=al*******.49.ALL&format=json">
    <input type="hidden" name="biz_content" value="{&quot;body&quot;:&quot;&quot;,&quot;enable_pay_channels&quot;:&quot;balance,moneyFund,bankPay,debitCardExpress,creditCardExpress,creditCard,pcredit,pcreditpayInstallment,coupon,point,voucher,mdiscount,honeyPay&quot;,&quot;out_trade_no&quot;:&quot;132ecf937ad84487aa6cbaeb2ec157fe&quot;,&quot;product_code&quot;:&quot;13&quot;,&quot;subject&quot;:&quot;SpringBoot 2.x微信支付在线教育网站项目实战&quot;,&quot;timeout_express&quot;:&quot;20m&quot;,&quot;total_amount&quot;:&quot;98&quot;}">
    <input type="submit" value="立即支付" style="display:none" >
</form>
<script>document.forms[0].submit();</script>

前端:

// 获取支付参数
  pay({
    // 这里可以传回调地址给后端(支付完成后会返回这个页面地址)
    }).then(res => {
      // 支付宝支付,这里只要提交表单
      let form='后端返回的支付宝表单数据'
      const div = document.createElement('formdiv');
      div.innerHTML = form;
      document.body.appendChild(div);      
      //document.forms[0].setAttribute('target', ' self');
      document.forms[0].submit();
      div.remove();
    })

注意:

刚开始的时候是写了窗口的target的,后来发现在IOS的系统中无法拉起支付宝支付(微信打开和Safari 浏览器),在IOS上面安装其他浏览器比如Chrome等,则可以进行支付,但无法回调。

1.将target取消,查看资料说Safari 安全策略拦截了网页打开新窗口,ios不要在新窗口唤醒支付宝app即可。

2.官方文档上的一句话:注意:在iOS系统中,唤起支付宝App支付完成后,不会自动回到浏览器或商户APP。用户可手工切回到浏览器或商户APP;支付宝H5收银台会自动跳转回商户return_url指定的页面。

关于IOS无法回调的问题,由于本次项目这个需求不是必须,就没有进行深究。但看到了其他文章有介绍https://blog.csdn.net/weixin_39972567/article/details/111483775

h5支付不能打开支付宝 ios_iOS支付宝H5支付无法返回APP解决方案

本文前大段在讲楼主是如何解决这个问题的,以及中间遇到的麻烦。赶时间的同学可以直接看最后的 最终解决方案。

在讨论之前,我们先看看官方文档上的一句话:注意:在iOS系统中,唤起支付宝App支付完成后,不会自动回到浏览器或商户APP。用户可手工切回到浏览器或商户APP;支付宝H5收银台会自动跳转回商户return_url指定的页面。

what? 官方直接跟我们说GG了?楼主不甘心,还是想尝试一下。

借鉴之前 iOS微信H5支付无法返回APP解决方案 的经验,先在 return_url 这个参数上做个尝试吧。

支付宝和微信不同的是,支付宝的return_url不需要在支付宝管理后台备案(填写),微信的redirect_url是需要的。

第一次尝试

webView拦截请求https://mapi.alipay.com/gateway.do,修改return_url参数为自己的URLScheme,比如 URLEncode(A.company.com://),结果失败了,进入支付宝报错的页面。仔细看了一下请求的其它参数,居然有个sign!支付宝文档上也有这个参数,居然校验了参数签名的,好吧,客户端篡改参数的方案宣告失败!

第二次尝试

既然不能篡改,那直接下单的时候填吧,请求后台的同学协助一下,在下单的时候把return_url参数改成 URLEncode(A.company.com://),结果还是失败了。后台同学提示我,return_url必须是HTTP/HTTPS开头,支付宝文档上有说明。

第三次尝试

那加上http试试,我又让后台同学把return_url改成  URLEncode(httpA.company.com://),同时把APP的URLSchemes改成 httpA.company.com,再次尝试,调起支付宝返回的时候打开了Safari,在Safari里面显示了我们支付中心的错误页面,return_url方案彻底失败了!

要不就算了,跟产品说支付宝无法实现支付完成后跳回APP,反正支付宝官方文档上都这么写了。

虽然这么想了,但是我还是继续翻看支付宝的文档,希望能找到点蛛丝马迹。

支付宝文档

schemeStr,这个关键字让我眼前一亮。

手机网站支付转Native支付:支付宝的意思是,我们提供了一个SDK,你接了之后就可以很方便的实现H5收银台(即在web上输入支付宝账号密码支付)到支付宝APP收银台的过渡。

如果你是一个"正规"APP开发者,至此已经可以解决你的问题了。按照支付宝文档接支付宝SDK即可,就能实现H5支付回调APP了。

但,这不是楼主想要的方案,由于工作需求的原因,楼主不想也不敢接支付宝的SDK,怕被苹果爸爸审核扫包啊。如果你的APP"应该"用苹果支付,即使你没有用到支付宝的功能,但是包含了支付宝的SDK,审核被发现了,也可能被拒绝的。

继续寻找解决办法。

下载了支付宝的Demo,试了下确实可以跳回APP。

楼主琢磨着,既然SDK能实现这个功能,说明支付宝还是支持的H5支付完成后返回APP功能的,并不是向文档上说的,"在iOS系统中,唤起支付宝App支付完成后,不会自动回到浏览器或商户APP。用户可手工切回到浏览器或商户APP",只是支付宝不愿意公开而已。

那就以这个支付宝Demo为切入点吧,虽然SDK中有schemeStr这个参数,但是SDK是黑盒啊,你不知道它在里面做了些什么。/**

*  支付接口

*

*  @param orderStr       订单信息

*  @param schemeStr      调用支付的app注册在info.plist中的scheme

*  @param completionBlock 支付结果回调Block,用于wap支付结果回调(非跳转钱包支付)

*/- (void)payOrder:(NSString *)orderStr

fromScheme:(NSString *)schemeStr

callback:(CompletionBlock)completionBlock;

追本溯源,最终打开支付宝APP都会走[UIApplication sharedApplication] openURL:]

在Demo工程里搜了一下,没有。但我肯定SDK里面肯定有!

whatever —— Method Swizzling#import #import @implementation UIApplication (TrackTimer)+ (void)load

{    static dispatch_once_t oneToken;    dispatch_once(&oneToken, ^{

SEL mySelector = NSSelectorFromString(@"my_openURL:");

SEL orginalSelector = NSSelectorFromString(@"openURL:");

Method myMethod = class_getInstanceMethod([self class], mySelector);

Method orginalMethod = class_getInstanceMethod([self class], orginalSelector);        BOOL didAddMethod = class_addMethod([self class], orginalSelector, method_getImplementation(myMethod), method_getTypeEncoding(myMethod));        if (didAddMethod) {

class_replaceMethod([self class], mySelector, method_getImplementation(orginalMethod), method_getTypeEncoding(orginalMethod));

}        else {

method_exchangeImplementations(myMethod, orginalMethod);

}

});

}

- (void)my_openURL:(NSURL*)url

{    NSLog(@"%@",url);

[self my_openURL:url];

}

打印结果如下

URLDecodealipaymatrixbwf0cml3://alipayclient/?{

"fromAppUrlScheme" : "alisdkdemo",

"requestType" : "SafePay",

"dataString" : "trade_no="2018041921001001270586523089"&pay_phase_id=""&biz_type="trade"&biz_sub_type="TRADE"&app_name="tb"&extern_token="1fc77c67c70ef70d58e2bf7c513d91a5"&appenv=""&pay_channel_id="alipay_sdk"&bizcontext="{"av":"1","sc":"h5tonative","ty":"ios_lite","appkey":"2014052600006128","sv":"h.a.3.5.3","an":"com.antfin.AliSDKDemo"}""

}

为什么前面会有一点乱码,alipaymatrixbwf0cml3,不管它了。fromAppUrlScheme,是不是很惊喜。

是不是支付宝H5支付都有这个参数呢?楼主赶紧用自己的项目尝试了一下,webView最终会有一个alipay://请求的,拦截它,看看参数URLDecode以后(部分字段我做了屏蔽)

alipay://alipayclient/?{"dataString":"h5_route_token="xxxxxxxxxxxxx"&is_h5_route="true"","requestType":"SafePay","fromAppUrlScheme":"alipays"}

也有fromAppUrlScheme这个参数,而且默认是支付宝APP的URLScheme: alipays。

对比一下发现,SDK中传入的schemeStr参数对应就是alipay:// 中的 fromAppUrlScheme字段。

由此楼主猜测,在 alipay:// 打开支付宝时,传入 fromAppUrlScheme,支付结束后就会跳到对应的APP。

最终,楼主在自己的项目中验证了上述猜测。

总结下吧

最终解决方案

方案一

接支付宝提供的SDK,schemeStr参数传入自己APP的URLScheme即可。 具体的 手机网站支付转Native支付

方案二

不需要接SDK,不需要添加支付宝白名单,webView拦截 alipay://alipayclient 请求,追加或修改参数 fromAppUrlScheme为你自己的URLScheme值(这一步可没那么简单,自己动手吧,偷笑),生成新的NSURL,然后用 [[UIApplication sharedApplication] openURL:] 打开即可。

2018.5.24更新(上面看懂了下面这段可以不用看)

总有人私信我问我怎么追加fromAppUrlScheme。可能是我说的"webView拦截",让初学者不明白吧,简单提一下。

在webView"发起请求的代理方法"里面拦截请求的URL,即如果请求是alipay://alipayclient开头的,说明这个请求就跳转支付宝的请求。替换里面fromAppUrlScheme的值为你自己的scheme值。(当然如果更严谨的话,应该是判断fromAppUrlScheme这个key是否存在,存在则替换其值,不存在则追加)。用替换好的字符串生成一个NSURL,用[[UIApplication sharedApplication] openURL:newURL]跳转支付宝。代理方法返回NO,即终止这次请求。
————————————————
版权声明:本文为CSDN博主「weixin_39972567」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39972567/article/details/111483775

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值