发票、收据与税务:一百零八张单据与七个必填字段

团队客户要一张能报销的单据,他删掉开错的发票重开,号段从此断了一处。发票不是账单截图的另一种排版,而是七个必填字段、连续号段、只能冲销不能删号的法律单据。每月 105 张收款单据加 3 张贷记单,含税地区那 285 美元税必须单列。

发票不是账单的截图,是一张能被第三方拿去审计的单据。

一、被删掉的 0341 号

三月,一个 12 人的团队客户来信,要一张「能报销的单据」。他打开后台,发现那张发票把 30 美元写成了 300 美元,顺手点了删除,重新开了一张。

以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。

新单据的编号是 INV-2026-0342,被删的那张是 0341。当月没有任何人提出问题:客户拿到了正确的票,后台少了一行,报表上的金额一分不差。

半年后客户做年度审计,把全年从这个供应商收到的十二张发票按号排成一列,采购只问了一句:「0341 去哪了?」

他答不上来。那张票在系统里从来没有存在过——没有作废记录,没有冲销单据,只有一个空洞。审计要的从来不是「金额对不对」,而是「每一张号都能解释」。

「删除」在很多框架里是最自然的一行代码,invoice.delete() 看起来比「作废」干净得多。代价是这张票在数据库里没有墓碑,日志里只有一条删除记录,半年后连你自己都无法证明当时删了什么。

他的补救办法是手写一张情况说明,附上银行流水,请客户财务把 0341 标为「已作废」。客户接受了,但第二年续约时采购提了一句「你们的单据流程要规范一点」——这句话的代价,比那张票本身贵得多。

这件事之后他做的第一件事不是改代码,是把后台按钮文案改了:原来的「删除」变成「作废并生成贷记单」,点下去必须填原因。文案改了,同类误操作少了八成。

这一篇讲的就是这件事:收款单据怎么开、号段怎么守、含税金额怎么拆,以及为什么这三件事在只有一个人的团队里最容易一起崩。

二、七个必填字段

发票(invoice)与收据(receipt)常被当成同一样东西,其实分工不同:收据证明「我已经收到这笔钱」,发票是「请为这些项目付款」。月付的 84 笔里,多数客户一辈子不会看第二眼;团队档的 14 笔里,超过一半会转给财务。

一张能被财务收下的发票,至少要填满七个字段:

字段本组基线上的取值缺了会怎样
发票号INV-2026-0342,按年连续无法引用,争议时说不清是哪一笔
开票日2026-10-26收入归属期无法确定
卖方主体注册主体全称与地址买方财务无法入账
买方主体客户公司名与税号跨境时无法适用协定税率
项目与数量团队档 1 席 × 30 美元 × 1 个月报销被退回重开
金额与税率净额 30.00,税率 20%,税额 6.00含税地区无法抵扣
付款状态已付 / 未付 / 已冲销客户重复付款或催款错发

七个字段里最容易被省掉的是后两个。金额只写一个总数,看起来「客户知道多少钱就行」;付款状态干脆不写,因为「系统里查得到」。但发票是给外部看的,外部没有你的后台。

数量和单价要分开写,不能只写总额。团队档一个席位 30 美元、周期一个月,就写「1 × 30 × 1」;客户加席位时,发票能看出加的是哪一项,而不是总额从 30 变成 60。

税率字段的价值在跨境时才显出来。同一个 30 美元的席位,卖给本地客户是含税价,卖给另一个地区的企业客户可能是零税率加反向征收,两张票的净额一样、税额不一样,靠的就是这一列。

付款状态决定了那封邮件是催款还是道谢。状态错一格,客户会收到「您的发票已逾期」而实际早已付清——这种邮件比不发更伤。

一张 30 美元的团队发票,含税后是 36 美元,净额 30、税额 6、总额 36 三行必须都在。少写税额那一行,客户的财务会把整张票退回,然后你的支持邮箱里会多一封「请重开」的邮件——本组每月 105 张单据,只要有 5% 被退回重开,就是 5 张的额外工时。

三、号段只能往前,不能回头

编号规则只有四条:按年重置、连续、不复用、不跳号。本组一年 1,296 张单据,守住这四条的成本几乎为零,破坏的代价却是一次审计缺口。

具体到实现,两件事必须写死:发票表只允许追加(append-only),作废不是删除行,而是把状态改成 voided 并生成一张贷记单(credit note)。贷记单有独立号段,字段里带原发票号,金额为负。

本组每月 3 张贷记单,来自三种情形:退款、开错金额、降级补差额。它们与 105 张收款单据一起构成 108 张/月,任何一张缺失都会让「号段连续」这条不成立。

连续性检查可以写成一条日任务:取当年最大号与当年行数,两者之差必须为 0;再取号段最小值,必须是 1。两个条件要一起看,才能过滤掉按年重置带来的正常跳变。

贷记单的金额记负数,号段记正数——这两件事不要混。金额为负是会计语言,号段为正才是单据语言;把贷记单塞进收款号段,等于在把 105 变成 108 的同时破坏了「一号一交易」。

退款时最省事的做法是直接改原发票状态,但那样客户手上那张票就变成「一张标着已退款、金额却还是原值」的发票。正确顺序是:原发票不动,另开贷记单,两张票一起构成一次完整冲销。

钱相关的表一共 7 张:customers / subscriptions / invoices / invoice_lines / payments / refunds / credit_notes。它们只占全库 34 张表的五分之一,却装着全部对外的承诺。

