Files
odoo_source/addons/payment_mercado_pago/controllers/main.py
T
Horacio TellezandAntoine Vandevenne 15058b6739 [ADD] payment_mercado_pago: integrate with Mercado Pago
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>
2022-08-30 20:21:54 +02:00

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.