Fastpay快付

其他

第三方支付账务系统论述

这篇文章来自文远前辈的分享,笔者从事多年银行账务系统的设计与研发,三年前进入互联网行业,进行第三方支付账务系统的设计,一路走来,感触良多。关于第三方支付账务系统如何建设、与银行核心账务系统的区别与联系、与公司大财务系统如何对接,在本文中会具体论述。小编拜读之后收获颇多,分享给大家,发现很多小伙伴都很关注这块内容,期待一起深挖这块内容,希望大家能够喜欢。1
2019年5月10日
其他

后大资管时代下的金融行业解决方案

在上一篇文章《银行业务架构与同业案例(超详细)》有说要写一系列金融企业架构的文章,企业架构是相对比较宏观的概念,为了便于梳理企业架构当下所处现状,以及未来走向如何,就先写了这这篇。本篇文章是站在宏观历史叙事的角度,以资管业务为切入点,来了解当前金融企业管理的重点、环境、趋势、目标和策略。资管业务的轻资本高收益,对于金融机构而言具有重大价值,随着资管新规的落地,中国大资管过去十年“监管套利、隐形刚兑”的商业模式难以为继,随着金融科技的兴起各金融机构纷纷开始进行资管业务的转型。此文适合人群:银行、保险、证券、信托等金融从业人员,业务架构师,业务分析师,系统架构师。此文解决问题:站在更大的历史趋势下看当下所处的位置资管业的现状、存在的问题、趋势、转型的方案此文分为四大部分:资管定义和历史行业现状行业发展趋势数字化转型方案1资管的定义和历史资产负债管理是管理企业的一种活动,用来协调企业对资产与负债做出决策,在给定风险承受能力和约束下,为实现企业财务目标而制定、实施、监督和修正企业资产和负债的有关决策过程,对任何利用投资来平衡负债的机构来说,资产负债管理都是一种实现“安全性、流动性、盈利性”经营目标的基础与重要且适用的财务管理手段,对银行、基金、信托和保险公司等金融机构而言更是常用的一个概念。随着各历史时期经营条件的变化,围绕盈利性、安全性和流动性等三个原则,先后经历了资产管理、负债管理、资产负债综合管理的三个发展阶段:★名词百科广义资产负债管理:值金融机构按一定的策略进行资产皮遏制,实现流动性、安全性和盈利性的有机统一。狭资产负债管理:是在利率波动的环境下,策略性的改变利率敏感性资产的配置状况,实现金融机构的经营目标,或者通过整体资产和负债的持续期,来维持机构正的净值。资产负债管理目的:从单一缺口分析,发展到统一管理市场风险与信用风险,实现资本最优配置资产负债管理对象:从初期的以存款、贷款、负债为主,演变为目前的几乎涵盖所有表内外业务资产负债管理风险:从初期的流动性风险为主,进化到目前涵盖流动性风险、市场风险和信用风险资产负债管理方法:随着金融市场和金融理论的发展而不断更新演进2资管业务现状近几年国内资管现状与美国20世纪70年代相近,银行业资产负债构造中,资金运用方面以长期房产贷款为主,资金筹措方面是短期资金,因此面临很大的利率风险(利率、期限长短不匹配)。图片源自:《商业银行资产负债管理》在资金端以新兴的智能投顾、结构性存款为代表,在资产端以大数据和智能风控、智能投研为代表,各金融从业机构纷纷加大科技投入,以寻求技术驱动业务发展。2存在的四大问题传统资管业务存在产品、运营、风控、投研4个方面不同程度存在问题。3面临的挑战近几年以金融科技为代表的新兴互联网金融业务加速金融脱媒,随着社会数字化程度提高金融弱关系、货币商品化、金融机构隐形化趋势突显,各金融机构纷纷开始进行数字化转型。4行业发展趋势5生态环境变化6数字化转型需要思考的问题更多数字化转型的思考参见之前的一篇文字《核心银行系统——数字化转型思考》7趋势8对IT提出的要求9四快目标10建设重点11策略与方向12金融科技场景匹配度13金融业务上云方案14小结本文主要为笔者参考业内标杆、咨询公司发布的报告等整理所成,限于笔者能力、时间、洞察力等因素未必展现的全面和准确。如果方案中笔者的一些观点和思路能给你带来一些思考或者从另一个角度考虑EA和IT建设,那将是笔者最大的欣慰。正如笔者在金融技术架构群群里曾说,开源的未必只有软件,还可以是想法等,本文PPT和参考素材均可在群里分享,如果有不同意见欢迎加群踢馆、交流。参考资料:《商业银行资产负债管理》易观数据报告XX咨询报告长按上方二维码即可关注学支付|找快付
2019年3月20日
其他

支付系统订单模型该如何设计?

