Skip to main content

A django app to emit and listen Redsys/Sermepa POS payments

Project description

Django sermepa es una aplicación muy al estilo de django-paypal para usar el TPV Virtual de Redsys/Sermepa, el TPV más usado en España.

Permite generar cobros puntuales, recurrentes por fichero o por referencia, y devoluciones.

La app tiene una vista que escucha las notificaciones del TPV (se debe pedir su activación a tu banco) y lanza signals para que sean procesadas por tu aplicación de cobros, para cambiar de estado el pedido, enviar emails de notificación…

Este fork implementa la versión 2.1 de Sermepa (SHA-256).

Versiones compatibles

  • Python: 3.8, 3.9, 3.10, 3.11, 3.12, 3.13

  • Django: 3.2, 4.0, 4.1, 4.2, 5.0, 5.1

Historial de versiones

  • 2.0.0: Soporte para Django 3.2 a 5.1 y Python 3.8 a 3.13. CI con GitHub Actions. Ver CHANGELOG.md para el detalle completo de cambios.

  • 1.1.5: Corrección de errores en form y mixin. Django 2.2 y Python 3.8.

  • 1.1.4: Corrección de errores de empaquetado, migraciones y readme. Django 1.11 y Python 3.6.

  • 1.1.3: Soporte django 1.4+ (probado en 1.4, 1.5, 1.6, 1.7).

  • 1.1.2: Compatible con python 2.7 y python 3.x.

Instalación

  1. Instala el proyecto usando pip:

    pip install django-sermepa-etxea

    O directamente desde GitHub:

    pip install git+https://github.com/Etxea/django-sermepa
  2. Añádelo a INSTALLED_APPS del settings.py:

INSTALLED_APPS += ('sermepa',)
  1. Aplica migraciones:

    python manage.py migrate

Configuración

  1. Añade los siguientes settings:

SERMEPA_URL_PRO = 'https://sis.redsys.es/sis/realizarPago'
SERMEPA_URL_TEST = 'https://sis-t.redsys.es:25443/sis/realizarPago'
SERMEPA_MERCHANT_CODE = '327234688'  # comercio de test
SERMEPA_TERMINAL = '002'
SERMEPA_SECRET_KEY = 'tu_clave_secreta_en_base64'
SERMEPA_CURRENCY = '978'  # Euros
SERMEPA_SIGNATURE_VERSION = 'HMAC_SHA256_V1'

Deberás modificar SERMEPA_MERCHANT_CODE, SERMEPA_SECRET_KEY, SERMEPA_TERMINAL con los datos proporcionados por tu banco.

  1. Añade la ruta de la respuesta de Sermepa a tus urls:

from django.urls import include, path

urlpatterns = [
    path('sermepa/', include('sermepa.urls')),
    # ...
]

Uso

  1. Programa los listeners de las signals de OK, KO y si quieres de error:

6.1 El listener recibe un objeto de tipo SermepaResponse con toda la información de la operación del TPV. Puedes usar un listener que procese todos los casos, o uno por cada caso (OK y KO):

def payment_ok(sender, **kwargs):
    '''sender es un objeto de clase SermepaResponse. Utiliza el campo Ds_MerchantData
    para asociarlo a tu Pedido o Carrito'''
    pedido = Pedido.objects.get(id=sender.Ds_MerchantData)
    pedido.estado = 'cobrado'
    pedido.Ds_AuthorisationCode = sender.Ds_AuthorisationCode
    pedido.save()
    send_email_success(pedido)

def payment_ko(sender, **kwargs):
    '''sender es un objeto de clase SermepaResponse'''
    pass

def sermepa_ipn_error(sender, **kwargs):
    '''Esta señal salta cuando el POST data recibido está mal firmado.'''
    pass

6.2 Asocia el listener a las señales, en algún punto que se cargue al iniciar el proyecto, por ejemplo en el models.py:

from sermepa.signals import payment_was_successful
from sermepa.signals import payment_was_error
from sermepa.signals import signature_error

payment_was_successful.connect(payment_ok)
payment_was_error.connect(payment_ko)
signature_error.connect(sermepa_ipn_error)
  1. Utiliza el form de SermepaPaymentForm para inicializar el botón de pago.

El botón de pago será un formulario POST a la url del TPV, firmado con tu clave secreta, que deberá pasar toda la información de la operación: modalidad de pago, importe (en céntimos), URLs de notificación, OK y KO, descripción, datos del comercio, identificador de tu pedido, identificador de la operación…

Existen diferentes modalidades de pago:

  1. Las compras puntuales, el Ds_Merchant_TransactionType=’0’ y el Ds_Merchant_Order debe ser un string siempre único y de 10 caracteres.

  2. Las suscripciones o pagos recurrentes. Existen 2 tipos, por fichero o por referencia.

2.1 Por fichero, tienen un límite de 12 meses o 12 cobros.

2.1.1 El primer cobro el Ds_Merchant_TransactionType=’L’ y el Ds_Merchant_Order debe ser siempre único.

