热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

支付系统中的对账处理

博主说:在支付系统中,对账是至关重要的一部分,一个完善的对账体系,是支付系统健壮的基石。正文可以说,对账是支付系统最头疼的事情。每一笔交易,都要做到各参与者的记录能够吻合,没有

博主说:在支付系统中,对账是至关重要的一部分,一个完善的对账体系,是支付系统健壮的基石。

正文

可以说,对账是支付系统最头疼的事情。每一笔交易,都要做到各参与者的记录能够吻合,没有偏差。对账系统的工作,是发现有差异的记录,即轧帐;然后通过人工或者自动的方式,解决这些差异,即平帐

对电商系统来说,每一笔交易,在所有相关主体侧都要能对得上:

  • 交易主体,如果发起人是个人,必须能够从个人交易历史记录中找到这笔交易。但大部分人不会保留电子记录,所以一般是提供可以下载的账单或交易记录,让用户自己对去。
  • 交易对手,一般是商户。商户侧对账处理同用户侧,也仅仅提供对账单。
  • 交易渠道侧,这是对账的重点,一是核实交易流水,二是核实交易佣金,毕竟是租用人家通道做结算的。

那有哪些记录需要对账? 目前主要是两个:一个是交易记录;一个是退款记录。 这里以交易记录的处理为例,退款记录可以类似处理。

1. 对账处理流程

一般来说,对账流程涉及到如下步骤: 渠道对账单下载、本地交易记录准备、轧账、平账。

1.1 渠道对账单下载

银行、第三方支付、银联等,基本都会提供对账单下载的功能。不过也有少数工作做不到位或者太到位的银行,只提供账单查询后台,不提供对账单下载功能。 对开发人员来说,这里有几个坑:

  • 对账单格式不一,文本、XML、CSV 的都有,为了后续能够统一处理,在账单下载完成后,需要进行标准化处理。
  • 下载方式不一,HTTP、HTTPS、FTP 的都有,下载程序需要按照渠道的协议来处理。
  • 下载时间不一,一般是凌晨 1 点后,到中午 12 才能用的也有,如果在预定的时间取不到数据,需要注意重试读取。
  • 稳定性差,FTP 服务器出问题那是常有的事。渠道侧解决方案往往就是重启。所以重试机制是必要的。

看一下第三方支付的对账单情况:

1

银行直连的对账情况:

2

1.2 渠道对账单标准化

找个例子大家看看, 比如微信的对账单,他是 CSV 格式的,包括如下信息:

  1. 交易时间:这是在微信侧的支付完成的时间,这个时间会成为一个陷阱。
  2. 公众号 ID、商户号、子商户号、设备号: 这些信息需要做验证,确保是自己的单子,不要让微信把老王家的单子也给发过来了。
  3. 微信订单号、商户订单号:这两个是对单的核心,前者是微信侧产生的订单号,在微信支付接口返回值中有,但是万一收不到这个返回值,那在本地记录中可能就空了;后者是我们发送给微信的订单号,一般用这个来做对单依据。两边的数据中都会有这个值。
  4. 用户标识、交易类型、交易状态、付款银行、货币种类、总金额、企业红包金额: 这几个就是对单的核心字段,必须确保双方是一致的。
  5. 商品名称、商户数据包、手续费、费率:这些是可选验证。

3

而某宝的对账单是文本格式的,用空格隔开。他们家的就简单很多,只有商户订单号、交易流水号、交易时间、支付时间、付款方、交易金额、交易类型和交易状态这些字段。

4

由于每个渠道的账单格式都不尽相同,在得到账单后,下一步是对账单做标准化处理,这样轧帐以及后续工作就可以统一处理了。标准化后的账单数据可以放在文件系统或者数据库中。这取决于交易数据量。每天百万以上的量,还是使用文件系统比较合适。数据库操作相对比较慢,也浪费资源。基于文件系统的标准化涉及如下内容:

  • 文件格式标准化:统一使用 CSV 或者 JSON 或者 XML 格式,如果是使用 Hadoop 或者 Spark 来对账,使用 CSV 是个不错的选择。
  • 文件存储统一化:文件目录和文件名都需要遵循统一命名规范。

为了加快处理速度,我们使用 HDFS 作为文件系统,有利于后续的对账的处理。

