在今年,我开发了一个支付中心系统,用于集合公司所有项目的支付功能配置,功能大致如下:
具体流程
高并发
为了实现高并发,我们采用了easyswoole框架,同时针对各个接口做了如下优化:
下单接口
对固定的商户数据做了缓存,避免每次查询数据库,
下单接口只有订单插入这一条io操作
支付成功异步回调接口
先即时判断成功数据,并进行更新,
同时会新开协程通知商户, 如果通知不成功,将通过异步队列通知给商户
高可用
为了实现高可用,我们实现了以下功能:
针对支付成功
1:为了避免系统异步通知出现问题,或者网络出现问题,在下单之后,将定时获取待支付订单,主动向支付平台(支付宝,微信) 查询订单状态,如果订单状态为支付成功,立即更新为支付成功,并异步通知商户 (根据订单的创建时间来进行修改频率)
2:为了避免系统异常终止出现的订单支付问题,在系统启动成功后,将立即执行步骤1
3:为了避免步骤1获取到用户不准备支付的订单,我们新增了过渡状态:订单准备支付状态 当用户创建订单,并请求支付方式接口时,将更新为此状态,只有此状态才会进行步骤1更新
4:订单状态如果为已创建,则在30分钟后自动过期订单,并同时请求支付平台(支付宝,微信) 关闭此订单 (也可在下单时预先设置订单过期时间)
5:在更新为已支付状态时,开启事务并加锁,确保其他进程无法访问此订单数据.
6:所有操作都有做异常日志记录
针对退款订单
1:为了使得退款合理化,我们新增了过渡状态:订单准备退款 只有在请求退款订单并未响应退款成功时才会更新为此状态
2:退款时,将新增一条退款订单记录,通过此记录向支付平台(支付宝,微信) 发起退款,此订单状态为 待退款 ,每条支付订单可多次重复退款,但是金额不能操作
3:因为微信退款为异步操作,同时避免在扩展其他支付方式出现问题,在申请退款之后,将定时获取待退款订单,主动向支付平台(支付宝,微信)请求退款订单信息,如果为退款成功,立即更新为退款成功,并异步通知商户 (根据订单的创建时间来进行修改频率)
4:由于退款订单到账银行卡最长需要7个工作日,所以系统将定时清理7日之前的待退款订单,更新为退款异常,并将原有支付订单改回支付成功状态
5:订单退款所有操作都带上了事务,并对相关数据加锁
6:所有操作都有做异常日志记录
以上2条保证了就算是系统死机,在开机后,也能保证之前的支付订单,退款订单等正常运行,就算是在更新为待退款状态时突然断电,下次也可以重新根据退款订单进行请求退款,也可以通过退款记录恢复退款状态
分布式部署
为了增加系统并发,系统实现了分布式部署,同时对redis,mysql做了集群兼容,只有订单这些重要数据才会直接走主库,其他查询都走从库
同时为了避免系统的定时任务,消费进程等出现冲突,额外实现了redis分布式锁