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

订阅模式下Stripe结账会话Price ID传递及前后端实现指引

解决方案

1. 明确:必须传递Price ID而非Product ID

Stripe Checkout的line_items字段要求传入Price ID(格式为price_xxx),而非Product ID(prod_xxx)。因为一个Product可以对应多个Price(比如月度/年度订阅、不同货币定价),你需要指定用户选择的具体价格版本。

2. 前端(Next.js)修改:传递选中的Price ID到后端

假设你的产品列表里每个产品都包含对应的Price ID(从Stripe后台或你自己的产品API获取),修改handleSubscription函数,在POST请求中带上priceId参数:

// 点击按钮时传入选中的priceId,比如从产品列表项中获取
const handleSubscription = async (priceId) => {
  try {
    const response = await AxiosInstance.post("/checkout-session", {
      price_id: priceId // 传递选中的Price ID到后端
    });
    
    const sessionId = response.data.sessionId;
    const stripe = await loadStripe(
      process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
    );
    const { error } = await stripe.redirectToCheckout({
      sessionId: sessionId,
    });

    if (error) {
      console.error("Error:", error);
    }
  } catch (err) {
    console.error("Request failed:", err);
  }
};

// 在产品按钮中调用示例:
// <button onClick={() => handleSubscription(product.price.id)}>订阅</button>

3. 后端(Django DRF)修改:接收并使用Price ID

修改CreateCheckoutSession视图,从请求体中获取price_id,验证后传入Stripe的Session创建参数:

class CreateCheckoutSession(APIView):
    def post(self, request):
        try:
            if not request.user.is_authenticated:
                return Response({'message': 'You need to register first.'}, status=403)

            # 从请求体获取Price ID
            price_id = request.data.get('price_id')
            if not price_id:
                return Response({'error': 'Price ID is required.'}, status=400)

            # 可选:验证Price ID有效性(增强安全性)
            # try:
            #     stripe.Price.retrieve(price_id)
            # except stripe.error.InvalidRequestError:
            #     return Response({'error': 'Invalid Price ID.'}, status=400)

            checkout_session = stripe.checkout.Session.create(
                client_reference_id=request.user.id,
                payment_method_types=['card'],
                line_items=[
                    {
                        'price': price_id,  # 使用传入的Price ID
                        'quantity': 1,
                    },
                ],
                mode='subscription',
                success_url=f"{os.environ['DOMAIN_URL']}/dashboard",
                cancel_url=os.environ['DOMAIN_URL'],
            )
            return Response({'sessionId': checkout_session.id})

        except InvalidRequestError as e:
            return Response({'error': str(e)}, status=400)
        except Exception as e:
            return Response({'error': str(e)}, status=500)

关键注意事项

  • 确保前端获取的是正确的Price ID:从Stripe后台的产品详情页可查看每个Price的ID,或通过Stripe API获取产品时从prices数组提取。
  • 后端Stripe API密钥需具备checkout.sessions.create权限(默认已包含)。
  • 即使无法测试结账页面,可通过Stripe Dashboard的Events查看会话创建状态,或在后端打印checkout_session内容验证参数正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 03:08:18