业务需求
通过一个二维码完成多种第三方支付方式支付的需求:
商户打印一个静态的二维码,顾客用app(比如支付宝、微信、百度钱包)扫这个二维码后,进入商户的一个付款页面,输入金额后,完成支付。
技术方案
一 生成二维码
通常线下场景是一个门店一个二维码,因此生成二维码时最好加入门店id参数。
可以方便使用统一门店编号定位到是哪个商户的交易,结算给哪个商户,收款成功后通知给哪个商户。
一般建议生成二维码的url不要太长,长度越短则生成的二维码识别率越高。
一般生成二维码的url示例为:https://www.test.com/?shop=1001
二 扫码识别
用户扫码时,可能会有许多种软件来扫,但能够处理支付宝交易的却只有支付宝客户端。因此需要做识别扫码来源并在页面作出提示,引导用户用支付宝扫码。
用户用app扫商户的二维码后,其实是用app浏览器打开到商户的页面, 商户页面通过识别浏览器header中的user-agent来判断是哪个app打开的。
常见App浏览器的user-agent 识别关键字:
支付宝: AlipayClient
微信: MicroMessenger
如果识别到不包含AlipayClient,则跳转到错误提示页面,引导用户用支付宝扫码。
支付宝扫码成功后,会将门店id提交到你的服务端,你可以存在session中或放在下一步你的授权回调地址参数中。
三 获取用户信息
扫码成功后,需要先获取到扫码用户的userid,不然下一步下单无法进行。
获取用户是使用支付宝的用户信息授权实现。
简单来说分为以下五步实现:
1.拼接你的授权地址,包含授权范围和回调地址 (授权范围用这个scope=auth_base,回调地址中你可以包含一些参数:如门店id)
2.让用户浏览器跳转到授权地址,授权后用户浏览器会请求你的回调地址
3.授权后你的回调地址会收到auth_code参数
4.你使用auth_code参数去换取user_id和access_token (access_token你用不上,一般只需要有user_id就可以下单了)
5.使用access_token可以去获取用户授权信息(这一步开发者一般用不上,授权范围为scope=auth_user时使用,可以获取用户更多信息)
以上几个步骤可以参考 网页授权获取用户信息https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.U57SiP&treeId=193&articleId=106001&docType=1#s3 中的第四步
拿到user_id后可以给下一步下单使用。
服务端拿到user_id后,user_id可以存session,也可以返回给用户页面隐藏域表单,并给用户页面显示付款页面。
四 下单
由于一码多付方案都是最简便方式,没有收银员输入金额的流程。
所以付款页面需要有输入框让用户填写付款金额,并提交表单发起付款。
目前已有了门店id,付款方userid,交易金额,开发者可以通过门店id在你的系统中查到配置的收款方账号信息。此时使用统一收单交易创建接口发起下单,接口文档:https://doc.open.alipay.com/docs/doc.htm?&docType=1&articleId=105591
下单成功后,支付宝会返回支付宝交易号,使用文档中的唤起收银台JSAPI来唤起收银台让用户付款。
服务端将脚本和订单号组装好返回给用户浏览器,用户支付宝浏览器会自动执行js并唤起收银台,让用户选择付款渠道和输入密码,完成付款。
完成付款后,用户页面会跳转到支付宝统一的付款成功页面
五 获取收银结果
服务端获取用户的付款状态有两种方式:
- 轮询查询
服务端发起下单后就异步子线程向支付宝发起交易查询请求(https://doc.open.alipay.com/docs/api.htm?spm=a219a.7395905.0.0.Q3YDvW&docType=4&apiId=757 ),每个5秒查一次,查1-2分钟,一旦查到付款成功则终止,如果超时了还未付款,则发起撤销请求(https://doc.open.alipay.com/docs/api.htm?docType=4&apiId=866 ),避免用户在离店之后付款产生单边账纠纷。
- 异步通知
下单时,根据文档在交易创建接口中传递notify_url公共参数,则付款成功后支付宝会给这个notify_url地址发起回调付款结果。
获取异步通知付款结果可以参考下面的异步通知文档
六 通知收银员
服务端获取到付款成功的结果后,需要通知收银员(直接让用户拿手机付款结果给收银员看是有风险的,如:用户拿付款成功的截图欺骗收银员,或用户付款成功但商户未入账。)。
最简单的方式是调用短信接口通知这个门店的收银员。如果你之前没有自建短信发送渠道,可以参考使用 阿里大于短信通知方案
创建订单+JSAPI唤起收银台支付
https://doc.open.alipay.com/docs/doc.htm?&docType=1&articleId=105591