Paddle 的税费预览最怕被当成「自己写一个税务计算器」。独立 SaaS 要做的是把 Paddle 已经算好的预估结果放到正确页面,再告诉用户最终金额会在 Checkout 里确认。

我会把这件事拆成 4 层:价格页估算、结账前确认、Checkout 实付、客服限制。四层混在一起,后面最容易出现「价格页显示 $10,Checkout 变成 $11,客服不知道该解释税还是解释套餐」这种小事故。

PricePreview 适合放哪一层

PricePreview 适合放在 pricing page。Paddle 当前 API 是 POST /pricing-preview,Paddle.js 里对应 Paddle.PricePreview()。它接收 priceId、数量、折扣和位置相关信息,返回每个价格的本地化金额、折扣、税额和格式化后的展示字段。

它不适合承担最终订单确认。Paddle 的定价页文档说得很清楚:PricePreview 返回的是 line item 计算结果,不包含 grand total。也就是说,你可以用它展示「Pro 月付在德国大概是多少」,但不要用它当购物车总价。

页面推荐方法能解决什么不该让它承担什么
首页价格区Paddle.PricePreview()本地币种、税费估算、折扣展示创建订阅、确认付款
价格对比页Paddle.PricePreview()多个套餐并排展示多商品总额
结账前确认页Paddle.TransactionPreview()line item 和 grand total真正扣款
Paddle CheckoutCheckout 本身最终付款、发票、交易记录产品内权限判定
自家后台webhook + 数据库权限开通、用量、客服记录替 Paddle 改税额

我的接入习惯是:价格页只展示估算,不展示过多财务细节。用户点击购买后,在 Checkout 或确认页看到最终金额。

税费预览的位置字段

税费和本地化价格都离不开客户位置。Paddle 文档给了几种输入:customer_ip_addressaddresscustomer_idaddress_idbusiness_id。Paddle.js 还支持传 countryCode,也可以在没有显式位置时自动按访问者 IP 估计。

未登录用户,用 IP 或国家选择器做估算就够了。已登录客户,优先用 Paddle 里的 customer、address 或 business 资料。B2B 客户升级套餐时,最好不要再按浏览器 IP 估税,因为财务地址才是账单依据。

const preview = await Paddle.PricePreview({
  items: [
    { priceId: "pri_01h...", quantity: 1 },
  ],
  address: {
    countryCode: "DE",
    postalCode: "10115",
  },
});

这段代码只表达接入形态,不是完整生产代码。已有客户不要把地址嵌进 customer 对象;按 Paddle 的 pricing preview 请求体传 customerIdaddressIdbusinessId。生产环境还要处理 Paddle 初始化、sandbox/live token、错误态、loading、地区切换和埋点。

tax_mode: location 的实际效果

Paddle 在 2025 年 10 月 7 日发布了 price.tax_modelocation 值。这个设置让价格按客户位置自动选择含税或税外展示。美国用户通常看到税外价,Checkout 再加 sales tax;欧洲用户通常看到含税价,总价里拆出 VAT。

Paddle 在 changelog 里举过一个 $10、10% 税率的示例:美国展示为 $10 + $1 tax = $11;欧洲展示为总价 $10,其中税前 $9.09、税 $0.91。文档也提醒税率只是示例,美国会细到州、县、市,欧洲也按国家不同。

2025 年 10 月 29 日,Paddle 又加入了账号级默认设置。路径是 Paddle Checkout 的 Sales tax settings,选择 Automatic based on location 后,新价格可以默认采用地区自动税费展示。已有价格不会被静默改掉,这一点对老项目很关键。

PricePreview 与 TransactionPreview 的分工

一句话:PricePreview 给价格页,TransactionPreview 给结账前总额。

需求用 PricePreview用 TransactionPreview
同时展示 Starter / Pro / Team 三个套餐合适太重
展示月付和年付切换后的单项价格合适可用但没必要
购物车里有订阅 + 一次性加购不够合适
订阅升级前展示 prorated total不够合适
结账前展示 grand total不合适合适
只想拿本地化货币符号合适可用但没必要

Paddle TransactionPreview 的 API 是 POST /transactions/preview,Paddle.js 里是 Paddle.TransactionPreview()。它返回交易预览,不会创建交易。对独立 SaaS 来说,它最有用的场景是 seat 加购、升级确认、一次性 setup fee 和订阅变更前的总额提示。

不要让用户在价格页看到一套数字,在确认页看到另一套数字却没有解释。价格页可以写「按地区预估」,确认页要写清楚 line item、tax、discount 和 total。

