以下情境为教学假设,人物与数字不代表经核实的真实案例。
破产不是「没钱了」这么简单,而是把有限的财产按顺位分给债权人。顺位在前的先拿,顺位在后的只能拿剩下的。一个普通债权人看到「公司账上还有资产」没有意义,因为那些资产可能已经被有担保债权和优先债权分完。失联则更模糊:对方可能只是不接电话,也可能已经没有可执行资产;回收率取决于还能不能找到人、找到资产,以及有没有平台或担保可以扣。
破产分配不是按「谁先催谁先拿」
破产分配的核心是顺位,不是催收顺序。一个先起诉的普通债权人,不会因为动作快就排到有担保债权前面;一个有担保的债权人,也不会因为一直没有催而失去优先位置。把有限的 estate 按顺位分,才是破产财务模型的基本结构。
本节用三个顺位做简化:有担保债权、优先债权、普通债权。具体顺位、申报程序、撤销权和跨境承认因司法辖区而异;本节只做财务估算,不构成法律意见。
回收率不是合同写的,而是由三件事决定:资产还剩多少、债权排在第几、以及同一顺位有多少人分。金额相同的两笔应收,顺位不同,回收率可能差一个数量级。
三个顺位与 Nord 的 11,264
回收率档位
| 顺位 | 典型债权 | 回收率档位(教学假设) | 示例取值 |
|---|---|---|---|
| 有担保 | 抵押、保留所有权、担保安排 | 60%–80% | 70% |
| 优先 | 员工工资、税费等 | 30%–50% | 40% |
| 普通 | 服务费、货款、平台结算款 | 5%–15% | 10% |
档位是教学假设,不是统计结果。真实回收率取决于资产质量、变现折扣、债权规模和司法效率;同一顺位里,大额债权人通常比小额债权人更有能力参与程序,但这也只是经验,不是保证。
顺位比回收率更重要。一个 70% 的有担保债权,如果担保物价值不足,实际回收可能低于 40%;一个 40% 的优先债权,如果 estate 已经被有担保债权耗尽,实际回收是 0。表格给的是「有钱可分」时的比例,不是「一定能分到」的承诺。
普通债权只能拿回 1,126
Nord Studio 的应收是 11,264 美元,主要是咨询服务费。服务费通常没有担保物,排在有担保和优先债权之后,所以按普通债权处理。取 10% 的示例回收率:
可回收 = 11,264 × 10% = 1,126
缺口 = 11,264 − 1,126 = 10,138
如果这笔应收有担保,按 70% 是 7,885;如果是优先债权,按 40% 是 4,506。三种顺位放在一起:
| 假设顺位 | 回收率 | 可回收 | 缺口 |
|---|---|---|---|
| 有担保 | 70% | $7,885 | $3,379 |
| 优先 | 40% | $4,506 | $6,758 |
| 普通 | 10% | $1,126 | $10,138 |
这张表的重点不是回收率,而是缺口。普通债权的缺口 10,138 相当于 Nord 年收入的 6.6%,也相当于 SDE 的 29.5%:10,138 ÷ 34,320 = 29.5%。Nord 的 SDE 只有 34,320 美元,一笔普通债权拿不回,就能吃掉近三成 SDE。
所以 Nord 的单一大额应收不是「一笔账」的问题,而是「一笔账能吃掉三成 SDE」的问题。前 3 家客户占 48%,如果其中一家破产,影响会比 LedgerLite 的单一客户大得多。LedgerLite 的应收 12,000 分散在 260 家客户,前 5 家占收入 31%,最大一家 9%;单一客户破产的应收敞口有限。
失联不是破产,但回收率可能更低
失联和破产是两种不同的状态。破产至少有一个 estate、一个程序和一群债权人;失联可能只是对方不接电话,也可能已经没有可执行资产。失联的回收率取决于还能不能找到人、找到资产、以及有没有平台或担保可以扣。
| 情形 | 回收概率档位 | 对应 bps(教学设定) | 说明 |
|---|---|---|---|
| 失联但仍在经营 | 中 | 3,000–5,000 | 可能通过持续沟通、平台扣款或和解收回 |
| 失联且无可执行资产 | 低 | 0–1,000 | 催收成本高于回收,核销更合理 |
| 失联但有个人担保 | 中高 | 4,000–6,000 | 取决于个人资产与担保范围 |
概率档位是教学设定,不是对具体案件的预测。失联的处理顺序不是「先找律师」,而是「先确认还有没有可扣的现金流」:平台未结算款、预付款、押金、托管账户,都是比诉讼更快的来源。
Tidecast 80% 收入走平台,平台在结算前先扣分成、退款和争议款;在本节的简化模型里,开发者的未结分成在平台清算中按普通债权处理,回收率取 10%,而不是按账面分成全额收回。Tidecast 的案例应收是 0,所以它的敞口不在应收账款,而在平台尚未结算的余额;平台依赖的量化见 10.1 云、支付、平台的关键依赖 。
失联还有一个时间维度。破产程序再慢,至少有一个可预期的流程;失联可能拖几年,也可能永远没有结果。如果回收概率是 20%,回收金额是 2,253,期望回收是 451,而追查成本已经超过 451,核销就是更理性的选择。坏账核销的账务处理见 4.1 坏账准备:计提、核销与转回 。
三种前置保护:预付款、托管、个人担保
破产分配是事后补救;更有效的是事前把敞口降下来。三种常见保护,用 Nord 的 11,264 做示例:
| 保护 | 机制 | 对 Nord 11,264 的影响(教学假设) | 总回收 |
|---|---|---|---|
| 预付款 30% | 交付前先收 30% | 先收 3,379,剩余 7,885 按普通债权 10% 回收 789 | $4,168 |
| 托管 20% | 2,253 留在第三方账户,不进破产财产 | 托管 2,253 + 剩余 9,011 的 10%(901) | $3,154 |
| 个人担保 50% | 5,632 可向个人追偿 | 个人资产足够时 5,632 + 剩余 5,632 的 10%(563) | $563–$6,195 |
预付款最强,因为它直接把应收从 11,264 降到 7,885;托管把一部分钱隔离在破产财产之外;个人担保增加了一个还款人,但回收取决于个人资产,不是签了字就一定能收到。
预付款也有成本。如果客户要求 5% 的折扣才接受预付,折扣是 11,264 × 5% = 563;扣掉折扣后的总回收 4,168 − 563 = 3,605,仍高于不保护的 1,126。这个比较不是「预付款一定好」,而是「用 563 的折扣换 3,042 的额外回收」:4,168 − 1,126 = 3,042。
托管适合里程碑交付:钱在第三方账户,按交付节点释放;它的成本是托管费和操作复杂度。个人担保适合对方是小型公司、创始人个人有资产的情形;如果对方本身是空壳,担保的回收率接近 0。
三种保护都不是法律意见;具体条款是否可执行、担保是否有效,因司法辖区而异。预付款、托管和担保的条款写法,属于合同结构,见 1.3 价格、调价与付款条款:金额、时点、前提与违约责任 。
写成代码:bankruptcy.ts
下面的 bankruptcy.ts 用 distributeEstate 按顺位分配 estate:先有担保,再优先,最后普通;每一笔债权有一个回收率上限,同一顺位按上限比例分配;estate 不够时按比例分,分完为止。residualEstateCents 是分完所有债权后剩下的钱。
// file: src/contract/bankruptcy.ts
// tier: L1
// verify: node --test test/contract/bankruptcy.test.ts
import { type Cents, add, sub } from "../core/money.ts";
import { type Bps, applyRate } from "../core/rate.ts";
import { type Result, fail, ok } from "../core/result.ts";
export type ClaimRank = 1 | 2 | 3;
export type BankruptcyClaim = {
name: string;
claimCents: Cents;
rank: ClaimRank;
recoveryBps: Bps;
};
export type ClaimPayout = {
name: string;
claimCents: Cents;
capCents: Cents;
paidCents: Cents;
shortfallCents: Cents;
};
export type WaterfallResult = {
estateCents: Cents;
payouts: ClaimPayout[];
totalPaidCents: Cents;
totalShortfallCents: Cents;
residualEstateCents: Cents;
};
function checkAmount(value: Cents, label: string): Result<true> {
if (!Number.isInteger(value) || value < 0) {
return fail(`${label} must be a non-negative integer amount in cents`);
}
return ok(true);
}
function checkRate(value: Bps, label: string): Result<true> {
if (!Number.isInteger(value) || value < 0 || value > 10000) {
return fail(`${label} must be between 0 and 10000 bps`);
}
return ok(true);
}
/**
* Split an amount pro rata across caps. Floor each share, then hand the
* remaining cents to the largest fractions, so the result always sums to the
* amount without float drift.
*/
function allocateProRata(amount: Cents, caps: Cents[]): Cents[] {
const totalCap = caps.reduce((acc, cap) => acc + cap, 0);
if (amount === 0 || totalCap === 0) {
return caps.map(() => 0);
}
if (amount >= totalCap) {
return [...caps];
}
const exact = caps.map((cap) => (amount * cap) / totalCap);
const shares = exact.map((value) => Math.floor(value));
const assigned = shares.reduce((acc, value) => acc + value, 0);
const order = exact
.map((value, index) => ({ index, fraction: value - Math.floor(value) }))
.sort((a, b) => b.fraction - a.fraction || a.index - b.index);
for (let i = 0; i < amount - assigned; i += 1) {
shares[order[i % order.length].index] += 1;
}
return shares;
}
/**
* Distribute a bankruptcy estate by claim rank. Rank 1 is paid first, then
* rank 2, then rank 3; each claim is capped by its teaching recovery rate.
* Seniority matters more than the recovery rate: a fully secured claim can
* consume the estate before a priority or unsecured claim sees anything.
*/
export function distributeEstate(
estateCents: Cents,
claims: BankruptcyClaim[],
): Result<WaterfallResult> {
const estate = checkAmount(estateCents, "estate");
if (!estate.ok) {
return estate;
}
const caps: Cents[] = [];
for (const claim of claims) {
if (claim.name.trim() === "") {
return fail("claim name cannot be empty");
}
const amount = checkAmount(claim.claimCents, `${claim.name} claim`);
if (!amount.ok) {
return amount;
}
if (claim.rank !== 1 && claim.rank !== 2 && claim.rank !== 3) {
return fail(`${claim.name} rank must be 1, 2 or 3`);
}
const recovery = checkRate(claim.recoveryBps, `${claim.name} recovery rate`);
if (!recovery.ok) {
return recovery;
}
caps.push(applyRate(claim.claimCents, claim.recoveryBps));
}
let remaining = estateCents;
const paid: Cents[] = claims.map(() => 0);
for (const rank of [1, 2, 3] as ClaimRank[]) {
const indices = claims
.map((claim, index) => ({ claim, index }))
.filter((entry) => entry.claim.rank === rank);
if (indices.length === 0) {
continue;
}
const groupCaps = indices.map((entry) => caps[entry.index]);
const groupCap = groupCaps.reduce((acc, cap) => acc + cap, 0);
const available = Math.min(remaining, groupCap);
const shares = allocateProRata(available, groupCaps);
indices.forEach((entry, offset) => {
paid[entry.index] = shares[offset];
});
remaining = sub(remaining, available);
}
const payouts = claims.map((claim, index) => ({
name: claim.name,
claimCents: claim.claimCents,
capCents: caps[index],
paidCents: paid[index],
shortfallCents: sub(claim.claimCents, paid[index]),
}));
const totalPaidCents = payouts.reduce((acc, payout) => add(acc, payout.paidCents), 0);
const totalShortfallCents = payouts.reduce(
(acc, payout) => add(acc, payout.shortfallCents),
0,
);
return ok({
estateCents,
payouts,
totalPaidCents,
totalShortfallCents,
residualEstateCents: remaining,
});
}
distributeEstate 的输入是 estate 美分和债权数组。Nord 的 11,264 美元普通债权是 1,126,400 美分,回收率 10%,cap 是 112,640 美分;estate 是 10,000,000 美分时,实付 112,640 美分,缺口 1,013,760 美分,剩余 estate 9,887,360 美分。
如果 estate 只有 500,000 美分,而有担保债权 1,000,000 美分、cap 700,000 美分,那么有担保债权先拿 500,000 美分,普通债权拿 0;这就是顺位的作用。优先债权在有担保债权之后、普通债权之前,同样的 estate 会先满足优先债权,再轮到普通债权。
同一顺位有多笔债权时,代码按 cap 比例分配,并把余下的分币分给小数部分最大的债权,保证总额正好等于可分配金额。它不是按「谁先申报谁先拿」,也不是按「谁金额大谁先拿」;同一顺位内按比例,是本节简化模型的口径。
代码不处理担保物估值、别除权、撤销权、跨境承认和申报期限;它只覆盖「按顺位和回收率分配 estate」的财务口径。具体程序与顺位因司法辖区而异,本节不构成法律意见。
小结
- 破产按顺位分钱:有担保、优先、普通;顺位比回收率更重要。
- Nord 的 11,264 普通债权按 10% 只回收 1,126,缺口 10,138,相当于 SDE 的 29.5%。
- 同一笔应收如果有担保按 70% 是 7,885,优先按 40% 是 4,506;顺位不同,结果差一个数量级。
- 失联不是破产;回收概率从 0–1,000 bps 到 4,000–6,000 bps,取决于是否仍在经营、有没有资产和担保。
- 预付款 30% 把总回收提高到 4,168;托管 20% 提高到 3,154;个人担保 50% 的区间是 563–6,195。
- 前置保护比事后分配更有效,但预付款有折扣成本,托管有费用,个人担保取决于个人资产。
阅读导航:上一节:4.2 催收升级与法律途径的成本收益 · 下一节:5.1 违约的四种形态 。
常见错误与边界
- 把「有资产」当「能拿回」。 estate 要先分给有担保和优先债权;普通债权人看到资产总额没有意义,要看分到自己顺位还剩多少。
- 把合同当担保。 签了合同不等于有担保物;服务费通常是普通债权,不会因为合同写了付款义务就自动排到前面。
- 用回收率代替顺位。 70% 的有担保债权和 70% 的普通债权不是一回事;顺位决定有没有钱可分,回收率只决定分到后拿多少。
- 忽略同一顺位的竞争。 同一顺位里不止你一个债权人;estate 不够时按比例分,不是按你的账面金额全额分。
- 把失联当破产。 失联没有 estate、没有程序,回收率可能更低;先找可扣的现金流,再考虑法律途径。
- 把平台余额当应收。 Tidecast 的案例应收是 0,但平台未结算款仍是敞口;它在平台清算中按普通债权处理,不是账面全额。
- 认为个人担保一定收回。 担保只增加一个还款人;对方个人没有资产时,担保的回收率接近 0。
- 忽略预付款的折扣成本。 预付款提高回收,但客户可能要求折扣;要把折扣和额外回收一起算,不能只看回收率。
- 把教学档位当统计结果。 60%–80%、30%–50%、5%–15% 是档位,不是对某个案件的预测;真实回收率取决于资产和程序。
- 只做事后分配,不做前置保护。 破产程序开始后,能改变的东西很少;预付款、托管和个人担保要在签约和交付前安排。
本节的边界是「破产与失联的回收估算」:只覆盖有担保、优先、普通三个顺位的回收率档位,以及预付款、托管、个人担保三种前置保护,不展开具体申报程序、担保物估值、撤销权、跨境承认和税务处理。所有回收率与概率均为教学假设;具体法律程序因司法辖区而异,本节不构成法律意见。坏账的账务处理见第 4.1 节,催收阶梯的期望值见第 4.2 节,合同矩阵与风险敞口横向对照见第 13 章。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。