Mercado Pago is the largest online payment platform in Latin America, supports more countries, currencies and payment methods in the region than other PSPs, and is more accessible to small businesses. This commit integrates Odoo with a combination of the Checkout Pro and Checkout API solutions of Mercado Pago to implement payments with redirection to the provider's payment page. Task - 2704764 Part-of: odoo/odoo#83957 Co-authored-by: Antoine Vandevenne (anv) <anv@odoo.com>
65 lines
3.0 KiB
Python
65 lines
3.0 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import logging
|
|
import pprint
|
|
|
|
from odoo import http
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.http import request
|
|
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class MercadoPagoController(http.Controller):
|
|
_return_url = '/payment/mercado_pago/return'
|
|
_webhook_url = '/payment/mercado_pago/webhook'
|
|
|
|
@http.route(_return_url, type='http', methods=['GET'], auth='public')
|
|
def mercado_pago_return_from_checkout(self, **data):
|
|
""" Process the notification data sent by Mercado Pago after redirection from checkout.
|
|
|
|
:param dict data: The notification data.
|
|
"""
|
|
# Handle the notification data.
|
|
_logger.info("Handling redirection from Mercado Pago with data:\n%s", pprint.pformat(data))
|
|
if data.get('payment_id') != 'null':
|
|
request.env['payment.transaction'].sudo()._handle_notification_data(
|
|
'mercado_pago', data
|
|
)
|
|
else: # The customer cancelled the payment by clicking on the return button.
|
|
pass # Don't try to process this case because the payment id was not provided.
|
|
|
|
# Redirect the user to the status page.
|
|
return request.redirect('/payment/status')
|
|
|
|
@http.route(
|
|
f'{_webhook_url}/<reference>', type='http', auth='public', methods=['POST'], csrf=False
|
|
)
|
|
def mercado_pago_webhook(self, reference, **_kwargs):
|
|
""" Process the notification data sent by Mercado Pago to the webhook.
|
|
|
|
:param str reference: The transaction reference embedded in the webhook URL.
|
|
:param dict _kwargs: The extra query parameters.
|
|
:return: An empty string to acknowledge the notification.
|
|
:rtype: str
|
|
"""
|
|
data = request.get_json_data()
|
|
_logger.info("Notification received from Mercado Pago with data:\n%s", pprint.pformat(data))
|
|
|
|
# Mercado Pago sends two types of asynchronous notifications: webhook notifications and
|
|
# IPNs which are very similar to webhook notifications but are sent later and contain less
|
|
# information. Therefore, we filter the notifications we receive based on the 'action'
|
|
# (type of event) key as it is not populated for IPNs, and we don't want to process the
|
|
# other types of events.
|
|
if data.get('action') in ('payment.created', 'payment.updated'):
|
|
# Handle the notification data.
|
|
try:
|
|
payment_id = data.get('data', {}).get('id')
|
|
request.env['payment.transaction'].sudo()._handle_notification_data(
|
|
'mercado_pago', {'external_reference': reference, 'payment_id': payment_id}
|
|
) # Use 'external_reference' as the reference key like in the redirect data.
|
|
except ValidationError: # Acknowledge the notification to avoid getting spammed.
|
|
_logger.exception("Unable to handle the notification data; skipping to acknowledge")
|
|
return '' # Acknowledge the notification.
|