支付宝扫码付款功能实现
背景
最近接到一个新需求,实现用户扫码,完了转账给用户。
需求分析
这需求说来也简单:
- 付款端(我),选择金额生成二维码;
- 用户打开支付宝,扫码收钱;
这里有两点需要注意的:
- 支付宝和微信均不提供付款码生成API,所以付款端提供的二维码不是付款码
- 用户可能会用微信和支付宝扫码,实际上区分用户所用的浏览器,这个也简单,请求头的user-agent包含MicroMessenger的就是微信,包含AlipayClient的就是支付宝。
那么获取用户就是下一个需要考虑的点,我得知道给谁转钱呀。这就没有办法弄成一码对不同浏览器了,因为支付宝和微信获取用户的方式都是必须在各自的浏览器上的。
支付宝的获取用户区分PC网页和生活号/H5,区别在于第1步,生活号/H5需要在前端页面用js发起请求。
微信授权
两个平台都需要引导用户访问指定规则的链接,所以一个码对应不同平台的想法破灭,那就只能老老实实的生成对应的二维码了。
目前只研发了支付宝的付款,因为微信需要开户后90天不间断的流水才能启用支付功能。
第一步 创建应用,添加功能
详见 支付宝接入准备 。需添加“单笔转账”的相关功能,然后进入开发设置中完成接口加签方式、IP白名单、应用网关、接口内容加密方式开发信息设置。详情请参见配置应用环境。
设置对应的公钥私钥,获取证书。把应用私钥保存到配置文件中;把应用公钥证书、支付宝公钥证书和支付宝CA根证书文件保存到项目中,后面会用到。
第二步 生成二维码,获取auth_code
这里的二维码对应的链接就是用户授权链接,支付宝分为PC网页和生活号/H5两种获取方式。
PC网页是我这次需求采用的方式,相对比较简单,拼接https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=APPID&scope=SCOPE&redirect_uri=ENCODED_URL&state=STATE即可。详见 PC 网页内获取用户信息。
- APPID为开发者应用的 APPID;
- SCOPE为接口权限值,目前只支持 auth_user 和 auth_base 两个值,本场景下auth_base(静默授权),用户感知的就是直接进入了回调页(即ENCODED_URL)。
建议不要用auth_user,首次授权需要用户手动点击同意,因此需要考虑用户拒绝授权的情况并进行相应容错。
- ENCODED_URL为授权回调地址,服务端接口会校验授权链接中配置的 redirect_uri 与上一步配置应用环境中配置的授权回调地址(如下图所示)是否一致。
注: ENCODED_URL需UrlEncode。
- STATE为商户自定义参数,用户授权后,重定向到 redirect_uri 时会原样回传给商户。此处可用自设的付款记录加密标识,即可做校验也可以防止重复付款。
生活号/H5详见生活号/H5。获取auth_code的步骤相差不大,只不过生活号/H5需用js发起请求。
第三步 获取用户id
用户扫上一步生成的二维码后,就会访问配置的redirect_uri,请求参数是auth_code和上一步配置的state。这里要先导入maven依赖信息: 服务端 SDK ,建议使用通用版。
获取到auth_code,就可以获取用户id了。代码如下:
/**
* 获取支付宝用户信息
* @param authCode
* @return
*/
public static String getUserId(String authCode) {
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");// 支付宝网关
certAlipayRequest.setAppId(