本文涉及“并行开发”思想:
假设实际开发工作中:支付&订单 两个模块,分别由两位同事并行开发;
一位同事在开发支付模块时,可能需要依赖订单模块的的类、方法、工具类,但负责订单的同事还没开发出来,还看不到订单的完整业务逻辑;
但是不可以因为这样就影响后端的并行开发(前端与后端间有并行开发,后端与后端间也有并行开发;因为后端项目非常庞大)
本文的支付模块会模拟并行开发场景;
跨业务开发的能力是衡量一个开发者是否优秀的标准之一。
功能:
支付宝对接 支付回调 查询支付状态
学习目标:
熟悉支付宝对接核心文档,调通支付宝支付功能官方DEMO
解析支付宝SDK对接源码
RSA1和RSA2验证签名及加解密
避免支付宝重复通知和数据校验
natapp外网穿透和tomcat remote debug
生成二维码,持久化到图片服务器
支付宝扫码支付功能对接:(支付宝的"当面付"产品)
一些重要官方文档
沙箱调试环境(买家账号测试、上家账号测试)
支付宝扫码支付主业务流程
支付宝扫码支付流程
支付宝扫码支付重要的字段
支付宝扫码支付重要细节
对接技巧(与外网联调)
官网DEMO调试
沙箱调试环境
是协助开发者进行接口功能开发及主要功能联调的辅助环境,沙箱环境模拟了开放平台部分商品的主要功能和主要逻辑
主动轮询和回调的区别?
主动轮询:好比是用一个老式水壶烧水,烧水的人过一会就要检查水有没有开;
回调:好比是水烧开了会自动通知的水壶,不用自己一直检查;
避免单边帐:
即支付宝和商城中,只有一边有记帐;
同步请求的加签和验证签名:这两个是为了保证数据传输的安全性
下面加签和验签:是为了保证数据安全性
加签:要通过私钥进行解密,只有自己和支付宝能看懂
加签字符集统一用utf8
验签:
请求了支付宝拿到参数,验证他,放在Content中;
回调的验证:
支付宝会提供官方验证:签名、金额、订单号、订单状态、交易状态、商户ID;
我们也可以用其中的参数与商城里的参数做校验,保证支付宝回调正确,也与商城参数能对上;
过滤掉重复的通知:
毕竟是别人回调你,我们不能把自己的检验标准完全交给别人;
支付宝回调一次,可能商城中参数发生了变化;若支付宝再回调一次,我们根据已改变的情况再变化,变化的结果就错了,我们要过滤掉重复的通知。
一定要验证并确保可接受的异步通知是支付宝发出的
通过支付宝的验证方法实现它;
若在线上实现,可以与对接人要发出异步通知的IP或其他验证方式
截图:验签方法 收到支付宝回调后,把回调参数放入Map中,方法返回Boolean,可判断是不是应该接受他;
回调请求的返回
指支付宝调商城,商城要给支付宝一个返回,返回有规则:
程序执行完成后应该打印输出success
(此字符必须一字不差),若商城反馈给支付宝的字符不是success
,支付宝服务器会不断重复通知,直至超过24小时22分钟;
一般情况下,25小时以内完成8次通知;
(通知间隔频率为4m 10m 10m 1h 2h 6h 15h)
扫码的对接技巧(针对回调)
1.路由器设置开放本地到外网(麻烦,喜欢折腾的同学可以试)
2.外网远程debug:若商城部署在阿里云,回调地址设置成阿里云服务器,保证远程代码版本和本地代码保持一致(若不一致会发生很诡异的情况);因为在外网,所以及时关闭开放的debug端口;
不推荐线上直接远程debug,风险高。
1).保持远端代码版本和本地代码版本一致
2).执行sudo vim ${tomcat}/bin/catalina.sh
进行编辑
3).添加如下配置,其中address为开放远程debug的端口号
CATALINA_OPTS="-server -Xdebug -Xnoagent- Djava.compiler=NONE- Xrunjdwp: transport=dt_socket, servery,suspend=n,address=5005"
4).把开放远程debug的端口驾到防火墙配置中
5).及时关闭开放的debug端口(实际工作中把公司端口开放到外网是很危险的,不建议做)
6). 编辑sudo vim /etc/sysconfig/iptables
添加如下配置 -A INPUT =p tcp -m tcp --dport 5005 -j ACCEPT
:wq
保存退出
重启防火墙 sudo service iptables restart
3.推荐 内网穿透:ngrok、natapp、花生壳(本文使用natapp)
可以得到一个外网可以访问的域名,和访问本机的IP或端口是一样的。
1).登录 http://natapp.cn
2).注册账号,选择购买隧道或用免费隧道(免费不稳定,可能会变)
3).设置对外开放的端口
4).下载对应的客户端,若用mac请先执行 sudo chmod a+x
赋予用户、用户组、其他用户执行权限
5).按照官网操作说明运行程序,加入authtoken
参数
6).通过开放的外网域名进行访问测试
https://openhome.alipay.com/platform/
1.沙箱登录
https://openhome.alipay.com/platform/appDaily.htm?tab=info
2.沙箱环境使用说明
下面有:详见生成RSA密钥,可以看看;
沙箱支持产品:我们这次只使用 当面付
等等。。。
3.如何使用沙箱环境
4.当面付产品介绍
https://docs.open.alipay.com/194/105170/
分条码支付和扫码支付,我们使用扫码支付
5.扫码支付接入指引
https://docs.open.alipay.com/194/106078/
6.当面付快速接入
https://docs.open.alipay.com/194/105170/
需要看扫码支付调用流程
扫码支付的接口调用顺序如下图所示:
使用SDK快速接入扫码支付
预下单接口 alipay.trade.precreate:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2"); //获得初始化的AlipayClient
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类
request.setBizContent("{" +
" \"out_trade_no\":\"20150320010101002\"," +
" \"total_amount\":\"88.88\"," +
" \"subject\":\"Iphone6 16G\"," +
" \"store_id\":\"NJ_001\"," +
" \"timeout_express\":\"90m\"}");//设置业务参数
AlipayTradePrecreateResponse response = alipayClient.execute(request);
System.out.print(response.getBody());
//根据response中的结果继续业务逻辑处理
关键入参
关键出参
退款流程
对账流程
下载账单文件的DEMO(Java)
接口调用结果码说明:正确返回10000;也有公共错误码链接查看错误详情;
7.当面付接入必读
https://docs.open.alipay.com/194/105322/
一.商户接入规范标准化
1)接口调用规范
针对唤起收银台的交易确保能够及时获得用户支付结果;
同一订单的部分退款确保退款请求号不重复;
2)异常处理
避免不合法的传参:错误会返回INVALID_PARAMETER
码,建议对他进行监控,发现便停止请求参数;
接口调用发生异常时能够正确处理;
3)支付体验
合理的轮询间隔以及轮询总时间:也不能24h持续轮询,这里建议轮询总时间30秒,间隔为3秒;
新建的订单都需要改变订单号:外部订单号重复会导致交易失败,建议对新建的订单进行跳号处理;
4)资金安全;
5)入参规范;
6)监控保障;
7)支付结果异步通知;
二.避免单边账
。。。
轮询+撤销的流程中,如轮询的结果一直为未付款,撤销一定要紧接着最后一次查询,当中不能有时间间隔。
。。。
8.当面付进阶功能
https://docs.open.alipay.com/194/105190/
参数名 参数说明
discountable_amount 可优惠金额
undiscountable_amount 不可优惠金额
授权流程
商品信息同步
9.当面付异步通知,仅用于扫码支付
https://docs.open.alipay.com/194/103296
各种参数都可以熟悉;
交易状态说明;
通知触发条件:WAIT_BUYER_PAY;
资金明细信息说明:支付渠道说明;
服务器异步通知页面特性;
异步返回结果的验签:
第五步:需要严格按照如下描述校验通知数据的正确性。(一定要保证回调是支付宝发来的,不是其他方)
商户需要验证该通知数据中的 out_trade_no是否为商户系统中创建的订单号,并判断 total_amount 是否确实为该订单的实际金额(即商户订单创建时的金额),同时需要校验通知中的 seller_id(或者seller_email) 是否为 out_trade_no 这笔单据的对应的操作方(有的时候,一个商户可能有多个 seller_id/seller_email),上述有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时,支付宝才会认定为买家付款成功。
在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。
对这句话举个例子:一个订单,我们已经收到「订单成功」的状态,已经改成「发货状态」,此时我们再接到回调通知,如果不判断他把它扭转成付款成功的话,数据就变成了错误数据;
注意:
状态 TRADE_SUCCESS 的通知触发条件是商户签约的产品「支持退款」功能的前提下,买家付款成功;
交易状态 TRADE_FINISHED 的通知触发条件是商户签约的产品「不支持退款」功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。
10.当面付的SDK和DEMO
https://docs.open.alipay.com/194/105201/
下载 当面付Demo
运行说明
在解压的当面付 Demo 中,找到properties
配置文件,将其中的appid, pid
,private_key
,public_key
的值替换为你申请的相关值。
参照各个 Demo 中的test
方法,进行 Demo 的运行。
详细说明和文件结构,请参考 Demo 内的readme
文档。
11.服务端的SDK
https://docs.open.alipay.com/54/103419
可下载;
SDK集成:把DEMO集成到项目中时,需要用服务端的SDK;
SDK集成示例;
方法说明:加签方法(若不用SDK调用,推荐此方法加签)、验签方法(异步通知时需要通道验签方法);
注意事项:1)AliPayClient实现类都是线程安全的,所以没有必要每次API请求都新建一个AlipayClient实现类;
2)创建AlipayClient实现类的实例时,指定format=json,相比xml格式,可以减少数据传输量,提升API请求效率。
12.生成RSA密钥
https://docs.open.alipay.com/291/105971
13.线上创建应用说明
https://docs.open.alipay.com/200/105310/
需要完善的内容:应用名称、应用图标;
添加应用功能;
配置应用环境;
应用申请上线:协作费用相关说明;
下载DEMO后,用IDEA打开;
若报错,检查JDK是否匹配,lib中加载的依赖是否合理(不然就删掉重新加载),其中两个Source依赖不需要;