【问题标题】:Why does Stripe CLI testing fail with dj-stripe?为什么使用 dj-stripe 进行 Stripe CLI 测试失败?
【发布时间】:2021-11-30 12:45:53
【问题描述】:

我正在尝试使用 Stripe CLI 验证这些 URL 是否适用于 DJ Stripe。最初我打算自己实现视图,但后来我决定使用 DJ Stripe。在我原来的视图中,CLI 仅在文件上侦听我的 URL 并运行 stripe trigger checkout.session.completed

✗ stripe listen --forward-to localhost:80/webhook/subscriptions
/
⡿ Checking for new versions... A newer version of the Stripe CLI is available, please update to: v1.7.4
⢿ Getting ready... > Ready! Your webhook signing secret is whsec_flxws0UD9fzx16CMB5krTZdzy5LI63SE (^C to quit)
2021-10-11 14:29:56   --> payment_intent.created [evt_3JjUC8KxszORsacj0V7a7Kll]
2021-10-11 14:29:56  <--  [200] POST http://localhost:80/webhook/subscriptions/ [evt_3JjUC8KxszORsacj0V7a7Kll]
2021-10-11 14:29:59   --> customer.created [evt_1JjUCBKxszORsacjAxsANDCu]
2021-10-11 14:29:59  <--  [200] POST http://localhost:80/webhook/subscriptions/ [evt_1JjUCBKxszORsacjAxsANDCu]
2021-10-11 14:29:59   --> payment_intent.succeeded [evt_3JjUC8KxszORsacj0ZPYDcwj]
2021-10-11 14:29:59  <--  [200] POST http://localhost:80/webhook/subscriptions/ [evt_3JjUC8KxszORsacj0ZPYDcwj]
2021-10-11 14:29:59   --> charge.succeeded [evt_3JjUC8KxszORsacj001d3jMs]
2021-10-11 14:30:00   --> checkout.session.completed [evt_1JjUCBKxszORsacjedLR1580]
2021-10-11 14:30:00  <--  [200] POST http://localhost:80/webhook/subscriptions/ [evt_3JjUC8KxszORsacj001d3jMs]
2021-10-11 14:30:00  <--  [200] POST http://localhost:80/webhook/subscriptions/ [evt_1JjUCBKxszORsacjedLR1580]

我的工作非 dj-stripe 代码如下:

@csrf_exempt
def stripe_subscription_webhook_received(request):

    stripe.api_key = cmu.get_stripe_api_key()
    webhook_secret = request.headers['STRIPE_SIGNATURE']
    payload = json.loads(request.body)

    try:
        event = stripe.Event.construct_from(payload, stripe.api_key)
    except ValueError as e:
        return HttpResponse(status=400)

    if event.type == 'checkout.session.completed':
        payment_intent = event.data.object
        print(payment_intent)
    elif event.type == 'invoice.paid':
        # bunch of events... 
        # ...
    else:
        print(f"Unhandled Stripe event type: {event.type}")
        cmu.email_self_about_stripe_webhook(event)

    return HttpResponse(status=200)

但是,当尝试使用 DJ Stripe URL 时,我收到 400 错误:

✗ stripe listen --forward-to localhost:80/stripe/my_product_webhook/
⡿ Checking for new versions... A newer version of the Stripe CLI is available, please update to: v1.7.4
⣻ Getting ready... > Ready! Your webhook signing secret is whsec_flxws0UD9fzx16CMB5krTZdzy5LI63SE (^C to quit)
2021-10-11 14:37:16   --> payment_intent.created [evt_3JjUJDKxszORsacj1newBYzm]
2021-10-11 14:37:16  <--  [400] POST http://localhost:80/stripe/my_product_webhook/ [evt_3JjUJDKxszORsacj1newBYzm]
2021-10-11 14:37:21   --> customer.created [evt_1JjUJIKxszORsacjp6CsOLt1]
2021-10-11 14:37:21  <--  [400] POST http://localhost:80/stripe/my_product_webhook/ [evt_1JjUJIKxszORsacjp6CsOLt1]
2021-10-11 14:37:21   --> payment_intent.succeeded [evt_3JjUJDKxszORsacj1swQx4Mu]
2021-10-11 14:37:21   --> charge.succeeded [evt_3JjUJDKxszORsacj13CHPHjY]
2021-10-11 14:37:21  <--  [400] POST http://localhost:80/stripe/my_product_webhook/ [evt_3JjUJDKxszORsacj1swQx4Mu]
2021-10-11 14:37:21  <--  [400] POST http://localhost:80/stripe/my_product_webhook/ [evt_3JjUJDKxszORsacj13CHPHjY]
2021-10-11 14:37:21   --> checkout.session.completed [evt_1JjUJJKxszORsacjrFkPSeX2]
2021-10-11 14:37:21  <--  [400] POST http://localhost:80/stripe/my_product_webhook/ [evt_1JjUJJKxszORsacjrFkPSeX2]

查看dj-stripe views.py 源代码,在给定return HttpResponseBadRequest() 的情况下,这可能是设计为返回400 错误。

