Django中从Stripe Webhook事件对象获取Customer ID失败原因排查
无法从Stripe Checkout Webhook获取Customer ID的原因及解决办法
问题场景
在Django中接收Stripe的checkout.session.completed Webhook事件时,尝试通过event["data"]["object"]["customer"]获取Customer ID,但返回值为None。相关代码和收到的事件片段如下:
处理Webhook的代码
@csrf_exempt def StripeWebhookView(request): CHECKOUT_SESSION_COMPLETED = "checkout.session.completed" payload = request.body sig_header = request.META["HTTP_STRIPE_SIGNATURE"] endpoint_secret='' try: event = stripe.Webhook.construct_event( payload, sig_header, endpoint_secret ) if event["type"] == CHECKOUT_SESSION_COMPLETED: customer_id_stripe = event["data"]["object"]["customer"] print('customer_id:', customer_id_stripe)
收到的Stripe事件核心片段
{ "data": { "object": { "customer": null, "customer_creation": "if_required", "customer_details": { "email": "anon@gmail.com", "name": "asdasd" }, "mode": "payment" } }, "type": "checkout.session.completed" }
原因
问题出在customer_creation参数的设置上:
- 当前Checkout Session设置了
customer_creation: "if_required",这意味着只有当交易必须绑定客户(比如订阅模式、需要保存支付方式)时,Stripe才会自动创建Customer实体。 - 而你的交易是
mode: "payment"(一次性支付),这种场景下Stripe默认不会强制生成Customer,所以customer字段为null。 - 事件里的
customer_details只是匿名买家的信息,并非关联了Stripe的Customer账号。
解决办法
方案1:强制生成Customer
创建Checkout Session时,把customer_creation设为always,这样无论哪种交易模式,Stripe都会自动创建Customer,Webhook事件里的customer字段就会返回有效的ID。
示例代码(创建Checkout Session时):
checkout_session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': 'price_xxxx', 'quantity': 1, }], mode='payment', success_url='http://127.0.0.1:8000/success/', cancel_url='http://127.0.0.1:8000/discovery/', customer_creation='always' # 关键设置 )
方案2:从Payment Intent提取(可选)
如果不想强制生成Customer,可以通过事件里的payment_intent字段,调用Stripe API获取对应的Payment Intent对象,尝试从中提取Customer ID(仅当Payment Intent关联了Customer时有效)。
修改Webhook处理代码:
if event["type"] == CHECKOUT_SESSION_COMPLETED: session = event["data"]["object"] customer_id_stripe = session.get("customer") if not customer_id_stripe: # 从Payment Intent获取 payment_intent = stripe.PaymentIntent.retrieve(session["payment_intent"]) customer_id_stripe = payment_intent.get("customer") print('customer_id:', customer_id_stripe)
内容的提问来源于stack exchange,提问作者tzur
相关产品推荐
相关产品推荐