Checkout 前的展示粒度

普通 B2C SaaS 不必把税务表格塞到价格页。用户只需要知道计划价格、本地币种和税费是否可能在结账页确认。过度展示会让页面像发票后台。

B2B SaaS 可以多显示两项:是否含税、是否支持填写税号。企业客户关心的不是按钮是不是漂亮,而是公司抬头、VAT ID、发票和采购流程能不能走通。

我会按这个粒度写:

用户类型价格页文案Checkout 或确认页文案
美国个人用户税费按州和地址在结账页确认显示 subtotal、sales tax、total
欧盟个人用户价格通常按地区含税展示显示 VAT included 和总额
欧盟公司用户可在结账时填写 VAT ID显示税号、公司资料和最终税额
已登录团队客户按账单地址预估显示 seat、proration、tax、total
地址不完整客户当前为地区估算要求补充地址后确认最终金额

这里不要写绝对承诺。税额会受地址、商品税类、客户类型、折扣、税号和 Paddle 当前计算结果影响。预览就是预览,最终以交易记录和发票为准。

客服限制的写法

Paddle 是 Merchant of Record,买家在 Paddle Checkout 完成交易。Paddle Buyer Terms 也说明,买家是通过 Paddle 的服务购买产品,产品由 Supplier 提供。这个结构决定了客服限制不能只写一句「有问题找我们」。

我会把客服脚本拆成两张表。

问题第一接手方原因
卡被扣款但未收到确认邮件Paddle / 买家支持邮件、付款确认和交易链路在 Paddle
取消订阅入口找不到Paddle 买家门户或 Paddle 支持Paddle Help Center 指向 paddle.net 处理订阅和退款请求
申请退款或税额退款Paddle 支持 + 你的客服知情Paddle 处理交易层,产品方要同步权限和客服记录
Pro 权限没开通你的 SaaS 客服webhook、workspace、entitlement 在自家系统
功能无法使用或数据异常你的 SaaS 客服产品交付不是 Paddle 能判断的事
发票抬头、税号和 VAT 问题看 Paddle 交易资料,再交给财务税务和交易字段来自 Paddle,企业解释要你配合

Paddle 帮助页给了两个现实入口:卖家可以通过 Dashboard chat 或 [email protected] 联系支持;买家可以去 paddle.net 处理订阅、退款和订单支持。你的产品客服页面最好把这两个入口分清楚。

价格页与后台登录的收口

价格页、Checkout、Paddle Dashboard、Stripe、银行和 Cloudflare 经常在同一轮上线里打开。价格预览出错时,开发者会来回查 priceId、tax mode、Webhook、发票和客服工单。临时设备、多人混用浏览器 profile、随手开主账号,都会让排查记录变乱。

账单后台建议固定负责人、固定设备、固定 2FA 和固定操作记录。如果你同时维护 Paddle、Stripe、GitHub Actions 和 Cloudflare,可以用独立开发者出海稳定专线承载核心后台操作。它解决的是后台访问和操作环境一致性,不替代 Paddle 权限、审计日志和 2FA。

上线前跑哪 8 个用例?

上线前别只测一个美国 IP 和一张测试卡。至少跑下面 8 个用例:

  1. 未登录用户打开价格页,PricePreview 返回本地币种和格式化金额。
  2. 用户手动切换国家,价格页金额随国家变化。
  3. 美国地址进入 Checkout,税外价和 sales tax 显示符合预期。
  4. 欧盟地址进入 Checkout,含税展示和 VAT 拆分符合预期。
  5. B2B 客户填写税号,发票和税额显示符合预期。
  6. 多 seat 或加购进入 TransactionPreview,grand total 与 Checkout 接近。
  7. 支付成功后,只通过 webhook 开通权限。
  8. 退款或取消订阅后,自家系统能同步收回权限或标记到期。

每个用例保存一条记录:国家、priceId、quantity、tax mode、preview total、checkout total、transaction id、webhook event id。后面客服问「为什么我看到的价格变了」,你有证据能查。

本文未覆盖

本文不替你判断具体税务注册义务,也不解释每个国家的 VAT、GST 或 sales tax 规则。Paddle 的 MoR 模型能处理交易层很多事项,但公司所得税、所在地申报、收入确认和税务居民身份仍要问专业顾问。

本文也没有验证 Paddle 所有支付方式和所有地区,只按 2026 年 5 月 24 日能比对到的 Paddle 官方 docs、changelog、Help Center 和 Buyer Terms 写接入限制。Paddle changelog 更新后,以官方页面为准。

相关阅读