
本文详解如何通过 stripe checkout 的 setup 模式预先收集客户支付方式、绑定为默认付款方法,并基于该客户创建带多阶段价格的 subscription schedule,从而安全完成首期收费与后续自动升级。
本文详解如何通过 stripe checkout 的 setup 模式预先收集客户支付方式、绑定为默认付款方法,并基于该客户创建带多阶段价格的 subscription schedule,从而安全完成首期收费与后续自动升级。
在 Stripe 中实现「首月固定价 → 次月同价 → 第 13 个月起切换为年度高价」这类分阶段订阅逻辑,不能直接在空客户(无支付方式)上创建 Subscription Schedule 并期待自动扣款——因为 Stripe 要求每个 SubscriptionSchedule 在 start_date 到来前,其关联客户必须拥有已确认、可扣款的默认支付方式(invoice_settings.default_payment_method)。你当前代码中仅创建了客户但未绑定卡,导致 Schedule 虽创建成功却无法触发首次计费,页面无限加载正是因前端未收到有效 session.url 或后端未正确重定向。
✅ 正确路径是:先通过 Stripe Checkout 的 setup 模式安全收卡 → 获取 PaymentMethod → 绑定为客户默认付款方式 → 再创建 Subscription Schedule。整个流程无需自行构建卡表单,完全复用 Stripe 官方托管页,兼顾合规性与开发效率。
✅ 推荐实现步骤(含关键代码)
1. 前端:发起 Setup 模式的 Checkout Session
修改你的 WordPress 表单,调用后端接口生成 setup 类型的 Session:
2. 后端:创建 Setup Session(PHP 示例)
function checkout_setup() {
\Stripe\Stripe::setApiKey('sk_test_51e7DRPLRnISGb5vSFxnvvuDx1GzhlBIFeazcmpEevsUFf29jHXJ1YgE2xaJ1lGfzjtKzE8uoN0eR9Klaq00CnMFWvfB');
// 创建客户(可选:传 email 提升体验)
$customer = \Stripe\Customer::create([
'email' => $_POST['email'] ?? null,
'name' => $_POST['name'] ?? null,
]);
// 创建 Setup Session:仅收卡,不扣款
$session = \Stripe\Checkout\Session::create([
'customer' => $customer->id,
'payment_method_types' => ['card'],
'mode' => 'setup',
'success_url' => 'https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => 'https://yoursite.com/cancel',
'billing_address_collection' => 'required', // 强制收集地址(推荐)
]);
// 返回前端跳转 URL
wp_send_json(['url' => $session->url]);
}
⚠️ 注意:
mode: 'setup'是关键——它告诉 Stripe 此 Session 仅用于保存支付方式,而非立即创建订阅或发票。
3. 处理 Setup 成功回调(Webhook 或 success_url 页面)
当用户完成卡片录入并返回 success_url 时,需用 session_id 检索 SetupIntent 并提取 PaymentMethod:
// 在 success.php 或 Webhook 中处理
$session = \Stripe\Checkout\Session::retrieve($_GET['session_id']);
$setupIntent = \Stripe\SetupIntent::retrieve($session->setup_intent);
// 将 PaymentMethod 设为客户默认付款方式
\Stripe\Customer::update($session->customer, [
'invoice_settings' => [
'default_payment_method' => $setupIntent->payment_method,
],
]);
4. 创建 Subscription Schedule(此时客户已具备有效默认卡)
$subscriptionSchedule = \Stripe\SubscriptionSchedule::create([
'customer' => $session->customer,
'start_date' => 'now',
'end_behavior' => 'release',
'phases' => [
// 第 1–12 个月:每月 price_1LRF5C...
[
'items' => [['price' => 'price_1LRF5CIne7DRPLRnwuLVE2pu', 'quantity' => 1]],
'iterations' => 12,
],
// 第 13 个月起:切换为年度价格 price_1LPujQ...
[
'items' => [['price' => 'price_1LPujQIne7DRPLRnj3EOweJN', 'quantity' => 1]],
// 不设 iterations → 持续到 subscription 取消
],
],
]);
✅ 至此,首次账单将在 start_date(即 now)立即生成并尝试扣款,后续按 phase 自动滚动。
? 关键注意事项
-
不要跳过 SetupIntent 验证:直接调用
Customer::create()+SubscriptionSchedule::create()不会触发任何支付,Stripe 会在首次账单时因无可用支付方式而失败。 -
Webhook 更可靠:建议用
setup_intent.succeededWebhook 替代success_url处理,默认支付方式绑定逻辑,避免用户手动关闭页面导致中断。 -
错误处理必加:所有 Stripe API 调用需包裹
try/catch,捕获\Stripe\Exception\CardException等异常并反馈给用户。 -
测试务必用 test cards:如
4242 4242 4242 4242(成功)、4000 0000 0000 0002(拒绝),验证全流程。
通过这一标准模式,你既复用了 Stripe 最安全的托管支付页,又精准实现了「先收卡、再排期、分阶计费」的业务需求,无需自建 PCI 合规表单,也规避了客户 ID 与支付方式脱节的核心陷阱。










