# -*- coding: utf-8 -*- ################################################################################# # # Copyright (c) 2015-Present Webkul Software Pvt. Ltd. () # ################################################################################# import re import logging import dateutil.parser import pytz from odoo import api, fields, models, _ from odoo.exceptions import ValidationError _logger = logging.getLogger(__name__) class AcquirerHyperPay(models.Model): _inherit = 'payment.acquirer' provider = fields.Selection(selection_add=[('hyperpay', 'HyperPay')], ondelete={'hyperpay': 'set default'}) hyperpay_authorization = fields.Char('Authorization', required_if_provider='hyperpay', groups='base.group_user', help='Authorization header with Bearer authentication scheme') hyperpay_merchant_id = fields.Char( 'Merchant Id', groups='base.group_user', help='The Merchant ID is required to authorize the request') def hyperpay_form_generate_values(self, values): hyperpay_tx_values = dict(values) if values.get('reference','/') != "/": tx = self.env['payment.transaction'].sudo().search([('reference', '=', values.get('reference'))]) hyperpay_tx_values.update({ "txId": tx.id }) return hyperpay_tx_values class HyperPayPaymentTransaction(models.Model): _inherit = 'payment.transaction' hyperpay_checkout_id = fields.Char('Checkout Id', groups='base.group_user', help='Unique checkout id for every hyper transasction') hyperpay_response_payload = fields.Text('Response Payload', help='Response payload from HyperPay') @api.model def _hyperpay_form_get_tx_from_data(self, data): reference, txn_id = data.get('ndc'), data.get('tx_id') if not reference or not txn_id: error_msg = _('HyperPay: received data with missing reference (%s) or txn_id (%s)') % (reference, txn_id) _logger.info(error_msg) raise ValidationError(error_msg) txs = self.env['payment.transaction'].search([('id', '=', int(txn_id))]) if not txs or len(txs) > 1: error_msg = 'HyperPay: received data for reference %s' % (reference) if not txs: error_msg += '; no order found' else: error_msg += '; multiple order found' _logger.info(error_msg) raise ValidationError(error_msg) return txs[0] def _hyperpay_form_validate(self, data): _logger.info('Validated HyperPay payment for tx %s: set as pending' % (self.reference)) result = data.get('result') result_code = result.get('code') res = { 'acquirer_reference': data.get('id'), 'state_message': result.get('description', '') } success_pattern = [ '^(000\.000\.|000\.100\.1|000\.[36])', '^(000\.400\.0[^3]|000\.400\.100)' ] pending_pattern = [ '^(000\.200)', '^(800\.400\.5|100\.400\.500)' ] if re.match(success_pattern[0], result_code) or re.match(success_pattern[1], result_code): date_validate = dateutil.parser.parse(data.get('timestamp')).astimezone(pytz.utc).replace(tzinfo=None) res.update(acquirer_reference=data.get('id'), date=date_validate) self._set_transaction_done() elif re.match(pending_pattern[0], result_code) or re.match(pending_pattern[1], result_code): self._set_transaction_pending() elif re.match('/^(000\.100\.2)/', result_code): self._set_transaction_error() else: error = 'Received unrecognized status for HyperPay payment %s: %s, set as error' % (self.reference, result_code) _logger.info(error) self._set_transaction_cancel() return self.write(res)