Skip to content

Redsys

Redsys usa redirección por formulario: la librería genera los parámetros firmados con HMAC-SHA256 y sirve una página hospedada que los auto-envía por POST al TPV de Redsys. Tú solo rediriges el navegador al redirect_url de la respuesta. La confirmación llega por notificación online a tu merchant_url.

Configuración

ts
import { RedsysGateway } from '@kaizen/payments-gateway'

RedsysGateway.register({
  merchant_code: process.env.REDSYS_MERCHANT_CODE!,
  terminal: process.env.REDSYS_TERMINAL!,
  secret_key: process.env.REDSYS_SECRET_KEY!,
  environment: 'test',                       // 'test' | 'production'
  merchant_url: process.env.REDSYS_MERCHANT_URL!,
  merchant_name: 'Mi Tienda',                // opcional
})
CampoTipoRequeridoDescripción
merchant_codestringCódigo de comercio (FUC)
terminalstringNúmero de terminal
secret_keystringClave secreta para la firma HMAC-SHA256
environment'test' | 'production'Selecciona el endpoint del TPV
merchant_urlstringURL de notificación online (normalmente /webhooks/redsys)
merchant_namestringNombre del comercio mostrado en la pasarela

Endpoints del TPV

environmentURL
testhttps://sis-t.redsys.es:25443/sis/realizarPago
productionhttps://sis.redsys.es/sis/realizarPago

Variables de entorno

Los valores los aportas tú desde tu propio entorno y se los pasas a RedsysGateway.register():

ini
REDSYS_MERCHANT_CODE=999008881
REDSYS_TERMINAL=001
REDSYS_SECRET_KEY=sq7HjrUOBfKmC576ILgskD5srU870gJ7
REDSYS_ENVIRONMENT=test          # 'test' | 'production'
REDSYS_MERCHANT_URL=https://tu-dominio.com/webhooks/redsys
REDSYS_MERCHANT_NAME=Mi Tienda   # opcional
VariableCampoRequeridoDescripción
REDSYS_MERCHANT_CODEmerchant_codeCódigo de comercio (FUC)
REDSYS_TERMINALterminalNúmero de terminal
REDSYS_SECRET_KEYsecret_keyClave secreta para la firma HMAC-SHA256
REDSYS_ENVIRONMENTenvironmenttest o production (elige el endpoint)
REDSYS_MERCHANT_URLmerchant_urlURL de notificación online (/webhooks/redsys)
REDSYS_MERCHANT_NAMEmerchant_nameNombre del comercio mostrado en la pasarela

Crear un cobro

bash
curl -X POST http://localhost:3000/payments/charge \
  -H 'content-type: application/json' \
  -d '{
    "gateway": "redsys",
    "amount": 4900,
    "currency": "EUR",
    "reference": "pedido-001",
    "redirect": {
      "success_url": "http://localhost:3000/ok",
      "cancel_url": "http://localhost:3000/ko"
    }
  }'

Requisitos de Redsys

  • redirect.success_url y redirect.cancel_url son obligatorios (se mapean a DS_MERCHANT_URLOK / DS_MERCHANT_URLKO). Sin ellos → 400.
  • Solo se soporta moneda EUR (código 978). Otra moneda → 400.
  • amount va en céntimos (4900 = 49,00 €).

Cómo se paga

La respuesta tiene el mismo formato que el resto de pasarelas: un redirect_url al que rediriges el navegador.

json
{
  "payment_id": "b9c1…",
  "gateway": "redsys",
  "status": "pending",
  "redirect_url": "http://localhost:3000/payments/redsys/redirect/b9c1…"
}

A diferencia de Stripe o PayPal, ese redirect_url no apunta al TPV directamente, sino a una página que monta la propia librería (GET /payments/redsys/redirect/:payment_id). Al abrirla, esa página auto-envía por POST el formulario firmado al TPV de Redsys:

html
<form action="https://sis-t.redsys.es:25443/sis/realizarPago" method="post">
  <input type="hidden" name="Ds_SignatureVersion" value="HMAC_SHA256_V1" />
  <input type="hidden" name="Ds_MerchantParameters" value="…" />
  <input type="hidden" name="Ds_Signature" value="…" />
</form>

Tú no construyes ese formulario: la librería lo genera y lo sirve. Los parámetros del comercio se serializan a JSON, se codifican en Base64 y se firman con HMAC-SHA256 derivando la clave por número de pedido. Desde tu lado, el flujo es idéntico al de cualquier otra pasarela: redirige el navegador al redirect_url.

Notificación y confirmación

Redsys llama a tu merchant_url (→ POST /webhooks/redsys). La librería:

  1. Decodifica Ds_MerchantParameters (Base64 url-safe).
  2. Verifica la firma Ds_Signature contra el número de pedido. Inválida → 400.
  3. Lee Ds_Response:
    • 0–99 → pago capturado → emite payment.captured.
    • cualquier otro → fallido → emite payment.failed.

El gateway_ref que casa la notificación con el Payment es el número de pedido (Ds_Order), generado por la librería al crear el cobro.