1.3 本地交易记录准备

本地交易记录的准备,总的来说有如下方法:

  • 啥都不做,直接用原始数据。鉴于大部分系统使用的是 MySQL,这也意味着在 MySQL 上做对账。对账时需要大量的数据查找工作,必然会影响线上业务。在数据规模较大,比如超过 100 万时,就不太合适了。
  • 当然,还有一个选择是使用备库来执行对账,这样既简单也不影响线上业务。这是典型的空间换时间的做法。
  • 如果业务大到需要分表分库才能处理,那对账数据准备也不一样。使用分库也不现实,因为分库一般是按照主体 id,而不是渠道 id,来分库,这样对账就需要在多个库上进行,效率反而降低了。而对分表分库建立从库也非常耗费资源。这种情况下,需要同步一份数据到(HDFS)文件系统中,或者 NOSQL 数据库上。

由于交易记录是支付系统核心数据,有大量的应用,如信用、风控等,都需要交易记录数据。这些应用对交易记录的需求还不完全一致,为了提升性能, 交易记录会使用异步的方式来将数据投递给使用方。 交易记录在入库时,投递消息到消息系统中。使用方监听这个消息,一旦收到新消息,则从交易记录库中查询数据,获取数据并更新到库中。关于此类数据同步的文章不少,这里就不详细介绍啦!

1.4 轧帐

轧帐是按照客户订单号来比较本地交易记录和渠道交易记录是否一致。从算法角度,是计算两个数组的差异。在单机运行时,可以采用的算法不少,这里不详细介绍。 我们推荐采用 MapReduce 来轧帐,这有个优势,可以按照订单号将渠道提供的记录和本地记录 shuffle 到同一个 reduce 处理上,这样就可以很容易进行数据比对。轧帐中最大的坑,莫过于切分点的问题。比如以整 0 点为切分点,那存在一个问题,本地 23:59 发起的交易,到了渠道侧,可能会在 00:01 处理,这一笔交易变成第二天的帐了。实际处理中,一笔交易在渠道侧处理,花上几分钟都有可能。 对于切分点附近无法确认的帐,做一个时间窗,在时间窗内的数据,留待第二天对账时继续处理。

1.5 平帐

发现两边不一致的数据,那应该如何处理?数据量不大时,记录起来,人工甄别就行。但如果数据量很大,每天上千条,人工处理就成本太高了。这个没有统一的处理方法,需要根据有问题的数据,做个分析,然后做自动处理。 针对交易记录的对账的处理,主要有如下情况:

  • 长款: 本地未支付,支付渠道已支付。这主要是本地未正确接收到渠道下发的异步通知导致。一般处理是将本地状态修改为已支付,并做响应的后续处理,比如通知业务方等。
  • 短款:本地已支付,但是支付渠道中无记录;或者本地无记录,支付渠道有记录。在排除跨日因素外,这种情况非常少见,需要了解具体原因后做处理。
  • 金额不一致: 本地已支付,支付渠道已支付,但是金额不同,这个需要人工核查。

针对退款的对账处理,主要有如下情况:

  • 本地未退款,支付渠道已退款,则以支付渠道为准,修改本地为已退款状态,并出发后续处理。
  • 本地已退款、支付渠道已退款,但是金额不同,需要人工核查。
  • 本地已退款,但是支付渠道无记录;或者支付渠道有记录,但是本地没有。 在排除跨日因素外, 这种情况非常少见,需要了解具体原因后做处理。

2. 对账架构

基于微服务的对账系统实现的一个参考架构如下:

4

2.1 对账单下载

对账单下载组件每天定时触发,从支付通道服务器上下载对账单。 目前主要有 HTTP(S) 和 FTP 两种对账单下载方式。 技术选型上,HTTP(S) 用 Apache httpclient 即可实现链接池和断点续传, FTP 也可以使用 Apache Commons Net API。不管是哪一个,都需要设置重试次数和链接超时间。重试次数和间隔的设置需要小心,重试太频繁,容易把服务器打死.;时间间隔太大,又会阻塞后续处理步骤。5~10 分钟是一个合适的重试间隔区间。链接超时指在服务器出现问题时,连接在指定时间内获取不到数据即自动断开。这个很容易被忽略。我们有一次系统出问题,是渠道侧的FTP假死后重启,导致我们的客户端挂住,一直在等待重新链接。此外,注意,有些对账单下载是支持分页下载的。

