From 08e34c1426156ff5107e6ca55e895af10251a847 Mon Sep 17 00:00:00 2001 From: luis Date: Wed, 24 Jun 2026 11:49:41 +0200 Subject: [PATCH] add payment_redsys_preauth --- payment_redsys_preauth/README.rst | 133 +++++ payment_redsys_preauth/__init__.py | 4 + payment_redsys_preauth/__manifest__.py | 15 + .../controllers/__init__.py | 2 + payment_redsys_preauth/controllers/main.py | 29 ++ .../data/payment_redsys.xml | 26 + payment_redsys_preauth/models/__init__.py | 2 + .../models/payment_provider.py | 135 +++++ .../models/payment_transaction.py | 150 ++++++ payment_redsys_preauth/readme/CONFIGURE.rst | 54 ++ .../readme/CONTRIBUTORS.rst | 3 + payment_redsys_preauth/readme/DESCRIPTION.rst | 1 + payment_redsys_preauth/readme/INSTALL.rst | 0 payment_redsys_preauth/readme/ROADMAP.rst | 9 + .../static/description/icon.png | Bin 0 -> 27527 bytes .../static/description/index.html | 480 ++++++++++++++++++ payment_redsys_preauth/static/img/bizum.png | Bin 0 -> 4959 bytes .../static/src/img/redsys_icon.png | Bin 0 -> 11108 bytes 18 files changed, 1043 insertions(+) create mode 100644 payment_redsys_preauth/README.rst create mode 100644 payment_redsys_preauth/__init__.py create mode 100644 payment_redsys_preauth/__manifest__.py create mode 100644 payment_redsys_preauth/controllers/__init__.py create mode 100644 payment_redsys_preauth/controllers/main.py create mode 100644 payment_redsys_preauth/data/payment_redsys.xml create mode 100644 payment_redsys_preauth/models/__init__.py create mode 100644 payment_redsys_preauth/models/payment_provider.py create mode 100644 payment_redsys_preauth/models/payment_transaction.py create mode 100644 payment_redsys_preauth/readme/CONFIGURE.rst create mode 100644 payment_redsys_preauth/readme/CONTRIBUTORS.rst create mode 100644 payment_redsys_preauth/readme/DESCRIPTION.rst create mode 100644 payment_redsys_preauth/readme/INSTALL.rst create mode 100644 payment_redsys_preauth/readme/ROADMAP.rst create mode 100644 payment_redsys_preauth/static/description/icon.png create mode 100644 payment_redsys_preauth/static/description/index.html create mode 100644 payment_redsys_preauth/static/img/bizum.png create mode 100644 payment_redsys_preauth/static/src/img/redsys_icon.png diff --git a/payment_redsys_preauth/README.rst b/payment_redsys_preauth/README.rst new file mode 100644 index 0000000..8adcc75 --- /dev/null +++ b/payment_redsys_preauth/README.rst @@ -0,0 +1,133 @@ +=========================================== +Pasarela de pago Redsys con preautorización +=========================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:1eb9535d052a619aa545a383869076ca1dc1fade22746cb3fe13afa726c3e3a3 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-Criptomart%2Ffoodcoopbcn-lightgray.png?logo=github + :target: https://github.com/Criptomart/foodcoopbcn/tree/12.0/payment_redsys_preauth + :alt: Criptomart/foodcoopbcn + +|badge1| |badge2| |badge3| + +Este módulo añade la opción de pago a través de la pasarela de Redsys con preautorización con tarjeta bancaria. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Parámetros +~~~~~~~~~~ + +* **Nombre del comercio**: Indicaremos el nombre del comercio. + +* **Número de comercio (FUC)**: Indicaremos el número de comercio que + nuestra entidad nos ha comunicado. + +* **Clave secreta de encriptación**: Indicaremos la clave de encriptación + que tiene el comercio. + +* **Número de terminal**: Indicaremos el terminal del TPV. + +* **Tipo de firma**: Seleccionaremos el tipo de firma del comercio. + +* **Tipo de moneda**: Seleccionaremos la moneda de nuestro terminal TPV + (Normalmente EUR - Euros). + +* **Tipo de transacción**: Indicaremos el tipo de transacción, 1. + +* **Idioma TPV**: Indicaremos el idioma en el TPV. + +* **Método de pago**: Indicaremos que tipo de pago se debe aceptar, pago con + tarjeta, Bizum u otro de los disponibles. + +* **URL_OK/URL_KO**: Durante el proceso del pago, y una vez que + se muestra al cliente la pantalla con el resultado del mismo, es + posible redirigir su navegador a una URL para las transacciones + autorizadas y a otra si la transacción ha sido denegada. A éstas + se las denomina URL_OK y URL_KO, respectivamente. Se trata + de dos URLs que pueden ser proporcionadas por el comercio. + +* **Porcentaje de pago**: Indicar el porcentaje de pago que se permite, si + se deja a 0.0 se entiende 100%. + +Nota +~~~~ + +Se tiene que verificar la configuración del comercio en el +módulo de administración de Redsys, donde la opción “Parámetros en las +URLs” debe tener el valor “SI”. + +En caso de que exista más de una base de datos en la instalación, cuando la +pasarela de pago envía el formulario a "/payment/redsys/return" odoo no sabe +con que base de datos procesar esta información, por lo que hay que establecer +los parametros **dbfilter** y **dbname** en el archivo de configuración. + +Para mostrar simultáneamente en el comercio electrónico varios de los métodos +de pago que proporciona Redsys, como pago con tarjeta y Bizum por ejemplo, +debemos duplicar el medio de pago y escoger en el campo método de pago el que +corresponda en cada caso. + +En los pagos con preautorización, el titular del TPV deberá solicitar al banco su activación. + + +Known issues / Roadmap +====================== + +De acuerdo a los requisitos de Redsys, el tamaño máximo del número de pedido +resultante (``Ds_Order``) es de 12 caracteres. Este addon trunca dicho +dato en el comienzo de la transacción, con el resultado de que, aunque Redsys +la aceptará, no se finalizará el pedido pedido en Odoo al retornar y entregará +un Error 500 a Redsys. +Para evitar esto, es recomendable seleccionar secuencias de pedido que se +ajusten a esta limitación, en particular de 10 o menos caracteres, al ser la +referencia un número extendido a partir del pedido, que incluye un guion y un +número secuencial para posibles repeticiones de pago. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Criptomart + +Contributors +~~~~~~~~~~~~ + +* `Criptomart `_: + + * Santi Noreña + +Maintainers +~~~~~~~~~~~ + +This module is part of the `Criptomart/foodcoopbcn `_ project on GitHub. + +You are welcome to contribute. diff --git a/payment_redsys_preauth/__init__.py b/payment_redsys_preauth/__init__.py new file mode 100644 index 0000000..822e370 --- /dev/null +++ b/payment_redsys_preauth/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3 - See https://www.gnu.org/licenses/agpl-3.0.html + +from . import models +from . import controllers diff --git a/payment_redsys_preauth/__manifest__.py b/payment_redsys_preauth/__manifest__.py new file mode 100644 index 0000000..6b75ed6 --- /dev/null +++ b/payment_redsys_preauth/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2024 - 2025 Criptomart +{ + "name": "Pasarela de pago Redsys con preautorización", + "category": "Payment Acquirer", + "summary": "Payment Acquirer: Redsys Implementation with Preauthorization", + "version": "16.0.0.0.1", + "author": "Criptomart", + "website": "https://git.criptomart.net/foodcoopbcn", + "depends": ["payment_redsys","sale_order_invoice_amount"], + "data": [ + "data/payment_redsys.xml" + ], + "license": "AGPL-3", + "installable": True, +} diff --git a/payment_redsys_preauth/controllers/__init__.py b/payment_redsys_preauth/controllers/__init__.py new file mode 100644 index 0000000..8b6d05e --- /dev/null +++ b/payment_redsys_preauth/controllers/__init__.py @@ -0,0 +1,2 @@ + +from . import main diff --git a/payment_redsys_preauth/controllers/main.py b/payment_redsys_preauth/controllers/main.py new file mode 100644 index 0000000..63b03ee --- /dev/null +++ b/payment_redsys_preauth/controllers/main.py @@ -0,0 +1,29 @@ +# © 2024 - 2025 criptomart.net +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +import pprint + +from odoo import http +from odoo.http import request +from odoo.addons.payment_redsys.controllers.main import RedsysController + +_logger = logging.getLogger(__name__) + + + +class RedsysController(RedsysController): + _return_url = '/payment/redsys/return' + _cancel_url = '/payment/redsys/cancel' + _exception_url = '/payment/redsys/error' + _reject_url = '/payment/redsys/reject' + + + @http.route(['/payment/redsys/result/'], type='http', auth='public',methods=['GET'], website=True) + def redsys_result(self, page, **post): + _logger.info('________ Redsys return sync: %s -- %s', + pprint.pformat(post), page) + # double check + if post: + request.env['payment.transaction'].sudo()._handle_notification_data('redsys', post) + return request.redirect('/payment/status') diff --git a/payment_redsys_preauth/data/payment_redsys.xml b/payment_redsys_preauth/data/payment_redsys.xml new file mode 100644 index 0000000..e6b8db2 --- /dev/null +++ b/payment_redsys_preauth/data/payment_redsys.xml @@ -0,0 +1,26 @@ + + + + + + Redsys Preautorización + + redsys + + Bussines name + 8888888 + Bussines description + xxxxxxxxxxxx -- SHA256 + 001 + 1 + + You will be redirected to the Redsys payment gateway after clicking on the payment button.

]]>
+
+ + + Bizum + + + +
diff --git a/payment_redsys_preauth/models/__init__.py b/payment_redsys_preauth/models/__init__.py new file mode 100644 index 0000000..9afbccd --- /dev/null +++ b/payment_redsys_preauth/models/__init__.py @@ -0,0 +1,2 @@ +from . import payment_provider +from . import payment_transaction diff --git a/payment_redsys_preauth/models/payment_provider.py b/payment_redsys_preauth/models/payment_provider.py new file mode 100644 index 0000000..17ddf9f --- /dev/null +++ b/payment_redsys_preauth/models/payment_provider.py @@ -0,0 +1,135 @@ +# © 2024 - 2025 criptomart +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +import json +import pprint +import requests +import urllib + +from odoo import models, api, exceptions, fields +from odoo.addons.payment.models.payment_provider import ValidationError +from odoo.tools.float_utils import float_compare +from odoo.tools.translate import _ +import odoo.exceptions + +_logger = logging.getLogger(__name__) + + +class PaymentProvider(models.Model): + _inherit = 'payment.provider' + + @api.depends('code') + def _compute_feature_support_fields(self): + super()._compute_feature_support_fields() + self.update({ + 'support_manual_capture': 'partial', + }) + + def get_redsys_rest_urls(self, environment): + """ Redsys Rest URLs + """ + if environment == 'prod': + return { + 'redsys_rest_url': + 'https://sis.redsys.es/sis/rest/trataPeticionREST', + } + else: + # redsys no acepta preautorizaciones en test, pero puede que cambie... + return { + 'redsys_rest_url': + 'https://sis-t.redsys.es:25443/sis/rest/trataPeticionREST', + } + + def _prepare_merchant_parameters(self, tx_values): + base_url = self._get_website_url() + callback_url = "http://botiga.foodcoopbcn.cat" + values = { + "Ds_Sermepa_Url": self._redsys_get_api_url(), + "Ds_Merchant_Amount": str(int(round(tx_values["amount"] * 100))), + "Ds_Merchant_Currency": self.redsys_currency or "978", + "Ds_Merchant_Order": ( + tx_values["reference"] and tx_values["reference"][-12:] or False + ), + "Ds_Merchant_MerchantCode": ( + self.redsys_merchant_code and self.redsys_merchant_code[:9] + ), + "Ds_Merchant_Terminal": self.redsys_terminal or "1", + "Ds_Merchant_TransactionType": (self.redsys_transaction_type or "1"), + "Ds_Merchant_Titular": tx_values.get( + "billing_partner", self.env.user.partner_id + ).display_name[:60], + "Ds_Merchant_MerchantName": ( + self.redsys_merchant_name and self.redsys_merchant_name[:25] + ), + "Ds_Merchant_MerchantUrl": ( + "%s/payment/redsys/return" % (callback_url or base_url) + )[:250], + "Ds_Merchant_MerchantData": self.redsys_merchant_data or "", + "Ds_Merchant_ProductDescription": ( + self.redsys_merchant_description + and self.redsys_merchant_description[:125] + ), + "Ds_Merchant_ConsumerLanguage": (self.redsys_merchant_lang or "001"), + "Ds_Merchant_UrlOk": "%s/payment/redsys/result/redsys_result_ok" % base_url, + "Ds_Merchant_UrlKo": "%s/payment/redsys/result/redsys_result_ko" % base_url, + "Ds_Merchant_Paymethods": self.redsys_pay_method or "T", + } + return self._url_encode64(json.dumps(values)).decode("utf-8") + + def _prepare_s2s_merchant_parameters(self, tx_values): + values = { + 'Ds_Merchant_Amount': str(int(round(tx_values['amount'] * 100))), + 'Ds_Merchant_Currency': self.redsys_currency or '978', + 'Ds_Merchant_Order': ( + tx_values['reference'] and tx_values['reference'][-12:] or + False), + 'Ds_Merchant_MerchantCode': ( + self.redsys_merchant_code and + self.redsys_merchant_code[:9]), + 'Ds_Merchant_Terminal': self.redsys_terminal or '1', + } + if 'transaction_type' in tx_values: + values.update({'Ds_Merchant_TransactionType': tx_values['transaction_type']}) + else: + values.update({'Ds_Merchant_TransactionType': + (self.redsys_transaction_type or '2')}), + return self._url_encode64(json.dumps(values)) + + def redsys_s2s_create_transaction(self, values): + self.ensure_one() + redsys_values = dict() + merchant_parameters = self._prepare_s2s_merchant_parameters(values) + redsys_values.update({ + 'Ds_SignatureVersion': str(self.redsys_signature_version), + 'Ds_MerchantParameters': merchant_parameters, + 'Ds_Signature': self.sign_parameters( + self.redsys_secret_key, merchant_parameters), + }) + return redsys_values + + def redsys_send_s2s_msg(self, values): + toSend = self.redsys_s2s_create_transaction(values) + url = self.get_redsys_rest_urls('prod')['redsys_rest_url'] + _logger.info('Redsys: sending rest values:\n%s', pprint.pformat(toSend)) + try: + if toSend and url: + response = requests.post(url, data=toSend) + else: + raise exceptions.ValidationError('Error en los parámetros de la petición rest') + except requests.exceptions.RequestException as e: + _logger.error('Redsys: Error sending rest transaction %s:\n%s', values['reference'], str(e)) + return False + if response and response.status_code != 200: + _logger.error('Redsys: Error sending rest transaction %s: %s', values['reference'], response.status_code) + return False + _logger.info('Redsys: rest response:\n%s', pprint.pformat(response.text)) + try: + errorCheck = response.json() + if errorCheck.get('errorCode', ''): + _logger.error('Redsys: Error recibido tx %s: %s', values['reference'], errorCheck.get('errorCode')) + except json.JSONDecodeError: + _logger.error('Error al decodificar la respuesta JSON para la transacción %s', values['reference']) + return False + return errorCheck + diff --git a/payment_redsys_preauth/models/payment_transaction.py b/payment_redsys_preauth/models/payment_transaction.py new file mode 100644 index 0000000..d99c675 --- /dev/null +++ b/payment_redsys_preauth/models/payment_transaction.py @@ -0,0 +1,150 @@ +# © 2024 - 2025 criptomart +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +import json +import pprint +import requests + +from odoo import models, api, exceptions, fields +from odoo.addons.payment.models.payment_provider import ValidationError +from odoo.tools.float_utils import float_compare +from odoo.tools.translate import _ + + +_logger = logging.getLogger(__name__) + + +class TxRedsysPreAuth(models.Model): + _inherit = 'payment.transaction' + + def _get_specific_rendering_values(self, processing_values): + if self.provider_code != "redsys": + return super()._get_specific_rendering_values(processing_values) + redsys_values = dict(processing_values) + merchant_parameters = self.provider_id._prepare_merchant_parameters( + processing_values + ) + redsys_values.update( + { + "api_url": self.provider_id._redsys_get_api_url(), + "Ds_SignatureVersion": str(self.provider_id.redsys_signature_version), + "Ds_MerchantParameters": merchant_parameters, + "Ds_Signature": self.provider_id.sign_parameters( + self.provider_id.redsys_secret_key, merchant_parameters + ), + } + ) + return redsys_values + + # chequea que el usuario cancele el pago 9915. cambia el stado de done a authorized + @api.model + def _get_redsys_state(self, status_code): + if 0 <= status_code <= 100: + return "authorized" + elif status_code <= 203: + return "pending" + elif status_code == 400: + return "cancel" + elif status_code == 900: + return "done" + elif 912 <= status_code <= 9915: + return "cancel" + else: + return "error" + + def _process_notification_data(self, data): + if self.provider_code != "redsys": + return super()._process_notification_data(data) + params = self.merchant_params_json2dict(data) + status_code = int(params.get('Ds_Response', '29999')) + state = self._get_redsys_state(status_code) + vals = { + 'state': state, + 'redsys_txnid': params.get('Ds_AuthorisationCode'), + } + state_message = "" + feedback_error = False + if state == 'done': + vals['state_message'] = _('Ok: %s') % params.get('Ds_Response') + self._set_done() + self._finalize_post_processing() + if state == 'authorized': + vals['state_message'] = _('Auth Ok: %s') % params.get('Ds_Response') + self._set_authorized() + self._finalize_post_processing() + elif state == 'pending': # 'Payment error: code: %s.' + state_message = _("Redsys: feedback error: %s" %(status_code)) + self._set_pending() + elif state == 'cancel': # 'Payment error: bank unavailable.' + state_message = _("Redsys: feedback error: %s" %(status_code)) + self._set_canceled() + else: + state_message = _("Redsys: feedback error: %s" %(status_code)) + self._set_error(state_message) + feedback_error = True + if state_message: + vals['state_message'] = state_message % { + "status_code": params.get("Ds_Response"), + "error_code": params.get("Ds_ErrorCode"), + } + if state == 'error': + _logger.warning(vals['state_message']) + self.write(vals) + + def _send_capture_request(self, amount_to_capture=None): + self.ensure_one() + self._ensure_provider_is_not_disabled() + _logger.info('Redsys: Capturing transaction %s -- %s', self.reference, amount_to_capture) + try: + if amount_to_capture: + values = {'amount': amount_to_capture} + else: + values = {'amount': sum(order.invoiced_amount for order in self.sale_order_ids)} + values.update({'reference': self.reference}) + values.update({'transaction_type': '2'}) + response = self.provider_id.redsys_send_s2s_msg(values) + if not response: + raise exceptions.ValidationError('Error mandando mensaje rest'); + if response.get('errorCode', ''): + raise exceptions.ValidationError('Ref %s: Error Code %s' %(self.reference, response.get('errorCode'))) + params = self.merchant_params_json2dict(response) + _logger.info('Redsys: parameters received:\n%s', pprint.pformat(params)) + if params['Ds_Response'] == '0900' and params['Ds_Order'] == self.reference: + self.provider_reference = params['Ds_AuthorisationCode'] + self._set_done() + _logger.info('Confirmacion de preautorizacion realizada con exito para la transaccion %s', self.reference) + message = ('Preautorizacion confirmada') + self.sale_order_ids.message_post(body=message) + else: + raise exceptions.ValidationError('Error en confirmacion de preautorizacion tx: %s - %s', self.reference, params['Ds_Response']) + except Exception as e: + _logger.exception('Redsys: Error capturando preautorización transacción %s:\n%s', self.reference, str(e)) + raise exceptions.UserError(_('Error capturing preauthorization for transaction %s:\n%s') % (self.reference, str(e))) + + def _send_void_request(self, amount_to_void=None): + self.ensure_one() + self._ensure_provider_is_not_disabled() + _logger.info('Redsys: Preauthorization cancel for transaction %s', self.reference) + try: + if amount_to_void: + values = {'amount': amount_to_void} + else: + values = {'amount': self.amount} + values.update({'reference': self.reference}) + values.update({'transaction_type': '9'}) + response = self.provider_id.redsys_send_s2s_msg(values) + if not response: + raise exceptions.ValidationError(_('error redsys_s2s_msg')) + if response.get('errorCode', ''): + raise exceptions.ValidationError('Ref %s: Error Code %s' % (self.reference, response.get('errorCode'))) + params = self.merchant_params_json2dict(response) + _logger.info('Redsys: parameters received):\n%s', pprint.pformat(params)) + if params['Ds_Response'] == '0400' and params['Ds_Order'] == self.reference: + self._set_canceled() + _logger.info('Preautorización cancelada con éxito para la transacción %s', self.reference) + else: + raise exceptions.ValidationError('No se pudo cancelar la preautorización para la transacción %s - %s', self.reference, params['Ds_Response']) + except Exception as e: + _logger.exception('Redsys Error cancelando preautorización tx %s:\n%s', self.reference, str(e)) + raise exceptions.UserError(_('Error cancelling preauthorization for transaction %s:\n%s') % (self.reference, str(e))) diff --git a/payment_redsys_preauth/readme/CONFIGURE.rst b/payment_redsys_preauth/readme/CONFIGURE.rst new file mode 100644 index 0000000..f23c184 --- /dev/null +++ b/payment_redsys_preauth/readme/CONFIGURE.rst @@ -0,0 +1,54 @@ +Parámetros +~~~~~~~~~~ + +* **Nombre del comercio**: Indicaremos el nombre del comercio. + +* **Número de comercio (FUC)**: Indicaremos el número de comercio que + nuestra entidad nos ha comunicado. + +* **Clave secreta de encriptación**: Indicaremos la clave de encriptación + que tiene el comercio. + +* **Número de terminal**: Indicaremos el terminal del TPV. + +* **Tipo de firma**: Seleccionaremos el tipo de firma del comercio. + +* **Tipo de moneda**: Seleccionaremos la moneda de nuestro terminal TPV + (Normalmente EUR - Euros). + +* **Tipo de transacción**: Indicaremos el tipo de transacción, 1. + +* **Idioma TPV**: Indicaremos el idioma en el TPV. + +* **Método de pago**: Indicaremos que tipo de pago se debe aceptar, pago con + tarjeta, Bizum u otro de los disponibles. + +* **URL_OK/URL_KO**: Durante el proceso del pago, y una vez que + se muestra al cliente la pantalla con el resultado del mismo, es + posible redirigir su navegador a una URL para las transacciones + autorizadas y a otra si la transacción ha sido denegada. A éstas + se las denomina URL_OK y URL_KO, respectivamente. Se trata + de dos URLs que pueden ser proporcionadas por el comercio. + +* **Porcentaje de pago**: Indicar el porcentaje de pago que se permite, si + se deja a 0.0 se entiende 100%. + +Nota +~~~~ + +Se tiene que verificar la configuración del comercio en el +módulo de administración de Redsys, donde la opción “Parámetros en las +URLs” debe tener el valor “SI”. + +En caso de que exista más de una base de datos en la instalación, cuando la +pasarela de pago envía el formulario a "/payment/redsys/return" odoo no sabe +con que base de datos procesar esta información, por lo que hay que establecer +los parametros **dbfilter** y **dbname** en el archivo de configuración. + +Para mostrar simultáneamente en el comercio electrónico varios de los métodos +de pago que proporciona Redsys, como pago con tarjeta y Bizum por ejemplo, +debemos duplicar el medio de pago y escoger en el campo método de pago el que +corresponda en cada caso. + +En los pagos con preautorización, el titular del TPV deberá solicitar al banco su activación. + diff --git a/payment_redsys_preauth/readme/CONTRIBUTORS.rst b/payment_redsys_preauth/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..e466f95 --- /dev/null +++ b/payment_redsys_preauth/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Criptomart `_: + + * Santi Noreña diff --git a/payment_redsys_preauth/readme/DESCRIPTION.rst b/payment_redsys_preauth/readme/DESCRIPTION.rst new file mode 100644 index 0000000..2604a50 --- /dev/null +++ b/payment_redsys_preauth/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Este módulo añade la opción de pago a través de la pasarela de Redsys con preautorización con tarjeta bancaria. diff --git a/payment_redsys_preauth/readme/INSTALL.rst b/payment_redsys_preauth/readme/INSTALL.rst new file mode 100644 index 0000000..e69de29 diff --git a/payment_redsys_preauth/readme/ROADMAP.rst b/payment_redsys_preauth/readme/ROADMAP.rst new file mode 100644 index 0000000..78f45e5 --- /dev/null +++ b/payment_redsys_preauth/readme/ROADMAP.rst @@ -0,0 +1,9 @@ +De acuerdo a los requisitos de Redsys, el tamaño máximo del número de pedido +resultante (``Ds_Order``) es de 12 caracteres. Este addon trunca dicho +dato en el comienzo de la transacción, con el resultado de que, aunque Redsys +la aceptará, no se finalizará el pedido pedido en Odoo al retornar y entregará +un Error 500 a Redsys. +Para evitar esto, es recomendable seleccionar secuencias de pedido que se +ajusten a esta limitación, en particular de 10 o menos caracteres, al ser la +referencia un número extendido a partir del pedido, que incluye un guion y un +número secuencial para posibles repeticiones de pago. diff --git a/payment_redsys_preauth/static/description/icon.png b/payment_redsys_preauth/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b25df9b7a5cea2eacc0280c025f6d1a2f048874d GIT binary patch literal 27527 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 e|F2=4N!#o`bJVJEIDqS7SW1so + + + + +Pasarela de pago Redsys con preautorización + + + +
+

