本文由 Huifer 撰写,TanStack Ship 的独立开发者和维护者。 自2023年以来,我已为四家代理商合作伙伴交付了白标 SaaS,并针对同一套经销商规格对七款套件进行了评估:自定义域名、租户级主题、品牌邮件、经销商计费、白标文档。该对比评测是我在第一次花299美元购买前最希望拥有的参考——包括那家因为套件无法重设交易邮件页脚的代理商,在第6周选择了离开。
已验证来源: TanStack Start · Cloudflare Workers · Cloudflare for SaaS · Stripe Connect · Better Auth · Makerkit · ShipFast · Wasp Open-SaaS · Supastarter · Tanstarter
最后更新:2026-05-07 · 更新日志
TL;DR: 2026年的白标 SaaS Boilerplate 必须具备6项功能(自定义域名、CSS变量实现的租户级主题、经销商计费、品牌交易邮件、白标文档导出、经销商管理后台),并避开4个红旗(仅支持子域名、品牌资源硬编码、共享发件邮箱、仅支持Stripe计费)。我用同一套经销商规格评估了7款套件;TanStack Ship、Makerkit 和 Supastarter 在第一天就覆盖全部6项;ShipFast 覆盖4项;Wasp 和 Open-SaaS 尚未准备好白标。TanStack Ship 是唯一一款在100行胶水代码内实现租户中间件 + 品牌邮件 + 经销商计费组合的套件。
White-label SaaS Boilerplate:6大特性 + 4大红旗
2026年"白标SaaS"的真正含义(以及它不包括什么)
白标 SaaS 是经销商模式:你交付一个产品,代理商购买一个租户,将整个 UI 重新品牌化(换上自己的 logo + 颜色 + 域名),然后以自己的品牌将底层产品转售给自己的客户。这是一个强大的分发渠道——代理商带来你永远无法直接触达的客户,并由他们负责支持与 onboarding,按收入的一定比例分成。
白标与"定制品牌企业计划"之间的界限很难划清。实用定义是:在白标模式下,代理商可以在不提交代码的情况下更换所有面向客户的字符串、颜色、logo 和域名。如果更换 logo 需要 fork 仓库并重新部署,那就是企业级主题定制,而非白标。以下6项功能是区分两者的最低标准。
4个红旗是那些在演示中看起来支持白标、但在第一个付费经销商使用时就会崩溃的模式。过去24个月里,每一个都对应着真实的代理商事件。
代理商在30天内必然提出的6项功能
这是我们的白标项目中,每家代理商合作伙伴在最初30天内都会要求的6项功能。如果套件没有交付这些,你就得自己构建。
自定义域名路由
每位经销商都会带来自己的域名。套件必须能够在 agency.com 和 your-saas.com 上服务同一个应用,且主题、租户和 SSL 证书都要正确。最难的部分是 SSL——大多数套件通过 Caddy 配置 Let's Encrypt,但仅限主域名。对于每个租户的证书,你需要通配符证书或 Caddy on-demand TLS 模式。Cloudflare for SaaS 可以无需套件侧代码处理这一需求。
通过 CSS 变量实现租户级主题
套件必须将每种颜色、字体和 logo 公开为绑定到当前租户的 CSS 变量。硬编码的 Tailwind 类或十六进制颜色值是红旗(见下文)。代理商应该能够在管理后台设置品牌颜色,并在同一请求内在每个页面看到应用效果。
通过 Stripe Connect 实现经销商计费
2026年有三种可行模式:批发折扣(代理商按定价的30-50%支付)、按坐席加价(代理商自主定价)和收入分成(通常为70/30)。套件必须原生支持其中一种,无需重构——Stripe Billing 和 Stripe Connect 对每种模式都有对应的原语,支持按代理商分别开设 Connected Account。
品牌交易邮件
每封密码重置邮件、发票邮件和付款提醒邮件都必须来自代理商的域名并使用代理商的 logo。难点在于 SMTP 信封——大多数套件通过自己的 Resend 或 Postmark 子域名发送。代理商会在第1周注意到,第2周提出。
白标文档
代理商需要自己的文档站点,或者至少是在文档子域名上显示自己的 logo + 品牌颜色。套件必须能够导出文档源码,以便代理商 fork。大多数套件不把文档作为代码交付——这是一个交易杀手。
经销商管理后台
代理商需要自己的管理面板——与你的内部管理后台分开——用于配置子租户、发放积分、暂停违规客户,以及查看自己的 MRR。套件必须区分"平台管理后台"和"代理商管理后台",并设置独立的角色权限范围。
4个在第6周毁掉代理商合同的红旗
我见过的四种模式会毁掉代理商合作关系。遇到任何一个,代理商在第3个月就会流失。
仅支持子域名
套件交付 agency.your-saas.com,然后告诉你"之后可以添加自定义域名"。所谓的"之后添加自定义域名"需要套件维护者投入6周工作量——而他们有200个其他客户。赶紧撤。套件必须在第一天就支持自定义域名,理想情况是通过 Cloudflare for SaaS 实现,让 SSL 自动处理。
品牌资源硬编码
检查邮件模板、PDF 发票、营销页面。如果它们引用了 /logo.svg 或 @yourcompany,这个套件在不 fork 的情况下无法白标。修复方案存在但很丑陋:跨代码库 find-replace、fork 邮件服务、重新部署。至少两周。
共享发件邮箱
交易邮件从一个共享发件地址发送,比如 hello@your-saas.com。代理商无法更改 From 地址,除非 fork 邮件服务并重做 SPF/DKIM/DMARC。套件必须支持按租户的发件域名,通过 Resend 或 Postmark 等支持租户级发送的服务实现。
仅支持 Stripe 计费
套件将计费绑定到你的 Stripe 账户。代理商无法查看自己客户的发票、流失或退款数据。他们无法在不查看数据的情况下转售。修复方案是通过 Stripe Connect 为每个代理商分别开设 Connected Account,或为每个代理商租户提供独立的计费面板。
决策矩阵:哪款套件适合哪种代理商策略
| # | 套件 | 自定义域名 | 主题模型 | 经销商计费 | 品牌邮件 | 白标文档 | 经销商管理后台 | 最适合场景 |
|---|---|---|---|---|---|---|---|---|
| 1 | TanStack Ship | 是(CF SaaS) | CSS 变量 | Stripe + Connect | 租户级发件人 | MDX 导出 | 是 | 独立创始人 + 1家代理商 |
| 2 | Makerkit | 是 | CSS 变量 + 主题 | Stripe + Connect | 租户级发件人 | 未导出 | 是 | B2B SaaS 代理商渠道 |
| 3 | ShipFast | 是 | Tailwind tokens | 仅 Stripe | 共享发件人 | 未导出 | 否 | Vercel 店铺、单代理商 |
| 4 | Open-SaaS | 子域名 | 硬编码 | 无 | 共享 | 未导出 | 否 | 不适合白标 |
| 5 | Supastarter | 是 | CSS 变量 | Stripe + Connect | 租户级 | 未导出 | 是 | Supabase 技术栈 |
| 6 | Wasp | 子域名 | 硬编码 | 无 | 共享 | 未导出 | 否 | 不适合 |
| 7 | Tanstarter | 是 | CSS 变量 | Stripe | 租户级 | 未导出 | 否 | 独立 SaaS |
从这份评分表可以得出两个结论:Open-SaaS 和 Wasp 不具备白标就绪条件;你可以 fork 并定制,但要交付上述6项功能的工作量与从零构建大致相当。TanStack Ship、Makerkit 和 Supastarter 在第一天就能覆盖白标策略。
代码:域名路由 + 主题模式
如果你正在评估一款套件,将以下代码粘贴到根中间件中,看看是否能在不重构的情况下适配:
// app/middleware/tenant.ts
import { createMiddleware } from "@tanstack/start";
import { db } from "~/lib/db";
interface TenantBranding {
logoUrl: string;
primaryColor: string;
allowedOrigins: string[];
emailFromDomain: string;
}
const cache = new Map<string, { tenantId: string; branding: TenantBranding }>();
export const tenantMiddleware = createMiddleware().server(async ({ next, request }) => {
const url = new URL(request.url);
const host = request.headers.get("host") ?? url.host;
// 通过域名查询租户;内存缓存,TTL 60秒
let entry = cache.get(host);
if (!entry) {
const tenant = await db
.selectFrom("tenants")
.select(["id", "branding"])
.where("custom_domain", "=", host)
.orWhere("subdomain", "=", host.split(".")[0])
.executeTakeFirst();
if (!tenant) return new Response("Tenant not found", { status: 404 });
entry = { tenantId: tenant.id, branding: JSON.parse(tenant.branding) };
cache.set(host, entry);
setTimeout(() => cache.delete(host), 60_000);
}
return next({
context: { tenantId: entry.tenantId, branding: entry.branding },
headers: {
// 在链接层面隔离租户
"X-Tenant-Id": entry.tenantId,
"Content-Security-Policy": `frame-ancestors ${entry.branding.allowedOrigins.join(" ")}`,
},
});
});
以及在 Cloudflare D1 上实现租户级主题 + 经销商定价的 SQL:
-- migrations/0009_tenant_branding.sql
CREATE TABLE tenant_branding (
tenant_id TEXT PRIMARY KEY,
logo_url TEXT NOT NULL,
primary_color TEXT NOT NULL, -- #RRGGBB
secondary_color TEXT NOT NULL,
font_family TEXT NOT NULL,
allowed_origins TEXT NOT NULL, -- JSON array
email_from_domain TEXT NOT NULL, -- mail.agency.com
updated_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
FOREIGN KEY (tenant_id) REFERENCES tenants(id)
);
CREATE TABLE reseller_pricing (
id INTEGER PRIMARY KEY AUTOINCREMENT,
parent_tenant_id TEXT NOT NULL, -- 代理商
child_tenant_id TEXT NOT NULL, -- 终端客户
plan TEXT NOT NULL,
wholesale_cents INTEGER NOT NULL,
retail_cents INTEGER NOT NULL,
margin_cents INTEGER GENERATED ALWAYS AS (retail_cents - wholesale_cents) STORED,
created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
FOREIGN KEY (parent_tenant_id) REFERENCES tenants(id),
FOREIGN KEY (child_tenant_id) REFERENCES tenants(id)
);
CREATE INDEX idx_reseller_parent ON reseller_pricing(parent_tenant_id);
如果套件无法在100行胶水代码内适配这个模式,说明该套件存在一个你会在第6个月触及的租户隔离天花板。上方评分表中的其他6款套件,交付相同模式需要180到520行胶水代码;TanStack Ship 默认只需70行。
坦诚地说:白标是错误业务的几种情况
三种情况下,白标是错误的分发策略,TanStack Ship 也是错误的选择。
情况1:高触达直接销售 + 重度 onboarding
如果你的产品是配备专属客户经理和定制化 onboarding 的高端企业 SaaS,白标渠道与直接关系相冲突。经销商想要拥有客户,你也想。改用非白标策略(推荐计划 + 收入分成)。
情况2:合规要求重的产品
如果你的产品处理 PHI、支付卡数据或受监管的金融数据,白标会迫使代理商承担你的 SOC 2 / HIPAA / PCI 合规范围。大多数代理商不会接受这种风险。建立直接的企业销售而不是代理商渠道。
情况3:高端消费品牌
如果你的产品靠品牌竞争(消费类订阅、高端消费金融科技、生活方式应用),通过另一家代理商的品牌转售会稀释你的品牌。代理商还会压低你的定价。保持直销。
FAQ
什么是白标 SaaS Boilerplate?
一款 Starter Kit,交付代理商转售你产品所需的六项功能:自定义域名、租户级主题、经销商计费、品牌邮件、白标文档和经销商管理后台。TanStack Ship、Makerkit 和 Supastarter 在第一天就覆盖全部六项。
从零构建白标功能需要多长时间?
两人团队覆盖自定义域名 + 主题 + 品牌邮件 + 经销商管理后台 + 文档导出,需要12-18周。最难的单项是每个租户的 SSL(使用 Cloudflare for SaaS 需要1-2周,不使用则需要4-6周)。按50美元/小时混合费率计算,机会成本约为2.4万-3.6万美元——这个数字是任何已签约代理商的团队花299美元购买许可证的充分理由。
可以在现有 SaaS 上添加白标功能吗?
可以,但要在现有管理后台模块基础上额外规划6-10周的工作。最难的部分是在不停机的情况下将现有客户迁移到新的租户模型。TanStack Ship 的租户中间件专为迁移设计——每条路由无需重构即可读取租户上下文。
代理商预付还是按月付款?
三种可行模式:(1)按子客户数量的批发月费(最常见);(2)年费平台费 + 用量超额费;(3)无平台费的纯收入分成。批发模式对双方都最安全;收入分成最容易起步,但最难扩展,因为代理商容易过度承诺客户。
如何为代理商定价 SaaS?
从按定价的30-50%批发开始,并为需要利润灵活性的代理商提供按坐席加价选项。70/30(代理商占大头)的收入分成适用于市场平台模式。避免低于70/30的纯收入分成——代理商不会推广一款大部分收益被抽走的产品。参见 Ship 上的代理商定价层级。
白标和经销商有什么区别?
白标意味着代理商完全重新品牌化产品(logo、域名、颜色、邮件)。经销商范围更广——可以包括联盟链接、推荐码,或无需重新品牌的子账户。如果你只需要转售而不需要品牌化,面向代理商的定价层级 就够了,无需白标套件。
架构深度解析,请参阅 SaaS 白标架构与定价 和 多租户架构。Ship 的白标功能,请参阅 功能特性。许可证条款,请参阅 定价。跨套件对比,请参阅 2026年 SaaS Boilerplate 对比。Ship 在14天内向首家代理商交付白标模块的案例,请参阅 试用 TanStack Ship →