[FIX] payment_mercado_pago: sanitarize tx reference in webhook url

Description of the issue/feature this PR addresses:
The webhook URLs used by MercadoPago are not sanitized and cause the payment to fail when the URL contains spaces or other non-ASCII characters.

Steps to reproduce the bug:
1. Instal the Argentine localization and configure "payment_mercado_pago" as the payment method (test or production).
2. Create an invoice and generate a payment link (the reference will be something like "FA-C 0001-000133444").
3. Initiate the payment process and it will generate an error in the last stage of payment (on the MercadoPago website).

- Mercadopago tests credentials TEST-4811719641145832-020115-c5caffc149634e3e9d72fde2b74544d8__LD_LA__-172837665
- Used payment methods: https://www.mercadopago.com.ar/developers/es/docs/checkout-api/additional-content/your-integrations/test/cards

- Credencial de test usada TEST-4811719641145832-020115-c5caffc149634e3e9d72fde2b74544d8__LD_LA__-172837665
- Metodo de pago usados: https://www.mercadopago.com.ar/developers/es/docs/checkout-api/additional-content/your-integrations/test/cards

Current behavior before PR:
Payment in MercadoPago cannot be confirmed when the reference contains spaces.

Desired behavior after PR is merged:
Payment in MercadoPago is confirmed even when the reference contains spaces.

Adhoc Ticket: 68591

closes odoo/odoo#148027

X-original-commit: 320b316df0a2c7df183f80db4a561ff5d1517e70
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
Martin Quinteros
2024-01-04 12:02:08 +00:00
parent f1a2fe43a4
commit 2f6b3a0ee0
2 changed files with 6 additions and 2 deletions
@@ -2,6 +2,7 @@
import logging
import pprint
from urllib.parse import quote as url_quote
from werkzeug import urls
@@ -58,8 +59,9 @@ class PaymentTransaction(models.Model):
"""
base_url = self.provider_id.get_base_url()
return_url = urls.url_join(base_url, MercadoPagoController._return_url)
sanitized_reference = url_quote(self.reference)
webhook_url = urls.url_join(
base_url, f'{MercadoPagoController._webhook_url}/{self.reference}'
base_url, f'{MercadoPagoController._webhook_url}/{sanitized_reference}'
) # Append the reference to identify the transaction from the webhook notification data.
# In the case where we are issuing a preference request in CLP or COP, we must ensure that
@@ -1,6 +1,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from unittest.mock import patch
from urllib.parse import quote as url_quote
from odoo.tests import tagged
from odoo.tools import mute_logger
@@ -19,6 +20,7 @@ class TestPaymentTransaction(MercadoPagoCommon, PaymentHttpCommon):
self.maxDiff = 10000 # Allow comparing large dicts.
return_url = self._build_url('/payment/mercado_pago/return')
webhook_url = self._build_url('/payment/mercado_pago/webhook')
sanitized_reference = url_quote(tx.reference)
self.assertDictEqual(request_payload, {
'auto_return': 'all',
'back_urls': {
@@ -33,7 +35,7 @@ class TestPaymentTransaction(MercadoPagoCommon, PaymentHttpCommon):
'title': tx.reference,
'unit_price': tx.amount,
}],
'notification_url': f'{webhook_url}/{tx.reference}',
'notification_url': f'{webhook_url}/{sanitized_reference}',
'payer': {
'address': {'street_name': tx.partner_address, 'zip_code': tx.partner_zip},
'email': tx.partner_email,