大家好,我是老三,好久不见,最近比较忙碌,状态也不是太好,很久没有输出。
最近在做对账系统的调研和设计,给大家分享一些对账系统的知识。
有个男人叫小帅,娶了个老婆,叫小美,早上,小美给小帅二十块钱买早餐,小帅买了包子、油条、豆浆回来,并说钱已经花完了,小美不信,拉着小帅到了早餐铺,拉着老板的账单对了一下,发现还剩两块钱……

这就是一个简单的对账场景,我们再看看电商的大概支付链路:

可以看到,涉及到的系统还是比较多的,对电商内部而言,可能涉及到支付、订单、风控、履约,对于外部而言,电商和第三方渠道,支付渠道和银行。内部部之间,想不出差错那简直得图灵、冯诺依曼诸神保佑,所以,对账系统,是交易最后也是非常重要的一环,
通过对账,能找到各个内、外部系统之间不一致的交易,并通过差错处理,厘清账务,防止资损。
电商系统内部的对账相对简单一些,不管是通接口、还是数据聚合,都可以跨服务、跨库地核对交易数据。
我们这里主要讨论电商平台和三方渠道的对账:
对于电商公司而言:
业务对账。资金对账。这篇文章我们主要讨论业务对账。
通过什么对账呢?
对于电商平台内部,需要把各个服务的交易相关数据聚合起来,一般是通过拉的方式:

对于外部的对账数据,各个支付渠道一般会提供对账单,不同渠道的对账单格式上不太一样:



对账文件当然是不能直接使用的,需要把三方渠道的对账单,清洗成对账系统用到的数据:

那对账文件是如何获取的呢?一般主要有两种方式:
那对账文件是什么时间生成的呢?国内的支付渠道一般对账单生成时间是T+1。

什么时候开始对账?对账一般分为两种:离线对账和实时对账。
我们这篇文章主要讲的就是离线对账,在对账单下载解析完成之后,开始对账,也就是所谓的T+1。例如支付宝,6点生成对账单,可以定时6:30去下载和解析对账单,解析落库之后,就可以开始进行对账。
实时对账呢,一般是对交易的状态进行监听(mq、binlog),监听到状态的变化,就开始核对。
看看离线对账的逻辑:
那么对账是以什么为基准呢?是本系统的订单,还是支付渠道的订单?
为了尽可能保证准确性,一般是双向的,也就是基于本系统订单,比较三方对账单,也基于三方对账单比较本系统对账单,进行复核。

通常要核对的是这几个点:
如果没有问题,那这比流水就对平了,反之就是发生了差错:

对于常见的有规律的差错单,我们可以设计一些规则来自动处理,比如跨日交易问题,可以查看前一日的交易记录,或者后一日的交易记录,查看是否能够对平。还有其它的一些汇率换算等等问题,都可以尝试对平。
对于对不平的账,就需要标记错帐,进行人工处理,例如发生了掉单,可以给用户退款;例如用户未退款,可以尝试拦截发货。

我们来看看一些对账系统的架构设计:




可以看到,主要就是那些东西,数据存储(DB、缓存、大数据)、数据订阅(binlog、mq、rpc)、task等等。
这篇文章给大家分享了一些对账系统的知识,老三对于对账系统,目前也只是调研和设计阶段,大家有什么意见可以和我交流,后续会给大家分享更多电商、支付相关的东西,点赞、关注不迷路!
对账参考和学习资料:
[1].《支付架构实战》
[3].支付对账系统怎么设计?
[5].对账系统从入门到精通
[7].[美团配送资金安全治理之对账体系建设
[8].有赞业务对账平台的探索与实践
我需要使用ActiveMerchant库在我们的一个Rails应用程序中设置支付解决方案。尽管这个问题非常主观,但人们对主要网关(BrainTree、Authorize.net等)的体验如何?它必须:处理定期付款。有能力记入个人帐户。能够取消付款。有办法存储用户的付款详细信息(例如Authotize.netsCIM)。干杯 最佳答案 ActiveMerchant很棒,但在过去一年左右的时间里,我在使用它时发现了一些问题。首先,虽然某些网关可能会得到“支持”——但并非所有功能都包含在内。查看功能矩阵以确保完全支持您选择的网关-http
前言微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的。一、申请流程和步骤图1-1注册微信支付账号获取微信小程序APPID获取微信商家的商户ID获取微信商家的API私钥配置微信支付回调地址绑定微信小程序和微信支付的关系搭建SpringBoot工程编写后台支付接口发布部署接口服务项目使用微信小程序或者UniAPP调用微信支付功能支付接口的封装配置jwt或者openid的token派发原生微信小程序完成支付对接二、注册商家2.1商户平台商家或者企业想要通过微信支付来进行商品的销售,必须先通过微信平台(pay.weixin.qq.com)去将商家进行注册。注册成
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭8年前。Improvethisquestion使用Ruby(也许还有Rails)工作。是否有任何方法可以接受和管理Ruby或Rails的比特币支付?
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭8年前。Improvethisquestion我想使用PaypalWebsitePaymentsStandard在我的Rails网站上实现支付解决方案。(参见https://www.paypal.com/IntegrationCenter/ic_standard_home.html
在我的网页上,我尝试按照手册使用JavaScript实现PayPal结帐:https://developer.paypal.com/docs/checkout/一切都适用于标准选项。例如,这很好用:paypal.Buttons({createOrder:function(data,actions){returnactions.order.create({purchase_units:[{amount:{currency_code:'EUR',value:'120.16'},description:'PurchaseUnittestdescription',custom_id:'6473
一、问题描述 微信小游戏的内购支付,接入的是米大师支付。先简单介绍下通用逻辑:1)、用户点击游戏内下单2)、客户端构造订单物品等参数并发给服务端3)、服务端接收后,生成唯一订单号等内部逻辑处理后,返回客户端下单需要的参数4)、客户端调用微信下单接口,wx.requestMidasPayment(Objectobject)|微信开放文档,并将结果上报给服务端5)、服务端根据客户端的支付上报结果,分时轮询对应订单的用户余额6)、对用户余额进行扣款,并修改对应订单状态7)、通知游戏服务端订单状态,并发货给用户初看,逻辑很清晰,没啥问题,但是第4步经常会返回错误的结果(客户端),比如没有返回(比
微信支付(微信支付分为3大步) 1.创建订单 1.1组织订单的信息对象(包含三个参数) 价格order_price,地址consignee_addr,商品信息goods 1.2发起请求创建订单(调接口) 1.3得到服务器响应的“订单编号” 2.订单预支付 2.1发起请求获取订单的支付信息(调接口) 2.2预付订单生成失败 2.3得到订单支付相关的必要参数 3.发起微信支付 3.1调用uni.requestPayment()发起微信支付 3.2未完成支付 3.3完成了支付,进一步
我正在将智能支付按钮集成到Paypal结账中paypal.Buttons({createOrder(data,actions){//...onApprove(data,actions){//...}).render('#paypal-button');除了使用PayPal帐户付款外,我们还希望用户无需创建paypal帐户即可使用SEPA或信用卡为我们的数字产品付款。我们不需要用户输入的账单地址或送货地址。我们已经拥有该信息并自行处理账单,但送货不适用。有没有办法使用JSSDK禁用地址输入(最好还有联系信息输入)?我可以传递给SDK资源或paypal.Buttons.render()方法
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭8年前。Improvethisquestion我正在寻找Chargify、Braintree或其他类似的在线支付解决方案。上下文是我正在使用NodeJS,现在只想测试如何在开发模式下使用在线支付。因此,对我而言,主要方面不是这些服务在实际应用程序中的工作方式,而是其中哪些具有为No
我正在构建一个列出三个不同订阅选项的支付页面,并使用Stripe的结账来管理支付。页面呈现正确,所有3个订阅选项都有应该链接到Stripe的“立即购买”按钮。我的问题是第一个按钮是唯一正确拉起Stripe结帐流程的按钮。按钮2和3抛出以下错误:未知操作找不到ChargesController的操作“索引”我的支付页面的相关部分是:">BuyNowvarhandler=StripeCheckout.configure({key:'',image:'/assets/my_logo.png',token:function(response){vartokenInput=$("").val(r