Nordlet

← 博客

用于多商家平台记账的双分录总账 API

一份技术指南,探讨不可变的双分录总账 API 的工作原理、平台为什么需要它们,以及将会计功能嵌入平台时应该关注的要点。

Nordlet Team · · 1 分钟阅读

大多数多商家平台发现自己遇到记账问题的方式往往如出一辙:新入职的财务人员打开打款电子表格,开始追问在买家付款和资金离开平台账户之间的这段时间里,究竟是谁在记录对卖家的负债。工程团队指向一张 transactions(交易)表。财务人员则指出,事件表并不等于账套。事件数据与真实会计之间的这道鸿沟,正是双分录总账 API 旨在弥合的地方。

这是一个兼具技术性与合规强制力的问题。多商家平台代持他人的资金、跨司法管辖区计算增值税,并代表卖家开具发票。在没有合规支撑的情况下,仅靠自研的交易表勉强维持,直到审计人员、税务机关或大客户要求出示凭证时,问题就会彻底暴露。

什么是真正的双分录总账 API

双分录总账 API 是一个通过 HTTP 暴露的可编程会计引擎。平台记录的每一笔财务事件都会被写入一条平衡的分录:至少包含一笔借方和一笔贷方,两者总额相等,并过账到会计科目表(Chart of Accounts)中指定的科目。该 API 会在写入时强制执行这种平衡,并存储这些分录,使其事后无法被静默修改。

其中的“双分录(double-entry)”源于拥有四百年历史的会计规则,即每笔交易至少影响两个科目。“API”意味着调用者是你的产品,而不是人类簿记员。“不可变(immutable)”意味着纠错只能通过红冲反向分录来完成,而不是通过篡改历史记录来实现。这三个属性结合在一起,才使得生成的账簿具备审计就绪(audit-ready)的价值,而不只是表面整洁。

一个实用的工作定义是:

双分录总账 API 接收来自应用程序的财务事件,将每一事件转换为针对既定会计科目表的平衡分录,以不可变的方式存储这些分录,并通过可预测的端点公开生成的总账、试算平衡表(trial balance)和财务报告。

Nordlet 正是围绕这一理念构建的:将真实账簿作为 API 提供,总账、增值税逻辑、开票和对账功能均可通过你产品已经在调用的同一组端点进行访问。

为什么多商家平台特别需要它

单一商家的 SaaS 通常可以每天与通用会计工具同步一次数据。但多商家平台无法这样做,原因有三。

首先,它们处于资金流动的正中央。买家向平台付款,平台代持资金,然后扣除手续费向卖家打款。每一次资金移动都是一个独立的会计事件,会影响不同的科目:现金、应付卖家款、平台收入、应交增值税、退款准备金等。带有 status 字段的 payments 表无法捕捉到这些全貌。

其次,它们跨越了不同的税务管辖区。一个在立陶宛、德国和波兰拥有卖家、且买家遍布整个欧盟的平台,必须针对每笔交易应用正确的增值税处理方式,在 VIES(欧盟增值税信息交换系统)中验证卖家的增值税号,并出具令各地税务机关满意的申报表。如果在应用代码中自行实现这些逻辑,然后与独立的会计系统进行对账,往往会让大多数平台在不知不觉中陷入混乱。

最后,业务体量不适合人工记账。一个月处理一万笔订单的平台会产生数万条分录。这些流程必须实现端到端自动化,否则财务团队就会成为业务增长的瓶颈。

API 的分步工作原理

其底层机制并不像听起来那么晦涩。一个典型的平台订单流程如下:

1. 平台发出财务事件。 买家完成结账。后端调用总账 API,传入诸如:订单 ID、买家、卖家、总金额、增值税率、平台佣金、币种和幂等性键(idempotency key)等信息。

2. 总账构建分录。 API 将该事件转化为借方和贷方。对于一笔直接的平台销售,这可能意味着:借记在途资金科目,贷记应付卖家净额科目,贷记平台佣金收入科目,并贷记税款部分的应交增值税科目。所有科目均保持平衡,并以原子性完成过账。

3. 不可变写入分录。 一旦过账,分录就会获得一个标识符和时间戳,并且无法修改。如果发现错误,你需要发布一笔反向冲销分录和一笔更正分录。审计追踪的意义正在于此。

4. 下游报告实时更新。 试算平衡表、应付卖家余额、增值税汇总表以及利润表(P&L)会立即反映出新分录的影响。没有夜间批处理任务,没有数据导出,也没有数字处于“结算中”的对账窗口期。

