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

Stripe Dashboard显示400但CLI返回200的Django Webhook问题

Stripe Webhook:CLI显示200但Dashboard显示400的疑问

为了做sanity check,我们在Django应用的Stripe Webhook中直接返回200状态码。从截图可见:

  • Stripe CLI显示事件正常接收,且返回了200状态码
  • 但Stripe Dashboard中对应事件却显示状态码400

想咨询:如果CLI能正常接收响应,Dashboard里的状态是否会产生实际影响?

测试用Webhook代码

@method_decorator(csrf_exempt, name='dispatch')
class StripeWebhook(APIView):
    def post(self, request, *args, **kwargs):
        return HttpResponse({status: "success"},status=200)
        # 以下是正常业务逻辑,当前仅做sanity check验证Dashboard是否能识别200
        print('received payment. in webhook')
        stripe.api_key = settings.STRIPE_TEST_SECRET
        event = None
        payload = request.body        
        sig_header = request.META["HTTP_STRIPE_SIGNATURE"]
        try:
            event = stripe.Webhook.construct_event(
                payload, sig_header, 'settings.WEBHOOK_SECRET'
            )
        except ValueError as e: 
            print("aaa")
            print(e)
            return HttpResponse(status=400)
        except stripe.error.SignatureVerificationError as e:
            print('bbb')
            print(e)
            return HttpResponse(status=400)
        
        
        if event['type'] == 'checkout.session.completed':
            print('payment success')
        elif event['type'] == 'payment_intent.payment_failed':
            # 处理支付失败事件
            print('payment failed')
            return HttpResponse('something went wrong', status=400)
        return HttpResponse({'status': 'success'})

相关截图

  • Stripe CLI日志:Stripe CLI日志
  • Stripe Dashboard事件状态:Stripe Dashboard事件状态

解答

1. Dashboard状态的实际影响

  • 仅用Stripe CLI做本地开发测试:Dashboard的状态不会影响本地测试流程,因为CLI是将Stripe事件转发到你的本地服务,和Stripe服务器直接请求你的公网Webhook地址是两条独立路径。
  • 需要Stripe服务器直接向线上/测试环境地址发送事件:Dashboard的400状态说明Stripe服务器请求你的Webhook地址时收到了错误响应,这会导致Stripe重试未成功的事件(最多重试3天),如果一直失败,可能会影响业务逻辑(比如支付成功事件未被处理,无法更新订单状态)。

2. 为什么CLI显示200但Dashboard显示400?

核心原因是两者的请求环境和验证逻辑不同:

  • CLI转发的是本地请求:你的本地服务能正常响应200,但公网Webhook地址可能存在问题(比如无法被公网访问、签名验证失败、响应格式不符合要求)。
  • 代码响应格式错误:测试代码里return HttpResponse({status: "success"},status=200)有两个问题:
    • status未加引号,生成的内容不是有效的JSON(Stripe要求Webhook响应最好是JSON格式,至少是合法的HTTP响应内容)
    • Django的HttpResponse不会自动将字典序列化为JSON,应该用JsonResponse({"status": "success"}, status=200),否则返回的内容可能被Stripe判定为无效,从而标记为400。
  • Webhook配置不一致:Dashboard中配置的Webhook地址、签名密钥可能和CLI使用的不一致,导致Stripe服务器请求时验证失败返回400。

3. 修复建议

  • 修正响应格式:将测试代码中的返回语句改为return JsonResponse({"status": "success"}, status=200)(需导入from django.http import JsonResponse)。
  • 验证公网地址可达性:确保Webhook地址能被公网访问,且签名密钥配置正确(不要用字符串'settings.WEBHOOK_SECRET',应直接引用settings.WEBHOOK_SECRET)。
  • 查看Dashboard事件详情:点击400状态的事件,查看具体错误信息(比如“Invalid signature”“Connection error”等),针对性修复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:54:55