diff --git a/addons/account_payment/controllers/payment.py b/addons/account_payment/controllers/payment.py index ecd331d2d9c..7427d768dad 100644 --- a/addons/account_payment/controllers/payment.py +++ b/addons/account_payment/controllers/payment.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from werkzeug import url_encode - from odoo import http, _ +from odoo.addons.portal.controllers.portal import _build_url_w_params from odoo.http import request, route @@ -68,7 +67,7 @@ class PaymentPortal(http.Controller): invoice_sudo = request.env['account.invoice'].sudo().browse(invoice_id) if not invoice_sudo: params['error'] = 'pay_invoice_invalid_doc' - return request.redirect('%s?%s' % (error_url, url_encode(params))) + return request.redirect(_build_url_w_params(error_url, params)) try: token = request.env['payment.token'].sudo().browse(int(pm_id)) @@ -76,7 +75,7 @@ class PaymentPortal(http.Controller): token = False if not token: params['error'] = 'pay_invoice_invalid_token' - return request.redirect('%s?%s' % (error_url, url_encode(params))) + return request.redirect(_build_url_w_params(error_url, params)) # find an existing tx or create a new one tx = request.env['payment.transaction'].sudo()._check_or_create_invoice_tx( @@ -97,7 +96,7 @@ class PaymentPortal(http.Controller): res = tx.confirm_invoice_token() if res is not True: params['error'] = res - return request.redirect('%s?%s' % (error_url, url_encode(params))) + return request.redirect(_build_url_w_params(error_url, params)) params['success'] = 'pay_invoice' - return request.redirect('%s?%s' % (success_url, url_encode(params))) + return request.redirect(_build_url_w_params(success_url, params)) diff --git a/addons/portal/controllers/portal.py b/addons/portal/controllers/portal.py index 14edafba7b3..e107517b210 100644 --- a/addons/portal/controllers/portal.py +++ b/addons/portal/controllers/portal.py @@ -83,6 +83,24 @@ def get_records_pager(ids, current): return {} +def _build_url_w_params(url_string, query_params, remove_duplicates=True): + """ Rebuild a string url based on url_string and correctly compute query parameters + using those present in the url and those given by query_params. Having duplicates in + the final url is optional. For example: + + * url_string = '/my?foo=bar&error=pay' + * query_params = {'foo': 'bar2', 'alice': 'bob'} + * if remove duplicates: result = '/my?foo=bar2&error=pay&alice=bob' + * else: result = '/my?foo=bar&foo=bar2&error=pay&alice=bob' + """ + url = urls.url_parse(url_string) + url_params = url.decode_query() + if remove_duplicates: # convert to standard dict instead of werkzeug multidict to remove duplicates automatically + url_params = url_params.to_dict() + url_params.update(query_params) + return url.replace(query=urls.url_encode(url_params)).to_url() + + class CustomerPortal(Controller): MANDATORY_BILLING_FIELDS = ["name", "phone", "email", "street", "city", "country_id"] diff --git a/addons/sale_payment/controllers/payment.py b/addons/sale_payment/controllers/payment.py index 7487b1b6ba9..5183e8c58e1 100644 --- a/addons/sale_payment/controllers/payment.py +++ b/addons/sale_payment/controllers/payment.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from werkzeug import url_encode - from odoo import http, _ +from odoo.addons.portal.controllers.portal import _build_url_w_params from odoo.http import request, route @@ -68,7 +67,7 @@ class PaymentPortal(http.Controller): order_sudo = request.env['sale.order'].sudo().browse(order_id) if not order_sudo: params['error'] = 'pay_sale_invalid_doc' - return request.redirect('%s?%s' % (error_url, url_encode(params))) + return request.redirect(_build_url_w_params(error_url, params)) try: token = request.env['payment.token'].sudo().browse(int(pm_id)) @@ -76,7 +75,7 @@ class PaymentPortal(http.Controller): token = False if not token: params['error'] = 'pay_sale_invalid_token' - return request.redirect('%s?%s' % (error_url, url_encode(params))) + return request.redirect(_build_url_w_params(error_url, params)) # find an existing tx or create a new one tx = request.env['payment.transaction'].sudo()._check_or_create_sale_tx( @@ -97,7 +96,7 @@ class PaymentPortal(http.Controller): res = tx.confirm_sale_token() if res is not True: params['error'] = res - return request.redirect('%s?%s' % (error_url, url_encode(params))) + return request.redirect(_build_url_w_params(error_url, params)) params['success'] = 'pay_sale' - return request.redirect('%s?%s' % (success_url, url_encode(params))) + return request.redirect(_build_url_w_params(success_url, params))