为了更好地支持交易业务的快速发展,马蜂窝支付中心从最初只支持基础支付和退款的「刀耕火种」阶段,经历了架构调整的「刮骨疗伤」阶段,完成了到实现综合产品平台形态的「沉淀蓄力」阶段的演进。算法
目前,马蜂窝支付中心集成了包括基础订单、收银台、路由管理、支付通道、清算核对、报表统计等多种能力,为马蜂窝度假(平台、定制)、交通(机票、火车票、用车)、酒店(开放平台、代理商)等近 20 条业务线提供服务。本文将围绕支付中心总体演变过程当中不一样阶段的核心部分进行简要介绍。数据库
初期为快速响应业务的支付、退款以及一些基础需求,支付中心主要负责接入支付通道(支付宝、微信、连连等),由各业务线分别实现收银台,而后调用支付中心进行支付。业务系统、支付中心和第三方通道的交互流程图以下:后端
各系统交互流程为:设计模式
业务发展初期,业务量较小,交易场景也比较单一,这样的设计能够快速响应业务需求,实现功能。但当业务复杂性不断提升,接入的业务也愈来愈多时,该架构就显得力不从心了。各业务线须要重复开发一些功能,而且支付中心不具有总体管控能力,开发维护成本愈来愈大。主要的问题包括:安全
为了兼顾对快速发展中的业务的需求响应和系统的高可用性,保证线上服务的质量,咱们快速进行了架构调整,开始了向支付中心 2.0 的演进。微信
2.0 架构将各业务的公共交易、支付、财务等沉淀到支付中心,并主要解决了如下三个主要问题:架构
支付中心 2.0 是整个交易系统快速发展的重要时段。在此过程当中,不只要进行架构的升级,还要保证服务的稳定。并发
目前支付中心对业务提供的主要能力包括:app
针对马蜂窝业务的特色,目前支持的核心交易场景包括:异步
演进过程当中,首先是对相对独立,同时做为统一体系基础的网关进行模块化。支付网关对外抽象出支付、退款、查询这些标准请求,而后在网关基础上逐步梳理各支付通道,并逐步抽取出基础订单模块,解耦业务功能与支付功能,同时可支持复杂的业务场景。目前的系统功能总体架构以下:
如图所示,从架构上主要分为三个层次:
产品层主要包含消费者可见的收银台、支付管理后台和财务核算、对帐的财会系统。本文重点介绍收银台的设计思路。
收银台包含 H5 收银台和 PC 收银台两部分:
移动端:
PC端:
如上图所示,收银台主要由三部分组成:订单基本信息(含订单号及支付金额)、订单详情(含日期信息、商品信息及基础信息)、支付方式(平台支付、信用支付等)。
因为收银台是整个支付中心面向用户的惟一入口,用户体验及安全性相当重要。为同时支持业务个性化和用户的一致性体验,收银台主要是经过定制化和配置化的方式实现。对业务同窗来说接入也很是简单,仅需经过订单号跳转至收银台页面,后续流程均由支付中心完成。
用户下单后到达收银台页面,收银台经过订单所属业务线、支付金额、是否合单等信息,展现可用的支付通道。同时风控系统会从商品、订单、用户行为等维度进行监控,屏蔽高风险的支付渠道。支付渠道出现故障时可在收银台暂停展现。
(1)定制化
(2)配置化
收银台的配置化主要根据各业务的属性(业务类型、品类等)对后续操做作必定的流程处理配置化,好比:
支付中心中的核心模块,包括基础订单、支付路由、支付通道等。
基础订单系统是链接交易业务线、支付中心和结算系统的桥梁,实现了业务和支付结算解耦。主要涵盖了业务建立订单、关单、支付、退款、回调通知等 API 模块。基础数据支持普通支付、合单支付、拆分支付、保险支付等多种场景的支付功能,各个系统的交互流程以下:
目前基础订单系统可支持以下两种特殊场景:
(1)一订单 VS 多商品
建立一个基础订单能够包含 N 个商品(商品信息包含商品名称、商品 ID、单价、数量、折扣等,订单信息包含用户 UID、手机号、支付金额、订单折扣等汇总基础信息),N 个商品对应 M 个业务子订单 (M≦N),全部业务子订单的业务类型若同样则为普通模式,不然为搭售模式;每一个业务订单对应一个对帐单元(支付成功后会将支付信息同步给对帐系统),一订单 VS 多商品的创单模式基本支持目前全部场景,包括将来可能的购物车模式。
(2)一订单 VS 多支付单
普通订单用户选择支付宝、微信等渠道会生成一个支付单;当金额超过 5000 元时能够选择拆分订单金额支付,此时会生成多个支付单;若是下单勾选保险就会走第三方合单支付,会生成两个支付单;同时拆分支付也会致使用户部分支付或者超额支付,监控会针对异常支付状况进行自动退款;大金额订单有 10% 以上的转换率提高, 一订单 VS 多支付单模型更好的支持了马蜂窝的支付场景。
通道路由主要包含两方面,一个是业务侧须要控制支付通道,一个是支付侧须要选择支付帐户。
(1)支付帐户管理
支付建立订单和处理回调等流程中,须要根据业务类型、支付方式和支付通道肯定支付帐号,早期版本这个对应关系是经过配置文件维护的。一个业务类型对应多个配置项,每新增一个业务须要增长多个配置,并且随着更多支付通道的接入,新增业务须要配置的信息也愈来愈多,不易维护。
通过优化,把现有的配置对应关系放到数据库中,数据表由业务类型、支付方式、支付通道惟一肯定一个收款帐号,支付帐号的具体参数信息仍是放在文件配置中。建立订单时根据业务类型、支付方式、支付通道查询收款帐号,把帐号信息记录到支付订单数据表,回调时直接从订单表查询支付帐号。
(2)支付通道管理
目前对接了支付宝、支付宝国际、微信、京东支付、applepay、连连支付、银联 2B 等第三方通道,每个通道下有多个支付产品。第三方通道的接口形式差别很大,可是都提供下单、退款、查询、支付通知、帐单下载等标准功能。支付中心对这些支付通道作了一次封装,用一个抽象类做为基类,使用模版方法设计模式,在基类中定义了一个标准流程,具体的实如今通道各自的实现类中。客户类只须要关心基类的公共方法,和具体通道无关。
支撑层包含监控报警、日志管理、加签验签、配置管理、消息总线等模块。其中日志使用 ELK 进行收集管理,系统配置采用公司自研的分布式配置中心进行管理,消息总线也是使用公司二次封装的 RabbitMQ 进行消息分发及消费。
因为支付系统对可用性有极高要求以及支付数据的敏感性,支付中心独立实现了监控报警系统,下面将详细描述该监控报警系统的功能及设计思路。
为保证监控的实时性及有效性,监控依赖的资源如数据库必须和业务库要进行隔离(避免鸡蛋放在同一个篮子里)。支付监控系统涵盖了 API 监控、 服务性能监控、数据库监控等,可以提供统一的报警、分析和故障排除能力。从异常数据采集到故障问题主动发现及稳定性趋势分析,为支付体系优化提供数据支撑。
(1)监控后台
后台主要包含监控用户管理以及监控项建立管理,用户能够根据需求对应的监控项目,可配置的参数涵盖 API 请求地址、请求方式、可用性、正确性、 响应时间等性能数据以及报警方式和策略;详细配置以下图:
接口监控能够针对固定 host IP 绑定以及设置超时时间,监控请求支持 GET、POST 两种方式,POST 方式能够设置固定请求参数辅助,监控频率支持分钟、秒两种级别配置;响应数据模块能够校验 HTTP code 是否异常,配置响应数据类型,比较检测返回 key 值,针对 DB 监控还能够设置 DB 查询超时时间;报警模块目前支持短信和邮件两种方式,能够设置最小、最大报警阈值,超过最大阈值每隔最大报警数会触发一次报警,规避了故障期间短信轰炸问题。
(2)监控核心
为了实现最快监控频率 10 秒,同时能够支持成千上万的监控项并行运行,支付监控采用了多进程管理的方式。父进程建立指定数量的子进程,每一个子进程完成固定数量的监控任务退出任务,此时父进程实时监控子进程状态并建立新的子进程执行任务;父进程还能够接受外部信号完成服务重启以及中止,流程以下:
(3)监控报警
执行监控项会根据监控配置进行接口请求以及返回数据分析处理,而后经过 Redis 计数方式按报警策略进行报警通知。平常监控短信示例:
(1)数据一致性
上文提到,咱们采用模块化的方式来解耦业务功能与支付功能。在这个过程当中,每引入一个模块就会涉及到系统交互问题,所以最核心的即是数据一致性问题。针对数据一致性问题须要引入事务,实时、延迟校验以及补偿机制保证数据的最终一致性。从架构看是很清晰的,可是对于整个改造过程是艰难的,犹如给飞行的飞机更换发动机,因此咱们也把这个过程形容为一个刮骨疗伤的阶段。
(2)稳定性
支付服务都是由第三方支付通道提供的,支付通道存在不稳定性。好比用户用支付宝支付了一笔订单,因为各类缘由,支付中心没有收到支付成功的通知,用户又用微信再次付款,致使重复支付。
为了解决这个问题,支付中心采用定时扫描的策略,主动发现重复支付单并自动执行退款,不须要人工参与。退款流程中,退款单须要通过申请、审核、调用退款接口等流程,在调接口环节,可能会发生失败。调用失败的退款单,会根据退避算法发起重试,逐渐加大重试间隔,直到次数超过限制。失败单数量超过阈值、或者有订单处于失败时间超过阈值时会触发报警。自动处理不了的退款单能够人工检测,或线下退款。
目前,马蜂窝支付中心已经具有支持多业务、多场景、多支付方式的能力,但想要实现一个真正意义上「百花齐放」的平台,还有不少地方须要改进和完善。
即将到来的支付中心 3.0 将以微服务的思想把单体应用按照业务进行解耦,会逐渐从一个高耦合的单一系统演变为众多子系统组成的高并发、高可用、支持更多交易支付场景的分布式系统。微服务化拆分后,在系统结构上将更加清晰,但对于总体系统的开发管理和维护也将带来更大的挑战。
伴随马蜂窝「内容+交易」的战略升级,支付中心也会探索更多的支付方式和能力,持续为各业务线赋能。
本文做者:马蜂窝电商支付结算团队。
(马蜂窝技术原创内容,转载务必注明出处保存文末二维码图片,谢谢配合。)