@jsm406/medusa-plugin-redsys 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/providers/redsys/service.js +1 -9
- package/README.md +514 -497
- package/package.json +1 -1
|
@@ -78,14 +78,6 @@ class RedsysProviderService extends utils_1.AbstractPaymentProvider {
|
|
|
78
78
|
}
|
|
79
79
|
// ---------- Authorize ----------
|
|
80
80
|
async authorizePayment(input) {
|
|
81
|
-
const sessionData = input.data;
|
|
82
|
-
if (sessionData?.status === "authorized" ||
|
|
83
|
-
sessionData?.status === "pending") {
|
|
84
|
-
return {
|
|
85
|
-
status: utils_1.PaymentSessionStatus.AUTHORIZED,
|
|
86
|
-
data: input.data,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
81
|
return {
|
|
90
82
|
status: utils_1.PaymentSessionStatus.PENDING,
|
|
91
83
|
data: input.data,
|
|
@@ -328,4 +320,4 @@ class RedsysProviderService extends utils_1.AbstractPaymentProvider {
|
|
|
328
320
|
}
|
|
329
321
|
RedsysProviderService.identifier = "redsys";
|
|
330
322
|
exports.default = RedsysProviderService;
|
|
331
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcmVkc3lzL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxxREFLa0M7QUFDbEMsNkNBQTRFO0FBOEI1RSwrQ0FBb0Q7QUFDcEQsbURBQXFEO0FBQ3JELG1EQUFzRDtBQUN0RCwrQ0FBb0Q7QUFNcEQsTUFBTSxRQUFRLEdBQUc7SUFDZixRQUFRLEVBQUUsS0FBSztJQUNmLGVBQWUsRUFBRSxHQUFHO0NBQ1osQ0FBQTtBQUVWLE1BQU0scUJBQXNCLFNBQVEsK0JBQXNDO0lBT3hFLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBZ0M7UUFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksT0FBTyxPQUFPLENBQUMsU0FBUyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ2hFLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG1EQUFtRCxDQUNwRCxDQUFBO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxJQUFJLE9BQU8sT0FBTyxDQUFDLFlBQVksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN0RSxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixzREFBc0QsQ0FDdkQsQ0FBQTtRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBWSxTQUErQixFQUFFLE9BQXNCO1FBQ2pFLEtBQUssQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFBO1FBRXZCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBQSw2QkFBZSxFQUFDO1lBQy9CLFNBQVMsRUFBRSxPQUFPLENBQUMs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
|
|
323
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcmVkc3lzL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxxREFLa0M7QUFDbEMsNkNBQTRFO0FBOEI1RSwrQ0FBb0Q7QUFDcEQsbURBQXFEO0FBQ3JELG1EQUFzRDtBQUN0RCwrQ0FBb0Q7QUFNcEQsTUFBTSxRQUFRLEdBQUc7SUFDZixRQUFRLEVBQUUsS0FBSztJQUNmLGVBQWUsRUFBRSxHQUFHO0NBQ1osQ0FBQTtBQUVWLE1BQU0scUJBQXNCLFNBQVEsK0JBQXNDO0lBT3hFLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBZ0M7UUFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksT0FBTyxPQUFPLENBQUMsU0FBUyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ2hFLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG1EQUFtRCxDQUNwRCxDQUFBO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxJQUFJLE9BQU8sT0FBTyxDQUFDLFlBQVksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN0RSxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixzREFBc0QsQ0FDdkQsQ0FBQTtRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBWSxTQUErQixFQUFFLE9BQXNCO1FBQ2pFLEtBQUssQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFBO1FBRXZCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBQSw2QkFBZSxFQUFDO1lBQy9CLFNBQVMsRUFBRSxPQUFPLENBQUMs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
|
package/README.md
CHANGED
|
@@ -1,497 +1,514 @@
|
|
|
1
|
-
# medusa-
|
|
2
|
-
|
|
3
|
-
Redsys / Sermepa TPV Virtual payment provider plugin for [MedusaJS v2](https://medusajs.com/).
|
|
4
|
-
|
|
5
|
-
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.
|
|
6
|
-
|
|
7
|
-
> **Production-proven**: This plugin is derived from a live production Medusa store processing real Redsys payments.
|
|
8
|
-
|
|
9
|
-
## Features
|
|
10
|
-
|
|
11
|
-
- Redsys hosted payment page / TPV Virtual redirect flow
|
|
12
|
-
- Sandbox and production environments
|
|
13
|
-
- One-step payment (immediate capture) and two-step payment (pre-authorization + capture)
|
|
14
|
-
- Full and partial refunds via Redsys API
|
|
15
|
-
- Payment cancellation
|
|
16
|
-
- Webhook handling with HMAC-SHA256 signature verification
|
|
17
|
-
- Spanish error messages for Redsys response codes
|
|
18
|
-
- Zero PCI scope — card data is handled by Redsys' secure page
|
|
19
|
-
|
|
20
|
-
## Prerequisites
|
|
21
|
-
|
|
22
|
-
- MedusaJS v2.13.0 or later
|
|
23
|
-
- Node.js v20 or later
|
|
24
|
-
- A [Redsys merchant account](https://comercios.redsys.es/) (or sandbox test credentials)
|
|
25
|
-
- `redsys-easy` v5.3.0+ (installed automatically as a dependency)
|
|
26
|
-
|
|
27
|
-
## Installation
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npm install medusa-
|
|
31
|
-
# or
|
|
32
|
-
yarn add medusa-
|
|
33
|
-
# or
|
|
34
|
-
pnpm add medusa-
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Configuration
|
|
38
|
-
|
|
39
|
-
### Environment Variables
|
|
40
|
-
|
|
41
|
-
Add the following to your `.env` file:
|
|
42
|
-
|
|
43
|
-
```env
|
|
44
|
-
REDSYS_SECRET_KEY=sq7Hj....
|
|
45
|
-
REDSYS_MERCHANT_CODE=999008881
|
|
46
|
-
REDSYS_TERMINAL=001
|
|
47
|
-
REDSYS_ENVIRONMENT=sandbox
|
|
48
|
-
REDSYS_NOTIFICATION_URL=https://your-api.com/hooks/payment/redsys_redsys
|
|
49
|
-
REDSYS_SUCCESS_URL=https://your-store.com/checkout/redsys-callback
|
|
50
|
-
REDSYS_ERROR_URL=https://your-store.com/checkout/redsys-callback?error=1
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
For sandbox testing, use the following test credentials from Redsys:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
Merchant Code: 999008881
|
|
57
|
-
Terminal: 001
|
|
58
|
-
Secret Key: sq7Hj.......
|
|
59
|
-
Environment: sandbox
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Medusa Configuration
|
|
63
|
-
|
|
64
|
-
In your `medusa-config.ts`:
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
import { defineConfig } from "@medusajs/framework/config"
|
|
68
|
-
|
|
69
|
-
export default defineConfig({
|
|
70
|
-
modules: [
|
|
71
|
-
{
|
|
72
|
-
resolve: "@medusajs/medusa/payment",
|
|
73
|
-
options: {
|
|
74
|
-
providers: [
|
|
75
|
-
{
|
|
76
|
-
resolve: "medusa-
|
|
77
|
-
id: "redsys",
|
|
78
|
-
options: {
|
|
79
|
-
secretKey: process.env.REDSYS_SECRET_KEY,
|
|
80
|
-
merchantCode: process.env.REDSYS_MERCHANT_CODE,
|
|
81
|
-
terminal: process.env.REDSYS_TERMINAL || "001",
|
|
82
|
-
environment:
|
|
83
|
-
process.env.REDSYS_ENVIRONMENT || "sandbox",
|
|
84
|
-
notificationUrl:
|
|
85
|
-
process.env.REDSYS_NOTIFICATION_URL,
|
|
86
|
-
successUrl: process.env.REDSYS_SUCCESS_URL,
|
|
87
|
-
errorUrl: process.env.REDSYS_ERROR_URL,
|
|
88
|
-
transactionType: "0", // "0" = immediate capture, "1" = pre-authorization
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
],
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
],
|
|
95
|
-
})
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Enable in Region
|
|
99
|
-
|
|
100
|
-
Enable the Redsys provider in your Medusa admin panel under **Settings > Regions** and select **Redsys** as a payment provider.
|
|
101
|
-
|
|
102
|
-
The provider ID will be:
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
pp_redsys_redsys
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Options
|
|
109
|
-
|
|
110
|
-
| Option | Type | Required | Default | Description |
|
|
111
|
-
|---|---|---|---|---|
|
|
112
|
-
| `secretKey` | string | Yes | — | Redsys HMAC-SHA256 secret key |
|
|
113
|
-
| `merchantCode` | string | Yes | — | Redsys merchant code (FUC) |
|
|
114
|
-
| `terminal` | string | No | `"001"` | Terminal number |
|
|
115
|
-
| `environment` | string | No | `"sandbox"` | `"sandbox"` or `"production"` |
|
|
116
|
-
| `notificationUrl` | string | No | — | Webhook URL for Redsys to POST transaction results |
|
|
117
|
-
| `successUrl` | string | No | — | URL to redirect after successful payment (URLOK) |
|
|
118
|
-
| `errorUrl` | string | No | — | URL to redirect after failed payment (URLKO) |
|
|
119
|
-
| `transactionType` | string | No | `"0"` | `"0"` = immediate capture, `"1"` = pre-authorization |
|
|
120
|
-
|
|
121
|
-
## Payment Flow
|
|
122
|
-
|
|
123
|
-
1. Customer selects **Redsys** as payment method
|
|
124
|
-
2. `initiatePayment()` creates a signed redirect form with Redsys merchant parameters
|
|
125
|
-
3. Customer clicks "Place Order" → storefront calls `cart.complete()` to create the order, stores a cookie mapping the Redsys internal order ID to the Medusa order ID, then auto-submits the redirect form to Redsys TPV
|
|
126
|
-
4. Customer completes payment on the Redsys hosted payment page
|
|
127
|
-
5. Redsys sends a **webhook notification** to `{backendUrl}/hooks/payment/redsys_redsys`
|
|
128
|
-
6. `getWebhookActionAndData()` validates the HMAC-SHA256 signature and updates the payment status
|
|
129
|
-
7. Redsys redirects the customer's browser to `successUrl` or `errorUrl` with the Redsys order ID as a query parameter
|
|
130
|
-
8. Storefront callback page reads the
|
|
131
|
-
|
|
132
|
-
### Important: authorizePayment Behavior
|
|
133
|
-
|
|
134
|
-
This plugin's `authorizePayment` returns `AUTHORIZED` for sessions with status `"pending"` **and** `"authorized"`. This is intentional for the redirect flow: the real authorization happens on Redsys TPV and is confirmed via webhook. Without this, `cart.complete()` would fail with a 400 error because Medusa requires the payment session to be authorized before completing the cart.
|
|
135
|
-
|
|
136
|
-
### ID Mapping (Redsys → Medusa)
|
|
137
|
-
|
|
138
|
-
The plugin generates a 12-character alphanumeric `orderId` (e.g. `97727XYIWRRF`) used as Redsys' merchant order reference. When the order is completed via `cart.complete()`, Medusa generates its own order ID (e.g. `order_01KR3B4X...`). These are **different IDs**.
|
|
139
|
-
|
|
140
|
-
The callback URL from Redsys only contains the Redsys order ID, not the Medusa order ID. To bridge this gap, the storefront stores
|
|
141
|
-
|
|
142
|
-
## Storefront Integration
|
|
143
|
-
|
|
144
|
-
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.
|
|
145
|
-
|
|
146
|
-
### 1. `src/lib/constants.tsx` — Register the payment method
|
|
147
|
-
|
|
148
|
-
Add Redsys to the payment info map and add a helper function:
|
|
149
|
-
|
|
150
|
-
```tsx
|
|
151
|
-
// Inside paymentInfoMap, add:
|
|
152
|
-
pp_redsys_redsys: {
|
|
153
|
-
title: "Credit / Debit Card",
|
|
154
|
-
icon: <CreditCard />,
|
|
155
|
-
},
|
|
156
|
-
|
|
157
|
-
// Add helper function:
|
|
158
|
-
export const isRedsys = (providerId?: string) => {
|
|
159
|
-
return providerId?.startsWith("pp_redsys_")
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### 2. `src/lib/data/cart.ts` — Add order completion without redirect
|
|
164
|
-
|
|
165
|
-
Add a `completeCartWithoutRedirect` function. The standard `placeOrder` does a `redirect()` (server-side), but Redsys needs to redirect the browser to the TPV instead. This function completes the cart, creates the order, but returns the result so the client can handle the TPV redirect:
|
|
166
|
-
|
|
167
|
-
```ts
|
|
168
|
-
export async function completeCartWithoutRedirect(cartId?: string) {
|
|
169
|
-
const id = cartId || (await getCartId())
|
|
170
|
-
|
|
171
|
-
if (!id) {
|
|
172
|
-
throw new Error("No existing cart found when completing cart")
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const headers = {
|
|
176
|
-
...(await getAuthHeaders()),
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const cartRes = await sdk.store.cart
|
|
180
|
-
.complete(id, {}, headers)
|
|
181
|
-
.then(async (cartRes) => {
|
|
182
|
-
const cartCacheTag = await getCacheTag("carts")
|
|
183
|
-
revalidateTag(cartCacheTag)
|
|
184
|
-
return cartRes
|
|
185
|
-
})
|
|
186
|
-
.catch(medusaError)
|
|
187
|
-
|
|
188
|
-
if (cartRes?.type === "order") {
|
|
189
|
-
const orderCacheTag = await getCacheTag("orders")
|
|
190
|
-
revalidateTag(orderCacheTag)
|
|
191
|
-
removeCartId()
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return cartRes
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### 3. `src/modules/checkout/components/payment-button/index.tsx` — Redsys payment button
|
|
199
|
-
|
|
200
|
-
Add a `RedsysPaymentButton` component that:
|
|
201
|
-
1. Reads the payment session data (formUrl, merchantParams, signature) from the cart
|
|
202
|
-
2. Calls `completeCartWithoutRedirect()` to create the order
|
|
203
|
-
3. Stores
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
import {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const [
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
//
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
input
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
1
|
+
# @jsm406/medusa-plugin-redsys
|
|
2
|
+
|
|
3
|
+
Redsys / Sermepa TPV Virtual payment provider plugin for [MedusaJS v2](https://medusajs.com/).
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
> **Production-proven**: This plugin is derived from a live production Medusa store processing real Redsys payments.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Redsys hosted payment page / TPV Virtual redirect flow
|
|
12
|
+
- Sandbox and production environments
|
|
13
|
+
- One-step payment (immediate capture) and two-step payment (pre-authorization + capture)
|
|
14
|
+
- Full and partial refunds via Redsys API
|
|
15
|
+
- Payment cancellation
|
|
16
|
+
- Webhook handling with HMAC-SHA256 signature verification
|
|
17
|
+
- Spanish error messages for Redsys response codes
|
|
18
|
+
- Zero PCI scope — card data is handled by Redsys' secure page
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
- MedusaJS v2.13.0 or later
|
|
23
|
+
- Node.js v20 or later
|
|
24
|
+
- A [Redsys merchant account](https://comercios.redsys.es/) (or sandbox test credentials)
|
|
25
|
+
- `redsys-easy` v5.3.0+ (installed automatically as a dependency)
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @jsm406/medusa-plugin-redsys
|
|
31
|
+
# or
|
|
32
|
+
yarn add @jsm406/medusa-plugin-redsys
|
|
33
|
+
# or
|
|
34
|
+
pnpm add @jsm406/medusa-plugin-redsys
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
### Environment Variables
|
|
40
|
+
|
|
41
|
+
Add the following to your `.env` file:
|
|
42
|
+
|
|
43
|
+
```env
|
|
44
|
+
REDSYS_SECRET_KEY=sq7Hj....
|
|
45
|
+
REDSYS_MERCHANT_CODE=999008881
|
|
46
|
+
REDSYS_TERMINAL=001
|
|
47
|
+
REDSYS_ENVIRONMENT=sandbox
|
|
48
|
+
REDSYS_NOTIFICATION_URL=https://your-api.com/hooks/payment/redsys_redsys
|
|
49
|
+
REDSYS_SUCCESS_URL=https://your-store.com/checkout/redsys-callback
|
|
50
|
+
REDSYS_ERROR_URL=https://your-store.com/checkout/redsys-callback?error=1
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For sandbox testing, use the following test credentials from Redsys:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Merchant Code: 999008881
|
|
57
|
+
Terminal: 001
|
|
58
|
+
Secret Key: sq7Hj.......
|
|
59
|
+
Environment: sandbox
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Medusa Configuration
|
|
63
|
+
|
|
64
|
+
In your `medusa-config.ts`:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { defineConfig } from "@medusajs/framework/config"
|
|
68
|
+
|
|
69
|
+
export default defineConfig({
|
|
70
|
+
modules: [
|
|
71
|
+
{
|
|
72
|
+
resolve: "@medusajs/medusa/payment",
|
|
73
|
+
options: {
|
|
74
|
+
providers: [
|
|
75
|
+
{
|
|
76
|
+
resolve: "@jsm406/medusa-plugin-redsys/providers/redsys",
|
|
77
|
+
id: "redsys",
|
|
78
|
+
options: {
|
|
79
|
+
secretKey: process.env.REDSYS_SECRET_KEY,
|
|
80
|
+
merchantCode: process.env.REDSYS_MERCHANT_CODE,
|
|
81
|
+
terminal: process.env.REDSYS_TERMINAL || "001",
|
|
82
|
+
environment:
|
|
83
|
+
process.env.REDSYS_ENVIRONMENT || "sandbox",
|
|
84
|
+
notificationUrl:
|
|
85
|
+
process.env.REDSYS_NOTIFICATION_URL,
|
|
86
|
+
successUrl: process.env.REDSYS_SUCCESS_URL,
|
|
87
|
+
errorUrl: process.env.REDSYS_ERROR_URL,
|
|
88
|
+
transactionType: "0", // "0" = immediate capture, "1" = pre-authorization
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Enable in Region
|
|
99
|
+
|
|
100
|
+
Enable the Redsys provider in your Medusa admin panel under **Settings > Regions** and select **Redsys** as a payment provider.
|
|
101
|
+
|
|
102
|
+
The provider ID will be:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
pp_redsys_redsys
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Options
|
|
109
|
+
|
|
110
|
+
| Option | Type | Required | Default | Description |
|
|
111
|
+
|---|---|---|---|---|
|
|
112
|
+
| `secretKey` | string | Yes | — | Redsys HMAC-SHA256 secret key |
|
|
113
|
+
| `merchantCode` | string | Yes | — | Redsys merchant code (FUC) |
|
|
114
|
+
| `terminal` | string | No | `"001"` | Terminal number |
|
|
115
|
+
| `environment` | string | No | `"sandbox"` | `"sandbox"` or `"production"` |
|
|
116
|
+
| `notificationUrl` | string | No | — | Webhook URL for Redsys to POST transaction results |
|
|
117
|
+
| `successUrl` | string | No | — | URL to redirect after successful payment (URLOK) |
|
|
118
|
+
| `errorUrl` | string | No | — | URL to redirect after failed payment (URLKO) |
|
|
119
|
+
| `transactionType` | string | No | `"0"` | `"0"` = immediate capture, `"1"` = pre-authorization |
|
|
120
|
+
|
|
121
|
+
## Payment Flow
|
|
122
|
+
|
|
123
|
+
1. Customer selects **Redsys** as payment method
|
|
124
|
+
2. `initiatePayment()` creates a signed redirect form with Redsys merchant parameters
|
|
125
|
+
3. Customer clicks "Place Order" → storefront calls `cart.complete()` to create the order, stores a cookie mapping the Redsys internal order ID to the Medusa order ID, then auto-submits the redirect form to Redsys TPV
|
|
126
|
+
4. Customer completes payment on the Redsys hosted payment page
|
|
127
|
+
5. Redsys sends a **webhook notification** to `{backendUrl}/hooks/payment/redsys_redsys`
|
|
128
|
+
6. `getWebhookActionAndData()` validates the HMAC-SHA256 signature and updates the payment status
|
|
129
|
+
7. Redsys redirects the customer's browser to `successUrl` or `errorUrl` with the Redsys order ID as a query parameter
|
|
130
|
+
8. Storefront callback page reads the sessionStorage to resolve the Medusa order ID and redirects to the order confirmation page
|
|
131
|
+
|
|
132
|
+
### Important: authorizePayment Behavior
|
|
133
|
+
|
|
134
|
+
This plugin's `authorizePayment` returns `AUTHORIZED` for sessions with status `"pending"` **and** `"authorized"`. This is intentional for the redirect flow: the real authorization happens on Redsys TPV and is confirmed via webhook. Without this, `cart.complete()` would fail with a 400 error because Medusa requires the payment session to be authorized before completing the cart.
|
|
135
|
+
|
|
136
|
+
### ID Mapping (Redsys → Medusa)
|
|
137
|
+
|
|
138
|
+
The plugin generates a 12-character alphanumeric `orderId` (e.g. `97727XYIWRRF`) used as Redsys' merchant order reference. When the order is completed via `cart.complete()`, Medusa generates its own order ID (e.g. `order_01KR3B4X...`). These are **different IDs**.
|
|
139
|
+
|
|
140
|
+
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 `redsys_map_{redsysOrderId}` → `{ medusaOrderId, countryCode }` in `sessionStorage` before redirecting to the TPV. The callback page reads this value to redirect to the correct order confirmation page.
|
|
141
|
+
|
|
142
|
+
## Storefront Integration
|
|
143
|
+
|
|
144
|
+
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.
|
|
145
|
+
|
|
146
|
+
### 1. `src/lib/constants.tsx` — Register the payment method
|
|
147
|
+
|
|
148
|
+
Add Redsys to the payment info map and add a helper function:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
// Inside paymentInfoMap, add:
|
|
152
|
+
pp_redsys_redsys: {
|
|
153
|
+
title: "Credit / Debit Card",
|
|
154
|
+
icon: <CreditCard />,
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// Add helper function:
|
|
158
|
+
export const isRedsys = (providerId?: string) => {
|
|
159
|
+
return providerId?.startsWith("pp_redsys_")
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 2. `src/lib/data/cart.ts` — Add order completion without redirect
|
|
164
|
+
|
|
165
|
+
Add a `completeCartWithoutRedirect` function. The standard `placeOrder` does a `redirect()` (server-side), but Redsys needs to redirect the browser to the TPV instead. This function completes the cart, creates the order, but returns the result so the client can handle the TPV redirect:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
export async function completeCartWithoutRedirect(cartId?: string) {
|
|
169
|
+
const id = cartId || (await getCartId())
|
|
170
|
+
|
|
171
|
+
if (!id) {
|
|
172
|
+
throw new Error("No existing cart found when completing cart")
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const headers = {
|
|
176
|
+
...(await getAuthHeaders()),
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const cartRes = await sdk.store.cart
|
|
180
|
+
.complete(id, {}, headers)
|
|
181
|
+
.then(async (cartRes) => {
|
|
182
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
183
|
+
revalidateTag(cartCacheTag)
|
|
184
|
+
return cartRes
|
|
185
|
+
})
|
|
186
|
+
.catch(medusaError)
|
|
187
|
+
|
|
188
|
+
if (cartRes?.type === "order") {
|
|
189
|
+
const orderCacheTag = await getCacheTag("orders")
|
|
190
|
+
revalidateTag(orderCacheTag)
|
|
191
|
+
removeCartId()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return cartRes
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 3. `src/modules/checkout/components/payment-button/index.tsx` — Redsys payment button
|
|
199
|
+
|
|
200
|
+
Add a `RedsysPaymentButton` component that:
|
|
201
|
+
1. Reads the payment session data (formUrl, merchantParams, signature) from the cart
|
|
202
|
+
2. Calls `completeCartWithoutRedirect()` to create the order
|
|
203
|
+
3. Stores the Redsys → Medusa order ID mapping in `sessionStorage` (with country code), then builds and auto-submits a `<form>` to Redsys' TPV
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
// Add import:
|
|
207
|
+
import { isManual, isRedsys, isStripeLike } from "@lib/constants"
|
|
208
|
+
import { completeCartWithoutRedirect, placeOrder } from "@lib/data/cart"
|
|
209
|
+
|
|
210
|
+
// Add case in PaymentButton's switch:
|
|
211
|
+
case isRedsys(paymentSession?.provider_id):
|
|
212
|
+
return (
|
|
213
|
+
<RedsysPaymentButton
|
|
214
|
+
notReady={notReady}
|
|
215
|
+
cart={cart}
|
|
216
|
+
data-testid={dataTestId}
|
|
217
|
+
/>
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
// Add the component:
|
|
221
|
+
const RedsysPaymentButton = ({
|
|
222
|
+
cart,
|
|
223
|
+
notReady,
|
|
224
|
+
"data-testid": dataTestId,
|
|
225
|
+
}: {
|
|
226
|
+
cart: HttpTypes.StoreCart
|
|
227
|
+
notReady: boolean
|
|
228
|
+
"data-testid"?: string
|
|
229
|
+
}) => {
|
|
230
|
+
const [submitting, setSubmitting] = useState(false)
|
|
231
|
+
const [errorMessage, setErrorMessage] = useState<string | null>(null)
|
|
232
|
+
|
|
233
|
+
const handlePayment = async () => {
|
|
234
|
+
setSubmitting(true)
|
|
235
|
+
|
|
236
|
+
const paymentSession = cart.payment_collection?.payment_sessions?.find(
|
|
237
|
+
(s) => s.status === "pending" && isRedsys(s.provider_id)
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
const redsysData = paymentSession?.data as Record<string, string> | undefined
|
|
241
|
+
|
|
242
|
+
if (!redsysData?.formUrl || !redsysData?.merchantParams || !redsysData?.signature) {
|
|
243
|
+
setErrorMessage("No se pudieron obtener los datos de pago de Redsys")
|
|
244
|
+
setSubmitting(false)
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const cartRes = await completeCartWithoutRedirect()
|
|
249
|
+
.catch((err) => {
|
|
250
|
+
setErrorMessage(err.message)
|
|
251
|
+
setSubmitting(false)
|
|
252
|
+
return null
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
if (!cartRes || cartRes.type !== "order") {
|
|
256
|
+
setErrorMessage(cartRes ? "Error al crear el pedido" : "")
|
|
257
|
+
setSubmitting(false)
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Store Redsys ID → Medusa ID mapping + country code in sessionStorage.
|
|
262
|
+
// The callback page reads this to redirect to the order confirmation.
|
|
263
|
+
const medusaOrderId = cartRes.order.id
|
|
264
|
+
const redsysOrderId = redsysData.orderId || ""
|
|
265
|
+
const countryCode = cart.shipping_address?.country_code?.toLowerCase() || "dk"
|
|
266
|
+
sessionStorage.setItem(
|
|
267
|
+
`redsys_map_${redsysOrderId}`,
|
|
268
|
+
JSON.stringify({ medusaOrderId, countryCode })
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
const form = document.createElement("form")
|
|
272
|
+
form.method = "POST"
|
|
273
|
+
form.action = redsysData.formUrl
|
|
274
|
+
|
|
275
|
+
const fields: Record<string, string> = {
|
|
276
|
+
Ds_SignatureVersion: redsysData.signatureVersion,
|
|
277
|
+
Ds_MerchantParameters: redsysData.merchantParams,
|
|
278
|
+
Ds_Signature: redsysData.signature,
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
Object.entries(fields).forEach(([name, value]) => {
|
|
282
|
+
const input = document.createElement("input")
|
|
283
|
+
input.type = "hidden"
|
|
284
|
+
input.name = name
|
|
285
|
+
input.value = value
|
|
286
|
+
form.appendChild(input)
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
document.body.appendChild(form)
|
|
290
|
+
form.submit()
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return (
|
|
294
|
+
<>
|
|
295
|
+
<Button
|
|
296
|
+
disabled={notReady || submitting}
|
|
297
|
+
isLoading={submitting}
|
|
298
|
+
onClick={handlePayment}
|
|
299
|
+
size="large"
|
|
300
|
+
data-testid={dataTestId}
|
|
301
|
+
>
|
|
302
|
+
Place order
|
|
303
|
+
</Button>
|
|
304
|
+
<ErrorMessage
|
|
305
|
+
error={errorMessage}
|
|
306
|
+
data-testid="redsys-payment-error-message"
|
|
307
|
+
/>
|
|
308
|
+
</>
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 4. `src/app/checkout/redsys-callback/page.tsx` — Callback page (new file)
|
|
314
|
+
|
|
315
|
+
Create a **client component** page that Redsys redirects to after payment. It reads the `orderId` query param (Redsys internal ID), looks up the real Medusa order ID from `sessionStorage`, and redirects to the order confirmation page:
|
|
316
|
+
|
|
317
|
+
```tsx
|
|
318
|
+
"use client"
|
|
319
|
+
|
|
320
|
+
import { useRouter, useSearchParams } from "next/navigation"
|
|
321
|
+
import { useEffect, useState } from "react"
|
|
322
|
+
|
|
323
|
+
export default function RedsysCallbackPage() {
|
|
324
|
+
const searchParams = useSearchParams()
|
|
325
|
+
const router = useRouter()
|
|
326
|
+
const [status, setStatus] = useState<"loading" | "error" | "success">("loading")
|
|
327
|
+
|
|
328
|
+
const isError = searchParams?.get("error") === "1"
|
|
329
|
+
const redsysOrderId = searchParams?.get("orderId")
|
|
330
|
+
|
|
331
|
+
useEffect(() => {
|
|
332
|
+
if (isError) {
|
|
333
|
+
setStatus("error")
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (!redsysOrderId) {
|
|
338
|
+
setStatus("success")
|
|
339
|
+
return
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const stored = sessionStorage.getItem(`redsys_map_${redsysOrderId}`)
|
|
343
|
+
|
|
344
|
+
if (stored) {
|
|
345
|
+
let orderData: { medusaOrderId: string; countryCode: string }
|
|
346
|
+
try {
|
|
347
|
+
orderData = JSON.parse(stored)
|
|
348
|
+
} catch {
|
|
349
|
+
orderData = { medusaOrderId: stored, countryCode: "dk" }
|
|
350
|
+
}
|
|
351
|
+
sessionStorage.removeItem(`redsys_map_${redsysOrderId}`)
|
|
352
|
+
router.replace(
|
|
353
|
+
`/${orderData.countryCode}/order/${orderData.medusaOrderId}/confirmed`
|
|
354
|
+
)
|
|
355
|
+
return
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
setStatus("success")
|
|
359
|
+
}, [isError, redsysOrderId, router])
|
|
360
|
+
|
|
361
|
+
if (status === "loading") {
|
|
362
|
+
return (
|
|
363
|
+
<div className="flex flex-col items-center justify-center min-h-[50vh] gap-4 p-8">
|
|
364
|
+
<p className="text-gray-600">Procesando pago...</p>
|
|
365
|
+
</div>
|
|
366
|
+
)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (status === "error") {
|
|
370
|
+
return (
|
|
371
|
+
<div className="flex flex-col items-center justify-center min-h-[50vh] gap-4 p-8">
|
|
372
|
+
<h1 className="text-2xl font-bold text-red-600">Pago no completado</h1>
|
|
373
|
+
<p className="text-gray-600">
|
|
374
|
+
La operación no se ha completado correctamente.
|
|
375
|
+
</p>
|
|
376
|
+
<a href="/" className="mt-4 px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
|
|
377
|
+
Volver a la tienda
|
|
378
|
+
</a>
|
|
379
|
+
</div>
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return (
|
|
384
|
+
<div className="flex flex-col items-center justify-center min-h-[50vh] gap-4 p-8">
|
|
385
|
+
<h1 className="text-2xl font-bold text-green-600">Pago procesado</h1>
|
|
386
|
+
<p className="text-gray-600">Tu pago ha sido procesado correctamente.</p>
|
|
387
|
+
<a href="/" className="mt-4 px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
|
|
388
|
+
Volver a la tienda
|
|
389
|
+
</a>
|
|
390
|
+
</div>
|
|
391
|
+
)
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### 5. `src/middleware.ts` — Bypass region redirect
|
|
396
|
+
|
|
397
|
+
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 `/checkout/redsys-callback` is not redirected. Add this early in the `middleware` function:
|
|
398
|
+
|
|
399
|
+
```ts
|
|
400
|
+
// Redsys callback URL — bypass region redirect
|
|
401
|
+
if (request.nextUrl.pathname.startsWith("/checkout/redsys-callback")) {
|
|
402
|
+
return NextResponse.next()
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### 6. `medusa-config.ts` — CORS
|
|
407
|
+
|
|
408
|
+
Ensure your storefront domain is allowed in CORS:
|
|
409
|
+
|
|
410
|
+
```ts
|
|
411
|
+
projectConfig: {
|
|
412
|
+
http: {
|
|
413
|
+
storeCors: "http://localhost:8000,https://your-store.com",
|
|
414
|
+
},
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Session Data Reference
|
|
419
|
+
|
|
420
|
+
The payment session `data` field returned by `initiatePayment`:
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
{
|
|
424
|
+
orderId: "1234ABCD5678",
|
|
425
|
+
amount: "2550",
|
|
426
|
+
currency: "978",
|
|
427
|
+
status: "pending",
|
|
428
|
+
transactionType: "0",
|
|
429
|
+
merchantParams: "base64...", // Base64-encoded merchant parameters
|
|
430
|
+
signature: "hmac...", // HMAC-SHA256 signature
|
|
431
|
+
signatureVersion: "HMAC_SHA256_V1",
|
|
432
|
+
formUrl: "https://sis-t.redsys.es:25443/sis/realizarPago"
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
These fields are used in step 3 to build the auto-submitting redirect form.
|
|
437
|
+
|
|
438
|
+
### Webhook
|
|
439
|
+
|
|
440
|
+
Medusa automatically exposes a webhook endpoint for the Redsys provider at:
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
/hooks/payment/redsys_redsys
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
For local development with sandbox, you must expose your backend to the internet (e.g., via [ngrok](https://ngrok.com/)) so Redsys can reach the webhook. Set `notificationUrl` to the ngrok URL.
|
|
447
|
+
|
|
448
|
+
**Important**: Redsys sends the notification to `notificationUrl` but the signature verification and payment status update happens through the Medusa webhook handler — make sure `notificationUrl` points to the same endpoint or forward notifications accordingly.
|
|
449
|
+
|
|
450
|
+
## Test Cards (Sandbox)
|
|
451
|
+
|
|
452
|
+
| Card Number | Brand | Behavior |
|
|
453
|
+
|---|---|---|
|
|
454
|
+
| 4548810000000003 | VISA | 3DS v2 approved |
|
|
455
|
+
| 5576441563045037 | Mastercard | 3DS v2 approved |
|
|
456
|
+
| 4548814479727229 | VISA | 3DS frictionless |
|
|
457
|
+
| 4548817212493017 | VISA | 3DS challenge |
|
|
458
|
+
| Any + CVV 999 | Any | Payment declined |
|
|
459
|
+
|
|
460
|
+
## Transaction Types
|
|
461
|
+
|
|
462
|
+
| Code | Type | Description |
|
|
463
|
+
|---|---|---|
|
|
464
|
+
| `"0"` | Payment | Authorization + immediate capture (default) |
|
|
465
|
+
| `"1"` | Pre-authorization | Reserve funds only |
|
|
466
|
+
| `"2"` | Confirmation | Capture pre-authorized funds |
|
|
467
|
+
| `"3"` | Refund | Full or partial refund |
|
|
468
|
+
| `"9"` | Cancellation | Cancel/void a transaction |
|
|
469
|
+
|
|
470
|
+
## Security
|
|
471
|
+
|
|
472
|
+
- **Never log PAN, CVV, or the secret key**. The provider strips sensitive fields from log output.
|
|
473
|
+
- **Always validate signatures server-side**. `getWebhookActionAndData()` uses `redsys-easy`'s `processRestNotification()` for HMAC-SHA256 verification.
|
|
474
|
+
- **Use HTTPS** for all communication with Redsys.
|
|
475
|
+
- **Do not trust client-side payment data**. The webhook with signature verification is the source of truth.
|
|
476
|
+
- The redirect flow keeps you out of PCI scope — card data is handled by Redsys' secure page.
|
|
477
|
+
|
|
478
|
+
## Currency Support
|
|
479
|
+
|
|
480
|
+
The plugin includes built-in numeric currency codes for all major currencies. If your currency is not listed, it defaults to EUR (`978`). See `src/types.ts` for the full list.
|
|
481
|
+
|
|
482
|
+
## Development
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
# Install dependencies
|
|
486
|
+
npm install
|
|
487
|
+
|
|
488
|
+
# Build
|
|
489
|
+
npm run build
|
|
490
|
+
|
|
491
|
+
# Run tests
|
|
492
|
+
npm test
|
|
493
|
+
|
|
494
|
+
# Watch mode (for local plugin development)
|
|
495
|
+
npm run dev
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Local Testing with a Medusa Project
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
# From your plugin directory
|
|
502
|
+
npm run dev
|
|
503
|
+
|
|
504
|
+
# In your Medusa project directory:
|
|
505
|
+
npx medusa plugin:add ../path-to/@jsm406/medusa-plugin-redsys
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
## License
|
|
509
|
+
|
|
510
|
+
MIT — see [LICENSE](./LICENSE) file for details.
|
|
511
|
+
|
|
512
|
+
## Support
|
|
513
|
+
|
|
514
|
+
For issues and questions, please open an issue on [GitHub](https://github.com/juansoler/medusa-plugin-redsys/issues).
|