-
Notifications
You must be signed in to change notification settings - Fork 341
Open
Description
Description
In stripe_webhook_view, when a payment_intent.succeeded event is received, invoice_id is extracted from Stripe's payment_intent metadata. However, there is no guard before dispatching the Celery task if invoice_id is absent from the metadata (which is valid for non-billing PaymentIntents or Stripe dashboard test events), the task is dispatched with invoice_id=None.
Affected Code
# app/eventyay/api/views/stripe.py
if event.type == 'payment_intent.succeeded':
invoice_id = event.data.object.get('metadata', {}).get('invoice_id')
update_billing_invoice_information.delay(invoice_id=invoice_id) # dispatched even if None
Impact
- Silent failure: The
update_billing_invoice_informationCelery task catches None and returns without raising an exception. Consequently, the task shows SUCCESS in monitoring even though nothing was updated, hiding billing processing errors. - Wasted resources: A Celery worker is scheduled and consumed for every non-billing payment_intent.succeeded event, even those that can never result in a billing update.
- Partial idempotency gap: The update() call in the task does not filter by current status, meaning rapid Stripe retries can produce multiple overlapping writes, resulting in an incorrect
paid_datetimevalue for audit purposes.
Proposed Fix
- Add a None guard in the view before dispatching the task
(if invoice_id:). - Add a
status=STATUS_PENDINGfilter in the Celery task's update() call to ensure exactly-once semantics and prevent concurrent workers from overwritingpaid_datetime.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
Backlog