@method_decorator(csrf_exempt, name="dispatch")
class ProcessWebhookView(View):
    """
    A Stripe Webhook handler view.
    This will create a WebhookEventTrigger instance, verify it,
    then attempt to process it.
    If the webhook cannot be verified, returns HTTP 400.
    If an exception happens during processing, returns HTTP 500.
    """

    def post(self, request):
        if "HTTP_STRIPE_SIGNATURE" not in request.META:
            # Do not even attempt to process/store the event if there is
            # no signature in the headers so we avoid overfilling the db.
            return HttpResponseBadRequest()

        trigger = WebhookEventTrigger.from_request(request)

        if trigger.is_test_event:
            # Since we don't do signature verification, we have to skip trigger.valid
            return HttpResponse("Test webhook successfully received!")

        if not trigger.valid:
            # Webhook Event did not validate, return 400
            return HttpResponseBadRequest()

        return HttpResponse(str(trigger.id))

我的目标是从我自己的 webhook 实现转移到使用 dj-stripe 中的内置 webhook 和触发器。但在开始迁移之前,我想验证 webhook 端点是否确实在工作。我是否在这里遗漏了一些关于如何让 Stripe CLI 与 dj-stripe URL 很好地配合的内容?在我的 settings.py 中,我有 DJSTRIPE_WEBHOOK_URL = "my_product_webhook/" 只是为了使 URL 更明确。困扰我的一件事是,我在查看 DEBUG 输出时的 URL 似乎有一个空格:stripe/ my_product_webhook/ [name='webhook'] 。看到我正在关注dj-stripe installation docs,我不清楚为什么在将path("stripe/", include("djstripe.urls", namespace="djstripe")), 添加到我的urls.py 后,这个URL 中会有一个空格。

编辑:记录 400 个错误:

django_web_1  | 2021-10-11 19:37:16,880 WARNING [django.request:224] log 1 281473210016224 Bad Request: /stripe/my_product_webhook/
django_web_1  | 172.23.0.4:49160 - - [11/Oct/2021:19:37:16] "POST /stripe/my_product_webhook/" 400 -
nginx_1       | 172.23.0.1 - - [11/Oct/2021:19:37:16 +0000] "POST /stripe/my_product_webhook/ HTTP/1.1" 400 0 "-" "Stripe/1.0 (+https://stripe.com/docs/webhooks)"
django_web_1  | 2021-10-11 19:37:21,199 WARNING [django.request:224] log 1 281473210016224 Bad Request: /stripe/my_product_webhook/
django_web_1  | 172.23.0.4:49162 - - [11/Oct/2021:19:37:21] "POST /stripe/my_product_webhook/" 400 -
nginx_1       | 172.23.0.1 - - [11/Oct/2021:19:37:21 +0000] "POST /stripe/my_product_webhook/ HTTP/1.1" 400 0 "-" "Stripe/1.0 (+https://stripe.com/docs/webhooks)"
django_web_1  | 2021-10-11 19:37:21,344 WARNING [django.request:224] log 1 281473210016224 Bad Request: /stripe/my_product_webhook/
django_web_1  | 172.23.0.4:49164 - - [11/Oct/2021:19:37:21] "POST /stripe/my_product_webhook/" 400 -
nginx_1       | 172.23.0.1 - - [11/Oct/2021:19:37:21 +0000] "POST /stripe/my_product_webhook/ HTTP/1.1" 400 0 "-" "Stripe/1.0 (+https://stripe.com/docs/webhooks)"
django_web_1  | 2021-10-11 19:37:21,458 WARNING [django.request:224] log 1 281473210016224 Bad Request: /stripe/my_product_webhook/
django_web_1  | 172.23.0.4:49170 - - [11/Oct/2021:19:37:21] "POST /stripe/my_product_webhook/" 400 -
nginx_1       | 172.23.0.1 - - [11/Oct/2021:19:37:21 +0000] "POST /stripe/my_product_webhook/ HTTP/1.1" 400 0 "-" "Stripe/1.0 (+https://stripe.com/docs/webhooks)"
django_web_1  | 2021-10-11 19:37:21,629 WARNING [django.request:224] log 1 281473210016224 Bad Request: /stripe/my_product_webhook/
nginx_1       | 172.23.0.1 - - [11/Oct/2021:19:37:21 +0000] "POST /stripe/my_product_webhook/ HTTP/1.1" 400 0 "-" "Stripe/1.0 (+https://stripe.com/docs/webhooks)"
django_web_1  | 172.23.0.4:49172 - - [11/Oct/2021:19:37:21] "POST /stripe/my_product_webhook/" 400 -

【问题讨论】:

  • 您在日志中看到了什么?我假设您在那里收到了一些可能有用的错误消息
  • 我不认为它们超级有用?我在最后添加了它们。我可以看到关于打开详细日志记录,但大概 dj-stripe 代码不喜欢测试 API,因为它缺少一些条纹签名将是我的猜测
  • 是的,我在那里也没有看到任何有用的东西 - 你从详细日志中看到了什么吗?

标签: django stripe-payments webhooks


【解决方案1】:
  1. 我认为你需要确保签名是正确的,你需要去dashboard &gt; developers &gt; webhook &gt; choose the hosted endpoint &gt; then on signing secret click reveal。它应该以whsec... 开头,然后确保DJSTRIPE_WEBHOOK_SECRET 相同。
  2. 如果这不起作用,您可以检查事件日志,它可能会告诉您错误 400 的原因是什么。因为在执行之前,它会检查 webhook 是否有效。您可以在其中一个 djstripe 模型上查看事件(忘记是哪一个)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 2018-04-08
    • 2023-03-08
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多