导读最近经历了一件事,就是小码农所在的公司因为被某大厂收购之后要进行融合了,其他方面的融合就没必要说了,今天咱们只是聊一下支付系统融合的事情。首先从很多互联网公司的发展经验来看,随着多条业务线的发展,最终都是会催生出建设统一支付系统的强烈需求。这是为什么呢?因为支付系统太重要了,它拥有公司所有的现金流水,是进行业务清算、财务核算、上市审计以及后续各类财务信息管理的关键系统之一。一家公司被收购后新老板们最关心的事也莫过于财务数据的准确性了,之前小码农从事支付系统的研发工作加入的都是已经比较成熟的团队,去建设的支付系统也都是为了帮助所在公司来实现上述的目标和战略,而所采用的策略也都是在强大的上层的支持下进行业务线统一支付入口的归集。只不过这一次作者所加入的是一家互联网创业公司,而在支付系统的建设上,也属于比较混乱和初级的阶段,因此在被收购后属于是在另外一个强大上层的支持下而被统一的一方而已。当然从客观的角度看,这也是一件非常合理的事情,因为一个大的集团公司无论是从成本还是统一管理的角度看都是没有必要重复建设多套支付系统的,而对一家被收购的公司而言,其支付系统肯定也是首先需要被融合的关键系统之一。作者对此持开放和乐观的态度,即使这个过程对个人会有一些影响。只是因为在此之前经历了很多的坎坷,觉得有很多事情还是值得总结一下,因此才想着写一篇文章来回忆下这个过程。而总结的目的,也只是希望能够对未来会经历这样一个过程的公司,有一点参考价值,因为即便是被融合,如果做的比较好的话也会让融合的过程会更加容易一些,至少还能得到一些口碑,否则就很容易遭人骂了,而从技术本身看也会是一种失败。被忽视的团队关于支付团队是否是被忽视的团队的问题,可能因公司而异(或者也许因不同公司处于关键岗位的技术Leader是否具备这样的经验和远见而异),可能有一些互联网创业公司在发展初期并不是很Care这件事,因为早期的业务也确实没有那么复杂,在业务代码中接个微信、支付宝能有多难,两三个人都嫌多还想引起什么样的重视?的确,作者最开始加入这家互联网创业公司时,真的就只是在业务代码中对接了一个支付宝、微信,看起来好像真的是没有那么复杂,在人员方面也就是两个没有太多支付经验的研发而已,连正式的支付订单流水表都没有,还基本上是与业务订单耦合在一起的那种。然而,似乎这一切好像也并没有影响公司业务的蓬勃发展,在线收款业务量也是增长迅速,每天好几个亿的进账。只是这个时候,会偶尔出现很多掉单而已,反正用户投诉了,写条SQL改下订单状态,要么退款,要么用SQL进行下业务处理。总之,看起来一切并没有那么复杂,只是后面又增加了几个新的支付渠道,而支付宝、微信这种因为开了新的入口(如和微信小程序合作,支付宝第三方合作之类)又申请了下新的微信、支付宝商户号。从截止到以上阶段的场景上分析,到目前为止都只是在单向的进行收款操作。而随后的事情可能就有点戏剧性了,因为突然某一天,发生了挤兑的事,系统的退款请求迅速增加,当然,此时大部分的退款请求还都只是走原路进行全额退款的操作,还没有部分退款等一些复杂的业务退款情况,而此时的退款掉单则有点扯了,因为这导致了大量用户已经退款,而业务系统逻辑并没有更新状态的情况,此时此刻也就为后续财务数据的混乱埋下了相应地伏笔(之前的支付掉单处理得不及时,也是在埋伏笔)。似乎更为糟糕的是,因为有些用户太过于忠诚,支付的订单时间过长,已经超出了第三方渠道允许进行原路退款返回的期限,而此时因为无法通过系统自动进行原路退款,最终没有办法客服小姐姐只能人工收集客户上报的资料(如支付宝账号),然后通过Excel由哪两位苦逼的开发去通过手工的方式整理后通过单独申请的支付宝代付账号进行转账退款操作,似乎这种方式也没有什么太大问题,只是比较原始而已。的确是这样,然而不幸的是,只是这种人工操作偶尔还会失败,需要重新发起和进行系统订单状态的更新(如果真的把钱给别人转成功了,得用SQL把状态给改了啊),而这个过程因为人工因素,导致了一些状态未更新的情况,以及转账重复的小失误,而这也为后续财务数据的混乱埋下了另外一笔伏笔。看到这里,也许不少同学都会诧异,这尼玛为啥不设计相应的机制来解决呢?所以,这个时候开始有人谈起了支付系统重构的问题。而此时作者正好加入这家公司,所以心想也算一个机会,于是也提出的自己的重构方案。细节不提了,只说一个基本的支付系统应该是什么样,如下图所示:于是作者激情满满的找到了领导,提出了自己的想法。然而,令人没想到的是,还有个Secret项目因为也涉及到一些支付功能的重构,所以需要找人相关人员沟通下,好吧,此时才知道原来支付系统已经在秘密地被重构了,只是正常开发和维护支付系统的人居然不知道这件事。也罢,而让人更意想不到的事,这是居然还不算完,因为还有另外一个团队,属于另外一个VP领导下的团队也在进行支付系统的重构,只是正常的支付团队以及秘密重构的项目都还彼此不知道而已。说到这里,仔细想想,作者也是很诧异,不过好歹因为作者提出的这个想法并鼓足勇气和大佬沟通,总算让大家彼此知道了这件事,也算是一个良好的进步和开端。而与此同时,还有另外一个团队在开发所谓的财务系统(实际上就是作者图中所规划的账务系统,当然后者因为种种扯淡的因素,在做了两月之后做黄了,以至于到目前为止仍然缺失这一块,而收购方希望融合方式则正是所有的业务线接入他们统一收银台的同时,还需要接入其账务系统,这样资金流、业务流就完成双向闭环了,这样业财核对、收入计算就可以通过集团统一而完备的系统进行集中处理了)。于是乎,好像此时此刻,这件事应该是向着好的方向发展了,支付系统应该是在比较充足的资源配置的情况下,并且经过合理的设计后开始有计划有步骤地重构了。然而,不幸的事,此时此刻又出现了新的搅局者,新来了一位似乎很有经验的产品经理,提出要建设一套很牛逼的统一交易系统,而支付系统当然只是其中底层的一个小部分而已。如此这般,最终经过N轮的扯皮、沟通以及团队利益的纠结争斗,最后就由某某团队开始进行支付系统的重构了,与此同时作者呢因为刚来,所以就做起了大家都觉得很不起眼的对账工作了。然而,后续支付系统的重构,并没有完成彻底的重新塑造,整个系统的订单模型并没有进行脱胎换骨的改造和升级,对于历史数据的处理,也是避重就轻,只是简单的在新的支付系统的代码层面进行了适配,并采用了无敌的双写策略,如此至今还是双写(客观地究其原因,因为那个团队实际参与重构的也只有2~3人,在经验和资源缺乏的情况下,也很难将这件事做的相对全面而完整)。以上种种也就为支付系统的先天残缺,资金数据的混乱以及后续为了适配各种新业务而疲于奔命,从而导致更多的不确定埋下了深深的伏笔。而这其中,又经历了不同主管Leader的更换,但似乎没有一个是专业的,于是造就了现如今的种种乱象。通过上述的坎坷历程的回顾,这可能并不像是一个技术问题,而更多的像是因为创业公司的技术管理混乱而导致一种扭曲的现象。也许换一个CTO就不一定会是这种状态,所以这种情况是否属于共性问题,也就需要大家自己根据自身公司的实际情况进行判断了。只是在这里作者将其笼统的归咎为对支付团队统一建设的一种忽视吧。有问题的组织关于这个问题,不同的公司的情况可能是不一样的,正如上面所说,早期在业务代码中对接个支付宝、微信的接口也许并不是太复杂的事,但是需要说明的是如果考虑到未来业务的扩展所导致的复杂性,并且在已经开始重构支付系统的情况下,则是一定要做到“麻雀虽小,五脏俱全”,之所以这么说,原因在于支付系统是一种对数据一致性要求非常高,但是又很难单纯的从某一个小的方面保证数据一致性的系统,它需要一个完整的体系来保证。而上面提到的复杂性,就有很多种情况了,例如如果涉及系统退款,退款本身就会存在诸多的复杂性,如全额原路退款、部分原路退款、在线转账退款、线下转账退款等,并且不同的支付渠道所能支持的程度还有差异。另外,如果涉及多渠道、同一渠道不同的商户主体,以及银行卡支付/非银行卡支付,海外支付多发的ChargeBack等情况,则带来的复杂性也会相应地增加。因为此时支付系统不仅需要满足参数配置化、渠道路由化等要求,支付方式、交易方式所产生的数据订单也需要具备完整的存储逻辑。当然,上述逻辑复杂度的增加也不是一开始就是这样的,而是随着业务发展逐步递增的。所以对于支付团队的配置,也没有必要一开始就配置一个大的团队,但是作为团队的技术Leader,一定要清楚在什么阶段需要什么样的人员配备,并且明确的指定一名具有一定专业度的支付团队技术Leader来带头进行有组织、有计划地重构工作,而不是在这个问题上含糊不清,因为按照个人的经验,在这个事情上的瞎竞争其实是没有什么好处的,最终可能会带来混乱。支付订单模型在具体讨论如何对支付订单模型进行设计讨论之前,和大家一起回顾了一些团队发展和建设的问题,因为至少在作者目前看来,最本质的问题并不是出在技术本身上,而是因为团队技术管理混乱,带来了一系列的恶果。但很多时候,也许以上种种并不是我们作为普通技术人员本身能够干预得了的,因为这往往牵扯很多技术以外的因素。那么如果假设你承担了这一角色,或者作为一名具体的工程师,在你具体重构或设计支付系统时,如何尽可能地想得长远一些呢?这里有作者根据自身经验设计的一套逻辑模型,供你参考。上图是一张精简的关于支付系统订单模型设计的图,在模型中我们将订单分为交易&支付两个层面,之所以要这么划分,是在于我们进行支付系统开发时很多时候是需要满足一部分业务逻辑的,而设置交易订单的目的则是为了屏蔽这种业务不确定性而带给支付订单本身的复杂性。在这个模型中,交易订单作为与业务交易映射的一张记录表,例如业务A通过支付系统发起了一笔充值交易(如10块钱),那么就会在交易订单中插入一条10块钱的充值交易流水,而这笔充值流水正常情况下可以通过相应地支付渠道进行支付,可以一次性支付10块钱(插入一条对应的支付订单流水),也可以支付两次5块钱,并且还可以分别使用不同的支付渠道(分别插入两笔对应的5块钱的支付订单流水),所以交易订单与支付订单的关系为1:N。之所以允许这样的情况发生,是因为在实践中,因为渠道限额,业务允许重复发起支付等原因,所以必须允许进行拆单支付的情况发生。而如果在这种情况下又需要允许交易进行退款的话,为了精简数据存储,对于交易订单可以通过状态机进行处理(如设置交易退款状态),而对于支付来说,退款本身也是支付流水,所以不应该直接在支付订单流水上进行状态更改,而是应该单独设计独立的退款流水表,只是需要在退款流水表中设置原始支付的订单信息,以及退款的具体方式即可。而支付退款本身又可以分为原路退款/非原路退款,而这两种退款方式又分别可以分为全额退款和部分退款两种情况,所以支付流水与退款流水之间又存在1:N的关系。还是举上面那个例子,如果用户充值交易所支付的10块钱,是一次性通过微信支付的,那么退款时如果时全额原路退款,则只需要插入一条与支付流水对应的10块钱的退款流水,并更新交易订单状态为“已退款”即可。如果是因为该用户的充值部分,使用了5块,剩下的5块钱可以退款,那么此时发起的就是原路部分退款,在退款流水表中插入一条与支付流水相关的5块钱的退款流水即可,但是此时需要将对应的交易订单状态更新为”部分退款“的状态。此外,以上情况如果由于支付订单时间太久,原支付渠道已无法再进行原路退款,此时只能通过线上或线下转账方式/代付方式进行退款的话,则为了完善模型,我们也需要在退款流水表中记录一条与原支付订单关联的退款流水,只是退款方式需要记录非原路退款的情况,并且在发起转账或代付退款后,需要在退款流水中关联对应的转账或代付流水号,之后根据实际退款的情况更新对应的交易订单状态为“已退款/部分退款”。而转账或代付本身因为又是一种单独的支付方式,所以此时我们需要在支付流水表中单独记录转账订单或代付订单,但因为此时与交易订单本身无直接关联,所以不需要产生新的交易流水。对于海外支付渠道因为产生了ChargeBack的情况,我们需要将其视为与转账类似的非原路退款方式,从而进行退款流水的记录,以及ChargeBack订单本身的记录,这一点对于海外支付渠道的支付逻辑完善以及ChargeBack本身的追溯会比较重要。按照这种模型进行支付订单结构的设计,并在一开始就撸清楚这些支付场景的对应的数据存储逻辑,会对未来系统的拆分扩展大有好处,因为至少数据逻辑是非常清晰的了。只是为了确保这套数据逻辑的一致性,我们还需要加强对账系统关于内部订单对账的逻辑,确保不出现异常和不一致的数据问题。以上就是本次作者关于支付部分想写的全部内容了,希望能够对一些正在经历支付系统构建的朋友们无论好坏有一点参考借鉴的意义。长按上方二维码即可关注学支付|找快付
2019年1月4日
其他

