WhyNotHugo / django-mercadopago

⚠️ Deprecated. Use https://github.com/jazzband/django-payments/ instead.
ISC License
33 stars 12 forks source link

Collection id is not always sent for view PaymentSuccessView(CSRFExemptMixin, View): #36

Open Dyend opened 3 years ago

Dyend commented 3 years ago

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).
WhyNotHugo commented 3 years ago

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

Dyend commented 2 years ago

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.