最近由于产品增加支付需求,研究了一下微信与支付宝的扫码支付。现在把学习心得和踩过的坑写出来,供大家参考。
前提
- 扫码支付分类两种情况:
- 卖家通过扫码设备,扫描买家的二维码,完成支付。——这种支付方式的应用环境:便利店、超市等的收银台
- 卖家调用支付平台的预订单接口,返回支付二维码连接地址,卖家系统调用二维码生成器,生成二维码,买家扫描二维码,完成支付。——这种支付方式的一个实际的案例就是亚马逊kindle下订单。
- 二维码生成器,可以调用google的Zxing即可。或者直接调用一些二维码的生成api。
- 这里讲的扫码支付,指的是第二种情况下的扫码支付。
微信扫码支付
- 微信扫码支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1
- 我们采用的是模式二,模式二相对于模式一而言操作相对简单 。
- 在操作微信支付,调用统一下单的时候,跟微信浏览器H5调起公众号支付差不多。只不过是这里我们不在需要获取用户的openid,直接将必要的参数封装起来,传递给微信的unifiedorder接口即可。在做同一单是封装参数如下:
在封装参数的时候要注意,微信对系统生成的订单长度是有限制的,太短的话,微信会认为不安全,无法生成统一订单。在将必要的参数封装成HasMap后,直接调用微信的签名生成方法,就可以生成签名。然后将签名封装后,即可调用统一下单接口。对统一下单的返回值解析,需要按照微信给出的要求去解析。微信支付的sdk同样提供了xmlToMap的方法,我们很容易的获取到相应的值。
- 支付成功后的异步通知,这里是需要注意的,而且微信官方文档也说了,为了防止假通知的产生,需要验证签名是否正确,需要验证订单号和金额是不是跟商户系统的订单号和金额匹配。在做签名验证的时候,需要注意的是,微信异步通知的签名使用的签名类型是:“HMACSHA256”。所以在验证的时候需要将sign_type作为参数传到相关的api中。
- 最后,需要注意的是,正确接受到通知后,需要向微信返回信息,否则,微信会不停的发通知过来。返回信息的格式按照官方文档提供的格式即可。
支付宝支付:
- 支付宝扫码支付的官方文档:https://docs.open.alipay.com/194
- 支付宝扫码支付即当面付有三种,1、条码支付,即卖家扫买家的支付宝付款码;2、扫码支付,即买家扫卖家的二维码;3、声波支付。这里我们采用的是第二种,扫码支付。
- 我们可以在search.maven中获取到alipay-sdk,还可以在官网上下载到当面付的demo。当面付的demo是在alipay-sdk基础上的二次封装。我们只需要按照readme.txt中所说的,修改相关属性,然后打包编译成jar包,引导我们的项目中既可以完成扫码支付。
- 下面便是支付宝扫码支付调用统一收单线下交易预创建(扫码支付)获取付款二维码连接的方法:
设置静态代码块,在使用到的时候,会直接调用支付宝的Configs.init()初始化公共参数。然后直接生成一个alipayTradeService的单例。既可使用。
- 虽然支付宝已经做到的很完美了,但是他没有给我们提供接收到异步通知以后解析通知的方法。所以如下代码段是对通知的解析,从post中获取到参数,并封装到map中去。
- 同样,在获取到异步通知以后,我们需要对签名进行校验,也需要对订单号和金额进行核对。并且要通知支付宝系统已经获取到了通知。
仅供大家参考。本来想贴源码上来,但是考虑到复制黏贴不能到达知识分享的目的。所以直接上截图。下面再简要总结一下我做支付时候的思路:
首先,我选择去找官方文档看一下哪一种扫码方式比较适合项目需求。
其次,确定好扫码方式后,我首先看了官方文档提供的时序图和开发步骤。
第三,熟悉完开发流程后,开始准备开发,准备好调用支付系统所需的商户系统的数据。
第四,下载支付平台提供的sdk和demo。仔细阅读readme并查看相关API。防止重复造轮子,提高开发效率。
第五,使用平台提供的API封装数据或者做数据校验,完成支付过程和回调过程。