5. Webhook 通知系统。 诸如 sale_invoice.paid 或 bank_transaction.matched 之类的事件会推送到你的端点,以便产品无需轮询即可做出响应。结合幂等性键,这意味着重试是安全的,网络卡顿时也不会混入重复数据。

重要的设计原则是:总账是财务事实的唯一来源(source of truth)。应用程序数据库则是产品状态的唯一来源。这两个系统之所以能够对账,是因为总账是由应用程序事件写入的,反之则不然。

会计科目表是设计的核心

在为平台设置总账时,大部分智力投入都集中在会计科目表上。这是借方和贷方归属的具名分类列表:各银行的现金科目、应付卖家科目(通常每个卖家一个,或者采用带子总账的汇总科目)、按类别划分的平台收入、按国家/地区划分的应交增值税、退款准备金、拒付(chargeback)准备金等。

以下是在各种平台中反复出现的几个设计模式:

  • 卖家资金属于负债,而非收入。 你代卖家持有的资金属于应付款项。将其视为收入并在以后将打款计入“费用”,是尽职调查中常见的经典错误。
  • 增值税是按国家/地区划分的独立负债。 如果你在多个欧盟司法管辖区运营,你需要为每个国家/地区设置不同的应交增值税科目,以便申报表能够清晰映射。
  • 费用必须在赚取的当月进行建模,而不是在打款时。权责发生制(accrual accounting)在这里是必不可少的。
  • 退款、拒付和争议都需要各自独立的科目,这样利润表才能反映真实情况,而不是正负销售额的盲目对冲。

一个优秀的总账 API 允许你定义一次该结构,然后充满信心地向其过账,而不必在结账代码中重新发明会计逻辑。

不可变性、期间锁定期与审计人员的关注点

不可变性听起来像是一个数据库细节。但它实际上决定了账簿能否获得审计人员的签字认可。

如果一个平台可以悄悄修改上一季度的分录,那么从会计意义上讲,上一季度的数字就是无法确定的。不可变总账强制执行了一条铁律:历史就是历史。更正必须作为更正清晰可见。期间锁定(period locking)进一步扩展了这一点:一旦某个月份关闭,未经明确的重新打开操作(该操作本身也会被记录日志),任何新分录或修改都无法写入该期间。

对于最终要进行融资、出售或面临税务审计的平台来说,这不是“锦上添花”的功能,而是让账簿经得起推敲的关键所在。Nordlet 的总账默认即围绕这一点构建,内置了不可变的双分录结构和期间锁定功能,而不是事后打补丁。

欧盟增值税:耗费工程时间的大户

增值税是大多数平台记账项目工期超支的重灾区。规则并非简单的“应用一个百分比”。它们取决于买家在哪里、卖家在哪里、销售的是什么、卖家是否注册了增值税、平台是否根据 2021 年电子商务规则被视为隐名供应商(deemed supplier),以及当地适用何种申报制度。

针对欧盟的严肃总账 API 至少应处理以下内容:

  • VIES 验证:用于验证卖家和买家的增值税号,理想情况下结果应被缓存并打在交易上
  • 按国家/地区划分的增值税率逻辑:包括优惠税率和豁免情况
  • i.SAF 报表生成:用于立陶宛的税务申报,以及其他成员国要求的同类结构化输出
  • Peppol BIS 3.0 电子发票:适用于向强制实施电子发票过渡的司法管辖区
  • OSS/IOSS 处理:用于跨境 B2C 销售

如果按国家/地区在应用程序代码中实现这一点,将需要一个完整的工程团队耗费大量精力,而且永远无法真正完工,因为规则一直在变。将其推入总账层是更为务实的做法。

对账是展现省时效果的地方

一旦总账成为唯一的事实来源,银行对账就不再是每月的痛苦折磨。银行对账单导入后,总账已经清楚知道应该存在什么,匹配过程在很大程度上是自动化的。

现实中的对账并非“完全零人工”。它的目标是“异常自动浮现”。对于顺利匹配的百分之九十的交易提供一键对账流程,再加上需要人工决策的百分之十的队列,这大致就是设计良好的对账 API 所能实现的效能。智能付款匹配可以处理部分付款、超额付款以及涵盖多张发票的付款,而无需人工为每种情况编写规则。

用于供应商和卖家打款的 SEPA 导出(pain.001 格式)闭环了出金环节。你在产品中批准打款,总账生成 SEPA 文件,银行进行处理,产生的资金变动随后自动对账归位。

自研、购买还是嵌入

平台团队通常会考虑三种路径。以下是它们在关键维度上的对比。

