使用Django搭建订阅服务时遭遇Stripe InvalidRequestError错误
嘿,我之前在Django里集成Stripe订阅系统的时候,也碰到过这个烦人的InvalidRequestError,给你分享几个我踩过的坑和解决思路,应该能帮到你!
首先先把你贴的models.py代码补全并格式化好,price字段一般用DecimalField来存储金额(因为要处理小数):
from django.db import models from django.contrib.auth.models import User from django.utils.timezone import now class Subscription(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) customer_id = models.CharField(max_length=255) subscription_id = models.CharField(max_length=225, unique=True) product_name = models.CharField(max_length=255) price = models.DecimalField(max_digits=10, decimal_places=2) # 补全常见的金额字段定义 created_at = models.DateTimeField(default=now)
接下来咱们一步步排查InvalidRequestError的常见原因:
先确认Stripe API密钥没搞混
这个是最容易犯的低级错误!测试环境一定要用pk_test_开头的可发布密钥和sk_test_开头的密钥,生产环境用pk_live_和sk_live_的。要是你在测试环境用了生产密钥,或者反过来,直接就会报请求无效。在Django的settings.py里要配置对:# settings.py STRIPE_PUBLISHABLE_KEY = 'pk_test_你的测试可发布密钥' STRIPE_SECRET_KEY = 'sk_test_你的测试密钥'检查你存到模型里的Stripe ID是不是真的有效
比如subscription_id和customer_id,必须是Stripe API返回的真实ID,不能自己随便生成个字符串存进去。举个例子,你创建订阅的视图代码得是这样的:import stripe from django.conf import settings from django.http import HttpResponseBadRequest from .models import Subscription from stripe.error import InvalidRequestError stripe.api_key = settings.STRIPE_SECRET_KEY def create_subscription(request): if not request.user.is_authenticated: # 处理未登录用户的情况 pass user = request.user try: # 第一步:创建Stripe客户 customer = stripe.Customer.create( email=user.email, source=request.POST.get('stripeToken') # 这个是前端Stripe.js生成的支付令牌 ) # 第二步:创建订阅,这里的price_id必须是你在Stripe后台创建的有效价格ID subscription = stripe.Subscription.create( customer=customer.id, items=[{"price": "price_你的测试价格ID"}], ) # 第三步:把Stripe返回的真实ID存到Django数据库 Subscription.objects.create( user=user, customer_id=customer.id, subscription_id=subscription.id, product_name="你的订阅产品名称", price=subscription.items.data[0].price.unit_amount / 100 # Stripe金额以分为单位,转成元 ) except InvalidRequestError as e: # 关键!捕获异常后打印具体错误信息,直接告诉你哪错了 print(f"Stripe错误详情: {e.user_message}") return HttpResponseBadRequest(f"订阅创建失败:{e.user_message}") # 处理成功后的跳转或响应 pass要是你自己随便写了个
subscription_id比如"sub_123"存进去,之后用这个ID调用Stripe API肯定会报错,因为Stripe根本没有这个订阅。一定要捕获异常看具体错误信息
别光看InvalidRequestError这个大类,Stripe的异常里有个user_message字段,会直接告诉你问题出在哪——比如“Invalid price ID: price_123”(价格ID无效)、“No such customer: cus_123”(客户不存在),这些具体信息比泛泛的错误类型有用100倍,先把这个打出来,就能精准定位问题。确认价格ID和环境匹配
你在Stripe测试后台创建的价格ID,只能用在测试环境的API请求里,生产环境的价格ID必须是在生产后台创建的,跨环境用也会报无效请求。
按照上面的步骤排查,尤其是先捕获异常看具体的错误提示,应该很快就能找到问题所在!
内容来源于stack exchange