微服务架构设计基础之立方体模型

背景对于现在的微服务架构的应用来说,对大量并发的及时响应是一项制胜能力。据用户行为分析平台统计,随行付的某一款APP产品每日请求就达到上千万次用户请求、加解密服务3000万次/日等等。这些微服务每时每刻在处理如此高强度的请求,对数据层的应对能力要求极高。如果我们把对速度的需求放在复杂的分布式数据架构背景下,是很难想象如何让应用应对如此巨大的数据访问量的。但很幸运,我们有方法做到。即立方体模型。立方体模型可扩展的分布式系统架构设计有一个朴素的理念,就是:通过加机器就可以解决容量和可用性的问题。对于一个迅速增长的应用而言,容量和性能是首当其冲要面临的问题。但随着时间的向前推移、应用规模不断的快速增长,除了面对性能与容量的问题外,还需要解决功能与模块数量上增长带来的系统复杂性问题、业务变化带来的差异化服务问题等。而多数情况下应用设计之初出于诸多因素的考量,并没有充分考虑或在设计之初就将此类问题提上日程,导致系统的重构成为常态,从而影响业务交付能力。对此,「架构即未来」一书中提出了更加系统的可扩展模型,可扩展模型是一个富有启发性的方法,描述了微服务三个维度的扩展方法,可以通过它来了解微服务架构的扩展维度。X轴:横向扩展模式,关注水平的数据和服务克隆Y轴:功能分解模式,关注应用中的职责的划分Z轴:数据分区模式,关注服务和数据的优先级划分X轴扩展X轴扩展是通过绝对平等的复制服务和数据,以解决容量和可用性的问题。以乘坐火车为例,因春运高峰集中,乘客人数也是平时时的几倍、甚至几十倍。12306为了提高运力都会采用复制的方法:增加火车数量。增加火车数量有效的提高春运运力、提高乘客出行体验。对于软件工程而言,比如加解密微服务的性能峰值1000TPS,通常我们需要提高TPS,会采取复制加解密服务:增加服务提供者。这就是X轴扩展的一个完美示例,说明了X轴扩展的思路,把工作无偏向的分配给「复制品」,各个「复制品」之间不共享任何内容、能独立提供服务。而对于软件技术来讲,X轴扩展主要有负载均衡和数据复制两种技术方式。负载均衡负载均衡是将用户的访问请求通过负载均衡器,均衡分配到由各个「复制品」组成的集群中去。当某个「复制品」出现故障,也能轻易地将相应「工作」转移给其它的复制品来「代为完成」。常用的硬件负载有F5、A10,软件负载Nginx。这中间涉及到的技术点包括了反向代理、DNS轮询、哈希负载均衡算法(一致性哈希)、动态节点负载均衡(如按CPU,I/O)等。它的难点在于要求集群中的「复制品」是不共享任何内容,也就是我们常说的无状态。数据复制数据复制是指在数据存储层进行绝对平等地数据迁移,用于解决存储层I/O瓶颈以及可用性上的问题。有多个「复制品」存储,使得每个「复制品」提供无差异的数据服务,我们需要在「复制品」之间同步或异步的复制数据。数据复制的方式包括了主从同步(读写分离)、双主同步等。因为数据存储天生就是有状态的,数据复制的难点在于如何保证一致性。为保证一致性,衍生了很多复杂的技术和中间件,比如Paxos选举算法、随行付Porter数据同步中间件等。识别热点服务多数情况下我们的应用中都会存在热点模块,我们可以理解为越基础的模块越容易成为热点模块。热点模块更加容易成为整个平台的瓶颈点,所以热点模块要尽早的采取扩展措施,扩展措施一般都采用X轴扩展方式。前后端分离其实在我们开发过程中,经常会给pc端、mobile、app端各自研发一套前端。其实对于这三端来说,大部分端业务逻辑是一样的。唯一区别就是交互展现逻辑不同。如果controller层在后端手里,后端为了这些不同端页面展示逻辑,分别维护这些controller,徒增和前端沟通端成本、在扩展性上面也不能达到很方便的扩展。前后端分离的好处在于:提升适配性提升响应速度提升性能(分后端可分别优化)Y轴扩展Y轴扩展是根据数据的类型或者交易执行的类型(或者两者都有)来划分工作职责。一般称为面向服务或面向资源的扩展。我们再以火车来举例,12306根据起点和终点的不同,划分了多条火车线路。每条火车线路的周期归属运输,交付着乘客的出行服务。这样做的好处是明显的,每条火车线路的任务更简单,从而能更高效的提供出行服务。与火车分工类似,为了降低系统复杂度,Y轴扩展会将庞大的整体应用拆分为一组服务。每个服务实现一组相关的功能,如核心交易、风险控制等。而在软件上常见的方案是服务化架构(SOA)、微服务化架构(Micro
2018年12月19日
其他

对称加密及AES加密算法

现在假设我们的明文数据为15字节,并且用Padding填充了最后一个字节,我们把这16个字节的数据放在一个4X4的矩阵里,这个矩阵我们称之为状态矩阵,下文中我们说到的状态矩阵就是指这个矩阵。
2018年11月28日
其他

从支付宝SDK的支付流程理解什么是公钥和私钥,什么是加密和数字签名

还有一个不同是,支付宝支付,服务端会直接返回给我们调起支付宝支付的orderString,而微信支付的话,服务端会返回给我们一些信息,我们需要将这些信息拼一个请求体来调起微信支付,不过都很简单。
2018年11月6日
其他

支付对账系统怎么设计?

所以,在进行某个渠道对账时需要根据条件将账单数据、支付平台订单数据分别清洗到两张中间表中,分别叫做账单待对账中间表(A表)、订单待对账中间表(B表),然后通过这两张表进行full
2018年10月24日
其他

带你一步步了解业务测打款系统的建立

支付宝离线任务会查询启用状态的支付宝账户记录,然后根据记录去找寻在该记录创建时间之前存在的待打款记录,修改改记录的状态,并且新插入一条打款记录(渠道明确指定支付宝打款)。后续流程可以沿用之前的设计。
2018年10月16日
其他

移动端支付系统如何设计有效地防重失效机制?

导读“目前在互联网应用的大部分支付场景中,对接支付宝、微信移动支付产品这样需要用户参与支付流程的支付方式已经变得非常普遍,类似的还有PC端银行网银支付;而通过绑定用户银行卡、对接银行卡快捷支付通道直接扣款的支付方式,虽然还在电商、保险、互联网金融、租房等行业被广泛应用,但是随着微信钱包、支付宝钱包这类移动互联网支付方式的兴起,用户规模的迅速增长,再加上用户银行卡信息安全、直连银行通道关闭等因素用户市场份额正在逐步减少”。实际上,这种需要客户端参与支付流程的方式相比银行卡快捷支付直接扣款这类支付方式,在支付系统的流程及订单结构等设计上是存在较大差异的,其中订单的防重失效机制的设计更是一个比较棘手的问题。参与过支付系统开发或在业务系统中开发支付功能的同学可能会遇到类似这样的业务需求:用户在外卖网站或App上购买了点了一份外卖,并通过微信支付进行付款,系统在收到用户支付完成的消息后,提示用户付款成功并派单给餐馆?初看这个问题,可能很多同学都会有疑问,这不是一个很简单的支付流程吗?大部分支付场景不都是这样的么?其实是这样的,作为正常的支付流程来讲,上述场景并没有什么问题,在整个系统链运行稳定的情况下,可能大部分参与者并不会有什么感觉;但是,作为一个具备专业精神的小码农来说,还是有很多异常场景需要考虑的,不然就可能会因为系统流程上设计的缺陷而给公司和用户体验造成比较大的伤害。那么上述需求中,会有什么样的异常场景呢?与支付系统防重失效机制的设计有什么关联?我们可以先来看一下以上场景在系统流程中的运行情况(需要放大查看):在上面的流程中,虽然从用户角度看可能只是几秒钟的事情,但实际上整个系统链是经历了一个比较长的调用过程。具体如下:用户在点外卖的过程中选择微信支付后,App会将支付请求发送给外卖后台系统,如果在整个外卖平台中,支付系统是一个独立的系统,则外卖业务后台服务会在生成业务订单后将支付请求发送给独立的“支付系统”进行处理;此时支付系统作为独立的中间系统会处理外卖平台业务后台发送过来的支付请求,记录其业务订单号并生成对应支付系统自身的支付流水号,并对支付流水进行状态初始化(这里涉及一个业务订单号&支付订单号如何匹配问题,会在后面的讨论中阐述);支付系统调用微信统一下单接口进行预支付(这里的操作方式就是类网银式的支付方式,先进行预支付然后由用户跳到站外进行支付),并同步得到微信支付返回的预支付订单信息,支付系统此时需要更新支付订单为pending状态表示处于预支付状态;然后支付系统将预支付信息同步给调用方—外卖业务后台,外卖业务后台再同步给外卖App;外卖App会根据预支付订单信息通过客户端支付SDK唤起微信支付客户端,由用户操作微信支付客户端直接向微信支付发起付款动作,需要注意的是,此时调用链已经转移到了站外,实际上此时用户是否支付或是否支付成功,无论是支付系统还是外卖系统及App本身都是无法直接感知到支付结果的,需要逐层回调;微信支付会通过循环调用的方式主动将支付结果回调给支付系统,再由支付系统回调给外卖业务系统,最后在用户直接感知前由App主动查询外卖业务系统订单支付状态,同时提示用户支付成功或支付处理中这样的信息;从上面的流程可以了解到,实际上大家平时在通过App购物时支付的一瞬间是经历了很复杂的流程。那么,不知道在支付的过程中有没有这样的体验?在点外卖后付款了,微信也提示支付成功了,但是外卖App却始终不显示点餐成功?即使选择重新支付也提示支付中,不允许重复支付?或者选择重新支付以后外卖App显示也显示点餐成功了,但是之前支付的钱却不见了,只能打客服投诉,各种麻烦?上述问题,在目前支付流程的设计上是必然会发生的,目前作者所在的公司也有类似的问题,虽然这种问题发生的概率可能不是特别高,但是绝对是破坏用户体验以及增加了客服的工作量,处理得是否得当是衡量一套支付系统是否强大的核心指标之一。那么怎样的设计才能很好地解决此类问题呢?从流程上看用户选择微信支付并唤起微信钱包付款后,实际上外卖平台支付系统已经感知不到系统的状态了,也就说此时用户是否完成了支付,平台是无法同步感知的,只能依赖于微信的主动通知回调,一般来说目前主流的支付公司都有一套完整的商户通知逻辑,会在支付完成后实时通知到商户。但是很多时候会有多种因素导致这种通知被延迟,比较常见的因素主要有网络、自身平台系统服务宕机、第三方渠道通知服务故障等。也就说会有用户支付了点外卖的钱,系统却没有实时显示支付成功的问题,也就是我们常说的短时掉单问题;或者用户没有及时支付,重新付款时却会被提示“支付中请勿重复提交”,也就是支付防重问题。对于掉单问题的处理,可以根据业务场景进行考虑,但无论是哪种方案,越快速补偿业务越能够有效地提升用户体验,减少系统异常处理流程,让防重机制更加灵敏,在避免重复支付问题的同时提高支付成功率。另外,是否允许用户重复支付,如何利用冲正机制有效提高用户体验的同时快速保障用户权益,也是需要在整体方案中进行考虑的方面。根据业务时效性要求不同,大致有两种方案:异步补偿机制。具体来说,就是支付流程按照正常的流程走,通过采用旁挂定时的方式扫描系统中一定时间策略范围内的pengding状态的订单,通过微信提供的订单查询接口主动轮询,一旦支付状态查询到终态即刻触发系统回调,完成支付订单及业务逻辑的补偿;另一方面,如果pengding状态订单通过轮询方式没有查询到最终状态则需要设置一定的重复轮询策略,例如5分钟、10分钟、20分钟、1小时、3小时、8小时、24小时这样,并在超过策略规定的时间及轮询次数后将支付流水更新为失效终态,并提供订单查询接口供业务平台完成自身业务订单逻辑的更新。系统示意图如下:通过旁挂式的方式,支付主流程会变的相对简单,只需要考虑正常的收单场景,对于很多业务实时性不太高的支付场景,这种方式也够用。但对于业务实时性要求非常高,并且对用户体验有极致要求的场景来说,这种方式显然也是存在明显问题的。我们还是拿点外卖这件事来说,外卖后台在接收到用户通过App发送的点餐支付请求后生成外卖订单并将支付请求发送给平台支付系统,支付系统一般来说会首先进行订单防重判断,即已经发起过的成功支付/支付中的请求不被允许发起第二次,支付成功的交易不允许重复发起。但是等待支付或支付失败的交易很多公司内部支付系统都会被要求允许发起二次付款,在外卖点餐环节,如果用户点餐了但是并没有立刻进行支付或者支付由于某种原因失败了,是可以重新发起付款的,在这种情况下,支付系统就会面临一个问题,由于不知道在进行预支付后用户是否完成了支付,对于是否应该继续让用户发起支付请求,防重逻辑就会变的迟钝,如果允许用户支付则可能出现重复扣款的问题,不允许则会影响用户体验,为了让整个机制变得合理,所以需要依赖于上述系统的补偿机制来进行回盘或失效处理。这里会遇到以下三种情况:1、用户最终未支付,则系统安装一定的轮询机制进行后续的订单失效处理即可;2、用户完成了支付,支付系统迟迟收不到微信的回调,通过逐步轮询的方式系统也会进行后续的订单回调补偿;但这里的问题是,如果异步补偿系统对订单的轮询不够及时(在支付订单量比较大的情况下,通过定时轮询的方式在时效性上较差),那么就会导致一个比较尴尬的情况,用户付完了钱,但是外卖订单很长时间显示未支付,无法进行派单,在轮询补偿系统完成回调后触发派单操作,但往往很可能已经过了饭点,并且很可能用户已经触发了申诉流程,外卖平台需要进行退款操作(增加客服工作量);3、则是用户当时并未及时支付,在订单失效前的某个时间,用户可能会选择重新付款,因为此时支付系统订单并未失效,会处于支付中状态,触发防重机制,无法再次发起付款;对于2、3两种情况,如果需要很好的满足业务要求,就要提高支付系统时效性,提高订单防重失效、快速回盘的处理时间。要达到这样的效果,往往单纯的依赖旁挂式的处理方案是很难达到的,而是需要让实时支付流程的设计变得更加智能和灵敏。实时支付流程优化设计为解决上面的问题我们需要在实时支付流程中加入异常优化机制,从整个流程的设计上去解决,让整个支付系统变得更加智能和灵敏,虽然这种方式看似让支付主流程变得复杂了很多,但从优化用户体验、提高系统灵敏度的角度看,这种复杂度是值得的并且是可以通过技术细节屏蔽的。那么具体应该怎样去设计这样的流程?详细如图所示(需点击放大):如上图所示,支付系统接收到前端发起的支付请求,系统首先需要进行防重判断,这里为了有效地防止并发请求,采用Codis锁的方式,即一笔业务支付订单请求发送到支付系统后首先获取Codis全局锁,如果存在锁则说明订单正常被处理/未被正常处理,此时我们需要进行锁更新时间判断,如果锁的更新时间与系统当前时间差10s,则此时会存在两种情况,一种就是这笔支付订单没有被正常支付,是应该被允许重新发起支付的;另一种可能则是用户可能支付成功了,只是渠道在支付结果回调的过程中出了问题导致系统掉单。这两种情况混在一起,系统并不能立刻识别出到底属于何种情况。这个问题是一个非常普遍和典型的问题,几乎很多公司都会遇到。此时,支付系统有两种选择,一种选择是执行严格的防重策略,即要求所有对接支付平台的业务系统每次调用支付请求都必须生成不同的商户订单号,支付系统对于同一个订单号无论支付成功与否都不允许将此商户支付单号重复发送给支付平台,这种方案与第三方支付公司的接口约定一致。这种防重策略粗暴简单,本质上是将逻辑的复杂性传到给了业务系统,也会让业务变的难受,如果支付平台在后期经历过重建,需要推动业务线切换的话,也往往会招致业务系统的反对。那么如何让支付平台本身来屏蔽这种复杂的细节,让业务尽可能无感知?两个订单号商户订单号:业务系统发起的向支付系统发起支付请求是生成的在商户系统中唯一标识一笔订单的标记。支付订单号:业务系统向支付系统发起支付请求后,支付平台本身生成的系统唯一标识一笔支付流水的标记,并且是支付系统与第三方支付渠道交互的唯一流水标识。为了达到以上目标需要在支付系统内部采用1:3(举例)的订单模型,即1笔业务订单号可以对应支付系统3笔支付订单流水,并且每笔支付流水允许被发起的条件是上笔支付流水数据库订单状态是未支付成功,并且需要在当前这笔支付流水重新生成后将上笔支付流水放入订单动态实效队列,进行快速失效处理。之所以采用以上方式,原因在于超过3次时间间隔超过30s(策略可以根据业务实践进行动态调整)还未完成支付的情况,系统基本可以认定属于恶意点击行为,可以直接拒绝此笔业务订单重新发起支付了。需要动态将上笔支付订单快速置为实效的原因在于,我们需要在内部设定一个逻辑:“如果支付订单处于实效状态并在后面接收到了第三方支付成功的回调,则需要系统自动发起该笔支付订单的原路退款逻辑,并确保该笔订单不会被通知到商户侧”。这种现象之所以出现,在于我们为了提高系统的实时性允许了少量重复扣款的情况发生,并进行了自动冲正逻辑。当然,在细节的处理上我们是在当前流水发起前对上笔流水已经进行了一轮订单实时查询,如果结果为支付成功,则此次请求会直接返回支付成功(或者,也可以提示已经支付成功,App主动查询支付系统的订单状态来完成回盘)。如果当前订单再次预支付成功,在同步返回预支付结果前需要更新Codis中订单锁的时间及发起次数。同时,在接受到第三方正常的支付成功回调后完成订单状态更新及商户通知后消除Codis锁。上述策略,为解决防重&二次支付问题提供了一种方案,当然还有很多细节的代码逻辑是需要考虑完善的,例如,实时查询超时的策略、退款的触发时间、用户提示等。此外,如果用户不再选择再次发起付款,系统中的存量订单也需要通过文中早些时候介绍过的异步补偿机制逐步将进行失效处理(具体策略机制可参考图示及之前的概述),只是如果在异步补偿机制过程中发现掉单的订单,是否正常回盘或自动给用户退款,就需要具体情况具体分析了。以上就是本文的全部内容了,在整个支付系统的搭建的过程中还有很多细节逻辑是可以优化的,需要根据具体业务进行实践与处理。鉴于经验和水平有限,不足之处,还请批评指正.转载声明:本文转载自「无敌码农」,搜索「无敌码农」即可关注。
2018年8月23日
其他

支付系统

架构不是静态的,而是动态演化的。只有能够不断应对环境变化的系统,才是有生命力的系统。所以即使你掌握了以上所有的业务细节,仍然需要演化式思维,在设计的同时,借助反馈和进化的力量推动架构的持续演进。
2018年8月14日
其他

支付公司账务系统的那些事

言归正传。账务系统是个什么鬼?单纯来看账务系统可能每个人都有自己的看法,在各自的角度来看也都没啥毛病。接下来炮哥就说说我自己的看法,欢迎交流探讨。
2018年8月9日
其他

10点读懂支付路由

比如可以从费率、优惠额度、QOS和使用率角度来评分,给优惠额度高一点的比重,这会导致高优惠额度的通道被优先命中。注意每个维度上的计算公式也不是一成不变的,比如使用率和QOS都是动态打分计算。
2018年5月22日
其他

支付系统-账户

账户系统记账完毕后,将定时以批量文件的方式送会计记账,同理,会计记账也将为每笔交易分配会计流水,对于会计记账,需支持一借一贷、一借多贷和多借一贷的记账模式。会计记账也分为记分户明细账和更新会计余额。
2018年5月18日
其他

【周一见】2018NO.3

根据征求意见稿,互联网机构对其代理销售金融机构的黄金产品,可提供产品展示服务,不得提供黄金清算、结算、交割等服务,不得提供黄金产品的转让服务,不得将代理的产品转给其他机构进行二级或多级代理。
2018年5月14日
其他

【周一见】2018NO.2

线上付款服务公司PayPal最新专利显示,PayPal已经研究出可以让用户使用智能眼镜在AR场景下购物以及支付的技术。当消费者注视货架的某项商品时,可以看到包含价格、付款方式,和退贷政策等虚拟资讯。
2018年5月7日
其他

【周一见】2018NO.1

4月26日,在中国支付清算协会举办的《中国支付清算行业运行报告(2018)》发布会上,中国人民银行支付结算司副司长樊爽文在《报告》点评环节发言,对当前支付清算市场的一些乱象做出批评。部分内容如下:
2018年4月30日
其他

解密支付公司的迁移技术方案

数据迁移并不是一项需要高大上的技术工作,它需要的是对业务逻辑的把控,对操作流程的理解,对新旧系统特性和环境的掌握,以及对细节的掌控,要深入骨髓般的理解系统才能做好,因此迁移是需要架构组来把关的。
2018年4月22日
其他

支付平台架构设计评审核心要点与最佳实践

不是所有更新操作都要加显示锁的,数据库引擎本身有行级别的锁,本身在更新行数据的时候是有同步和互斥操作的,我们可以利用这个行级别的锁,控制锁的时间窗口最小,一次来保证高并发的场景下更新数据的有效性。
2018年4月18日
其他

完整的支付系统整体架构

协议支付也称代收或者代扣,代收指渠道授权商户可以从用户的银行账户中扣款,一般用于定期扣款,不用于日常消费。比如水电煤气、有线电视费。协议支付是通过封装银行、第三方支付提供的代扣或者快捷接口来实现。
2018年4月16日
其他

支付系统架构模块划分与设计

上述操作,除了对账、查单外,每个操作实现的主流程,一般会包括参数校验,支付路由,生成订单,风险评估,调用渠道服务,更新订单和发送消息这7步,对于一些比较复杂的服务,还会涉及到异步同通知处理的步骤。
2018年4月12日
其他

Fastpay快付项目主页

Fastpay项目目前托管于码云,地址为:https://gitee.com/robertleepeak/fastpay,可以点击文章下面“阅读原文”链接直达项目主页,亦可识别下面的二维码直达主页。
2018年4月1日
其他

解密支付平台建设资金底线防火墙的杀手级设计方案

单边是收单业务中最典型的资金底线风险,单边这个词汇来自于财务行业,在收单的结算流程中,很容易出现一种“单边账”的情况,单边账:即一方的账目发生变化,而另一方没有,那么随之而来的问题就是,钱去哪儿了?
2018年4月1日