django-mercadopago
django-mercadopago copied to clipboard
Collection id is not always sent for view PaymentSuccessView(CSRFExemptMixin, View):
This causes an exception when is not sent, here i will show an example with credit card payment and its json anwser
{
"collection_id": ["155448647"],
"collection_status": ["approved"],
"payment_id": ["155448647"],
"status": ["approved"],
"external_reference": ["orden-5"],
"payment_type": ["credit_card"],
"merchant_order_id": ["3125411900"],
"preference_id": ["-----------"],
"site_id": ["MLC"],
"processing_mode": ["aggregator"],
"merchant_account_id": ["null"]
}
here with debit card:
{
"payment_id": ["155448647"],
"payment_status": ["approved"],
"external_reference": ["orden-4"],
"payment_method_id": ["webpay"]
}
as we can see collection id is not sent with debit card payment, but payment_id yes and is the same id.
here is the exception :
Internal Server Error: /mercadopago/post_payment/orden-4
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 581, in get_or_create
return self.get(**kwargs), False
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 435, in get
raise self.model.DoesNotExist(
django_mercadopago.models.Notification.DoesNotExist: Notification matching query does not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.NotNullViolation: null value in column "resource_id" of relation "mp_notification" violates not-null constraint
DETAIL: Failing row contains (5, p, null, 2021-09-10 02:35:34.826117+00, 1, unp, 5).
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django_mercadopago/views.py", line 45, in dispatch
return super().dispatch(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django_mercadopago/views.py", line 93, in get
notification, created = _create_notification(
File "/usr/local/lib/python3.9/site-packages/django_mercadopago/views.py", line 27, in _create_notification
notification, created = Notification.objects.update_or_create(
File "/usr/local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 608, in update_or_create
obj, created = self.select_for_update().get_or_create(defaults, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 588, in get_or_create
return self.create(**params), True
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 453, in create
obj.save(force_insert=True, using=self.db)
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 763, in save_base
updated = self._save_table(
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 868, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 906, in _do_insert
return manager._insert(
File "/usr/local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 1270, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1416, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column "resource_id" of relation "mp_notification" violates not-null constraint
DETAIL: Failing row contains (5, p, null, 2021-09-10 02:35:34.826117+00, 1, unp, 5).
Hmmm, odd. I've never seen that happen (after thousands of orders).
"MLC" is "MercadoLibre Colombia", right? I wonder if it's a quirk (or bug?) that's only seen in that region.
I assume these are not the real numbers, right? It would make no sense that two different payments have the same id.
I guess the right thing to do would be to try using collection_id, and if that's missing, paymen_id. Should also fail if none of them is set:
https://github.com/WhyNotHugo/django-mercadopago/blob/984b952870d2254f75fdf080aa94b1033d024dff/django_mercadopago/views.py#L103
MLC is "mercado libre chile" and yes those are not real numbers. I asked on mercado pago support and their anwser was "the field payment_id will be always sent in payment notifications, however collection_id can change with integration type, for example can be order id in products that generate orders."
Right now i'm in production with my fork of this repo, i changed collection id with payment_id, and everything is working fine.
But maybe the best solution is what you said, so it wont dont break anything.