@paykit-sdk/redsys 1.0.0

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/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # @paykit-sdk/redsys
2
+
3
+ Redsys inSite provider for PayKit.
4
+
5
+ ## Overview
6
+
7
+ This package integrates Redsys's inSite payment method into PayKit. inSite allows customers to enter their card details directly on your website through secure iframes hosted by Redsys, without redirecting to an external payment page.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @paykit-sdk/redsys
13
+ # or
14
+ pnpm add @paykit-sdk/redsys
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```typescript
20
+ import { createEndpointHandlers, PayKit } from '@paykit-sdk/core';
21
+ import { redsys } from '@paykit-sdk/redsys';
22
+
23
+ // Configure the provider
24
+ const provider = redsys();
25
+ // or with manual config:
26
+ import { createRedsys } from '@paykit-sdk/redsys';
27
+ const provider = createRedsys({
28
+ merchantCode: process.env.REDSYS_MERCHANT_CODE,
29
+ terminal: process.env.REDSYS_TERMINAL,
30
+ secretKey: process.env.REDSYS_SECRET_KEY,
31
+ environment: 'sandbox', // or 'production'
32
+ transactionType: '0', // '0' = immediate, '1' = pre-auth
33
+ });
34
+
35
+ export const paykit = new PayKit(provider);
36
+ export const endpoints = createEndpointHandlers(paykit);
37
+ ```
38
+
39
+ ## Environment Variables
40
+
41
+ | Variable | Description |
42
+ |----------|-------------|
43
+ | `REDSYS_MERCHANT_CODE` | Your Redsys merchant code |
44
+ | `REDSYS_TERMINAL` | Terminal number |
45
+ | `REDSYS_SECRET_KEY` | HMAC-SHA256 secret key from Redsys backend |
46
+ | `REDSYS_TRANSACTION_TYPE` | `"0"` (immediate) or `"1"` (pre-authorization) |
47
+
48
+ ## Flow
49
+
50
+ 1. **Create Checkout** → returns merchant parameters + signature for inSite iframe
51
+ 2. **Frontend loads inSite** → renders secure card input iframes
52
+ 3. **User enters card** → Redsys returns `operationId`
53
+ 4. **Create Payment** → pass `operationId` in `provider_metadata.operationId`
54
+ 5. **Webhooks** → server-side notifications for payment status
55
+
56
+ ## Frontend Integration
57
+
58
+ The `createCheckout` response includes inSite parameters in metadata:
59
+
60
+ ```typescript
61
+ const checkout = await paykit.createCheckout(params);
62
+
63
+ // These fields from checkout.metadata are needed for inSite:
64
+ const {
65
+ redsys_merchant_params,
66
+ redsys_signature,
67
+ redsys_signature_version,
68
+ redsys_merchant_code,
69
+ redsys_terminal,
70
+ } = checkout.metadata;
71
+ ```
72
+
73
+ Load the Redsys inSite script and initialize:
74
+
75
+ ```html
76
+ <script src="https://sis-t.REDsys.es:25443/sis/rest/register/v2/redsysV3.js"></script>
77
+
78
+ <script>
79
+ // After checkout is created:
80
+ getInSiteForm(
81
+ 'card-form', // container ID
82
+ {}, // button styles
83
+ {}, // body styles
84
+ {}, // box styles
85
+ {}, // input styles
86
+ 'Pay now', // button text (HTML encoded)
87
+ callbackFunction, // callback with operationId
88
+ terminal,
89
+ orderId
90
+ );
91
+ </script>
92
+ ```
93
+
94
+ ## License
95
+
96
+ MIT
@@ -0,0 +1,7 @@
1
+ import { RedsysOptions, RedsysProvider } from './redsys-provider.mjs';
2
+ import '@paykit-sdk/core';
3
+
4
+ declare const createRedsys: (config: RedsysOptions) => RedsysProvider;
5
+ declare const redsys: () => RedsysProvider;
6
+
7
+ export { RedsysOptions, RedsysProvider, createRedsys, redsys };
@@ -0,0 +1,7 @@
1
+ import { RedsysOptions, RedsysProvider } from './redsys-provider.js';
2
+ import '@paykit-sdk/core';
3
+
4
+ declare const createRedsys: (config: RedsysOptions) => RedsysProvider;
5
+ declare const redsys: () => RedsysProvider;
6
+
7
+ export { RedsysOptions, RedsysProvider, createRedsys, redsys };
package/dist/index.js ADDED
@@ -0,0 +1,543 @@
1
+ 'use strict';
2
+
3
+ var core = require('@paykit-sdk/core');
4
+ var crypto = require('crypto');
5
+
6
+ // src/index.ts
7
+ var RedsysOptionsSchema = core.schema()(
8
+ core.Schema.object({
9
+ merchantCode: core.Schema.string().min(1),
10
+ terminal: core.Schema.string().min(1),
11
+ secretKey: core.Schema.string().min(1),
12
+ isSandbox: core.Schema.boolean(),
13
+ transactionType: core.Schema.enum(["0", "1"]).optional(),
14
+ redsysUrl: core.Schema.string().optional(),
15
+ debug: core.Schema.boolean().optional()
16
+ })
17
+ );
18
+ var PROVIDER_NAME = "redsys";
19
+ var CURRENCY_MAP = {
20
+ EUR: 978,
21
+ USD: 840,
22
+ GBP: 826,
23
+ JPY: 392
24
+ };
25
+ var RESPONSE_CODES = {
26
+ "0000": "Transaction approved",
27
+ "0101": "Card expired",
28
+ "0102": "Card temporarily blocked",
29
+ "0106": "Attempts exceeded",
30
+ "0116": "Insufficient balance",
31
+ "0129": "Invalid card security code",
32
+ "0184": "Cardholder authentication failed",
33
+ "0190": "Card issuer unavailable",
34
+ "0904": "Merchant not registered"
35
+ };
36
+ var RedsysProvider = class extends core.AbstractPayKitProvider {
37
+ opts;
38
+ _client;
39
+ isSandbox;
40
+ constructor(opts) {
41
+ super(RedsysOptionsSchema, opts, PROVIDER_NAME);
42
+ this.opts = opts;
43
+ this.isSandbox = opts.isSandbox ?? false;
44
+ this._client = new core.HTTPClient({
45
+ baseUrl: this._getRedsysUrl(),
46
+ headers: { "Content-Type": "application/json" },
47
+ retryOptions: { max: 3, baseDelay: 1e3, debug: false }
48
+ });
49
+ }
50
+ providerName = PROVIDER_NAME;
51
+ get _native() {
52
+ throw new core.NotImplementedError(
53
+ "Native SDK not available for Redsys. Use inSite iframe.",
54
+ this.providerName,
55
+ { futureSupport: true }
56
+ );
57
+ }
58
+ _getRedsysUrl() {
59
+ if (this.opts.redsysUrl) return this.opts.redsysUrl;
60
+ return this.opts.isSandbox ? "https://sis.redsys.es/sis/realizarPago" : "https://sis-t.REDsys.es:25443/sis/realizarPago";
61
+ }
62
+ _getCurrencyNum(currency) {
63
+ return CURRENCY_MAP[currency.toUpperCase()] ?? 978;
64
+ }
65
+ _generateOrderId() {
66
+ return crypto.randomBytes(6).toString("hex").toUpperCase();
67
+ }
68
+ /**
69
+ * Build the Base64-encoded merchant parameters for inSite
70
+ */
71
+ _buildMerchantParams(orderId, amount, currency) {
72
+ const currencyNum = this._getCurrencyNum(currency);
73
+ const params = {
74
+ DS_MERCHANT_MERCHANTCODE: this.opts.merchantCode,
75
+ DS_MERCHANT_TERMINAL: this.opts.terminal,
76
+ DS_MERCHANT_ORDER: orderId,
77
+ DS_MERCHANT_AMOUNT: String(amount),
78
+ DS_MERCHANT_CURRENCY: String(currencyNum),
79
+ DS_MERCHANT_TRANSACTIONTYPE: this.opts.transactionType ?? "0",
80
+ DS_MERCHANT_CONSUMERLANGUAGE: "1",
81
+ DS_MERCHANT_PRODUCTDESCRIPTION: "Payment",
82
+ DS_MERCHANT_TITULAR: ""
83
+ };
84
+ const jsonStr = JSON.stringify(params);
85
+ return Buffer.from(jsonStr).toString("base64");
86
+ }
87
+ /**
88
+ * Generate HMAC-SHA256 signature for inSite
89
+ *
90
+ * Signature = HMAC-SHA256(secretKey, base64(params) + orderId)
91
+ * Order is important: base64Params + orderId (both as-is, no separators)
92
+ */
93
+ _sign(orderId, base64Params) {
94
+ const data = base64Params + orderId;
95
+ return crypto.createHmac(
96
+ "sha256",
97
+ Buffer.from(this.opts.secretKey, "base64")
98
+ ).update(data).digest("base64").replace(/\+/g, "-").replace(/\//g, "/").replace(/=+$/, "");
99
+ }
100
+ /**
101
+ * Create checkout for inSite
102
+ *
103
+ * Returns merchant parameters and signature for the frontend iframe.
104
+ * The frontend will load redsysV3.js and render the inSite form.
105
+ */
106
+ createCheckout = async (params) => {
107
+ const { error, data } = core.createCheckoutSchema.safeParse(params);
108
+ if (error) {
109
+ throw core.ValidationError.fromZodError(
110
+ error,
111
+ this.providerName,
112
+ "createCheckout"
113
+ );
114
+ }
115
+ const { amount: rawAmount, currency = "EUR" } = core.validateRequiredKeys(
116
+ ["amount", "currency"],
117
+ data.metadata ?? {},
118
+ "The following fields must be present in the metadata of createCheckout: {keys}"
119
+ );
120
+ const orderId = data.metadata?.orderId ?? this._generateOrderId();
121
+ const amount = Math.round(Number(rawAmount));
122
+ const merchantParams = this._buildMerchantParams(
123
+ orderId,
124
+ amount,
125
+ currency
126
+ );
127
+ const signature = this._sign(orderId, merchantParams);
128
+ let customer = null;
129
+ if (core.isIdCustomer(data.customer)) {
130
+ customer = { id: data.customer.id };
131
+ } else if (core.isEmailCustomer(data.customer)) {
132
+ customer = { email: data.customer.email };
133
+ }
134
+ return {
135
+ id: `redsys_${orderId}`,
136
+ customer,
137
+ session_type: "one_time",
138
+ payment_url: this._getRedsysUrl(),
139
+ products: [{ id: data.item_id, quantity: data.quantity }],
140
+ currency,
141
+ amount,
142
+ subscription: null,
143
+ metadata: {
144
+ ...core.stringifyMetadataValues(data.metadata ?? {}),
145
+ [core.PAYKIT_METADATA_KEY]: JSON.stringify({ orderId, currency }),
146
+ // These are passed to frontend for inSite initialization
147
+ redsys_merchant_params: merchantParams,
148
+ redsys_signature: signature,
149
+ redsys_signature_version: "HMAC_SHA256_V1",
150
+ redsys_merchant_code: this.opts.merchantCode,
151
+ redsys_terminal: this.opts.terminal
152
+ }
153
+ };
154
+ };
155
+ retrieveCheckout = async (id) => {
156
+ throw new core.ResourceNotFoundError(
157
+ "checkout",
158
+ id,
159
+ this.providerName
160
+ );
161
+ };
162
+ updateCheckout = async (id, _params) => {
163
+ throw new core.NotImplementedError(
164
+ "updateCheckout",
165
+ this.providerName,
166
+ { futureSupport: true }
167
+ );
168
+ };
169
+ deleteCheckout = async (_id) => {
170
+ return null;
171
+ };
172
+ /**
173
+ * Create payment using operation ID from inSite
174
+ *
175
+ * The operation ID is returned by the inSite iframe when the user
176
+ * completes the card entry. The frontend should pass it in
177
+ * provider_metadata.operationId.
178
+ */
179
+ createPayment = async (params) => {
180
+ const { error, data } = core.createPaymentSchema.safeParse(params);
181
+ if (error) {
182
+ throw core.ValidationError.fromZodError(
183
+ error,
184
+ this.providerName,
185
+ "createPayment"
186
+ );
187
+ }
188
+ const operationId = data.provider_metadata?.operationId;
189
+ if (!operationId) {
190
+ throw new core.ValidationError(
191
+ "operationId is required for Redsys inSite payments. Pass it in provider_metadata.operationId.",
192
+ {
193
+ provider: this.providerName,
194
+ method: "createPayment",
195
+ field: "operationId"
196
+ }
197
+ );
198
+ }
199
+ const metadataItem = JSON.parse(
200
+ data.metadata?.[core.PAYKIT_METADATA_KEY] ?? "{}"
201
+ );
202
+ const orderId = metadataItem.orderId;
203
+ const result = await this._executePayment(
204
+ orderId,
205
+ operationId,
206
+ Number(data.amount),
207
+ String(data.currency)
208
+ );
209
+ if (result.Ds_Response === "0000" || String(result.Ds_Response).startsWith("00")) {
210
+ return {
211
+ id: result.Ds_AuthorisationCode ? `${orderId}_${result.Ds_AuthorisationCode}` : operationId,
212
+ amount: data.amount,
213
+ currency: data.currency,
214
+ customer: data.customer ? typeof data.customer === "string" ? { id: data.customer } : data.customer : null,
215
+ status: "succeeded",
216
+ metadata: core.stringifyMetadataValues(data.metadata ?? {}),
217
+ item_id: data.item_id,
218
+ requires_action: false,
219
+ payment_url: null
220
+ };
221
+ }
222
+ throw new core.OperationFailedError(
223
+ `Payment failed: ${RESPONSE_CODES[String(result.Ds_Response)] ?? `Code ${result.Ds_Response}`}`,
224
+ this.providerName,
225
+ { cause: new Error(JSON.stringify(result)) }
226
+ );
227
+ };
228
+ /**
229
+ * Execute payment via Redsys REST API
230
+ */
231
+ async _executePayment(orderId, operationId, amount, currency) {
232
+ const currencyNum = this._getCurrencyNum(currency);
233
+ const amountStr = String(amount);
234
+ const params = {
235
+ DS_MERCHANT_MERCHANTCODE: this.opts.merchantCode,
236
+ DS_MERCHANT_TERMINAL: this.opts.terminal,
237
+ DS_MERCHANT_ORDER: orderId,
238
+ DS_MERCHANT_AMOUNT: amountStr,
239
+ DS_MERCHANT_CURRENCY: String(currencyNum),
240
+ DS_MERCHANT_TRANSACTIONTYPE: this.opts.transactionType ?? "0",
241
+ DS_MERCHANT_IDOPERACION: operationId
242
+ };
243
+ const base64Params = Buffer.from(JSON.stringify(params)).toString(
244
+ "base64"
245
+ );
246
+ const signature = this._sign(orderId, base64Params);
247
+ const { ok, value: result } = await this._client.post("/", {
248
+ body: JSON.stringify({
249
+ Ds_SignatureVersion: "HMAC_SHA256_V1",
250
+ Ds_MerchantParameters: base64Params,
251
+ Ds_Signature: signature
252
+ })
253
+ });
254
+ if (!ok || !result) {
255
+ throw new core.OperationFailedError(
256
+ "Redsys REST API error: request failed",
257
+ this.providerName
258
+ );
259
+ }
260
+ return result;
261
+ }
262
+ retrievePayment = async (id) => {
263
+ throw new core.NotImplementedError(
264
+ "retrievePayment",
265
+ this.providerName,
266
+ {
267
+ futureSupport: true
268
+ }
269
+ );
270
+ };
271
+ updatePayment = async (id, _params) => {
272
+ throw new core.NotImplementedError(
273
+ "updatePayment",
274
+ this.providerName,
275
+ { futureSupport: true }
276
+ );
277
+ };
278
+ deletePayment = async (_id) => {
279
+ return null;
280
+ };
281
+ capturePayment = async (id, _params) => {
282
+ if (this.opts.transactionType === "1") {
283
+ throw new core.NotImplementedError(
284
+ "capturePayment",
285
+ this.providerName,
286
+ { futureSupport: true }
287
+ );
288
+ }
289
+ throw new core.NotImplementedError(
290
+ "capturePayment only available for pre-authorization (transactionType=1)",
291
+ this.providerName
292
+ );
293
+ };
294
+ cancelPayment = async (id) => {
295
+ throw new core.NotImplementedError(
296
+ "cancelPayment",
297
+ this.providerName,
298
+ { futureSupport: true }
299
+ );
300
+ };
301
+ createCustomer = async (params) => {
302
+ throw new core.ProviderNotSupportedError("createCustomer", "gopay", {
303
+ reason: "Redsys doesn't support creating customers"
304
+ });
305
+ };
306
+ retrieveCustomer = async (_id) => {
307
+ return null;
308
+ };
309
+ updateCustomer = async (id, _params) => {
310
+ throw new core.NotImplementedError(
311
+ "updateCustomer",
312
+ this.providerName,
313
+ { futureSupport: true }
314
+ );
315
+ };
316
+ deleteCustomer = async (_id) => {
317
+ return null;
318
+ };
319
+ createSubscription = async (_params) => {
320
+ return this._notSupported("createSubscription");
321
+ };
322
+ retrieveSubscription = async (_id) => {
323
+ return this._notSupported("retrieveSubscription");
324
+ };
325
+ updateSubscription = async (_id, _params) => {
326
+ return this._notSupported("updateSubscription");
327
+ };
328
+ deleteSubscription = async (_id) => {
329
+ return this._notSupported("deleteSubscription");
330
+ };
331
+ cancelSubscription = async (_id) => {
332
+ return this._notSupported("cancelSubscription");
333
+ };
334
+ createRefund = async (params) => {
335
+ const { error, data } = core.createRefundSchema.safeParse(params);
336
+ if (error) {
337
+ throw core.ValidationError.fromZodError(
338
+ error,
339
+ this.providerName,
340
+ "createRefund"
341
+ );
342
+ }
343
+ const { currency = "EUR" } = core.validateRequiredKeys(
344
+ ["currency"],
345
+ data.metadata ?? {},
346
+ "The following fields must be present in the metadata of createRefund: {keys}"
347
+ );
348
+ const metadataItem = JSON.parse(
349
+ data.metadata?.[core.PAYKIT_METADATA_KEY] ?? "{}"
350
+ );
351
+ const orderId = metadataItem.orderId;
352
+ if (!orderId) {
353
+ throw new core.ValidationError(
354
+ "orderId not found in payment metadata",
355
+ {
356
+ provider: this.providerName,
357
+ method: "createRefund",
358
+ field: "orderId"
359
+ }
360
+ );
361
+ }
362
+ const result = await this._refundPayment(
363
+ orderId,
364
+ data.amount,
365
+ currency
366
+ );
367
+ const code = String(result.Ds_Response ?? result.Ds_Restock);
368
+ if (code === "0000" || code.startsWith("00")) {
369
+ return {
370
+ id: `refund_${crypto.randomBytes(4).toString("hex")}`,
371
+ amount: data.amount,
372
+ currency,
373
+ reason: "refund",
374
+ metadata: {}
375
+ };
376
+ }
377
+ throw new core.OperationFailedError(
378
+ `Refund failed: ${RESPONSE_CODES[code] ?? `Code ${code}`}`,
379
+ this.providerName,
380
+ { cause: new Error(JSON.stringify(result)) }
381
+ );
382
+ };
383
+ async _refundPayment(orderId, amount, currency) {
384
+ const currencyNum = this._getCurrencyNum(currency);
385
+ const params = {
386
+ DS_MERCHANT_MERCHANTCODE: this.opts.merchantCode,
387
+ DS_MERCHANT_TERMINAL: this.opts.terminal,
388
+ DS_MERCHANT_ORDER: orderId,
389
+ DS_MERCHANT_AMOUNT: String(amount),
390
+ DS_MERCHANT_CURRENCY: String(currencyNum),
391
+ DS_MERCHANT_TRANSACTIONTYPE: "3"
392
+ // Refund
393
+ };
394
+ const base64Params = Buffer.from(JSON.stringify(params)).toString(
395
+ "base64"
396
+ );
397
+ const signature = this._sign(orderId, base64Params);
398
+ const { ok, value: result } = await this._client.post("/", {
399
+ body: JSON.stringify({
400
+ Ds_SignatureVersion: "HMAC_SHA256_V1",
401
+ Ds_MerchantParameters: base64Params,
402
+ Ds_Signature: signature
403
+ })
404
+ });
405
+ if (!ok || !result) {
406
+ throw new core.OperationFailedError(
407
+ "Redsys REST API error: refund failed",
408
+ this.providerName
409
+ );
410
+ }
411
+ return result;
412
+ }
413
+ /**
414
+ * Handle Redsys webhook notifications
415
+ *
416
+ * Redsys sends POST to notificationUrl with:
417
+ * - Ds_MerchantParameters (Base64 encoded response)
418
+ * - Ds_Signature (HMAC signature)
419
+ * - Ds_SignatureVersion
420
+ */
421
+ handleWebhook = async (payload, _webhookSecret) => {
422
+ const { body } = payload;
423
+ const dataAsObject = JSON.parse(body);
424
+ const paramsBase64 = dataAsObject.Ds_MerchantParameters;
425
+ if (!paramsBase64) {
426
+ throw new core.WebhookError("Missing Ds_MerchantParameters", {
427
+ provider: this.providerName
428
+ });
429
+ }
430
+ const paramsJson = Buffer.from(paramsBase64, "base64").toString(
431
+ "utf-8"
432
+ );
433
+ const params = JSON.parse(paramsJson);
434
+ const dsResponse = String(params.Ds_Response ?? "");
435
+ const dsOrder = params.Ds_Order;
436
+ const dsAmount = params.Ds_Amount;
437
+ const dsMerchantData = params.Ds_MerchantData;
438
+ const signature = dataAsObject.Ds_Signature;
439
+ const expectedSig = this._sign(dsOrder, paramsBase64);
440
+ const sigOk = signature === expectedSig;
441
+ if (!sigOk) {
442
+ throw new core.WebhookError("Invalid Redsys webhook signature", {
443
+ provider: this.providerName
444
+ });
445
+ }
446
+ const events = [];
447
+ if (dsResponse === "0000" || dsResponse.startsWith("00")) {
448
+ const customerId = core.parseJSON(
449
+ Buffer.from(dsMerchantData, "base64").toString("utf-8"),
450
+ core.Schema.object({
451
+ customerId: core.Schema.string().optional()
452
+ })
453
+ )?.customerId ?? null;
454
+ const amountNum = Number(dsAmount) / 100;
455
+ const paymentId = `${dsOrder}_${params.Ds_AuthorisationCode ?? "unknown"}`;
456
+ events.push(
457
+ {
458
+ event: "redsys.payment.succeeded",
459
+ data: {
460
+ order_id: dsOrder,
461
+ amount: amountNum,
462
+ response_code: dsResponse,
463
+ customer_id: customerId
464
+ }
465
+ },
466
+ core.paykitEvent$InboundSchema({
467
+ type: "payment.succeeded",
468
+ created: (/* @__PURE__ */ new Date()).getTime(),
469
+ id: crypto.randomBytes(8).toString("hex").slice(0, 15),
470
+ data: {
471
+ id: paymentId,
472
+ amount: amountNum,
473
+ currency: "EUR",
474
+ customer: customerId ? { id: customerId } : null,
475
+ status: "succeeded",
476
+ metadata: {},
477
+ item_id: null,
478
+ requires_action: false,
479
+ payment_url: null
480
+ }
481
+ })
482
+ );
483
+ } else {
484
+ events.push(
485
+ {
486
+ event: "redsys.payment.failed",
487
+ data: {
488
+ order_id: dsOrder,
489
+ response_code: dsResponse,
490
+ error_message: RESPONSE_CODES[dsResponse] ?? `Code ${dsResponse}`
491
+ }
492
+ },
493
+ core.paykitEvent$InboundSchema({
494
+ type: "payment.failed",
495
+ created: (/* @__PURE__ */ new Date()).getTime(),
496
+ id: crypto.randomBytes(8).toString("hex").slice(0, 15),
497
+ data: {
498
+ id: dsOrder,
499
+ amount: Number(dsAmount) / 100,
500
+ currency: "EUR",
501
+ customer: null,
502
+ status: "failed",
503
+ metadata: {},
504
+ item_id: null,
505
+ requires_action: false,
506
+ payment_url: null
507
+ }
508
+ })
509
+ );
510
+ }
511
+ return events;
512
+ };
513
+ _notSupported(method) {
514
+ throw new core.NotImplementedError(
515
+ `Redsys doesn't support ${method}`,
516
+ this.providerName,
517
+ { futureSupport: true }
518
+ );
519
+ }
520
+ };
521
+
522
+ // src/index.ts
523
+ var createRedsys = (config) => new RedsysProvider(config);
524
+ var redsys = () => {
525
+ const envVars = core.validateRequiredKeys(
526
+ ["REDSYS_MERCHANT_CODE", "REDSYS_TERMINAL", "REDSYS_SECRET_KEY"],
527
+ process.env ?? {},
528
+ "Missing required environment variables: {keys}"
529
+ );
530
+ const isSandbox = process.env.NODE_ENV !== "production";
531
+ return createRedsys({
532
+ merchantCode: envVars.REDSYS_MERCHANT_CODE,
533
+ terminal: envVars.REDSYS_TERMINAL,
534
+ secretKey: envVars.REDSYS_SECRET_KEY,
535
+ isSandbox,
536
+ debug: isSandbox,
537
+ transactionType: process.env.REDSYS_TRANSACTION_TYPE ?? "0"
538
+ });
539
+ };
540
+
541
+ exports.RedsysProvider = RedsysProvider;
542
+ exports.createRedsys = createRedsys;
543
+ exports.redsys = redsys;