2.2 对账单转换

将对账单转换为标准格式的账单,为对账 MapReduce 任务执行提供支持。每个渠道的对账单格式不一,需要分别开发转换程序。 转换程序主要就两个操作: 解析源文件和转换成标准格式并输出。

2.3 轧账MR

如上所述,轧账 MapReduce 程序在 Hadoop 上运行,以交易号为 Key,核对渠道订单和本地交易记录之间的差异,输出差异记录。最后将差异记录导入到差异表中。

总之,对账工作,即复杂也不复杂。需要细心,对业务要有深入的了解,并选择合适的架构。


转载声明:本文转自个人博客「凤凰牌老熊」,支付系统的对账处理。


推荐阅读
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • Mantis Bug Tracker:高效缺陷管理与跟踪系统
    缺陷管理平台Mantis,也做MantisBT,全称MantisBugTracker。Mantis是一个基于PHP技术的轻量级的开源缺陷跟踪系统,以Web操作的形式提供项目管理及缺 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • 本文详细介绍了在CentOS 6.5 64位系统上使用阿里云ECS服务器搭建LAMP环境的具体步骤。首先,通过PuTTY工具实现远程连接至服务器。接着,检查当前系统的磁盘空间使用情况,确保有足够的空间进行后续操作,可使用 `df` 命令进行查看。此外,文章还涵盖了安装和配置Apache、MySQL和PHP的相关步骤,以及常见问题的解决方法,帮助用户顺利完成LAMP环境的搭建。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 如何高效启动大数据应用之旅?
    在前一篇文章中,我探讨了大数据的定义及其与数据挖掘的区别。本文将重点介绍如何高效启动大数据应用项目,涵盖关键步骤和最佳实践,帮助读者快速踏上大数据之旅。 ... [详细]
  • 2016-2017学年《网络安全实战》第三次作业
    2016-2017学年《网络安全实战》第三次作业总结了教材中关于网络信息收集技术的内容。本章主要探讨了网络踩点、网络扫描和网络查点三个关键步骤。其中,网络踩点旨在通过公开渠道收集目标信息,为后续的安全测试奠定基础,而不涉及实际的入侵行为。 ... [详细]
  • NoSQL数据库,即非关系型数据库,有时也被称作Not Only SQL,是一种区别于传统关系型数据库的管理系统。这类数据库设计用于处理大规模、高并发的数据存储与查询需求,特别适用于需要快速读写大量非结构化或半结构化数据的应用场景。NoSQL数据库通过牺牲部分一致性来换取更高的可扩展性和性能,支持分布式部署,能够有效应对互联网时代的海量数据挑战。 ... [详细]
  • Linux学习精华:程序管理、终端种类与命令帮助获取方法综述 ... [详细]
  • 本书《.NET Core 2.* 开发者指南》是面向开发者的全面学习与实践手册,涵盖了从基础到高级的各个层面。书中详细解析了 .NET Core 的核心概念,包括如何创建 .NET Core 网站,并通过视频教程直观展示操作过程。此外,还深入探讨了 Startup 类的作用、项目目录结构的组织方式以及如何在应用中使用静态文件等内容。对于希望深入了解 .NET Core 架构和开发技巧的开发者来说,本书提供了丰富的实践案例和详尽的技术指导。 ... [详细]
  • 本研究聚焦于利用Java、PHP和Python开发的汽车销售管理系统,旨在为计算机科学专业学生的毕业设计提供参考。项目采用BS架构,结合多种编程语言的优势,实现高效的数据管理和用户交互。该系统不仅涵盖了汽车销售的核心功能,还通过集成先进的技术栈,提升了系统的稳定性和扩展性。 ... [详细]
  • 本文将深入探讨MySQL与MongoDB在游戏账户服务中的应用特点及优劣。通过对比这两种数据库的性能、扩展性和数据一致性,结合实际案例,帮助开发者更好地选择适合游戏账户服务的数据库方案。同时,文章还将介绍如何利用Erlang语言进行高效的游戏服务器开发,提升系统的稳定性和并发处理能力。 ... [详细]
  • nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
author-avatar
关圣钊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有