• Модуль интеграций
  • Сообщество
  • Блог
Документация
Плагины и интеграцииВсе расширения для Medusa от сообществаСтартерыЗапускайте проекты быстрее с готовыми решениями
ЭкспертыПодберите специалиста для разработки и развития вашего проекта на MedusaКейсыПосмотрите примеры Medusa в продакшене и успешные внедрения
Представляем готовый к продакшену Medusa DTC Starter от Gorgo

26 августа 2026 г. · Продукт

Gorgo снижает затраты на адаптацию Medusa к локальным рынкам.

Мы разрабатываем плагины интеграции, осуществляем поддержку и развиваем сообщество разработчиков на Medusa в Telegram.

  • Ресурсы Medusa
  • Плагины и интеграции
  • Модуль интеграций
  • Стартеры
  • Эксперты
  • Кейсы
  • Medusa Чат в Telegram
  • Medusa Новости в Telegram
  • Документация Gorgo
  • Связаться с нами
  • TelegramGitHub
Плагины
R

Redsys

Плагин платёжного провайдера Redsys / Sermepa TPV Virtual для Medusa v2

npm install @jsm406/medusa-plugin-redsys
Категория
Платежи
Создано
Jsm406
Версия
1.1.4
Последнее обновление
4 недели назад
Ежемесячные загрузки
Загрузка данных
Звезды на Github
0
npmNPMGitHubGithub

@jsm406/medusa-plugin-redsys

Redsys / Sermepa TPV Virtual payment provider plugin for MedusaJS v2.

This plugin enables payment processing through Redsys' hosted payment page (TPV Virtual) via redirect flow. Customers are redirected to the Redsys secure payment page to complete their transaction.

Production-proven: This plugin is derived from a live production Medusa store processing real Redsys payments.

Features

  • Redsys hosted payment page / TPV Virtual redirect flow
  • Bizum mobile payment support via Redsys TPV
  • Sandbox and production environments
  • One-step payment (immediate capture) and two-step payment (pre-authorization + capture)
  • Full and partial refunds via Redsys API
  • Payment cancellation
  • Webhook handling with HMAC-SHA256 signature verification
  • Secure webhook correlation: a payment is only authorized after a valid, fully matching webhook (order, session, amount, currency, provider, merchant, terminal and transaction type)
  • Spanish error messages for Redsys response codes
  • Zero PCI scope — card data is handled by Redsys' secure page

Prerequisites

  • MedusaJS v2.13.0 or later
  • Node.js v20 or later
  • A Redsys merchant account (or sandbox test credentials)
  • v5.3.0+ (installed automatically as a dependency)
  • PostgreSQL (the plugin persists a table)

Installation

Configuration

Environment Variables

Add the following to your file:

For sandbox testing, use the following test credentials from Redsys:

Medusa Configuration

In your :

Enable in Region

Enable the Redsys provider(s) in your Medusa admin panel under Settings > Regions:

  • Credit/Debit Card: Select Redsys as a payment provider
    • Provider ID:
  • Bizum: Select Redsys Bizum as a payment provider
    • Provider ID:

You can enable one or both providers depending on which payment methods you want to offer.

Options

OptionTypeRequiredDefaultDescription
stringYes—Redsys HMAC-SHA256 secret key
stringYes—Redsys merchant code (FUC)
stringNoTerminal number
stringNo or
stringNo—Webhook URL for Redsys to POST transaction results
stringNo—URL to redirect after successful payment (URLOK)
stringNo—URL to redirect after failed payment (URLKO)
stringNo = immediate capture, = pre-authorization

Payment Flow

  1. Customer selects Redsys as payment method → Medusa creates a Payment Session ()
  2. generates a secure Redsys , records a payment reference ( ↔ payment session, amount, currency, merchant, terminal, transaction type) in the table, and creates a signed redirect form
  3. Customer clicks "Place Order" → the storefront saves in and auto-submits the redirect form to Redsys TPV. is NOT called here — no order is created before the payment exists
  4. Customer completes payment on the Redsys hosted payment page
  5. Redsys sends a webhook notification to
  6. verifies the HMAC signature and validates the order, session, amount, currency, provider, merchant, terminal and transaction type against the stored reference, then marks it as confirmed
  7. Medusa authorizes/captures the payment and completes the cart server-side, creating the order
  8. Redsys redirects the customer's browser to or with the Redsys order ID as a query parameter
  9. Storefront callback page reads the saved , retries if needed, and redirects to the order confirmation page