Pasarela de pago Redsys con preautorización

+ + +

Beta License: AGPL-3 Criptomart/foodcoopbcn

+

Este módulo añade la opción de pago a través de la pasarela de Redsys con preautorización con tarjeta bancaria.

+

Table of contents

+ +
+

Configuration

+
+

Parámetros

+
    +
  • Nombre del comercio: Indicaremos el nombre del comercio.
  • +
  • Número de comercio (FUC): Indicaremos el número de comercio que +nuestra entidad nos ha comunicado.
  • +
  • Clave secreta de encriptación: Indicaremos la clave de encriptación +que tiene el comercio.
  • +
  • Número de terminal: Indicaremos el terminal del TPV.
  • +
  • Tipo de firma: Seleccionaremos el tipo de firma del comercio.
  • +
  • Tipo de moneda: Seleccionaremos la moneda de nuestro terminal TPV +(Normalmente EUR - Euros).
  • +
  • Tipo de transacción: Indicaremos el tipo de transacción, 1.
  • +
  • Idioma TPV: Indicaremos el idioma en el TPV.
  • +
  • Método de pago: Indicaremos que tipo de pago se debe aceptar, pago con +tarjeta, Bizum u otro de los disponibles.
  • +
  • URL_OK/URL_KO: Durante el proceso del pago, y una vez que +se muestra al cliente la pantalla con el resultado del mismo, es +posible redirigir su navegador a una URL para las transacciones +autorizadas y a otra si la transacción ha sido denegada. A éstas +se las denomina URL_OK y URL_KO, respectivamente. Se trata +de dos URLs que pueden ser proporcionadas por el comercio.
  • +
  • Porcentaje de pago: Indicar el porcentaje de pago que se permite, si +se deja a 0.0 se entiende 100%.
  • +
