dj-stripe / dj-stripe

dj-stripe automatically syncs your Stripe Data to your local database as pre-implemented Django Models allowing you to use the Django ORM, in your code, to work with the data making it easier and faster.
https://dj-stripe.dev
MIT License
1.56k stars 474 forks source link

Failing webhook events in dj-stripe regarding Plan and Price #2051

Closed ogreyard closed 1 week ago

ogreyard commented 2 weeks ago

Describe the bug Webhook events forwarded by locally running the stripe cli are not being processed correctly and yield error 500.

To Reproduce First time integration of dj-stripe. Created a pricing table with monthly, yearly prices - with a standard price for the monthly subscription. Embedded that pricing table to frontend page. Set whsec_... and other environment variables correctly, since some events are processed with 200 OK. Working through the order flow, being in test mode. Ordering a subscription works in the web frontend dialog, and gives a success message in the end. What's not working is the processing of events in the django backend, see errors below. Error is thrown persistently. Fresh database init and migrate did not change a thing.

Software versions

Error logs:

127.0.0.1 - - [28/Apr/2024 16:46:07] "POST /api/stripe/webhook/ HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 670, in _create_from_stripe_object
    instance = cls.stripe_objects.get(id=id_)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/db/models/query.py", line 650, in get
    raise self.model.DoesNotExist(
djstripe.models.billing.Plan.DoesNotExist: Plan matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/contrib/staticfiles/handlers.py", line 80, in __call__
    return self.application(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/core/handlers/wsgi.py", line 131, in __call__
    response = self.get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/core/handlers/base.py", line 140, in get_response
    response = self._middleware_chain(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/core/handlers/exception.py", line 57, in inner
    response = response_for_exception(request, exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/core/handlers/exception.py", line 140, in response_for_exception
    response = handle_uncaught_exception(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/core/handlers/exception.py", line 181, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django_extensions/management/technical_response.py", line 40, in null_technical_500_response
    raise exc_value.with_traceback(tb)
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/views/generic/base.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/utils/decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/views/generic/base.py", line 142, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/views.py", line 47, in post
    trigger = WebhookEventTrigger.from_request(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/webhooks.py", line 268, in from_request
    raise e
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/webhooks.py", line 249, in from_request
    obj.process(save=False, api_key=api_key)
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/webhooks.py", line 363, in process
    self.event = Event.process(self.json_body, api_key=api_key)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/core.py", line 1656, in process
    ret.invoke_webhook_handlers()
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/core.py", line 1668, in invoke_webhook_handlers
    webhooks.call_handlers(event=self)
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/webhooks.py", line 98, in call_handlers
    handler_func(event=event)
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/event_handlers.py", line 353, in other_object_webhook_handler
    _handle_crud_like_event(target_cls=target_cls, event=event)
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/event_handlers.py", line 455, in _handle_crud_like_event
    obj = target_cls.sync_from_stripe_data(data, api_key=event.default_api_key)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 1051, in sync_from_stripe_data
    instance, created = cls._get_or_create_from_stripe_object(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 790, in _get_or_create_from_stripe_object
    cls._create_from_stripe_object(
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 660, in _create_from_stripe_object
    stripe_data = cls._stripe_object_to_record(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 410, in _stripe_object_to_record
    field_data, skip, is_nulled = cls._stripe_object_field_to_foreign_key(
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 536, in _stripe_object_field_to_foreign_key
    ) = field.related_model._get_or_create_from_stripe_object(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 790, in _get_or_create_from_stripe_object
    cls._create_from_stripe_object(
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 660, in _create_from_stripe_object
    stripe_data = cls._stripe_object_to_record(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 410, in _stripe_object_to_record
    field_data, skip, is_nulled = cls._stripe_object_field_to_foreign_key(
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 536, in _stripe_object_field_to_foreign_key
    ) = field.related_model._get_or_create_from_stripe_object(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 790, in _get_or_create_from_stripe_object
    cls._create_from_stripe_object(
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 687, in _create_from_stripe_object
    instance._attach_objects_post_save_hook(
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/djstripe/models/base.py", line 613, in _attach_objects_post_save_hook
    setattr(target, field.name, self)
  File "/Users/admin/Code/platform-311/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 237, in __set__
    raise ValueError(
ValueError: Cannot assign "<Plan: €39.00 EUR/month .... >": "Product.default_price" must be a "Price" instance.
2024-04-28 18:44:15   --> customer.subscription.deleted [evt_...]
2024-04-28 18:44:15  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:44:17  <--  [500] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:45:42   --> customer.created [evt_...]
2024-04-28 18:45:42   --> setup_intent.created [evt_...]
2024-04-28 18:45:42  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:45:43   --> setup_intent.requires_action [evt_...]
2024-04-28 18:45:43  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:45:43  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:45:59   --> payment_method.attached [evt_...]
2024-04-28 18:45:59  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:00   --> setup_intent.succeeded [evt_...]
2024-04-28 18:46:00   --> mandate.updated [evt_...]
2024-04-28 18:46:01  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:01  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:02   --> checkout.session.completed [evt_...]
2024-04-28 18:46:02   --> customer.updated [evt_...]
2024-04-28 18:46:02   --> invoice.finalized [evt_...]
2024-04-28 18:46:03   --> invoice.paid [evt_...]
2024-04-28 18:46:03   --> invoice.payment_succeeded [evt_...]
2024-04-28 18:46:03   --> customer.subscription.created [evt_...]
2024-04-28 18:46:03   --> invoice.created [evt_...]
2024-04-28 18:46:03  <--  [500] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:03  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:04  <--  [500] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:05  <--  [500] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:06  <--  [500] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:07  <--  [500] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:08  <--  [500] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:46:42   --> invoice.upcoming [evt_...]
2024-04-28 18:46:42  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]
2024-04-28 18:49:23   --> billing_portal.configuration.updated [evt_...]
2024-04-28 18:49:23  <--  [200] POST https://localhost:8000/api/stripe/webhook/ [evt_...]

Thanks for your support.

ogreyard commented 1 week ago

seemed to be related to some cached migrations. Deleted pychache folders and now it's working