如何实现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
相关产品推荐
相关产品推荐