一个具体取舍:发票 PDF 的生成大约 600 行代码,涉及字体嵌入、中文换行、金额大写、分页与页码。它不影响计费正确性,只影响观感与合规外观,属于可以外包、或直接用通道托管页(hosted invoice)的部分——这一条在第九篇算账时会再出现一次。

那 600 行里,大约 200 行在处理中文断行与字体子集,150 行在金额大写与货币符号,剩下的才是排版。这也是它适合外包的原因:难点不在业务,在排版细节。

四、含税与不含税:285 美元不是收入

本组全部数字都是不含税口径:1,710 是净收入,税不在这里面。含税地区要另算。

以 20% 为教学假设:

口径客户支付净收入税备注
不含税(基线)1,7101,7100税由客户自行申报
含税 20%1,7101,425285代收代缴,不是收入

最容易犯的错是把含税金额整笔记成收入:1,710 全部进账,月度确认收入立刻虚高 285,一年就是 3,420。这笔钱躺在银行账户里,看起来像利润,实际是负债。

正确做法是三条并行:确认收入只记 1,425;税单独进一张应缴表;发票上净额、税率、税额分三行列。混合地区时按客户所在地逐笔判断,不要用「平均税率」摊销——那会让每一个地区都不准。

三张表的关系也要说清:invoices 记应收,payments 记实收,确认收入是第三张按期间摊的表。含税时 payments 的金额是含税总额,确认收入只拿净额,差额进应缴税表。

还有一层:本组 344 个账号里,含税地区的占比并不高,但团队档客户几乎都在其中。假设 20 个团队席位里有 12 个在含税地区,对应 360/月含税收入,拆开是净额 300、税 60。这个拆分要能按客户逐行查到,不能只有一个总数。

月付与年付在税上处理不同:年付 5,400 一次性收款,税也一次性发生,但净收入要按月摊 450。收与确认分离、税与收入分离,两条线各自独立。

汇率是另一个制造差异的地方。本组统一以美元记账,不做多币种;一旦接受本地货币付款,结算单金额与本币入账金额之间就会差出一笔汇兑损益,那笔钱不属于收入。

一句话原则:发票上的每一个数字,都要能在三张表里找到落点。找不到落点的数字,迟早会在对账时变成一个无法解释的差额。

复算:把单据量、含税拆分与号段风险各算一遍,四个数字互相独立,但必须同时对得上。

105 + 3 = 108 张/月;108 × 12 = 1,296 张/年
含税 1,710 ÷ 1.2 = 1,425 净收入;税 1,710 − 1,425 = 285/月
285 × 12 = 3,420/年
发票号连续性:1,296 张/年,跳 1 号即审计缺口 1 处

五、行动清单与复算验收

  • 把发票表改成只追加,作废走状态位,代码里不出现任何删除
  • 给号段加唯一约束与连续性日检,跳号当天告警而不是月底发现
  • 七个必填字段写进 PDF 模板,缺字段直接拒绝生成
  • 贷记单独立号段,字段必须带原发票号与冲销原因
  • 确认收入表与税额表分开,含税地区按客户所在地逐笔判断
  • 用一张 20% 的样例发票手工复算净额、税额与总额三行
  • 核对 108 张/月是否等于 105 张收款单据加 3 张贷记单
  • 抽查最近 12 张发票号,确认没有空洞、没有复用、没有手改

验收标准: 随便抽一张发票,能说清它的号在序列里的位置、七个字段的值,以及它在确认收入与税额两张表里各记了多少。

使用边界与实操验收

边界一:这不是税务或法律意见。 七个字段是最小集合,不同地区对发票内容、语言、存档年限的要求差别很大,正式对外前应当让当地会计过一遍字段清单,而不是照抄这一篇。

边界二:20% 是教学假设,不是报价。 真实税率随地区、品类与客户身份变化,跨境 B2B 还可能适用反向征收(reverse charge)。本篇只用它演示「含税金额必须拆成净额与税」这一条结构,不主张任何具体税率。

边界三:本组 1,710 是不含税口径。 凡写「收入」的复算一律用它;含税地区的税必须单列进应缴表,不得并进确认收入。把 285 混进去,20,520 的年化口径立刻失效。

边界四:号段按年重置只是一种做法。 也有主体不分年、连续到底的方案,关键不是哪种更正统,而是跳号可解释、作废有单据、任何人拿到一张票都能回溯到原交易。

边界五:电子发票、纸质发票与平台代开未展开。 本篇假设你自己出票;若用通道托管页或平台代开,号段责任在对方,但「作废只能冲销」这条仍然成立,你仍要保存冲销记录。

关键参考与核验范围

  • Hosted invoices :托管发票页能省掉 PDF 生成与投递两段代码,适合先跑通流程再考虑自建。
  • Credit notes :说明贷记单如何冲销原发票而不改动号段,是本篇第三节的实现依据。
  • Stripe Tax :税率与登记义务按地区计算的口径,用来判断哪些客户需要含税单据。
  • Invoicing integration :发票对象、行项目与状态流转的整体结构,对应本篇的七字段与 7 张表。

以上链接于 2026-10-26 实测可公开访问;未核验版本、价格与配额。核验日期:2026-10-26。

系列导航

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「Indie」更多文章

  1. 开源项目验收:十项能力、四维评分与三种不该开源的项目
  2. 治理、fork 与退出:17 位贡献者、82% 的提交与一次改协议的代价
  3. 双许可与企业版:九家询价、两家成交与 4,800 美元