我的支付总结(三) 常见问题

支付系统的要求:安全、高效。安全是基本,高效是追求。

要达成两个目标,难免会遇到各种坑,下面挑几个典型的问题来讲述,并附上简单的应对方案。

请求超时问题

网络的可靠性要依赖硬件,所以只要是网络调用,必然要考虑超时问题,另外因为支付系统一般内部验证操作多,请求处理时间长,比一般系统超时的概率更大。

支付系统内的每一个请求都应该谨慎处理,而对于无法确定结果的超时请求更不能轻易确定终态,绝对不能像一个简单的网页请求一样重试一次。

一般采取保守策略,将交易状态保持在一个无害的默认状态(处理中或未支付),等待下次触发处理。

请求超时本身易处理,但它导致的后续问题会很多,下面会提到。

终态判断处理问题

返回码映射

终态的判断应该是支付系统内最重要也是最容易踩坑的地方,这个处理的复杂程度真的太依赖三方系统的状态码设置了。由于成功和处理中的状态只有一种,而错误则会有各种各样的原因,有的错误可以重试,有的错误是系统错误。分清交易失败的原因,关系到系统如何下一步处理交易,所以错误明细码的设计十分重要。

对于一个返回码设计良好的系统,如微信、支付宝,有业务结果码和明细错误码之分,我们进行终态判断和返回码映射时,可以首先以业务结果码为准,在业务结果为失败时,再去检查明细错误码。

而一个设计不那么好的系统,将业务结果码和明细错误码混淆在一起,判断结果就比较坑,要么将错误码列出对比,要么用很危险的else

此问题无法真正避免,只能给出谨慎映射,多向三方系统求证的建议。

查询无交易记录

无交易记录应该是最危险的返回码了,偏偏因为偶发的网络波动,交易请求受理超时,这个码还不可避免。 正常逻辑的情况下,无交易记录是没发到三方系统,当然是失败,可是如果在代付交易中,三方系统告诉你,别轻易置失败,万一你参数传错了呢,钱付出去我们可不赔哟~你还那么有自信么。。。

解决方案中最保守的方式当然是作为处理中来处理,然后人工介入处理,这个只能用在交易量不是太大,网络偏稳定的情况下,目前我们只在代付交易中使用此策略。

另外一种方式是搭配请求时的响应信息来判断,如果三方系统响应信息为成功时,查询为无此交易,那自然是参数或系统逻辑等问题,迅速报警通知处理。如果请求受理时为超时,那么便可以认为是网络问题没有发送成功了,有时候还是要对自己的代码有一些信心的。

交易及时性问题

交易及时性不是一个很严重的问题,甚至在支付系统中,太有及时性的交易还会使用户不太放心。但作为一个程序员,追求效率是天性嘛,我们还是希望尽早获取到交易结果,但这也可能导致踩坑。

太早的查询

查询太早导致问题会出现在两种场景:请求超时、三方系统设计问题。

  • 请求超时:请求超时时,系统在过了超时时间后断开连接不再阻塞,立刻发起查询请求的话,三方系统可能刚接收到请求,正在进行参数验证,数据还未落地,此时会收到无此交易的响应,我们将交易作为失败处理后,交易可能在之后成功。所以查询一定要有延迟,一定要给三方系统足够的时间来处理交易。
  • 三方系统设计问题:如xx,在受理交易时使用了中间件,中间件挂掉后,我们查询无此交易,但他们重启中间件后又处理交易,竟然又成功了。这个最好在之前能问清三方系统的处理方式,并针对性地设置查询延迟。

频繁的查询

太多频繁的查询是无意义的,交易正在三方系统中处理,查询不会使交易被迅速处理,还会造成网络资源和系统资源的浪费,如果你还记得与三方系统的每一次交互都要重视,那么查询日志也没法看了。

解决此问题,要:

  • 避免“过早”的查询,这要考虑三方系统的处理速度;
  • 合理设置查询时间间隔,一些交易需要更长的处理时间,可以设置梯度时间间隔;
  • 处理无意义的查询,如查询“无此交易”,那么进行多少次结果都不会变,再进行查询就是无意义的;

隔日账问题

隔日账问题在对账过程中不可避免,由于服务器时间有差异,交易处理也需要时间,在凌晨附近发生的交易可能会遭遇此问题,这会给对账造成一定的困扰,但合理的处理方式不会有太大的问题:

自己系统与三方系统对账文件不一致时调用查询接口在缺失交易的系统内查询,先确认交易的存在,再分析交易时间。如在隔日附近,则暂不处理,待次日对账文件的对比。

如某一系统内交易不存在,或交易不太可能会发生隔日账问题,这便需要系统之间人工来处理了,不过这不也是对账的意义所在么。

并发效率问题

并发锁

并发问题在所有系统内都会存在,只是支付系统内处理不好后果会很严重,处理方式一般是事务、互斥锁。

支付系统单系统内使用这些方式也没有问题,只是锁的粒度会略大,至少需要保证一个模块内交易处理的原子性。 分布式系统内就要考虑分布式锁了,这些业内也都有很多解决方案了。