El tpv responde con el mismo valor pasado en la variable Ds_Order más 2 dígitos adicionales indicando el número de transacción (la primera es 00)

2.1.2 Los cobros sucesivos se debe pasar el Ds_Merchant_TransactionType=’M’ y el primer Ds_Merchant_Order

2.2 Por referencia, no tiene límite de tiempo ni de cobros. Este sistema soporta cobros de 0€ para activaciones y cambios de tarjetas.

2.2.1 El primer cobro el Ds_Merchant_TransactionType=’0’ y el Ds_Merchant_Order=’REQUIRED’

El tpv responde con un nuevo parámetro Ds_Merchant_Identifier, que hay que almacenar (idreferencia)

2.2.2 Los cobros sucesivos son Ds_Merchant_TransactionType=’0’ y el Ds_Merchant_Order=idreferencia (el valor que nos han pasado en el primero cobro)

Mira el código del ejemplo (sermepa_test/views.py) para más info:

from django.shortcuts import render
from django.urls import reverse
from sermepa.forms import SermepaPaymentForm
from sermepa.models import SermepaIdTPV

def form(request, trans_type='0'):
    site = Site.objects.get_current()
    amount = int(5.50 * 100)  # El precio es en céntimos de euro

    sermepa_dict = {
        "Ds_Merchant_Titular": 'John Doe',
        "Ds_Merchant_MerchantData": 12345,
        "Ds_Merchant_MerchantName": 'ACME',
        "Ds_Merchant_ProductDescription": 'petardos',
        "Ds_Merchant_Amount": amount,
        "Ds_Merchant_Terminal": settings.SERMEPA_TERMINAL,
        "Ds_Merchant_MerchantCode": settings.SERMEPA_MERCHANT_CODE,
        "Ds_Merchant_Currency": settings.SERMEPA_CURRENCY,
        "Ds_Merchant_MerchantURL": "http://%s%s" % (site.domain, reverse('sermepa_ipn')),
        "Ds_Merchant_UrlOK": "http://%s%s" % (site.domain, reverse('end')),
        "Ds_Merchant_UrlKO": "http://%s%s" % (site.domain, reverse('end')),
        "Ds_Merchant_Order": SermepaIdTPV.objects.new_idtpv(),
        "Ds_Merchant_TransactionType": '0',
    }
    form = SermepaPaymentForm(merchant_parameters=sermepa_dict)

    return render(request, 'form.html', {'form': form, 'debug': settings.DEBUG})

y el form.html:

<html>
<body>
    {% if debug %}
        {{ form.sandbox }}
    {% else %}
        {{ form.render_form }}
    {% endif %}
</body>
</html>
  1. El TPV enviará una respuesta (SermepaResponse) con la información que se le ha enviado más nuevos datos relacionados con el pago. A destacar:

  • Ds_MerchantData es el mismo valor enviado en el formulario en el campo Ds_Merchant_MerchantData. Debería contener el identificador de tu Pedido o Carrito

  • Ds_Merchant_Identifier: la referencia para cobros recurrentes sucesivos si se utiliza el pago por referencia.

  • Ds_ExpiryDate: Fecha de expiración de la tarjeta

  • Ds_Card_Number: Número asteriscado de la tarjeta

  • Ds_AuthorisationCode: Código de la operación autorizada, para poder hacer una devolución posterior.

  1. Prueba el formulario de compra puntual en http://localhost:8000/ o http://localhost:8000/L/

Desarrollo

Ejecutar tests:

pip install pytest pytest-django
DJANGO_SETTINGS_MODULE=settings pytest sermepa/tests.py -v

Ejecutar tests en múltiples versiones con tox:

pip install tox
tox

Licencia

MIT License

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_sermepa_etxea-2.1.1.tar.gz (12.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_sermepa_etxea-2.1.1-py3-none-any.whl (14.0 kB view details)

Uploaded Python 3

File details

Details for the file django_sermepa_etxea-2.1.1.tar.gz.

File metadata

  • Download URL: django_sermepa_etxea-2.1.1.tar.gz
  • Upload date:
  • Size: 12.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_sermepa_etxea-2.1.1.tar.gz
Algorithm Hash digest
SHA256 87ee73c8fcdec4635415bf953390f7c690a6239adde067f0aaa5967116d6344b
MD5 e7c6ee4d10eded88948fc226a81e26bb
BLAKE2b-256 9be48d19f0457fb5f4d1a7c923b20120d08a12e43d90d544cf63658e322301c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_sermepa_etxea-2.1.1.tar.gz:

Publisher: publish.yml on etxea/django-sermepa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_sermepa_etxea-2.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_sermepa_etxea-2.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 097266782db3eaf3e2663ec2c3a350f6cd9a081b6d817e7c8b60e5eaa15b2078
MD5 ed956845bdd9c27ac7b8355f093a09ec
BLAKE2b-256 38e924ff34ae51717bb5666580661b5daf2e4153331c479664acbb4eed341572

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_sermepa_etxea-2.1.1-py3-none-any.whl:

Publisher: publish.yml on etxea/django-sermepa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page