Using django-stripe's built-in webhook support

Viewed 1579

I'm using Django 3.0, dj-stripe 2.0, and the Stripe CLI. dj-stripe provides native support for Stripe webhooks, and their documentation says to include the following in my django project's main urls.py file to expose the webhook endpoint:

url(r"^stripe/", include("djstripe.urls", namespace="djstripe")),

I have done this, but how do I now leverage the endpoint?

As a separate experiment, I created a payments app, setup the URL conf, and successfully called the view when triggering the non dj-stripe webhook endpoint via the Stripe CLI. But it doesn't use any dj-stripe functionality:

# project urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('stripe/', include("djstripe.urls", namespace="djstripe")),
    path('payments/', include("payments.urls", namespace="payments")),
]
# payments/urls.py

from django.urls import path

from . import views

app_name="payments"

urlpatterns = [
    path("", views.my_handler, name="my-handler"),
]
# payments/views.py

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_handler(request, **kwargs):
    print(request.body)
    return HttpResponse(status=200)

Running stripe listen --forward-to localhost:8000/payments/ and, in a separate window, stripe trigger product.created returns a 200 response.

But stripe listen --forward-to localhost:8000/stripe/webhook/ and stripe trigger product.created returns a 500.

Thank you in advance for your help.

[UPDATE]

I have not modified the default DJSTRIPE_WEBHOOK_URL or DJSTRIPE_WEBHOOK_VALIDATION settings. In settings.py I have:

STRIPE_LIVE_PUBLIC_KEY = os.environ.get("STRIPE_LIVE_PUBLIC_KEY")
STRIPE_LIVE_SECRET_KEY = os.environ.get("STRIPE_LIVE_SECRET_KEY")
STRIPE_TEST_PUBLIC_KEY = os.environ.get("STRIPE_TEST_PUBLIC_KEY")
STRIPE_TEST_SECRET_KEY = os.environ.get("STRIPE_TEST_SECRET_KEY")
STRIPE_LIVE_MODE = os.environ.get("STRIPE_LIVE_MODE")
DJSTRIPE_WEBHOOK_SECRET = "*************************************"

The test keys are pulled from env/bin/activate:

export STRIPE_LIVE_PUBLIC_KEY="pk_live_****...."
export STRIPE_LIVE_SECRET_KEY="sk_live_****...."
export STRIPE_TEST_PUBLIC_KEY="pk_test_****...."
export STRIPE_TEST_SECRET_KEY="sk_test_****...."
export STRIPE_LIVE_MODE="False"

When I run stripe listen --forward-to localhost:8000/stripe/webhook/ and trigger stripe trigger customer.created I get the following 500 error:

stripe.error.InvalidRequestError: Request req_NTtzsTFS8uVdfL: No such customer; a similar object exists in test mode, but a live mode key was used to make this request.

But I don't understand how my keys could be getting mixed up, because the webhooks work fine when I trigger the same event and listen via the /payments/ endpoint.

Thank you again for your time.

1 Answers

In summary, you need to decorate a handler function using the @webhooks.handler decorator.

You have some examples in the webhooks section of the dj-stripe documentation.

Related