redsys-easy 5.2.4 → 5.2.6

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/lib/client.d.ts CHANGED
@@ -87,6 +87,8 @@ export interface RedsysAPI {
87
87
  restIniciaPeticion: RestIniciaPeticion;
88
88
  restTrataPeticion: RestTrataPeticion;
89
89
  createRedirectForm: CreateRedirectForm;
90
+ processRedirectNotification: ProcessRestNotification;
91
+ processDirectRestNotification: ProcessRestNotification;
90
92
  processRestNotification: ProcessRestNotification;
91
93
  processSoapNotification: ProcessSoapNotification;
92
94
  createSoapNotificationAnswer: CreateSoapNotificationAnswer;
package/lib/crypto.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  /**
3
2
  * Adds padding to a buffer.
4
3
  *
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * @public
11
11
  */
12
- export declare const useSingleInputFormatter: <AF extends (input: any) => B, B, C extends readonly unknown[], D>(fn: (args_0: B, ...args_1: C) => D, inputFormatter: AF) => (input: Parameters<AF>[0], ...otherArgs_0: C) => D;
12
+ export declare const useSingleInputFormatter: <AF extends (input: any) => B, B, C extends readonly unknown[], D>(fn: (...args: [B, ...C]) => D, inputFormatter: AF) => ((input: Parameters<AF>[0], ...otherArgs: [...C]) => D);
13
13
  /**
14
14
  * Applies an output formatter to a function
15
15
  *
@@ -1,7 +1,7 @@
1
1
  import type { BaseOutputParams, RestNotificationOutputParams, SoapNotificationOutputParams, RequestOutputParams, RestIniciaPeticionOutputParams, RestTrataPeticionOutputParams, ResolvedTransactionTrait } from '../types/output-params';
2
2
  import type { BaseFormatterOutput, NotificationFormatterOutput, RequestFormatterOutput, RestIniciaPeticionFormatterOutput, RestTrataPeticionFormatterOutput, ResolvedTransactionTraitFormatterOutput } from './types';
3
3
  export declare const baseOutputFormatter: <RawOutputParams extends BaseOutputParams>(raw: RawOutputParams) => BaseFormatterOutput<RawOutputParams>;
4
- export declare const formatPrice: (params: Omit<ResolvedTransactionTrait, 'Ds_Response'>) => Omit<ResolvedTransactionTraitFormatterOutput, 'response'>;
4
+ export declare const formatPrice: (params: Omit<ResolvedTransactionTrait, "Ds_Response">) => Omit<ResolvedTransactionTraitFormatterOutput, "response">;
5
5
  /**
6
6
  * REST notification formatter
7
7
  *
package/lib/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export { RedsysError, ValidationError, ParseError, HTTPError, GatewayError, Resp
11
11
  export type { RedirectInputParams, RestIniciaPeticionInputParams, RestTrataPeticionInputParams } from './types/input-params';
12
12
  export type { RestIniciaPeticionOutputParams, RestTrataPeticionOutputParams, RestNotificationOutputParams, SoapNotificationOutputParams } from './types/output-params';
13
13
  export type { ResponseJSONSuccess, RedirectForm, ThreeDSv2MethodNotificationBody, ThreeDSv1ChallengeNotificationBody, ThreeDSv2ChallengeNotificationBody } from './types/api';
14
+ export { serializeAndSignJSONRequest, deserializeAndVerifyJSONResponse, } from './rest/json';
14
15
  export { create3DSMethodForm, create3DSv1ChallengeForm, create3DSv2ChallengeForm, deserializeThreeDSMethodData, deserializeCres } from './rest/3ds';
15
16
  export type { ThreeDSBrowserClientInfo, ThreeDSMethodForm, ThreeDSv1ChallengeForm, ThreeDSv2ChallengeForm, ThreeDSMethodData, ThreeDSCres } from './types/3ds-params';
16
17
  export { detectSoapVersion, mimicSoapNotificationReceiver, mimicSoap11NotificationResponse, mimicSoap12NotificationResponse } from './soap/utils';
package/lib/index.esm.js CHANGED
@@ -1927,7 +1927,7 @@ const deserializeJSONMerchantParams = (strPayload) => {
1927
1927
  if (typeof strPayload !== 'string') {
1928
1928
  throw new ParseError('Payload must be a base-64 encoded string');
1929
1929
  }
1930
- const payload = JSON.parse(decodeURIComponent(Buffer.from(strPayload, 'base64').toString('utf8')));
1930
+ const payload = JSON.parse(Buffer.from(strPayload, 'base64').toString('utf8'));
1931
1931
  if (typeof payload !== 'object' || payload == null) {
1932
1932
  throw new ParseError('Cannot parse notification payload');
1933
1933
  }
@@ -2126,6 +2126,22 @@ const serializeAndSignJSONRequest = (merchantKey, requestParams) => {
2126
2126
  return sha256SignJSONRequest(merchantKey, serializedParams, requestParams);
2127
2127
  };
2128
2128
 
2129
+ /**
2130
+ * Tries to decode x-www-form-urlencoded values of an object
2131
+ */
2132
+ const decodeUrlEntries = (params) => {
2133
+ return Object.fromEntries(Object.entries(params).map((entry) => {
2134
+ let processedValue = entry[1];
2135
+ if (typeof entry[1] === 'string') {
2136
+ try {
2137
+ processedValue = decodeURIComponent(entry[1].replaceAll('+', ' '));
2138
+ }
2139
+ catch (_) { }
2140
+ }
2141
+ return [entry[0], processedValue];
2142
+ }));
2143
+ };
2144
+
2129
2145
  const serializeSoapNotificationResponse = ({ allow: allowOperation }) => {
2130
2146
  const answer = allowOperation ? 'OK' : 'KO';
2131
2147
  return `<Response Ds_Version="0.0"><Ds_Response_Merchant>${answer}</Ds_Response_Merchant></Response>`;
@@ -2270,14 +2286,44 @@ const createRedsysAPI = (config) => {
2270
2286
  };
2271
2287
  };
2272
2288
  /**
2273
- * Processes a JSON REST notification
2289
+ * Processes a URLOK/URLKO query notification
2274
2290
  */
2275
- const processRestNotification = (
2291
+ const processRedirectNotification = (
2292
+ /** Body of JSON notification, as a POJO (Plain Old Javascript Object) */
2293
+ body) => {
2294
+ // A notification can't contain a gateway error, it didn't initiate the request
2295
+ const params = deserializeAndVerifyJSONResponse(config.secretKey, body);
2296
+ return decodeUrlEntries(params);
2297
+ };
2298
+ /**
2299
+ * Processes a direct JSON REST notification
2300
+ */
2301
+ const processDirectRestNotification = (
2276
2302
  /** Body of JSON notification, as a POJO (Plain Old Javascript Object) */
2277
2303
  body) => {
2278
2304
  // A notification can't contain a gateway error, it didn't initiate the request
2279
2305
  return deserializeAndVerifyJSONResponse(config.secretKey, body);
2280
2306
  };
2307
+ /**
2308
+ * Processes either a URLOK/URLKO query or a JSON REST notification
2309
+ *
2310
+ * @remarks
2311
+ * This utility exists only for backwards compatibility. Users are adviced
2312
+ * not to rely on the autodetection of this tool and use specific functions
2313
+ * @see {@link processRedirectNotification}
2314
+ * @see {@link processDirectRestNotification}
2315
+ *
2316
+ * @deprecated
2317
+ */
2318
+ const processRestNotification = (
2319
+ /** Body of JSON notification, as a POJO (Plain Old Javascript Object) */
2320
+ body) => {
2321
+ // A notification can't contain a gateway error, it didn't initiate the request
2322
+ const params = deserializeAndVerifyJSONResponse(config.secretKey, body);
2323
+ return typeof params.Ds_Date === 'string' && params.Ds_Date.includes('%2F')
2324
+ ? decodeUrlEntries(params)
2325
+ : params;
2326
+ };
2281
2327
  /**
2282
2328
  * Parses and verifies the body of a SOAP notification
2283
2329
  */
@@ -2303,6 +2349,8 @@ const createRedsysAPI = (config) => {
2303
2349
  restIniciaPeticion,
2304
2350
  restTrataPeticion,
2305
2351
  createRedirectForm,
2352
+ processRedirectNotification,
2353
+ processDirectRestNotification,
2306
2354
  processRestNotification,
2307
2355
  processSoapNotification,
2308
2356
  createSoapNotificationAnswer
@@ -2734,7 +2782,7 @@ for (const [key, value] of Object.entries(CURRENCIES)) {
2734
2782
  const LANGUAGES = {
2735
2783
  es: '1',
2736
2784
  en: '2',
2737
- ca: '3',
2785
+ ca: '3', // Codigo ISO "ca" compartido por catalan(3) y valenciano(10)
2738
2786
  fr: '4',
2739
2787
  de: '5',
2740
2788
  nl: '6',
@@ -3495,4 +3543,4 @@ const restTrataPeticionOutputFormatter = (raw) => {
3495
3543
  };
3496
3544
  };
3497
3545
 
3498
- export { CARDBRANDS, COUNTRIES, CURRENCIES, GatewayError, HTTPError, LANGUAGES, PRODUCTION_URLS, ParseError, REV_CARDBRANDS, REV_COUNTRIES, REV_CURRENCIES, REV_LANGUAGES, RedsysError, ResponseError, SANDBOX_URLS, TRANSACTION_TYPES, ValidationError, assertSuccessfulResponse, assertSuccessfulResponseCode, create3DSMethodForm, create3DSv1ChallengeForm, create3DSv2ChallengeForm, createRedsysAPI, deserializeCres, deserializeThreeDSMethodData, detectSoapVersion, getResponseCodeMessage, getSISErrorCodeMessage, isResponseCodeOk, mimicSoap11NotificationResponse, mimicSoap12NotificationResponse, mimicSoapNotificationReceiver, randomTransactionId, redirectInputFormatter, restIniciaPeticionInputFormatter, restIniciaPeticionOutputFormatter, restNotificationOutputFormatter, restTrataPeticionInputFormatter, restTrataPeticionOutputFormatter, soapNotificationOutputFormatter, useOutputFormatter, usePromiseOutputFormatter, useSingleInputFormatter };
3546
+ export { CARDBRANDS, COUNTRIES, CURRENCIES, GatewayError, HTTPError, LANGUAGES, PRODUCTION_URLS, ParseError, REV_CARDBRANDS, REV_COUNTRIES, REV_CURRENCIES, REV_LANGUAGES, RedsysError, ResponseError, SANDBOX_URLS, TRANSACTION_TYPES, ValidationError, assertSuccessfulResponse, assertSuccessfulResponseCode, create3DSMethodForm, create3DSv1ChallengeForm, create3DSv2ChallengeForm, createRedsysAPI, deserializeAndVerifyJSONResponse, deserializeCres, deserializeThreeDSMethodData, detectSoapVersion, getResponseCodeMessage, getSISErrorCodeMessage, isResponseCodeOk, mimicSoap11NotificationResponse, mimicSoap12NotificationResponse, mimicSoapNotificationReceiver, randomTransactionId, redirectInputFormatter, restIniciaPeticionInputFormatter, restIniciaPeticionOutputFormatter, restNotificationOutputFormatter, restTrataPeticionInputFormatter, restTrataPeticionOutputFormatter, serializeAndSignJSONRequest, soapNotificationOutputFormatter, useOutputFormatter, usePromiseOutputFormatter, useSingleInputFormatter };
package/lib/index.js CHANGED
@@ -1929,7 +1929,7 @@ const deserializeJSONMerchantParams = (strPayload) => {
1929
1929
  if (typeof strPayload !== 'string') {
1930
1930
  throw new ParseError('Payload must be a base-64 encoded string');
1931
1931
  }
1932
- const payload = JSON.parse(decodeURIComponent(Buffer.from(strPayload, 'base64').toString('utf8')));
1932
+ const payload = JSON.parse(Buffer.from(strPayload, 'base64').toString('utf8'));
1933
1933
  if (typeof payload !== 'object' || payload == null) {
1934
1934
  throw new ParseError('Cannot parse notification payload');
1935
1935
  }
@@ -2128,6 +2128,22 @@ const serializeAndSignJSONRequest = (merchantKey, requestParams) => {
2128
2128
  return sha256SignJSONRequest(merchantKey, serializedParams, requestParams);
2129
2129
  };
2130
2130
 
2131
+ /**
2132
+ * Tries to decode x-www-form-urlencoded values of an object
2133
+ */
2134
+ const decodeUrlEntries = (params) => {
2135
+ return Object.fromEntries(Object.entries(params).map((entry) => {
2136
+ let processedValue = entry[1];
2137
+ if (typeof entry[1] === 'string') {
2138
+ try {
2139
+ processedValue = decodeURIComponent(entry[1].replaceAll('+', ' '));
2140
+ }
2141
+ catch (_) { }
2142
+ }
2143
+ return [entry[0], processedValue];
2144
+ }));
2145
+ };
2146
+
2131
2147
  const serializeSoapNotificationResponse = ({ allow: allowOperation }) => {
2132
2148
  const answer = allowOperation ? 'OK' : 'KO';
2133
2149
  return `<Response Ds_Version="0.0"><Ds_Response_Merchant>${answer}</Ds_Response_Merchant></Response>`;
@@ -2272,14 +2288,44 @@ const createRedsysAPI = (config) => {
2272
2288
  };
2273
2289
  };
2274
2290
  /**
2275
- * Processes a JSON REST notification
2291
+ * Processes a URLOK/URLKO query notification
2276
2292
  */
2277
- const processRestNotification = (
2293
+ const processRedirectNotification = (
2294
+ /** Body of JSON notification, as a POJO (Plain Old Javascript Object) */
2295
+ body) => {
2296
+ // A notification can't contain a gateway error, it didn't initiate the request
2297
+ const params = deserializeAndVerifyJSONResponse(config.secretKey, body);
2298
+ return decodeUrlEntries(params);
2299
+ };
2300
+ /**
2301
+ * Processes a direct JSON REST notification
2302
+ */
2303
+ const processDirectRestNotification = (
2278
2304
  /** Body of JSON notification, as a POJO (Plain Old Javascript Object) */
2279
2305
  body) => {
2280
2306
  // A notification can't contain a gateway error, it didn't initiate the request
2281
2307
  return deserializeAndVerifyJSONResponse(config.secretKey, body);
2282
2308
  };
2309
+ /**
2310
+ * Processes either a URLOK/URLKO query or a JSON REST notification
2311
+ *
2312
+ * @remarks
2313
+ * This utility exists only for backwards compatibility. Users are adviced
2314
+ * not to rely on the autodetection of this tool and use specific functions
2315
+ * @see {@link processRedirectNotification}
2316
+ * @see {@link processDirectRestNotification}
2317
+ *
2318
+ * @deprecated
2319
+ */
2320
+ const processRestNotification = (
2321
+ /** Body of JSON notification, as a POJO (Plain Old Javascript Object) */
2322
+ body) => {
2323
+ // A notification can't contain a gateway error, it didn't initiate the request
2324
+ const params = deserializeAndVerifyJSONResponse(config.secretKey, body);
2325
+ return typeof params.Ds_Date === 'string' && params.Ds_Date.includes('%2F')
2326
+ ? decodeUrlEntries(params)
2327
+ : params;
2328
+ };
2283
2329
  /**
2284
2330
  * Parses and verifies the body of a SOAP notification
2285
2331
  */
@@ -2305,6 +2351,8 @@ const createRedsysAPI = (config) => {
2305
2351
  restIniciaPeticion,
2306
2352
  restTrataPeticion,
2307
2353
  createRedirectForm,
2354
+ processRedirectNotification,
2355
+ processDirectRestNotification,
2308
2356
  processRestNotification,
2309
2357
  processSoapNotification,
2310
2358
  createSoapNotificationAnswer
@@ -2736,7 +2784,7 @@ for (const [key, value] of Object.entries(CURRENCIES)) {
2736
2784
  const LANGUAGES = {
2737
2785
  es: '1',
2738
2786
  en: '2',
2739
- ca: '3',
2787
+ ca: '3', // Codigo ISO "ca" compartido por catalan(3) y valenciano(10)
2740
2788
  fr: '4',
2741
2789
  de: '5',
2742
2790
  nl: '6',
@@ -3520,6 +3568,7 @@ exports.create3DSMethodForm = create3DSMethodForm;
3520
3568
  exports.create3DSv1ChallengeForm = create3DSv1ChallengeForm;
3521
3569
  exports.create3DSv2ChallengeForm = create3DSv2ChallengeForm;
3522
3570
  exports.createRedsysAPI = createRedsysAPI;
3571
+ exports.deserializeAndVerifyJSONResponse = deserializeAndVerifyJSONResponse;
3523
3572
  exports.deserializeCres = deserializeCres;
3524
3573
  exports.deserializeThreeDSMethodData = deserializeThreeDSMethodData;
3525
3574
  exports.detectSoapVersion = detectSoapVersion;
@@ -3536,6 +3585,7 @@ exports.restIniciaPeticionOutputFormatter = restIniciaPeticionOutputFormatter;
3536
3585
  exports.restNotificationOutputFormatter = restNotificationOutputFormatter;
3537
3586
  exports.restTrataPeticionInputFormatter = restTrataPeticionInputFormatter;
3538
3587
  exports.restTrataPeticionOutputFormatter = restTrataPeticionOutputFormatter;
3588
+ exports.serializeAndSignJSONRequest = serializeAndSignJSONRequest;
3539
3589
  exports.soapNotificationOutputFormatter = soapNotificationOutputFormatter;
3540
3590
  exports.useOutputFormatter = useOutputFormatter;
3541
3591
  exports.usePromiseOutputFormatter = usePromiseOutputFormatter;
package/lib/rest/3ds.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { ThreeDSv1ChallengeOutputParams, ThreeDSv2ChallengeOutputParams, Th
4
4
  *
5
5
  * @public
6
6
  */
7
- export declare const create3DSMethodForm: (emv3dsParams: Pick<ThreeDSv2PreAuthWithMethodOutputParams, 'threeDSServerTransID' | 'threeDSMethodURL'>, notificationURL: string) => ThreeDSMethodForm;
7
+ export declare const create3DSMethodForm: (emv3dsParams: Pick<ThreeDSv2PreAuthWithMethodOutputParams, "threeDSServerTransID" | "threeDSMethodURL">, notificationURL: string) => ThreeDSMethodForm;
8
8
  /**
9
9
  * Creates parameters for a 3DS v1 challenge form
10
10
  *
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Tries to decode x-www-form-urlencoded values of an object
3
+ */
4
+ export declare const decodeUrlEntries: <T extends object>(params: T) => T;
@@ -1,3 +1,3 @@
1
1
  import type { ParsedSoapNotifiation, SoapNotificationResponse } from '../types/api';
2
2
  export declare const serializeSoapNotificationResponse: ({ allow: allowOperation }: SoapNotificationResponse) => string;
3
- export declare const deserializeSoapNotification: (xml: string) => ParsedSoapNotifiation['Message'];
3
+ export declare const deserializeSoapNotification: (xml: string) => ParsedSoapNotifiation["Message"];
@@ -1,3 +1,3 @@
1
1
  import type { ParsedSoapNotifiation, SoapNotificationResponse } from '../types/api';
2
- export declare const verifySoapNotification: (merchantKey: string, xml: string, msg: ParsedSoapNotifiation['Message']) => void;
2
+ export declare const verifySoapNotification: (merchantKey: string, xml: string, msg: ParsedSoapNotifiation["Message"]) => void;
3
3
  export declare const signSoapNotificationResponse: (merchantKey: string, serializedResponse: string, response: SoapNotificationResponse) => string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "redsys-easy",
3
3
  "description": "Node JS interface for Redsys payment gateway",
4
- "version": "5.2.4",
4
+ "version": "5.2.6",
5
5
  "author": "Javier Garcia <javiertury@gmail.com>",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -62,6 +62,7 @@
62
62
  "@typescript-eslint/eslint-plugin": "^5.62.0",
63
63
  "@typescript-eslint/parser": "^5.62.0",
64
64
  "cheerio": "1.0.0-rc.12",
65
+ "commit-and-tag-version": "^12.5.0",
65
66
  "eslint": "^8.46.0",
66
67
  "eslint-config-prettier": "^8.10.0",
67
68
  "eslint-config-standard-with-typescript": "^37.0.0",
@@ -76,10 +77,9 @@
76
77
  "lint-staged": "^13.2.3",
77
78
  "markdown-magic": "^2.6.1",
78
79
  "rimraf": "^5.0.1",
79
- "rollup": "^3.27.1",
80
+ "rollup": "^3.29.5",
80
81
  "rollup-plugin-typescript2": "^0.35.0",
81
82
  "simple-git-hooks": "^2.9.0",
82
- "standard-version": "^9.5.0",
83
83
  "ts-expect": "^1.3.0",
84
84
  "ts-jest": "^29.1.1",
85
85
  "typescript": "^5.1.6"
@@ -118,6 +118,6 @@
118
118
  "docs:api": "api-documenter markdown --input-folder ./api/temp --output-folder ./docs",
119
119
  "docs:readme": "md-magic --path ./README.md",
120
120
  "docs": "pnpm run docs:api && pnpm run docs:readme",
121
- "release": "pnpm run test && standard-version --dry-run && pnpm run docs && git add docs CHANGELOG.md && standard-version --commit-all"
121
+ "release": "pnpm run test && commit-and-tag-version --dry-run && pnpm run docs && git add docs CHANGELOG.md && commit-and-tag-version --commit-all"
122
122
  }
123
123
  }