订阅模式下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
相关产品推荐
相关产品推荐