Security: authorizePayment Behavior

A payment session is only authorized after a valid HMAC-confirmed webhook that fully matches the stored payment reference. returns for any session whose reference is missing, not confirmed, or mismatched (amount, currency, session, provider, merchant or transaction type). It never trusts the stored field, so a — or even a forged — status can never authorize a payment on its own.

ID Mapping (Redsys → Medusa)

The plugin generates a 12-character alphanumeric (e.g. ) used as Redsys' merchant order reference. When the cart is completed after payment, Medusa generates its own order ID (e.g. ). These are different IDs.

The callback URL from Redsys only contains the Redsys order ID, not the Medusa order ID. To bridge this gap, the storefront stores the mapping → in before redirecting to the TPV. The callback page uses the to retrieve/complete the order and redirect to the correct confirmation page.

Storefront Integration

Redsys is a redirect-based payment method (no card input in your storefront — the customer enters card data on Redsys' secure TPV). You must adapt your Medusa Next.js storefront with the changes below.

Security: starting with v1.1.1 the storefront must not call before redirecting to Redsys. Doing so would fail anyway (the payment is not authorized yet) and previously created unpaid orders. The Redsys webhook completes the cart after the payment is confirmed.

1. — Register the payment methods

Add Redsys and Bizum to the payment info map and add helper functions:

2. Payment buttons and callback page

The full copyable implementation lives in . The two critical changes vs. older versions:

  • The payment buttons no longer call before redirecting to Redsys. They only store in under and submit the redirect form. The HMAC-confirmed webhook completes the cart server-side.
  • The callback page reads from the URL, recovers the , and retries with exponential backoff to bridge the race between the browser redirect and the webhook arrival.

3. — Bypass region redirect

If your storefront uses middleware to enforce region/country code prefixes in URLs (as the default Medusa Next.js storefront does), add a bypass so is not redirected. Add this early in the function:

4. — CORS

Ensure your storefront domain is allowed in CORS:

Session Data Reference

The payment session field returned by :

Note: The identifier in the callback URL is the value returned by the library and is normal. This does not indicate a problem — the actual signature computation follows the Redsys v4.1 specification.

Webhook

Medusa automatically exposes webhook endpoints for the Redsys providers at:

For local development with sandbox, you must expose your backend to the internet (e.g., via ngrok) so Redsys can reach the webhook. Set to the ngrok URL.

Important: Redsys sends the notification to but the signature verification and payment status update happens through the Medusa webhook handler — make sure points to the same endpoint or forward notifications accordingly.

Persistence:

The plugin creates and manages a small table to guarantee that only payments it initiated can ever be confirmed:

ColumnPurpose
Redsys order ID (primary key)
Real Medusa payment session ()
or
Medusa cart, if available
, , Expected amount/currency
, , Expected merchant/terminal/type
, , Set by the validated webhook

The table is created lazily with on first use, so no manual migration is required. A webhook can only confirm a payment that the plugin itself recorded in /, and only if every field matches.

Test Cards (Sandbox)

Card Payments

Card NumberBrandBehavior
4548810000000003VISA3DS v2 approved
5576441563045037Mastercard3DS v2 approved
4548814479727229VISA3DS frictionless
4548817212493017VISA3DS challenge
Any + CVV 999AnyPayment declined

Bizum (Sandbox)

Important: In sandbox, Bizum transactions cannot exceed 10€. Use a discount coupon or low-price test product.

FieldValue
Phone number
PIN
SMS code

Test scenarios by amount:

AmountResult
< 5€Payment approved
5€ - 10€Payment approved
10€ - 15€Payment declined (exceeds sandbox limit)
> 15€Payment declined (no Bizum user)

Transaction Types

CodeTypeDescription
PaymentAuthorization + immediate capture (default)
Pre-authorizationReserve funds only
ConfirmationCapture pre-authorized funds
RefundFull or partial refund
CancellationCancel/void a transaction

Security

  • Never log PAN, CVV, or the secret key. The provider strips sensitive fields from log output.
  • Always validate signatures server-side. uses 's , which verifies the HMAC signature before anything else.
  • The webhook is the only source of truth. A payment is authorized only when a valid webhook confirms a payment the plugin previously recorded, and the amount, currency, provider, merchant, terminal and transaction type all match. Reusing an old is impossible because each payment session gets its own reference.
  • Use HTTPS for all communication with Redsys.
  • Do not trust client-side payment data. The webhook with signature verification is the source of truth.
  • Amounts are normalized. is received in the smallest unit (e.g. ) and converted back to the main unit () before being passed to Medusa.
  • Unsupported currencies fail closed. An unknown currency throws instead of silently charging in EUR.
  • The redirect flow keeps you out of PCI scope — card data is handled by Redsys' secure page.

Upgrading from < 1.1.1

Sessions created before v1.1.1 do not carry a and have no payment reference, so they will not be authorized (fail-closed). Customers in the middle of a checkout will need to refresh / recreate their payment session. This is intentional: it is safer to reject than to authorize an unverified payment.

Currency Support

The plugin includes built-in numeric currency codes for all major currencies (see for the full list). Unsupported currencies are rejected with an error rather than silently falling back to EUR.

Development

Local Testing with a Medusa Project

License

MIT — see LICENSE file for details.

Version History

v1.1.2 (2026-08-31)

  • Fixed: Install-time peer dependency conflict — removed from (aligned with the official convention; only is required).

v1.1.1 (2026-08-31) — Security release

  • SECURITY: Never authorize a Redsys payment before an HMAC-confirmed webhook
  • SECURITY: Correlate webhooks with the real Medusa payment session ID () instead of an artificial ID
  • SECURITY: Validate order, amount, currency, provider, merchant, terminal and transaction type before confirming a webhook
  • SECURITY: Persist a payment reference () for every initiated payment, preventing reuse of previously confirmed s
  • SECURITY: Generate Redsys order IDs using cryptographic randomness instead of
  • SECURITY: Reject unsupported currencies instead of silently falling back to EUR
  • FIX: Normalize webhook amounts ( in cents → main unit) before passing them to Medusa
  • FIX: Return for preauthorizations and for immediate captures in webhook actions
  • FIX: Tighten Redsys response-code validation (4-digit payment codes 0000-0099, confirmation/refund 900, cancellation 400)
  • FIX: Make generate a fresh and keep MerchantData at fixed 3-position layout
  • FIX: Storefront flow no longer creates the order before the payment (see )

v1.1.0 (2026-06-16)

  • Added: Bizum payment method support via Redsys TPV
  • New provider with parameter
  • Full lifecycle support: initiate, authorize, capture, cancel, refund, webhook
  • Same configuration as card provider (can share credentials)
  • Separate webhook endpoint at

v1.0.12 (2026-05-13)

  • Fixed: Response code validation for payment authorization (codes 0-99), refunds/confirmations (code 900), cancellations (code 400)
  • Note: The in the callback URL is normal - it's the identifier returned by the redsys-es library. The actual HMAC computation follows Redsys v4.1 specification.

v1.0.0 (2025-05-05)

  • Initial release

Support

For issues and questions, please open an issue on GitHub.

Еще в этой категории

Посмотреть все
Платежи
Braintree logo

Braintree

От Lambda Curry

Поддержка платежей и 3D Secure через Braintree

Загрузка данных
GitHubnpm
Платежи
Pay. logo

Pay.

От Webbers

Принимайте кредитные карты, цифровые платежи и купи сейчас, плати потом

Загрузка данных
GitHubnpm
Платежи
Mollie logo

Mollie

От Variable Vic

Легко принимайте мультивалютные платежи через Mollie

Загрузка данных
GitHubnpm

Еще от этого автора

Посмотреть все
Другое
P

Product reviews

От Jsm406

Плагин отзывов о товарах для Medusa v2. Форк @lambdacurry/medusa-product-reviews с совместимостью с Zod v4 и Medusa 2.14+

Загрузка данных
GitHubnpm
1npm install @jsm406/medusa-plugin-redsys
2# or
3yarn add @jsm406/medusa-plugin-redsys
4# or
5pnpm add @jsm406/medusa-plugin-redsys
1REDSYS_SECRET_KEY=sq7Hj....
2REDSYS_MERCHANT_CODE=999008881
3REDSYS_TERMINAL=001
4REDSYS_ENVIRONMENT=sandbox
5REDSYS_NOTIFICATION_URL=https://your-api.com/hooks/payment/redsys_redsys
6REDSYS_SUCCESS_URL=https://your-store.com/checkout/redsys-callback
7REDSYS_ERROR_URL=https://your-store.com/checkout/redsys-callback?error=1
1Merchant Code: 999008881
2Terminal: 001
3Secret Key: sq7Hj.......
4Environment: sandbox
1import { defineConfig } from "@medusajs/framework/config"
2
3export default defineConfig({
4 modules: [
5 {
6 resolve: "@medusajs/medusa/payment",
7 options: {
8 providers: [
9 {
10 resolve: "@jsm406/medusa-plugin-redsys/providers/redsys",
11 id: "redsys",
12 options: {
13 secretKey: process.env.REDSYS_SECRET_KEY,
14 merchantCode: process.env.REDSYS_MERCHANT_CODE,
15 terminal: process.env.REDSYS_TERMINAL || "001",
16 environment:
17 process.env.REDSYS_ENVIRONMENT || "sandbox",
18 notificationUrl:
19 process.env.REDSYS_NOTIFICATION_URL,
20 successUrl: process.env.REDSYS_SUCCESS_URL,
21 errorUrl: process.env.REDSYS_ERROR_URL,
22 transactionType: "0", // "0" = immediate capture, "1" = pre-authorization
23 },
24 },
25 // Bizum provider (optional - uses same credentials)
26 {
27 resolve: "@jsm406/medusa-plugin-redsys/providers/redsys-bizum",
28 id: "redsys-bizum",
29 options: {
30 secretKey: process.env.REDSYS_SECRET_KEY,
31 merchantCode: process.env.REDSYS_MERCHANT_CODE,
32 terminal: process.env.REDSYS_TERMINAL || "001",
33 environment:
34 process.env.REDSYS_ENVIRONMENT || "sandbox",
35 notificationUrl:
36 process.env.REDSYS_BIZUM_NOTIFICATION_URL || process.env.REDSYS_NOTIFICATION_URL,
37 successUrl: process.env.REDSYS_SUCCESS_URL,
38 errorUrl: process.env.REDSYS_ERROR_URL,
39 transactionType: "0",
40 },
41 },
42 ],
43 },
44 },
45 ],
46})
1// Inside paymentInfoMap, add:
2pp_redsys_redsys: {
3 title: "Credit / Debit Card",
4 icon: <CreditCard />,
5},
6"pp_redsys-bizum_redsys-bizum": {
7 title: "Bizum",
8 icon: <Smartphone />,
9},
10
11// Add helper functions:
12export const isRedsys = (providerId?: string) => {
13 return providerId?.startsWith("pp_redsys_redsys") && !providerId?.includes("bizum")
14}
15
16export const isRedsysBizum = (providerId?: string) => {
17 return providerId?.startsWith("pp_redsys-bizum")
18}
1// Redsys callback URL — bypass region redirect
2if (request.nextUrl.pathname.startsWith("/checkout/redsys-callback")) {
3 return NextResponse.next()
4}
1projectConfig: {
2 http: {
3 storeCors: "http://localhost:8000,https://your-store.com",
4 },
5}
1{
2 orderId: "1234ABCD5678", // Redsys merchant order (12 chars, ^\d{4}[A-Z0-9]{8}$)
3 medusaSessionId: "payses_...", // Real Medusa payment session ID — never the Redsys order
4 cartId: "cart_...", // Optional
5 amount: "2550", // Smallest currency unit (cents)
6 currency: "978", // Redsys numeric currency code
7 status: "pending",
8 transactionType: "0",
9 merchantParams: "base64...", // Base64-encoded merchant parameters
10 signature: "hmac...", // HMAC-SHA256 signature
11 signatureVersion: "HMAC_SHA256_V1", // Version identifier returned by redsys-easy
12 formUrl: "https://sis-t.redsys.es:25443/sis/realizarPago"
13}
1/hooks/payment/redsys_redsys (Card payments)
2/hooks/payment/redsys-bizum_redsys-bizum (Bizum payments)
1# Install dependencies
2npm install
3
4# Build
5npm run build
6
7# Run tests
8npm test
9
10# Watch mode (for local plugin development)
11npm run dev
1# From your plugin directory
2npm run dev
3
4# In your Medusa project directory:
5npx medusa plugin:add ../path-to/@jsm406/medusa-plugin-redsys