question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Card matching query does not exist on Customer.add_card from stripe token from stripe checkout.js

See original GitHub issue

Describe the bug I’m running an app which uses stripe checkout in the front end (Source imported from here https://checkout.stripe.com/v2/checkout.js ), in which the user enters their credit card information and then Stripe provides a token which is passed to our API for further processing. On our server we use DJstripe to create a customer and then call add_card with the token from the stripe checkout to add the user’s card. Since upgrading to DJstripe 2.6.2 (Previously 2.5.1), we sometimes run into a djstripe.models.payment_methods.Card.DoesNotExist: Card matching query does not exist error when attempting to add the card. Before the upgrade our system has processed thousands of payments with this same set up with no issues. Typically we are seeing this problem in about 1 in 5 payment attempts.

From our server logs, I can see that when the error occurs, a number of webhooks are received and processed between the time that the add_card action is started and when the error trace is printed out. One of the webhooks being processed is started before the error trace, and completes after the error trace, so it really seems like some sort of race condition problem related to the webhooks. In some cases, the webhooks all complete without errors, and in other cases, the webhook handler also raises a similar Card.DoesNotExist error

Full trace:

[2022-10-31T01:49:00.948455283Z] app[web.1]: ERROR 2022-10-30 21:49:00,412 log 302 140720089622336 Internal Server Error: /subscribe/
[2022-10-31T01:49:00.948487892Z] app[web.1]: Traceback (most recent call last):
[2022-10-31T01:49:00.948493567Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/base.py", line 583, in _create_from_stripe_object
[2022-10-31T01:49:00.948498572Z] app[web.1]:     instance = cls.stripe_objects.get(id=id_)
[2022-10-31T01:49:00.948503185Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
[2022-10-31T01:49:00.948507907Z] app[web.1]:     return getattr(self.get_queryset(), name)(*args, **kwargs)
[2022-10-31T01:49:00.948512467Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/query.py", line 435, in get
[2022-10-31T01:49:00.948516964Z] app[web.1]:     raise self.model.DoesNotExist(
[2022-10-31T01:49:00.948521326Z] app[web.1]: djstripe.models.payment_methods.Card.DoesNotExist: Card matching query does not exist.
[2022-10-31T01:49:00.948525947Z] app[web.1]: 
[2022-10-31T01:49:00.948530448Z] app[web.1]: During handling of the above exception, another exception occurred:
[2022-10-31T01:49:00.948535195Z] app[web.1]: 
[2022-10-31T01:49:00.948539640Z] app[web.1]: Traceback (most recent call last):
[2022-10-31T01:49:00.948544260Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute
[2022-10-31T01:49:00.948549387Z] app[web.1]:     return self.cursor.execute(sql, params)
[2022-10-31T01:49:00.948553967Z] app[web.1]: psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "djstripe_card_stripe_id_1dd55072_uniq"
[2022-10-31T01:49:00.948558639Z] app[web.1]: DETAIL:  Key (id)=(card_1Lyn5mGRvRnAJwTxHV5AQTS7) already exists.
[2022-10-31T01:49:00.948563054Z] app[web.1]: 
[2022-10-31T01:49:00.948567452Z] app[web.1]: 
[2022-10-31T01:49:00.948571724Z] app[web.1]: The above exception was the direct cause of the following exception:
[2022-10-31T01:49:00.948576137Z] app[web.1]: 
[2022-10-31T01:49:00.948580371Z] app[web.1]: Traceback (most recent call last):
[2022-10-31T01:49:00.948584843Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/base.py", line 704, in _get_or_create_from_stripe_object
[2022-10-31T01:49:00.948589488Z] app[web.1]:     cls._create_from_stripe_object(
[2022-10-31T01:49:00.948594015Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/base.py", line 596, in _create_from_stripe_object
[2022-10-31T01:49:00.948598603Z] app[web.1]:     instance.save()
[2022-10-31T01:49:00.948603013Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 739, in save
[2022-10-31T01:49:00.948607581Z] app[web.1]:     self.save_base(using=using, force_insert=force_insert,
[2022-10-31T01:49:00.948629782Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 776, in save_base
[2022-10-31T01:49:00.948635021Z] app[web.1]:     updated = self._save_table(
[2022-10-31T01:49:00.948639363Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 881, in _save_table
[2022-10-31T01:49:00.948644971Z] app[web.1]:     results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
[2022-10-31T01:49:00.948649643Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/base.py", line 919, in _do_insert
[2022-10-31T01:49:00.948654197Z] app[web.1]:     return manager._insert(
[2022-10-31T01:49:00.948658540Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
[2022-10-31T01:49:00.948663127Z] app[web.1]:     return getattr(self.get_queryset(), name)(*args, **kwargs)
[2022-10-31T01:49:00.948667512Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/query.py", line 1270, in _insert
[2022-10-31T01:49:00.948672061Z] app[web.1]:     return query.get_compiler(using=using).execute_sql(returning_fields)
[2022-10-31T01:49:00.948676482Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/cachalot/monkey_patch.py", line 37, in inner
[2022-10-31T01:49:00.948681022Z] app[web.1]:     return original(compiler, *args, **kwargs)
[2022-10-31T01:49:00.948685392Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/cachalot/monkey_patch.py", line 113, in inner
[2022-10-31T01:49:00.948689919Z] app[web.1]:     return original(write_compiler, *args, **kwargs)
[2022-10-31T01:49:00.948694317Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1416, in execute_sql
[2022-10-31T01:49:00.948698989Z] app[web.1]:     cursor.execute(sql, params)
[2022-10-31T01:49:00.948703350Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/raven/contrib/django/client.py", line 127, in execute
[2022-10-31T01:49:00.948707898Z] app[web.1]:     return real_execute(self, sql, params)
[2022-10-31T01:49:00.948712411Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/cachalot/monkey_patch.py", line 137, in inner
[2022-10-31T01:49:00.948717005Z] app[web.1]:     return original(cursor, sql, *args, **kwargs)
[2022-10-31T01:49:00.948721458Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 66, in execute
[2022-10-31T01:49:00.948725997Z] app[web.1]:     return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
[2022-10-31T01:49:00.948730549Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
[2022-10-31T01:49:00.948735119Z] app[web.1]:     return executor(sql, params, many, context)
[2022-10-31T01:49:00.948739492Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 79, in _execute
[2022-10-31T01:49:00.948744007Z] app[web.1]:     with self.db.wrap_database_errors:
[2022-10-31T01:49:00.948748442Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/utils.py", line 90, in __exit__
[2022-10-31T01:49:00.948757510Z] app[web.1]:     raise dj_exc_value.with_traceback(traceback) from exc_value
[2022-10-31T01:49:00.948762415Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute
[2022-10-31T01:49:00.948893559Z] app[web.1]:     return self.cursor.execute(sql, params)
[2022-10-31T01:49:00.948912659Z] app[web.1]: django.db.utils.IntegrityError: duplicate key value violates unique constraint "djstripe_card_stripe_id_1dd55072_uniq"
[2022-10-31T01:49:00.948918328Z] app[web.1]: DETAIL:  Key (id)=(card_1Lyn5mGRvRnAJwTxHV5AQTS7) already exists.
[2022-10-31T01:49:00.948923122Z] app[web.1]: 
[2022-10-31T01:49:00.948927415Z] app[web.1]: 
[2022-10-31T01:49:00.948931693Z] app[web.1]: During handling of the above exception, another exception occurred:
[2022-10-31T01:49:00.948936130Z] app[web.1]: 
[2022-10-31T01:49:00.948940620Z] app[web.1]: Traceback (most recent call last):
[2022-10-31T01:49:00.948945372Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py", line 47, in inner
[2022-10-31T01:49:00.948950138Z] app[web.1]:     response = get_response(request)
[2022-10-31T01:49:00.948954602Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/base.py", line 181, in _get_response
[2022-10-31T01:49:00.948959230Z] app[web.1]:     response = wrapped_callback(request, *callback_args, **callback_kwargs)
[2022-10-31T01:49:00.948963812Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/base.py", line 70, in view
[2022-10-31T01:49:00.948968417Z] app[web.1]:     return self.dispatch(request, *args, **kwargs)
[2022-10-31T01:49:00.948972788Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/base.py", line 98, in dispatch
[2022-10-31T01:49:00.948977427Z] app[web.1]:     return handler(request, *args, **kwargs)
[2022-10-31T01:49:00.948981813Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/edit.py", line 142, in post
[2022-10-31T01:49:00.948986376Z] app[web.1]:     return self.form_valid(form)
[2022-10-31T01:49:00.948990764Z] app[web.1]:   File "/app/payment/views.py", line 534, in form_valid
[2022-10-31T01:49:00.948995282Z] app[web.1]:     user = form.create_customer()
[2022-10-31T01:49:00.948999722Z] app[web.1]:   File "/app/payment/forms.py", line 175, in create_customer
[2022-10-31T01:49:00.949004196Z] app[web.1]:     customer.add_card(self.cleaned_data.get('stripe_token'))
[2022-10-31T01:49:00.949008633Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/core.py", line 1029, in add_card
[2022-10-31T01:49:00.949013292Z] app[web.1]:     new_payment_method = DjstripePaymentMethod.from_stripe_object(
[2022-10-31T01:49:00.949017753Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/payment_methods.py", line 42, in from_stripe_object
[2022-10-31T01:49:00.949022310Z] app[web.1]:     model.sync_from_stripe_data(data)
[2022-10-31T01:49:00.949026708Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/base.py", line 946, in sync_from_stripe_data
[2022-10-31T01:49:00.949063242Z] app[web.1]:     instance, created = cls._get_or_create_from_stripe_object(
[2022-10-31T01:49:00.949069927Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/base.py", line 719, in _get_or_create_from_stripe_object
[2022-10-31T01:49:00.949074588Z] app[web.1]:     return cls.stripe_objects.get(id=id_), False
[2022-10-31T01:49:00.949079763Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
[2022-10-31T01:49:00.949084473Z] app[web.1]:     return getattr(self.get_queryset(), name)(*args, **kwargs)
[2022-10-31T01:49:00.949088916Z] app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/django/db/models/query.py", line 435, in get
[2022-10-31T01:49:00.949093398Z] app[web.1]:     raise self.model.DoesNotExist(
[2022-10-31T01:49:00.949097784Z] app[web.1]: djstripe.models.payment_methods.Card.DoesNotExist: Card matching query does not exist.

To Reproduce I have been unable to reliably reproduce

Software versions

  • Dj-Stripe version: 2.6.2
  • Python version: 3.10.6
  • Django version: 3.2.15
  • Stripe API version: 2020-08-27
  • Database type and version: PostgreSQL 10.21

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
arnav13081994commented, Nov 8, 2022

@martinmain93 I think that’s the best you can do at the moment. But please test thoroughly to ensure there are no unwarranted side effects.

@jleclanche Perhaps we can add a default retry mechanism for all methods using idempotency keys?

0reactions
martinmain93commented, Nov 10, 2022

Here’s the traceback. In this case, I’ve added a workaround by detecting if this specific error has been raised, and then trying to detect if the customer has a valid source. If the user has a valid source (after retrying a few times), then we ignore the error.

2022-11-10T16:19:29.027608052Z app[web.1]: Traceback (most recent call last):
2022-11-10T16:19:29.027613702Z app[web.1]:   File "/app/payment/forms.py", line 140, in handle_add_card
2022-11-10T16:19:29.027618648Z app[web.1]:     keep_trying(customer.add_card, self.cleaned_data.get('stripe_token'))
2022-11-10T16:19:29.027623555Z app[web.1]:   File "/app/payment/utils.py", line 201, in keep_trying
2022-11-10T16:19:29.027628293Z app[web.1]:     raise e
2022-11-10T16:19:29.027632781Z app[web.1]:   File "/app/payment/utils.py", line 191, in keep_trying
2022-11-10T16:19:29.027637462Z app[web.1]:     return func(
2022-11-10T16:19:29.027642075Z app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/djstripe/models/core.py", line 1046, in add_card
2022-11-10T16:19:29.027646922Z app[web.1]:     new_stripe_payment_method = stripe_customer.sources.create(source=source)
2022-11-10T16:19:29.027651690Z app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/stripe/api_resources/list_object.py", line 32, in create
2022-11-10T16:19:29.027678004Z app[web.1]:     return self._request(
2022-11-10T16:19:29.027683092Z app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/stripe/stripe_object.py", line 282, in _request
2022-11-10T16:19:29.027687712Z app[web.1]:     response, api_key = requestor.request(method_, url_, params, headers)
2022-11-10T16:19:29.027692248Z app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/stripe/api_requestor.py", line 122, in request
2022-11-10T16:19:29.027696801Z app[web.1]:     resp = self.interpret_response(rbody, rcode, rheaders)
2022-11-10T16:19:29.027733054Z app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/stripe/api_requestor.py", line 399, in interpret_response
2022-11-10T16:19:29.027741953Z app[web.1]:     self.handle_error_response(rbody, rcode, resp.data, rheaders)
2022-11-10T16:19:29.027746591Z app[web.1]:   File "/app/.heroku/python/lib/python3.10/site-packages/stripe/api_requestor.py", line 159, in handle_error_response
2022-11-10T16:19:29.027751156Z app[web.1]:     raise err
2022-11-10T16:19:29.027755574Z app[web.1]: stripe.error.InvalidRequestError: Request req_f1KnW7iEfL4nOZ: You cannot use a Stripe token more than once: tok_1M2dSxGRvRnAJwTxwzHQpKas.

There must have been something that changed between Djstripe 2.5 and 2.6. Our system seems to be hacked-together working for now, with lots of error catching and retrying, but our server logs are crammed with Webhook error messages every time anyone does anything stripe related.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Stripe API reference – Tokens – curl
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries....
Read more >
Save payment details during payment | Stripe Documentation
Use the Payment Intents API to save payment details from a purchase. There are several use cases: Charge a customer for an e-commerce...
Read more >
React Stripe.js reference | Stripe Documentation
js script and initializes a Stripe object. Pass the returned Promise to Elements . A Stripe object or a Promise resolving to a...
Read more >
Stripe JS Reference
This reference documents every object and method available in Stripe's browser-side JavaScript library, Stripe.js. Use our React Stripe.js reference if you ...
Read more >
Stripe Elements | Stripe Documentation
Stripe Elements is a set of prebuilt UI components for building your web checkout flow. It's available as a feature of Stripe.js, our...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found