只是加锁就意味着效率损耗,合理拆分出交易核心模块,并对这些模块添加锁。另外使用合理的“进程-数据”分配方式,也会减少锁冲突。

幂等

保持交易中的幂等很重要,它是避免重复支付的基石。 即使系统设计完全,我们还是要追求业务逻辑上的幂等,这也就意味着更多的查询确认,同时意味着效率下降。

效率下降不可避免,我们可以使用缓存来降低效率下降的幅度,在缓存中设置交易状态标识,对交易状态标识异常的交易再去数据库查询。

异步拆分尴尬

异步可以抗并发,提高效率,放之四海皆准。支付系统对异步的依赖更强是因为支付系统由于其处理流程冗长更易达到效率瓶颈。

面对异步我们首先要解决的问题是异步拆分的粒度问题,粗粒度的拆分效率能提升的效率有限,细粒度的拆分调控起来不易,处理异步拆分的粒度,看交易量吧,不做过度设计。

进行异步拆分时,每一步都需要一个触发进程,此进程可以是常进程轮询,也可以是cron进程,事件机制来触发自然是更好的,但它对消息队列的要求很高,设计也较复杂。

除此之外还需要一个确认进程,确保下一步的进程顺利接收处理了,在后续进程受理失败时,能够及时重试处理。

测试坑

测试是开发中必不可少的步骤,自己测和测试来测,总要完全走一遍流程才敢放心上线。

支付测试略坑了: 首先测试环境的布置,支付系统牵涉到多个三方系统的交互,靠谱的系统都会提供测试系统,可是难免有些系统不提供测试环境,或者测试限制颇多,限支付行,限金额等,还要提防其测试系统忽然就挂了。然后是线上测试,更要小心翼翼,一个不慎就是资金损失。

为了提供良好的测试环境,我们引入“MOCK”功能,mock 中文意思为“模仿”,即通过模拟三方系统的返回值来测试本系统的稳定性。

但 mock 的代码侵入性略强,完整的 mock 模块必然有if else语句的存在,由于支付相关的系统较多,要搭建完整的 mock 系统不容易,单点 mock 需要各处埋点。整体 mock 的又不便于测试特定功能。

小结

支付的坑包括但不限于本文介绍的这些,可能还会有其他奇怪的问题,文章没有介绍到。

若想尽量避免支付系统的坑,那么一定要保持着保守的态度,将状态或交易保持无害。有些需要事务操作,但无法使用典型事务的场景,将次要的一开始执行,即使出了问题,有重试、回滚等操作,也不会造成影响。

支付总结暂时到此为止。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

超多干货!支撑起腾讯公司计费业务的TDSQL

深度技术文章,第一时间送达! 作者介绍: bluesea,腾讯金融云专家工程师,从事分布式数据库TDSQL研发工作。出版著作:《数据库查询优化器的艺术 原理解析...

2037
来自专栏后端技术探索

高并发场景:下单后定时发短信的问题

问题描述:让您做一个电商平台,您如何设置一个在买家下订单后的”第60秒“发短信通知卖家发货,您需要考虑的是 像淘宝一样的大并发量的订单。

771
来自专栏IT技术精选文摘

分布式系统一致性保障方案总结

引言 在互联网系统中,理想的情况下,肯定是希望系统能够同时满足“一致性”、“可用性”和“分区容忍性”。 但是基于熟悉的CAP定律也好,还是BASE理论, 我们知...

24310
来自专栏WindCoder

Elixir和OTP中面向过程的编程指南

这篇文章感觉介绍语言是次,讲解各种各种分类以及面向过程的思想为主。本身我也没接触过Elixir,这次也权当开拓视野了。最后附加了一个英语单词的小解,当学习之余的...

461
来自专栏Linyb极客之路

分布式之消息队列复习精讲

庆幸的是两位朋友都很有上进心,于是博主写这篇文章,帮助他们复习一下关于消息队列中间件这块的要点

902
来自专栏CSDN技术头条

说实话,分布式系统的复杂度远大于它的好处

最近,有一位酷酷的程序员小哥(由网站头像可得)在Hacker Noon网上发表了一篇名为《全面解析分布式系统》的文章。和以往烂大街的分布式教程不太一样,这位小哥...

852
来自专栏原创

基于AngularJS的个推前端云组件探秘

AngularJS是google设计和开发的一套前端开发框架,他能帮助开发人员更便捷地进行前端开发。AngularJS是为了克服HTML在构建应用上的不足而设计...

4278
来自专栏圣杰的专栏

eShopOnWeb 知多少

eShopOnWeb是基于ASP.NET Core构建,官方创建这样一个示例项目的目的,我想无非以下几点:

661
来自专栏Spark学习技巧

从零开始 Spark 性能调优

1323
来自专栏企鹅号快讯

分布式事务的总结与思考

思来想去,个人觉得要理解「分布式事务」,必须先知道什么是“事务(Transaction)”。 当然,这里提到的“事务”是在事务型数据库(Transactiona...

1819

扫码关注云+社区