+
+
+

Nota

+

Se tiene que verificar la configuración del comercio en el +módulo de administración de Redsys, donde la opción “Parámetros en las +URLs” debe tener el valor “SI”.

+

En caso de que exista más de una base de datos en la instalación, cuando la +pasarela de pago envía el formulario a “/payment/redsys/return” odoo no sabe +con que base de datos procesar esta información, por lo que hay que establecer +los parametros dbfilter y dbname en el archivo de configuración.

+

Para mostrar simultáneamente en el comercio electrónico varios de los métodos +de pago que proporciona Redsys, como pago con tarjeta y Bizum por ejemplo, +debemos duplicar el medio de pago y escoger en el campo método de pago el que +corresponda en cada caso.

+

En los pagos con preautorización, el titular del TPV deberá solicitar al banco su activación.

+
+
+
+

Known issues / Roadmap

+

De acuerdo a los requisitos de Redsys, el tamaño máximo del número de pedido +resultante (Ds_Order) es de 12 caracteres. Este addon trunca dicho +dato en el comienzo de la transacción, con el resultado de que, aunque Redsys +la aceptará, no se finalizará el pedido pedido en Odoo al retornar y entregará +un Error 500 a Redsys. +Para evitar esto, es recomendable seleccionar secuencias de pedido que se +ajusten a esta limitación, en particular de 10 o menos caracteres, al ser la +referencia un número extendido a partir del pedido, que incluye un guion y un +número secuencial para posibles repeticiones de pago.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Criptomart
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is part of the Criptomart/foodcoopbcn project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/payment_redsys_preauth/static/img/bizum.png b/payment_redsys_preauth/static/img/bizum.png new file mode 100644 index 0000000000000000000000000000000000000000..8af46a769ce8f2108322bdab641e084b39b1bb2e GIT binary patch literal 4959 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 literal 0 HcmV?d00001 diff --git a/payment_redsys_preauth/static/src/img/redsys_icon.png b/payment_redsys_preauth/static/src/img/redsys_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e9ddbae18a4b23b8ad990eb8147e43222dc184e7 GIT binary patch literal 11108 zcmV-qE1T4bP)hewb^C83Xd28J(NBN+ z(_e7A-D?0-f8YDw_o4gmzyBlc?d^VDzbtUGK?s3i7*thNd4s`VTTf3XR znYg86abXiX2{M7h^(;MIbAw(!=k3XyMLK6AW|-nZuZf`xV(9_}Tb0gvOpSosDA`ot z*jKicM3Z^O6Iqg(0!k^|E`tico2oK5UYCvnX0!IwIg3m|0*-(fnnsz|KoiVy$Lvr_ zA*C$+z6euAAo7D~laC?N$Dj~JsOGz z+{0hJXB%FZ!JmHnAcN5~LI{LX+_R&V`)^rODo?>y9POXv@mB^o*cD-DGD9j`Kq+vW zI^lqu4NXBlb;kx))|Q`B4+T7TVw4B>bTJ;!qKb8`F8A=6cW|auko7tcx^5%y^ zdDddruK{Zckv@u;e1!b?Be>Kk1`2^fq>rIIt5BZROt-KA4t7QOf6tyKn#?1FQ}|Eb zzMjTPKL<}oc=FXDQaK9%O%uH14J*+!fmDj#@f834`-j=}$^eCH|>kMu?P&9CfbFq%f!M2S#S*SLFoD~%O?ma460lD$YHxp+0(h_7gAH?79d1o2FsMLK6W zBQOwfn>1GVO6HHt(D=wLYxv`PH?y`rSbC>J2nLH~f9B}cbO?9Q0=WW4bN3wi# zPZuW!W9UVbqrJ9_U%SB>VUPztcnjb7 z#P!^LWi!5FR~AB0uq6*Z*Ub<2_W_D{rofkQ0Y8fdEYmAYT9 zVAD6AI%|}ns1JK7_n1(WE)*r5R^~Cet)qb}+benC$&>u^6DLd0&s&nyBXN`v9PEy; z|8xXRJF7>JoSEYH|K9-=j=`SI%hDi}%oI2_7~_hzv)y?qFy`vdi-LfT)-Y@9%Xz6M z3Ic{>8HiCbSl85-@&4=E(2B}i2#6-KbPmVQvA@>V2MKr#as`{`PL5F*^3YNh!0XZx zLLhC0$JA-6^ke86mUKp9T@%y=y-Xx>Jn&Q}@pPfo6BKZ4aEfDtQ)i1TM2Wn-EqU?O zIPciea!y(1!?H=9QV{mL*xV9!$m3j3Q2@7Ws;8yutQ({W!SG~;SUO+2PS-TrY69pQ z#4`o{;nCxaCbDd54za4XjBvn>l!~sg1Wz9wAzL(Ilv31&yj;DynwPsLN)0#-x1n9& zQc0yK6xD?QPL0HgX9`pVTub≧$%#Xo8(v>iOQj-gCSKDHUrP%K0xhti&i9!4!*p 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