Odoo18-Base/addons/payment_mercado_pago/controllers/main.py
2025-01-06 10:57:38 +07: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.