以下情境为教学假设,人物与数字不代表经核实的真实案例。
报价是谈判桌上的数字,税后所得才是银行账户里的数字。两者之间隔着税率、税基、纳税时点和交易结构。同样是 768,768 美元的报价,一次性确认、三年分期确认、资产收购或股权收购,最终到手的现金可能差出五位数。对独立开发者来说,这个差额往往等于一整年的生活支出,不能等到交割前才算。
这一节只做一件事:把报价换算成税后所得,再比较一次性确认与分期确认的时间价值。税率使用教学假设,不引用任何法条,也不构成税务建议。真实的税务处理取决于主体、辖区、交易结构和当期法规,必须由当地专业人士按交割时的规则核对。
从报价到税后:四个到手金额
本节统一使用一个教学假设:长期资本利得税率 20%,州税 5%,合计 25%。这个 25% 不是任何辖区的现行税率,也不是对某个具体交易的税务结论;它只是一个便于横向比较的算例。把税率拆成两部分,是为了提醒读者:税负通常不是单一数字,而是多层规则的叠加。
三案例的四条退出路径代入后得到四个税后金额:
| 案例与路径 | 报价 | 教学税额(25%) | 税后所得 | 税后/报价 |
|---|---|---|---|---|
| LedgerLite 战略收购 | 768,768 | 192,192 | 576,576 | 75.0% |
| Tidecast 整体出售 | 248,708 | 62,177 | 186,531 | 75.0% |
| Nord 4.5× SDE | 154,440 | 38,610 | 115,830 | 75.0% |
| Nord 3.0× SDE | 102,960 | 25,740 | 77,220 | 75.0% |
计算很直接:税额等于报价乘 25%,税后等于报价减税额。LedgerLite 的 768,768 乘 25% 是 192,192,减完剩 576,576;Tidecast 的 248,708 乘 25% 是 62,177,减完剩 186,531;Nord 的两条路径分别是 154,440 和 102,960,税后是 115,830 和 77,220。
四个金额都保留了 75% 的比例,因为税率相同。真正不同的是绝对额和后面的用途:576,576 可以支撑一套配置,186,531 只能支撑一套更小的配置,77,220 在 Nord 的成本结构下连 12 个月都撑不满。比例相同不代表处境相同,这是后两节要展开的内容。
这里有三处刻意的简化。第一,不区分资产收购与股权收购的税基差异;真实交易里,谁纳税、按什么基数纳税、能不能享受分期,都会改变结果。第二,不处理亏损结转、抵免、预提和重复征税;这些规则因辖区而异,本节只用单一税率。第三,不把托管、earn-out 和营运资金调整放进税基;它们会改变「什么时候确认多少收入」,而不是简单地把报价乘一个比例。
LedgerLite 的 70/30 结构就是一个例子:现金 70% 在交割日支付,earn-out 30% 在 12 个月后按 ARR 达标情况支付。如果税务上按收到金额确认,那么第一年确认的税基不是 768,768,而是交割日收到的现金加上当年实际支付的 earn-out。具体时点要看交易文件和当地规则;本节先把「对价结构」和「税务时点」分开,避免把 70/30 误当成 70% 的税。
三年等额分期:名义总额不变,现值变少
把 LedgerLite 的 768,768 拆成三年等额,每年应税 256,256,每年按 25% 缴税 64,064,每年税后 192,192。三年名义税后合计仍然是 576,576,和一次性确认完全一样。差别只在时间:一次性确认在交割日拿到 576,576;分期确认在第一、二、三年各拿 192,192。
为了比较不同时点的钱,需要一个折现率。本节使用 8% 年化教学假设,把每年的税后金额折回交割日:
| 年份 | 应税金额 | 税额(25%) | 税后金额 | 折现因子(8%) | 现值 |
|---|---|---|---|---|---|
| 第 1 年 | 256,256 | 64,064 | 192,192 | 0.9259 | 177,956 |
| 第 2 年 | 256,256 | 64,064 | 192,192 | 0.8573 | 164,774 |
| 第 3 年 | 256,256 | 64,064 | 192,192 | 0.7938 | 152,568 |
| 合计 | 768,768 | 192,192 | 576,576 | 495,297 |
逐行四舍五入相加是 495,298,代码先按美分汇总再取整是 495,297,差 1 美元来自舍入位置。无论用哪个数,结论一样:名义税后 576,576,折现后只有约 495,297,时间价值吃掉约 81,279,相当于税后所得的 14.1%。
81,279 不是「分期手续费」,也不是「税变多了」。税仍然是 192,192,一分没多;损失来自钱晚到。第一年的 192,192 要等 12 个月,第二年的要等 24 个月,第三年的要等 36 个月。折现率越高、期限越长,这个损失越大。如果折现率降到 0,分期和一次性的现值完全相同,损失归零。
公式可以写成:
年应税 = 报价 ÷ 年数
年税额 = 年应税 × 教学税率
年税后 = 年应税 − 年税额
现值 = Σ 年税后 ÷ (1 + 折现率)^年
折现损失 = 一次性税后 − 分期现值
把这套公式套到另外三个金额上,得到同一组比例、不同绝对值的结果:
| 案例 | 报价 | 一次性税后 | 三年分期现值 | 折现损失 | 损失/一次性税后 |
|---|---|---|---|---|---|
| LedgerLite | 768,768 | 576,576 | 495,297 | 81,279 | 14.1% |
| Tidecast | 248,708 | 186,531 | 160,236 | 26,295 | 14.1% |
| Nord 4.5× | 154,440 | 115,830 | 99,502 | 16,328 | 14.1% |
| Nord 3.0× | 102,960 | 77,220 | 66,334 | 10,886 | 14.1% |
四个案例的损失比例完全一样,因为年数、税率和折现率一样;绝对损失从 10,886 到 81,279 不等,因为报价不同。这提醒一件事:比较分期方案时,不能只看「分几年」,还要看金额、折现率和买方的信用。同样是把 30% 的对价延后一年,在 102,960 的交易里损失 10,886,在 768,768 的交易里损失 81,279;后者更值得为提前收款去谈判。
Tidecast 的分期还有一个细节:248,708 除以 3 不是整数美元,按美分拆分会出现 1 美分的余数。代码把余数放在最后一年,所以前两年各 8,290,266 美分、最后一年 8,290,268 美分,三年名义税后合计 18,653,099 美分,比一次性税后 18,653,100 美分少 1 美分。这个差额来自逐行税额的舍入,不是税务规则。书中表格用整数美元展示,代码保留美分,两者相差不超过 1 美分。
分期省税在什么条件下才划算
「分期省税」这个说法只在一部分情况下成立。如果分期只是把同一笔收入摊到几年、每年仍按 25% 计税,那么它没有省税,只是延后纳税;延后纳税的代价就是上面的折现损失。真正能省税的情况是:分期让每年应税所得落进更低的税率档,或者让某一年可以用亏损、抵免或扣除额抵消。
为了把「税率下降」和「时间价值」放在同一张表里,假设三年等额分期把实际税率从 25% 降到 20%,其余假设不变:
| 分期实际税率 | 年税后 | 三年名义税后 | 分期现值(8%) | 与一次性 25% 税后 576,576 比 |
|---|---|---|---|---|
| 25% | 192,192 | 576,576 | 495,297 | −81,279 |
| 20% | 205,005 | 615,014 | 528,317 | −48,259 |
| 12.69% | 223,730 | 671,190 | 约 576,576 | 约 0 |
税率从 25% 降到 20%,名义税后从 576,576 增加到 615,014,多了 38,438;但折现后只有 528,317,仍比一次性 25% 的 576,576 少 48,259。也就是说,5 个百分点的税率下降,还不足以补偿三年分期在 8% 折现率下的时间价值。
要让分期和一次性打平,分期实际税率需要降到约 12.69%。这个数是算出来的,不是谈出来的:
盈亏平衡税率 = 1 − 一次性税后 ÷ (年应税 × 年金系数)
= 1 − 576,576 ÷ (256,256 × 2.5771)
= 12.69%
2.5771 是 8% 折现率、3 年期的年金系数,等于 1/1.08 + 1/1.08² + 1/1.08³。分期税率高于 12.69%,分期就不如一次性;低于 12.69%,分期才在现值上胜出。25% 到 12.69% 是 12.31 个百分点,这个降幅在真实税务里并不常见,所以「为了省税而接受长期分期」通常不是一笔划算的交易,除非分期同时解决了买方的支付能力问题。
还有三个因素会改变这个结论。第一,折现率。如果创始人把拿到的钱用于一个年化回报 15% 的项目,分期的机会成本更高,盈亏平衡税率会更低;如果钱只是放在低收益账户里,折现率可以调低。第二,信用风险。分期付款本质上是卖方给买方一笔无担保贷款;买方违约时,税可能已经按确认金额产生,现金却收不回来。第三,托管和 earn-out 的叠加。LedgerLite 的 70/30 结构里,30% 的 earn-out 已经在承担经营风险,如果这部分再分期,风险会叠加,而不是分散。
因此,分期的正确比较不是「总价一样就一样」,而是「把每一笔现金流按到账时间折现,再减去违约概率的期望损失」。本节只做第一步;违约概率、担保和清偿顺序属于交易结构问题,见 7.2 现金、票据与 earn-out 与 7.3 陈述保证、赔偿与托管 。
把税后与分期写成代码
下面的 after-tax.ts 把组合税率、一次性税后和三年等额分期固化。combinedRateBps 把资本利得率和州税率相加;afterTax 返回税额、税后和有效税率;installmentPlan 生成每年的应税、税额、税后、折现因子和现值,并算出折现损失与盈亏平衡税率。
// file: src/capital/after-tax.ts
// tier: L1
// verify: node --test test/capital/after-tax.test.ts
import { type Cents } from "../core/money.ts";
import { type Bps, applyRate, divide } from "../core/rate.ts";
import { type Result, fail, ok } from "../core/result.ts";
export type TaxAssumptions = {
capitalGainsBps: Bps;
stateBps: Bps;
};
export type AfterTax = {
grossCents: Cents;
taxCents: Cents;
netCents: Cents;
effectiveRateBps: Bps;
};
export type InstallmentRow = {
year: number;
grossCents: Cents;
taxCents: Cents;
netCents: Cents;
discountFactor: number;
presentValueCents: Cents;
};
export type InstallmentPlan = {
years: number;
rows: InstallmentRow[];
nominalTaxCents: Cents;
nominalNetCents: Cents;
presentValueCents: Cents;
lumpSumNetCents: Cents;
deferralLossCents: Cents;
breakEvenTaxBps: Bps;
};
function validBps(value: Bps): boolean {
return Number.isInteger(value) && value >= 0 && value <= 10000;
}
/**
* Combines the long-term capital gains rate and the state rate into one
* teaching rate. Both inputs are assumptions, not a tax table.
*/
export function combinedRateBps(assumptions: TaxAssumptions): Result<Bps> {
if (
!validBps(assumptions.capitalGainsBps) ||
!validBps(assumptions.stateBps)
) {
return fail("tax rates must be between 0 and 10000 basis points");
}
const combined = assumptions.capitalGainsBps + assumptions.stateBps;
if (combined > 10000) {
return fail("combined tax rate cannot exceed 100%");
}
return ok(combined);
}
export function afterTax(
grossCents: Cents,
assumptions: TaxAssumptions,
): Result<AfterTax> {
if (!Number.isInteger(grossCents) || grossCents < 0) {
return fail("gross proceeds must be a non-negative integer amount");
}
const rate = combinedRateBps(assumptions);
if (!rate.ok) {
return rate;
}
const taxCents = applyRate(grossCents, rate.value);
const netCents = grossCents - taxCents;
return ok({
grossCents,
taxCents,
netCents,
effectiveRateBps: grossCents === 0 ? 0 : divide(taxCents, grossCents),
});
}
/**
* Splits proceeds into equal annual installments. The last year absorbs the
* cent remainder. Every year pays the same teaching rate, and each net amount
* is discounted to close at the annual discount rate. The break-even tax rate
* is the rate at which discounted installments equal the lump-sum after-tax
* amount; above it, deferral loses to paying tax at close.
*/
export function installmentPlan(
grossCents: Cents,
years: number,
assumptions: TaxAssumptions,
annualDiscountBps: Bps,
): Result<InstallmentPlan> {
if (!Number.isInteger(grossCents) || grossCents <= 0) {
return fail("gross proceeds must be a positive integer amount");
}
if (!Number.isInteger(years) || years <= 0 || years > 40) {
return fail("years must be an integer between 1 and 40");
}
if (!validBps(annualDiscountBps)) {
return fail("discount rate must be between 0 and 10000 basis points");
}
const rate = combinedRateBps(assumptions);
if (!rate.ok) {
return rate;
}
const lumpTaxCents = applyRate(grossCents, rate.value);
const lumpSumNetCents = grossCents - lumpTaxCents;
const base = Math.floor(grossCents / years);
const remainder = grossCents - base * years;
const discountRate = annualDiscountBps / 10000;
const rows: InstallmentRow[] = [];
let nominalTaxCents = 0;
let nominalNetCents = 0;
let presentValueCents = 0;
let annuityFactor = 0;
for (let year = 1; year <= years; year += 1) {
const gross = year === years ? base + remainder : base;
const taxCents = applyRate(gross, rate.value);
const netCents = gross - taxCents;
const discountFactor = 1 / Math.pow(1 + discountRate, year);
const rowPresentValueCents = Math.round(netCents * discountFactor);
nominalTaxCents += taxCents;
nominalNetCents += netCents;
presentValueCents += rowPresentValueCents;
annuityFactor += discountFactor;
rows.push({
year,
grossCents: gross,
taxCents,
netCents,
discountFactor,
presentValueCents: rowPresentValueCents,
});
}
const averageGrossCents = grossCents / years;
const breakEvenNetCents = lumpSumNetCents / annuityFactor;
const rawBreakEvenBps = Math.round(
(1 - breakEvenNetCents / averageGrossCents) * 10000,
);
const breakEvenTaxBps = Math.min(10000, Math.max(0, rawBreakEvenBps));
return ok({
years,
rows,
nominalTaxCents,
nominalNetCents,
presentValueCents,
lumpSumNetCents,
deferralLossCents: lumpSumNetCents - presentValueCents,
breakEvenTaxBps,
});
}
代码里有三个刻意保留的边界。第一,税率是输入参数,不是内置常量;25% 只是测试和书中的教学值,真实使用时要按交割时的规则替换。第二,分期假设每年等额、同一税率、年末付款;真实的分期可能按季度、按里程碑或不规则金额,折现因子要逐笔调整。第三,盈亏平衡税率假设每年应税金额相同;如果分期金额不等,应该用各年应税金额的现值加权,而不是简单平均。
把 LedgerLite 代入:报价 76,876,800 美分,税率 2,500 个基点,一次性税额 19,219,200 美分、税后 57,657,600 美分;三年分期每年应税 25,625,600 美分、税额 6,406,400 美分、税后 19,219,200 美分;按 8% 折现,现值 49,529,743 美分,折现损失 8,127,857 美分,盈亏平衡税率 1,269 个基点。换算成美元就是 768,768、576,576、495,297、81,279 和 12.69%。
这套代码不处理税基调整、亏损结转、抵免、预提和跨境双重征税,也不处理托管与 earn-out 的确认时点。它回答的是「同一笔报价,在不同确认节奏下值多少今天的钱」,不是「你应该缴多少税」。后者必须按当期法规和具体交易结构单独测算;本节的所有税率、折现率和期限都是教学假设。
小结
- 税后所得是报价乘「1 − 教学税率」。25% 是长期资本利得 20% 加 5% 州税的假设,不是现行税率,也不构成税务建议。
- LedgerLite 768,768 税后 576,576;Tidecast 248,708 税后 186,531;Nord 154,440 和 102,960 税后 115,830 和 77,220。
- 三年等额分期不改变名义税后总额,但按 8% 折现后,LedgerLite 的 576,576 只值 495,297,时间价值损失 81,279,占税后所得的 14.1%。
- 四个案例的折现损失比例相同,绝对损失不同;金额越大,提前收款越值得谈判。
- 分期只有在实际税率降到约 12.69% 以下时才在现值上打平一次性 25%;仅把 25% 延后三年,仍然是亏的。
- 分期还要叠加买方信用风险、托管和 earn-out 的经营风险;总价相同不代表风险相同。
阅读导航:上一节:9.3 交接期与知识转移 · 下一节:10.2 再投资与资产配置 。
常见错误与边界
- 把报价当到手金额。 768,768 的报价在 25% 教学税率下只剩 576,576;用报价安排支出,会高估 192,192 的购买力。
- 把 25% 当成真实税率。 20% 加 5% 是教学假设,不是任何辖区的现行税率;真实税负取决于主体、辖区、交易结构和当期法规。
- 把分期当免税。 分期只改变确认时点,不自动减少税额;25% 不变时,三年名义税后和一次性完全相同。
- 用名义总额比较分期。 576,576 分三年还是 576,576,但按 8% 折现只值 495,297;名义相同不等于现值相同。
- 忽略折现率的选择。 折现率越高,分期损失越大;用 0% 折现会把分期算得过于有利。
- 忽略买方信用。 分期是卖方给买方的信用;买方违约时,税可能已经产生,现金却收不回来。
- 把托管、earn-out 和分期混在一起。 三种工具的风险不同,叠加后不是简单的比例相加;LedgerLite 的 30% earn-out 已经承担经营风险。
- 用单一年份税率算累进税。 真实税率可能随所得档位变化;把 25% 套到所有年份,会低估或高估某一年的税负。
- 忽略税基差异。 资产收购和股权收购的纳税主体、税基和时点不同;用同一个 25% 乘报价,只是教学简化。
- 忘记记录假设。 税率、折现率、年数和付款时点都要写进交易备忘录;没有假设的税后测算是不可复算的。
本节的边界是「单一税率、等额分期、年末付款」的静态模型:不处理累进税率、亏损结转、抵免、预提、跨境双重征税,也不处理托管与 earn-out 的确认时点。它足够回答「这笔报价税后大概多少、分期值多少今天的钱」,但不足以替代交割时的税务测算。下一节把税后所得放进配置框架,回答「这笔钱怎么分、能产生多少可支出现金流」。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。