title: Using django-stripe's built-in webhook support
body: <p>I'm using Django 3.0, dj-stripe 2.0, and the Stripe CLI. <a href="https://dj-stripe.readthedocs.io/en/stable-2.0/index.html" rel="nofollow noreferrer">dj-stripe</a> provides native support for Stripe webhooks, and their documentation says to include the following in my django project's main <code>urls.py</code> file to expose the webhook endpoint:</p>
  <p><code>url(r&quot;^stripe/&quot;, include(&quot;djstripe.urls&quot;, namespace=&quot;djstripe&quot;)),</code></p>
  <p>I have done this, but how do I now leverage the endpoint?</p>
  <p>As a separate experiment, I created a <code>payments</code> 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 <code>dj-stripe</code> functionality:</p>
  <pre><code># project urls.py
  
  from django.contrib import admin
  from django.urls import path, include
  
  urlpatterns = [
      path('admin/', admin.site.urls),
      path('stripe/', include(&quot;djstripe.urls&quot;, namespace=&quot;djstripe&quot;)),
      path('payments/', include(&quot;payments.urls&quot;, namespace=&quot;payments&quot;)),
  ]
  </code></pre>
  <pre><code># payments/urls.py
  
  from django.urls import path
  
  from . import views
  
  app_name=&quot;payments&quot;
  
  urlpatterns = [
      path(&quot;&quot;, views.my_handler, name=&quot;my-handler&quot;),
  ]
  </code></pre>
  <pre><code># 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)
  </code></pre>
  <p>Running <code>stripe listen --forward-to localhost:8000/payments/</code> and, in a separate window, <code>stripe trigger product.created</code> returns a <code>200</code> response.</p>
  <p>But <code>stripe listen --forward-to localhost:8000/stripe/webhook/</code> and <code>stripe trigger product.created</code> returns a <code>500</code>.</p>
  <p>Thank you in advance for your help.</p>
  <p>[UPDATE]</p>
  <p>I have not modified the default <code>DJSTRIPE_WEBHOOK_URL</code> or <code>DJSTRIPE_WEBHOOK_VALIDATION</code> settings. In <code>settings.py</code> I have:</p>
  <pre><code>STRIPE_LIVE_PUBLIC_KEY = os.environ.get(&quot;STRIPE_LIVE_PUBLIC_KEY&quot;)
  STRIPE_LIVE_SECRET_KEY = os.environ.get(&quot;STRIPE_LIVE_SECRET_KEY&quot;)
  STRIPE_TEST_PUBLIC_KEY = os.environ.get(&quot;STRIPE_TEST_PUBLIC_KEY&quot;)
  STRIPE_TEST_SECRET_KEY = os.environ.get(&quot;STRIPE_TEST_SECRET_KEY&quot;)
  STRIPE_LIVE_MODE = os.environ.get(&quot;STRIPE_LIVE_MODE&quot;)
  DJSTRIPE_WEBHOOK_SECRET = &quot;*************************************&quot;
  </code></pre>
  <p>The test keys are pulled from <code>env/bin/activate</code>:</p>
  <pre><code>export STRIPE_LIVE_PUBLIC_KEY=&quot;pk_live_****....&quot;
  export STRIPE_LIVE_SECRET_KEY=&quot;sk_live_****....&quot;
  export STRIPE_TEST_PUBLIC_KEY=&quot;pk_test_****....&quot;
  export STRIPE_TEST_SECRET_KEY=&quot;sk_test_****....&quot;
  export STRIPE_LIVE_MODE=&quot;False&quot;
  </code></pre>
  <p>When I run <code>stripe listen --forward-to localhost:8000/stripe/webhook/</code> and trigger <code>stripe trigger customer.created</code> I get the following 500 error:</p>
  <pre><code>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.
  </code></pre>
  <p>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 <code>/payments/</code> endpoint.</p>
  <p>Thank you again for your time.</p>