概述

在C2C业务里面,难免会涉及到个人转账问题。通过支付宝完成转账便捷可控,成为首选项。但应用与支付宝之间切换账号去复制、黏贴来填充目标账户信息,容易降低用户信任及造成用户在此过程流失。所幸支付宝官方还是留下了一些小渠道,支付宝转帐支付宝可以网页唤起并锁定账户及金额,支付宝转银行卡也能网页唤起并预填充银行卡信息,下面一一来说实现逻辑。

唤起支付宝转账到支付宝

可通过支付宝转账URI可以唤起支付宝转账到支付宝账户,并锁定账户、金额、备注。实现最终效果UIR为:alipays://platformapi/startapp?appId=20000067&url=alipays%3A%2F%2Fplatformapi%2Fstartapp%3FappId%3D20000123%26actionType%3Dscan%26biz_data%3D%7B%22s%22%3A%22money%22%2C%22u%22%3A%222088402759328420%22%2C%22a%22%3A%226.66%22%2C%22m%22%3A%22PID%E8%BD%AC%E8%B4%A6%22%7D ,通过相机扫描URI的二维码即可跳转到支付宝完成锁定金额的转账,二维码如图:

锁金额转账二维码

实现方法

最终URI拆解,其中alipays://platformapi/startapp?appId=20000067 为支付宝收款码页面;url 参数值为 alipays://platformapi/startapp?appId=20000123&actionType=scan&biz_data={"s":"money","u":"2088402759328420","a":"6.66","m":"PID转账"} encode 后的值,其中url参数中的biz_data值涉及几个参数:u 为用户的PID、a 为付款金额、 m 为付款信息;

支付宝PID

支付宝PID为支付宝账户的ID,可通过支付宝账户扫一扫功能,扫描https://render.alipay.com/p/f/fd-ixpo7iia/index.html 转化的二维码获取,二维码如下图:

获取支付宝账户PID

现在你可以拿起你的支付宝,拼接一个属于自己的任意金额的收款二维码了~

官方的方法不能用了,那就用起民间的获取方式:https://www.dedemao.com/alipay/authorize_demo.php,已将上图二维码替换成可用的了。——2020.03.10

小伙伴反馈说这个链接不能用了,检查下确实出问题了!那只能比较麻烦的到PC登录支付宝账号获取 PID 了。如果后续有新的获取PID的方式出现,再更新了。——2020.02.17

唤起支付宝转账到银行卡

可通过支付宝转账到银行卡URI唤起支付宝转账到银行卡并填充目标银行卡信息,实现最终效果UIR为:alipays://platformapi/startapp?appId=09999988&actionType=toCard&sourceId=bill&cardNo=6214865110032519&bankAccount=%E6%B1%9F%E7%82%9C%E5%8B%87&money=1&amount=1&bankMark=CMB&bankName=%E6%8B%9B%E5%95%86%E9%93%B6%E8%A1%8C&。扫下面二维码体验:

支付宝转账到银行卡预填充信息

实现方法

URI再 encode 前为 :alipays://platformapi/startapp?appId=09999988&actionType=toCard&sourceId=bill&cardNo=621486***2519&bankAccount=XXX&money=1&amount=1&bankMark=CMB&bankName=招商银行

拆解URI,其中alipays://platformapi/startapp?appId=09999988 为唤起支付宝转账到银行卡的页面URI、actionType=toCard 转账类型 toCard-到银行卡、 cardNo=6217000030001234567、银行卡号、bankAccount=XXX 银行账户名、money=0.01 转账金额、amount=0.01 转账额度、bankMark=CCB 银行代号、bankName=招商银行 银行名称。

如果你使用了第一个URI直接扫码,跳转到支付宝后,会看见一个空白页面,可能你会说这个方法行不通,既然能写出这个方法,那肯定是能通的,只是你的步骤出错了。

唤起支付宝转账到银行卡并预填充银行卡账户的步骤如下:

graph LR
start((开始)) --> openFlightMode[开启飞行模式]
openFlightMode --> clickLink[点击链接]
clickLink --> toAlipay(跳转到支付宝)
toAlipay --> closeFlightMode[关闭飞行模式]
closeFlightMode --> refreshPage(自动刷新页面)
refreshPage --> stop((结束))

跟着流程走一遍,你会有惊喜的。

支付宝还提供了通过银行卡账号来获取银行信息的接口,这样就不用自己维护银行代号及名称了,接口地址为https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?cardNo=6226661203661552&cardBinCheck=true,传入卡号carNo 即返回银行代号。

风险

浏览器差异

面对市面上不同操作系统,不同系统版本,甚至不同浏览器的杂乱环境中,必然会遇到很多问题,阻止唤起功能的实现。

iOS系统Safari的表现

在iOS系统中的Safari表现算是正常,点击链接或者扫描链接二维码后,会提示是否跳转到支付宝,只要确认即可完成跳转并发起转账。

Andriod系统中自带浏览器表现

各个系统厂商对于系统浏览器的自定义程度不同,故出现的结果也大相庭径,七层楼主要测试的系统为小米的M8,自带浏览器能顺利唤起。但是隔壁小哥的华为,始终无法唤起支付宝。

不同浏览器厂商表现

谷歌浏览器和iOS中Saferi表现一致,无障碍进行跳转。天下第一浏览器UC的表现比较不友好,首次点击按钮时候,会提示是否跳转,选择取消后,再也无法唤起。

解决办法

抛开这些浏览器来说,将该功能以Webview的方式植入APP中,修改APP的Webview配置即可完美唤起。Webview的配置增加下面代码即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
if (url.contains("alipays://platformapi")) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
} else {
view.loadUrl(url);
}
return true;
}

支付宝风控

跳转到支付宝没问题了,但是部分用户由于频繁收款、付款将会被支付宝风控,导致跳转到目标页面后,提示“由于系统原因无法直接识别,请打开支付宝,直接用首页扫一扫功能,谢谢。”,如下图所示:

异常提示

到这步就是和支付宝斗智斗勇的过程了,什么飞行模式跳转啊,什么延时跳转啊~

总结

网页唤起支付宝客户端并发起转账功能总算是研究到符合项目需求了,这些渠道也算是阿里故意放出来的漏洞吧~总体来说,多研究总是能有很多收获。