方案 投产时间 审计就绪度 欧盟增值税处理 是否契合产品内部
自研总账 12 至 24 个月以上 完全取决于你的团队 自行按国家/地区开发 是
同步至 Xero / QuickBooks 数周 会计端表现良好,平台专属流程表现薄弱 部分支持,需外挂插件 否,保存在独立工具中
嵌入总账 API(如 Nordlet) 数周 通过不可变总账和期间锁定内建 内置欧盟支持,含 VIES 和 i.SAF 是,通过 API 和 SDK

如果你的核心产品本身就是会计软件,那么自研是可以辩护的。对于其他所有企业而言,这种经济账往往划不来。与传统会计工具同步适用于单一实体企业,但在面对复杂的平台业务流时就会捉襟见肘:拆单付款、卖家子总账、按国家/地区划分的增值税以及平台被视为隐名供应商的场景,都无法与专为单一公司账簿设计的工具完美映射。

嵌入 API 优先的总账是现代平台的共同趋势。账簿存在于你的产品体验内部,卖家可以在你的 UI 中看到各自的财务状况,而合规重担则在基础设施层得到了妥善处理。

评估总账 API 时应关注的要点

在与供应商通话时,建议手头常备这份精简的检查清单:

  • 不可变的双分录存储,采用反向分录更正机制,而非可编辑的行
  • 期间锁定功能,并记录重新打开的操作日志
  • 每个写入端点均支持幂等性键
  • 提供产品所需响应事件的 Webhook,而不仅仅是轮询 API
  • 团队实际使用的语言的强类型 SDK
  • 按国家/地区划分的增值税逻辑,包括 VIES、i.SAF 或同类规范以及 OSS/IOSS
  • 多实体(Multi-company)支持,以防你运营多个实体或有此计划
  • 精细的基于角色的访问控制,能够区分开发人员、会计师和查看者
  • 支持 XLSX、PDF 和 JSON 格式的报告导出,并在大型报告就绪时发送 Webhook 通知
  • 镜像生产环境行为的沙盒环境,而非精简版的演示

如果供应商在技术通话中无法演示前三点,后面的内容也就无需多谈了。

我的首选实施步骤

如果一个平台要从头开始这项工作,以下顺序可以最大限度地减少痛苦:

  1. 在编写任何代码之前,先在白板上绘制出实际的资金流向。谁在什么时间、以什么币种、在何种增值税处理下欠谁多少钱。
  2. 根据该图草拟会计科目表。应付卖家款、平台收入、按国家/地区划分的应交增值税、准备金。在投入生产之前,请会计师进行审核。
  3. 选择总账层:自研、同步或嵌入。诚实评估你的团队究竟能够交付和维护哪一种。
  4. 端到端实现一个流程:从订单到开票、打款再到对账。证明它是平衡的。然后进行规模化扩展。
  5. 一旦第一个月份顺利结账,立即开启期间锁定。这种纪律性会带来复利效应。

那些做对这一点的团队将总账视为核心基础设施,而不是事后的报表附庸。这就是思维的转变,它能让与审计员、投资者或税务机关的财务对话变得简短高效,而不是漫长煎熬。

FAQ

双分录总账 API 与会计软件集成(integration)是同一回事吗?

不是。集成通常会延迟将产品中的数据同步到外部会计工具中。而总账 API 本身就是会计系统,支持直接、实时的写入。这种区别至关重要,因为集成在边缘场景下会丢失保真度:例如部分付款、多币种、平台拆单等。总账 API 可以原生记录这些场景。

难道我们不能直接使用 Stripe 或 Adyen 的报告吗?

支付处理商的报告告诉你的是资金通过处理商的流向。它们并不是双分录账簿。它们不了解尚未打款的应付卖家款、跨国的增值税负债,也不了解非支付处理商的费用。它们只是总账的一个输入源,而不能取代总账。

实际中的“不可变”究竟有多不可变?

分录无法被编辑。更正只能是通过引用原始分录来创建新的分录。这是一项设计决策,而不是技术决策。任何称职的总账都会强制执行这一点。之所以要在意这一点,是因为“我们为了对上银行账而修改了它”正是导致账簿不再值得信任的典型模式。

非欧盟平台该怎么办?

双分录的底层机制是通用的,但税务逻辑则不然。为欧盟增值税调优的总账 API 可以很好地处理欧盟重度业务,并且能够支持非欧盟交易,但在投入使用之前,如果你的主要市场是美国销售税或拉丁美洲电子发票制度,请务必仔细核实其具体的合规覆盖范围。

实际实施需要多长时间?

对于拥有清晰事件模型的平台,嵌入总账 API 直至跑通端到端的一个流程,通常需要几周的工程时间。从传统架构进行完整迁移(包括历史数据)则需要更长时间。变量通常几乎总是现有数据的状态,而不是 API 本身。