Files
odoo_source/addons/payment_ogone/controllers/main.py
T
Horacio Tellez 5badb3fca8 [IMP] payment(_*): normalize logs across all acquirers
The logs for payments contain the transaction reference whenever possible.
Before logs for transactions contained the reference or the id of the
transaction in an inconsitent way. No transactions are identified by
reference whenever possible.

The logs for payments for the same function on different acquirers should
have the same format. Same flow step for different acquirers had
information passed in different formats. Now at each step of a transaction
flow log messages have the same format regardless of the acquirer.

Overall the payment logs should have an uniform format. Hopefully
understanding log messages related to transactions should be easier, as
now log format is independent of the acquirer and transaction are easily
identified by reference.

Task - 2545450

closes odoo/odoo#79547

Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
2021-11-29 15:40:54 +00:00

83 lines
3.6 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import pprint
import re
import werkzeug
from odoo import _, http
from odoo.exceptions import ValidationError
from odoo.http import request
_logger = logging.getLogger(__name__)
class OgoneController(http.Controller):
_return_url = '/payment/ogone/return'
_backward_compatibility_urls = [
'/payment/ogone/accept', '/payment/ogone/test/accept',
'/payment/ogone/decline', '/payment/ogone/test/decline',
'/payment/ogone/exception', '/payment/ogone/test/exception',
'/payment/ogone/cancel', '/payment/ogone/test/cancel',
'/payment/ogone/validate/accept',
'/payment/ogone/validate/decline',
'/payment/ogone/validate/exception',
] # Facilitates the migration of users who registered the URLs in Ogone's backend prior to 14.3
@http.route(
[_return_url] + _backward_compatibility_urls, type='http', auth='public',
methods=['GET', 'POST'], csrf=False
) # 'GET' or 'POST' depending on the configuration in Ogone backend
def ogone_return_from_redirect(self, **feedback_data):
""" Process the data returned by Ogone after redirection to the Hosted Payment Page.
This route can also accept S2S notifications from Ogone if it is configured as a webhook in
Ogone's backend.
:param dict feedback_data: The feedback data
"""
# Check the source and integrity of the data
data = self._homogenize_data(feedback_data)
self._verify_signature(feedback_data, data)
# Handle the feedback data
_logger.info("handling redirection from Ogone with data:\n%s", pprint.pformat(data))
request.env['payment.transaction'].sudo()._handle_feedback_data('ogone', data)
return request.redirect('/payment/status')
def _homogenize_data(self, data):
""" Format keys to follow an homogenized convention inspired by Ogone Directlink API.
The keys received from Ogone APIs have inconsistent formatting and must be homogenized to
allow re-using the same methods. We reformat them to follow a unified nomenclature inspired
by DirectLink's order direct endpoint.
Formatting steps:
1) Uppercase key strings: 'Something' -> 'SOMETHING', 'something' -> 'SOMETHING'
2) Remove the prefix: 'CARD.SOMETHING' -> 'SOMETHING', 'ALIAS.SOMETHING' -> 'SOMETHING'
"""
return {re.sub(r'.*\.', '', k.upper()): v for k, v in data.items()}
def _verify_signature(self, sign_data, data):
""" Check that the signature computed from the feedback matches the received one.
:param dict sign_data: The original feedback data used to compute the signature
:param dict sign_data: The formatted feedback data used to find the tx and received sig
:return: None
:raise: ValidationError if the signatures don't match
"""
acquirer_sudo = request.env['payment.transaction'].sudo()._get_tx_from_feedback_data(
'ogone', data
).acquirer_id # Find the acquirer based on the transaction
received_signature = data.get('SHASIGN')
expected_signature = acquirer_sudo._ogone_generate_signature(sign_data)
if received_signature != expected_signature.upper():
raise ValidationError(
"Ogone: " + _(
"Received data with invalid signature. expected: %(exp)s ; received: %(rec)s ; "
"data:\n%(data)s",
exp=expected_signature, rec=received_signature, data=pprint.pformat(sign_data)
)
)