关于 polar-migration
面向开发者的 Polar 账单迁移指南,涵盖 Stripe 辅助迁移及其他服务商的迁移方式,并说明客户映射、订阅切换和核对要点。
主要功能
- 01Stripe 迁移流程
- 02其他账单服务商迁移指南
- 03客户与订阅映射
- 04切换事件处理
- 05测试与核对指南
适用场景
- 01规划从 Stripe 迁移到 Polar
- 02从其他服务商迁移订阅
- 03实现切换期间的 Webhook 处理
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ polarsource/ agent-toolkit --skill polar-migration安装后在 Claude Code 中输入/polar-migration确认已加载。
详细介绍
Polar 迁移指南
Polar 迁移指南是权威信息来源;在提出任何建议前,请先阅读。本文概述应用需要完成的工作。
选择迁移路径
- 从 Stripe 迁移:使用 Polar 在设置 → 迁移中提供的辅助迁移功能。Polar 会导入产品、价格和客户,Stripe 会将已保存的银行卡直接复制到 Polar 的支付处理商,Polar 则会按照相同的已付费周期逐个切换订阅。大多数客户无需执行任何操作。迁移功能正在逐步推出;如果看不到该选项卡,请联系 Polar 支持。
- **从 Paddle、Lemon Squeezy 或其他平台迁移:**没有自动迁移功能。请先联系 Polar 支持,然后按照下方的“其他服务商”部分操作。客户需要在 Polar 上重新结账。
所有迁移都必须遵守的规则
- 除非由 Polar 执行切换,否则绝不要停止、取消或暂停旧服务商的计费,也不要激活已迁移的 Polar 订阅。不要编写自己的切换脚本:这会导致重复扣费。
- 绝不要处理原始银行卡数据,也绝不要在聊天中索要 Stripe 或 Polar 密钥。
- 将应用中不可变的客户 ID 用作 Polar 客户的
external_id(结账时传入external_customer_id)。不要使用电子邮件地址;除非旧服务商的 ID 已是应用的规范 ID,否则也不要使用旧服务商的 ID。external_id一经设置便无法更改。 - 每个订阅必须且只能由一个系统负责下一次续订。请记录由哪个系统负责,而不是根据设置了哪些 ID 来推断。
- 过去的付款记录保留在旧服务商中。不要为 Polar 未处理的交易创建 Polar 订单,并保留旧账户以处理退款、争议和会计事务。
从 Stripe 迁移
控制面板负责连接 Stripe、导入商品目录、复制银行卡并切换订阅。应用负责首尾阶段以及中间发生的事件。
1. 将新销售转移到 Polar
先集成 Polar 结账和 Webhook(polar-integration),并在每次结账时传入 external_customer_id。此后,新客户会在 Polar 上订阅,而现有订阅仍由 Stripe 续订。在 Stripe 不再有任何续订之前,请将 Stripe ID 保留在数据库中。
共存期间,访问权限检查必须接受任一服务商提供的有效权益;取消订阅或更改套餐时,则应发送给负责该订阅计费的系统。
2. 映射导入的客户
导入过程会创建或复用 Polar 客户,但 Polar 无法获知应用中的客户 ID。请仅根据准确且唯一的电子邮件地址,将每位导入客户匹配一次,然后为 external_id 仍为空的客户设置你的 ID。对于缺失、重复或已更改的电子邮件地址,请提交审核,不要猜测。
import { polar } from "./polar"; // client from polar-integration
const customer = await polar.customers.get(polarCustomerId);
if (customer.external_id === null) {
await polar.customers.update(polarCustomerId, { external_id: appCustomerId });
}
导入的产品会成为新的 Polar 产品。请明确将每个内部套餐映射到新的 Polar 产品 ID 和价格 ID,切勿按名称映射。权益不会导入:如果访问权限依赖权益,请在切换前将权益附加到导入的产品上。
3. 为切换做好准备
Polar 会立即取消 Stripe 上每个已切换的订阅,不按比例计费,也不会生成最终账单。切换前:
-
关闭 Stripe 的订阅取消邮件(Settings → Billing → Subscriptions and emails),并暂停任何由取消触发的 Stripe 自动化。
-
让 Stripe 的
customer.subscription.deleted处理程序忽略已切换的订阅,以免撤销访问权限或发送取消邮件:if (subscription.cancellation_details?.comment?.startsWith("Migrated to Polar")) { return; // billing moved to Polar; reconcile through subscription.migrated instead } -
将 Polar 的
subscription.migrated事件作为切换信号。该事件包含provider和provider_subscription_id。将其作为幂等的更新或插入处理:把 Polar 订阅 ID 关联到 Stripe 订阅,并记录由 Polar 负责下一次扣款。不要因此授予或撤销访问权限,也不要发送欢迎邮件:case "subscription.migrated": await recordMigratedSubscription({ stripeSubscriptionId: event.provider_subscription_id, polarSubscriptionId: event.data.id, }); break;
每个已切换的订阅都会收到 subscription.updated、subscription.migrated 和 customer.state_changed 事件,顺序不定。迁移不会发送 subscription.created 或 subscription.active,导入也不会发送 product.created 或 customer.created。
4. 切换、核对并清理
在仪表板中启动切换。此操作无法撤销;将在 24 小时内续订的订阅会留在 Stripe,直到下一次扣款尝试。之后,请确认每个已迁移的订阅都只在 Polar 扣款,并且只关联到一个客户和一项权益。只有在 Stripe 上不再有订阅续订后,才停用 Stripe 结账和订阅代码。
请提前了解以下限制:Stripe Connect 平台账户和印度的 Stripe 账户无法使用自动迁移流程。通过 Stripe Managed Payments 售出的订阅,以及包含多件商品、数量大于 1,或处于逾期、未付款或暂停状态的订阅,需要特别处理或会留在 Stripe。只会复制银行卡;复制真实银行卡需要使用正式环境的 Stripe 账户,且 Stripe 密钥模式必须与 Polar 环境一致。
如需全面评估,Polar 的指南中提供了一个编码助手提示词,可在修改代码前生成迁移计划和核对协议。
其他服务商
重新创建商品目录
计费周期属于商品,且每种货币的商品只能有一个固定价格。按月和按年计费需要创建两个商品:
await polar.products.create({
name: "Pro (Monthly)",
recurring_interval: "month",
prices: [{ amount_type: "fixed", price_amount: 2900, price_currency: "usd" }],
});
await polar.products.create({
name: "Pro (Yearly)",
recurring_interval: "year",
prices: [{ amount_type: "fixed", price_amount: 29000, price_currency: "usd" }],
});
重新创建权益(许可证密钥、文件下载、Discord 角色等),并使用 polar.products.updateBenefits(productId, { benefits: [benefitId] }) 将它们关联起来。
迁移客户
如果希望客户在结账前就出现在 Polar 中,可以提前创建客户:
await polar.customers.create({ external_id: appCustomerId, email, name });
无法通过 API 创建付费订阅;除 Stripe 的复制功能外,已保存的银行卡也无法在不同支付处理商之间迁移。每位客户都需要在 Polar 上结账,并在那里输入银行卡信息。请发送使用 external_customer_id 创建的结账链接。
为避免同一计费周期被重复扣款,请安排旧订阅在当前周期结束时取消,并为 Polar 结账设置一个覆盖剩余天数的试用期,使用 trial_interval: "day" 和 trial_interval_count。请联系 Polar 支持,确认此方案是否适用于你的情况。
许可证密钥
许可证密钥无法导入。在过渡期间,请继续通过旧服务商验证现有密钥;新购买的客户将获得 Polar 密钥。
与客户沟通
- **Stripe 迁移:**客户无需采取任何操作。Polar 会在首次账单邮件(例如首次续订收据)中添加迁移通知。如果希望客户先从你这里得知此事,请在切换前发送简短通知。
- **其他服务商:**客户需要重新结账。请明确告知他们需要在 Polar 上输入银行卡信息、何时会被扣款,以及旧订阅会在已付费周期结束时终止。
测试
先使用 Stripe 测试模式账户在 Polar 的沙盒中运行迁移。沙盒会验证应用端(客户映射、subscription.migrated 处理、访问检查),但无法复制真实银行卡。请参阅 polar-testing,了解沙盒设置和本地 webhook 测试。