H5页面调用刷卡支付时,如何正确唤起银联支付界面?
我在做移动端H5的刷卡支付功能,后端返回了一个form表单,让我直接提交到银联的URL。但我在iOS Safari和安卓微信里测试时,有时候能跳转,有时候直接白屏或者没反应,不知道是不是我提交方式有问题。
我试过用JavaScript动态创建表单然后submit(),也试过直接document.write整个表单再自动提交,都不太稳定。下面是我现在用的代码:
<form id="payForm" action="https://gateway.95516.com/gateway/api/frontTransReq.do" method="post">
<input type="hidden" name="version" value="5.1.0" />
<input type="hidden" name="encoding" value="UTF-8" />
<input type="hidden" name="txnType" value="01" />
<!-- 其他签名参数... -->
</form>
<script>
document.getElementById('payForm').submit();
</script>
先说结论,通用的做法是让后端直接返回一个完整的HTML页面,前端不要用JS去处理表单插入和提交,这样最稳定。
你现在的做法问题在于JS动态创建表单后立即submit(),很多浏览器(尤其是iOS Safari)还没来得及把表单渲染到DOM树里,提交动作就执行了,结果就是白屏或者没反应。
最稳定的方案是这样:
让后端返回一个完整的HTML页面,大概长这样:
前端收到后端的响应后,直接用
window.location.href或者window.open()跳转到这个页面URL(后端可以把这个HTML存成一个临时文件或者直接输出),页面加载完自动提交,稳得一批。如果你非要在前端处理表单字符串,那千万别用
document.write,这玩意儿在微信里基本废了。正确的姿势是这样:核心要点就几个:
第一,表单必须先真正插入到DOM里,不能只存在于内存中。
第二,提交要稍微延迟一下,等浏览器完成渲染,
setTimeout50到100毫秒就够了。第三,iOS上如果在异步回调里(比如ajax的success回调)直接触发跳转,会被Safari的安全策略拦截,因为不是用户主动触发的。解决办法是先弹一个确认框让用户点一下,或者用我上面说的后端返回完整页面的方案。
第四,微信里有时候会拦截外跳,建议让后端配置好商户域名白名单,或者用微信的
WeixinJSBridge调起支付。说实话最省事的方案就是后端拼好HTML直接返回,前端一个跳转完事,别折腾什么动态创建了,容易出幺蛾子。