为什么使用dj-stripe测试Stripe CLI失败?



我正试图验证url是否适用于带有Stripe CLI的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条纹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实现转向使用j-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安装文档,我不清楚为什么这个URL在添加path("stripe/", include("djstripe.urls", namespace="djstripe")),到我的URL .py后会有一个空间。

编辑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 -
  1. 我认为你需要确保签名是正确的,你需要去dashboard > developers > webhook > choose the hosted endpoint > then on signing secret click reveal。应该从whsec...开始,然后确保DJSTRIPE_WEBHOOK_SECRET是相同的。
  2. 如果这不起作用,你可以检查事件日志,它可能会告诉你是什么导致错误400。因为在它进入你的实现之前,它会检查webhook是否有效。你可以在一个djstripe模型上检查事件(忘了是哪个)。

最新更新