From 2f6b3a0ee0224dc230b5278a8feed7ef58186e21 Mon Sep 17 00:00:00 2001 From: Martin Quinteros Date: Tue, 2 Jan 2024 12:32:38 -0300 Subject: [PATCH] [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) --- addons/payment_mercado_pago/models/payment_transaction.py | 4 +++- addons/payment_mercado_pago/tests/test_payment_transaction.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/payment_mercado_pago/models/payment_transaction.py b/addons/payment_mercado_pago/models/payment_transaction.py index 847e1fbb94c..5d6fd9e22f7 100644 --- a/addons/payment_mercado_pago/models/payment_transaction.py +++ b/addons/payment_mercado_pago/models/payment_transaction.py @@ -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 diff --git a/addons/payment_mercado_pago/tests/test_payment_transaction.py b/addons/payment_mercado_pago/tests/test_payment_transaction.py index 28e40935413..a92649d4443 100644 --- a/addons/payment_mercado_pago/tests/test_payment_transaction.py +++ b/addons/payment_mercado_pago/tests/test_payment_transaction.py @@ -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,