You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Stripe订阅首三月预付、后续按月自动续费

解决方案:Stripe 预付首三月+后续按月订阅实现

针对你的需求(注册时预付3个月共30美元,之后按月10美元自动续费),推荐两种可行的实现方案,其中Subscription Schedule方案更优雅,适合统一管理订阅生命周期。


方案一:使用Subscription Schedule(推荐)

这种方式能统一管理整个订阅周期,首笔费用可立即通过前端确认支付,无需等待1小时自动扣费。

后端Flask代码调整

import stripe
from flask import request, jsonify

stripe.api_key = "你的Stripe秘钥"
MONTHLY_PRICE_ID = "你的月费10美元Price ID" # 在Stripe后台创建的每月10美元订阅价格

@app.route("/api/subscribe", methods=["POST"])
def create_subscription_schedule():
    request_data = request.get_json()
    payment_method_id = request_data["paymentMethodId"]
    user_email = request_data["email"]
    user_name = request_data["name"]

    # 1. 创建Customer并关联支付方式
    customer = stripe.Customer.create(
        email=user_email,
        name=user_name,
        payment_method=payment_method_id,
        invoice_settings={"default_payment_method": payment_method_id}
    )

    # 2. 创建包含两个阶段的Subscription Schedule
    schedule = stripe.SubscriptionSchedule.create(
        customer=customer.id,
        start_date="now",
        end_behavior="release", # 周期结束后转为普通订阅
        payment_behavior="default_incomplete", # 生成待确认的PaymentIntent
        expand=["subscription.latest_invoice.payment_intent"], # 展开获取支付意图
        phases=[
            # 第一阶段:一次性收取3个月费用(30美元),仅执行1次
            {
                "items": [{"price": MONTHLY_PRICE_ID, "quantity": 3}],
                "iterations": 1,
                "collection_method": "charge_automatically"
            },
            # 第二阶段:每月收取10美元,无限循环
            {
                "items": [{"price": MONTHLY_PRICE_ID, "quantity": 1}],
                "collection_method": "charge_automatically"
            }
        ]
    )

    # 提取PaymentIntent的client_secret返回给前端
    payment_intent = schedule["subscription"]["latest_invoice"]["payment_intent"]
    return jsonify({
        "clientSecret": payment_intent["client_secret"],
        "scheduleId": schedule["id"]
    })

前端React代码调整

import { useStripe, useElements } from "@stripe/react-stripe-js";

const CheckoutForm = () => {
  const stripe = useStripe();
  const elements = useElements();

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!stripe || !elements) return;

    // 1. 创建支付方式
    const { paymentMethod, error: pmError } = await stripe.createPaymentMethod({
      element: elements.getElement("card")!
    });

    if (pmError) {
      console.error(pmError.message);
      return;
    }

    try {
      // 2. 调用后端创建订阅计划
      const response = await fetch("/api/subscribe", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          paymentMethodId: paymentMethod.id,
          email: "user@example.com",
          name: "Test User"
        })
      });

      const data = await response.json();

      // 3. 确认支付,完成首笔费用收取
      const { error: confirmError } = await stripe.confirmCardPayment(
        data.clientSecret,
        { payment_method: paymentMethod.id }
      );

      if (confirmError) {
        console.error(confirmError.message);
      } else {
        // 支付成功,跳转至确认页面
        window.location.href = "/subscription-success";
      }
    } catch (err) {
      console.error("请求失败:", err);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div className="card-element">
        {/* 你的CardElement组件 */}
      </div>
      <button type="submit" disabled={!stripe}>
        立即订阅(预付30美元)
      </button>
    </form>
  );
};

export default CheckoutForm;

关键说明

  • 设置payment_behavior="default_incomplete"会生成待确认的PaymentIntent,避免Stripe自动扣费的延迟问题。
  • 通过expand参数直接获取PaymentIntent的client_secret,无需额外查询。
  • 前端调用stripe.confirmCardPayment立即完成支付,首笔费用实时到账。

方案二:一次性Charge + 后续订阅

如果需要分开处理预付费用和后续订阅,可以采用先收取一次性费用,再创建延后启动的订阅。

后端Flask代码

import stripe
from datetime import datetime, timedelta
from flask import request, jsonify

stripe.api_key = "你的Stripe秘钥"
MONTHLY_PRICE_ID = "你的月费10美元Price ID"

@app.route("/api/subscribe", methods=["POST"])
def subscribe_with_one_time_charge():
    request_data = request.get_json()
    payment_method_id = request_data["paymentMethodId"]
    user_email = request_data["email"]
    user_name = request_data["name"]

    # 1. 创建Customer
    customer = stripe.Customer.create(
        email=user_email,
        name=user_name,
        payment_method=payment_method_id,
        invoice_settings={"default_payment_method": payment_method_id}
    )

    # 2. 收取30美元一次性预付费用
    charge = stripe.Charge.create(
        amount=3000, # 单位为分,30美元=3000分
        currency="usd",
        customer=customer.id,
        payment_method=payment_method_id,
        confirm=True,
        return_url="https://your-domain.com/success" # 用于3DS验证跳转
    )

    if charge.status != "succeeded":
        return jsonify({"error": "预付费用支付失败"}), 400

    # 3. 创建3个月后启动的按月订阅
    three_months_later = datetime.now() + timedelta(days=90)
    subscription = stripe.Subscription.create(
        customer=customer.id,
        items=[{"price": MONTHLY_PRICE_ID}],
        start_date=int(three_months_later.timestamp()), # 转为Unix时间戳
        collection_method="charge_automatically"
    )

    return jsonify({
        "chargeId": charge.id,
        "subscriptionId": subscription.id,
        "message": "预付成功,订阅已创建"
    })

前端注意事项

如果支付需要3DS验证,后端会返回PaymentIntent的client_secret,前端需调用stripe.confirmCardPayment完成验证流程。


内容的提问来源于stack exchange,提问作者Cels

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 23:04:53