awesome-node-checkout 2.0.0 → 2.1.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/CHANGELOG.md +35 -0
- package/README.md +280 -2
- package/dist/adapters/express/index.d.ts +69 -1
- package/dist/adapters/express/index.d.ts.map +1 -1
- package/dist/adapters/express/index.js +147 -2
- package/dist/adapters/express/index.js.map +1 -1
- package/dist/checkout-configurator.d.ts +106 -0
- package/dist/checkout-configurator.d.ts.map +1 -1
- package/dist/checkout-configurator.js +515 -0
- package/dist/checkout-configurator.js.map +1 -1
- package/dist/events/checkout-event-bus.d.ts +11 -1
- package/dist/events/checkout-event-bus.d.ts.map +1 -1
- package/dist/events/checkout-event-bus.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/mandate-provider.interface.d.ts +40 -0
- package/dist/interfaces/mandate-provider.interface.d.ts.map +1 -0
- package/dist/interfaces/mandate-provider.interface.js +18 -0
- package/dist/interfaces/mandate-provider.interface.js.map +1 -0
- package/dist/models/checkout-config.model.d.ts +16 -0
- package/dist/models/checkout-config.model.d.ts.map +1 -1
- package/dist/models/errors.d.ts +1 -1
- package/dist/models/errors.d.ts.map +1 -1
- package/dist/models/errors.js.map +1 -1
- package/dist/models/mandate.model.d.ts +166 -0
- package/dist/models/mandate.model.d.ts.map +1 -0
- package/dist/models/mandate.model.js +19 -0
- package/dist/models/mandate.model.js.map +1 -0
- package/dist/providers/nexi/nexi.provider.d.ts +125 -1
- package/dist/providers/nexi/nexi.provider.d.ts.map +1 -1
- package/dist/providers/nexi/nexi.provider.js +652 -10
- package/dist/providers/nexi/nexi.provider.js.map +1 -1
- package/dist/providers/paypal/paypal.provider.d.ts +44 -1
- package/dist/providers/paypal/paypal.provider.d.ts.map +1 -1
- package/dist/providers/paypal/paypal.provider.js +519 -0
- package/dist/providers/paypal/paypal.provider.js.map +1 -1
- package/dist/providers/satispay/satispay.provider.d.ts +86 -1
- package/dist/providers/satispay/satispay.provider.d.ts.map +1 -1
- package/dist/providers/satispay/satispay.provider.js +417 -0
- package/dist/providers/satispay/satispay.provider.js.map +1 -1
- package/dist/utils/redact.d.ts +15 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/redact.js +60 -0
- package/dist/utils/redact.js.map +1 -0
- package/dist/utils/url.d.ts +12 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +19 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +2 -2
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAC7F,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAC7F,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AACnG,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAClF,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,OAAO,EACP,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAGhF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACtF,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAG3F,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAGhF,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,YAAY,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAGrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ISO_4217_ALPHA3_CODES = exports.SatispayProvider = exports.NexiProvider = exports.PayPalProvider = exports.InMemoryTransactionStore = exports.CheckoutListenerError = exports.CheckoutEventBus = exports.BasePaymentProvider = exports.CheckoutError = exports.CheckoutConfigurator = void 0;
|
|
3
|
+
exports.appendMandateRef = exports.ISO_4217_ALPHA3_CODES = exports.SatispayProvider = exports.NexiProvider = exports.PayPalProvider = exports.InMemoryTransactionStore = exports.CheckoutListenerError = exports.CheckoutEventBus = exports.BasePaymentProvider = exports.CheckoutError = exports.CHARGE_REF_PATTERN = exports.MANDATE_REF_PATTERN = exports.isMandateProvider = exports.CheckoutConfigurator = void 0;
|
|
4
4
|
// ---- Configurator ----------------------------------------------------------
|
|
5
5
|
var checkout_configurator_1 = require("./checkout-configurator");
|
|
6
6
|
Object.defineProperty(exports, "CheckoutConfigurator", { enumerable: true, get: function () { return checkout_configurator_1.CheckoutConfigurator; } });
|
|
7
|
+
var mandate_provider_interface_1 = require("./interfaces/mandate-provider.interface");
|
|
8
|
+
Object.defineProperty(exports, "isMandateProvider", { enumerable: true, get: function () { return mandate_provider_interface_1.isMandateProvider; } });
|
|
9
|
+
var mandate_model_1 = require("./models/mandate.model");
|
|
10
|
+
Object.defineProperty(exports, "MANDATE_REF_PATTERN", { enumerable: true, get: function () { return mandate_model_1.MANDATE_REF_PATTERN; } });
|
|
11
|
+
Object.defineProperty(exports, "CHARGE_REF_PATTERN", { enumerable: true, get: function () { return mandate_model_1.CHARGE_REF_PATTERN; } });
|
|
7
12
|
var errors_1 = require("./models/errors");
|
|
8
13
|
Object.defineProperty(exports, "CheckoutError", { enumerable: true, get: function () { return errors_1.CheckoutError; } });
|
|
9
14
|
// ---- Abstract --------------------------------------------------------------
|
|
@@ -26,4 +31,6 @@ Object.defineProperty(exports, "SatispayProvider", { enumerable: true, get: func
|
|
|
26
31
|
// ---- Utils -----------------------------------------------------------------
|
|
27
32
|
var parsing_util_1 = require("./utils/parsing.util");
|
|
28
33
|
Object.defineProperty(exports, "ISO_4217_ALPHA3_CODES", { enumerable: true, get: function () { return parsing_util_1.ISO_4217_ALPHA3_CODES; } });
|
|
34
|
+
var url_1 = require("./utils/url");
|
|
35
|
+
Object.defineProperty(exports, "appendMandateRef", { enumerable: true, get: function () { return url_1.appendMandateRef; } });
|
|
29
36
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+EAA+E;AAC/E,iEAA+D;AAAtD,6HAAA,oBAAoB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+EAA+E;AAC/E,iEAA+D;AAAtD,6HAAA,oBAAoB,OAAA;AAM7B,sFAA4E;AAAnE,+HAAA,iBAAiB,OAAA;AAoB1B,wDAAiF;AAAxE,oHAAA,mBAAmB,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAChD,0CAAgD;AAAvC,uGAAA,aAAa,OAAA;AAGtB,+EAA+E;AAC/E,4FAAgF;AAAvE,qIAAA,mBAAmB,OAAA;AAE5B,+EAA+E;AAC/E,kEAAsF;AAA7E,sHAAA,gBAAgB,OAAA;AAAE,2HAAA,qBAAqB,OAAA;AAGhD,+EAA+E;AAC/E,oFAAgF;AAAvE,uIAAA,wBAAwB,OAAA;AAEjC,+EAA+E;AAC/E,sEAAoE;AAA3D,iHAAA,cAAc,OAAA;AAGvB,gEAA8D;AAArD,6GAAA,YAAY,OAAA;AAGrB,4EAA0E;AAAjE,qHAAA,gBAAgB,OAAA;AAGzB,+EAA+E;AAC/E,qDAA6D;AAApD,qHAAA,qBAAqB,OAAA;AAC9B,mCAA+C;AAAtC,uGAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IPaymentProvider } from './payment-provider.interface';
|
|
2
|
+
import { ChargeRequest, ChargeResult, Mandate, MandateCallbackInput, MandatePendingState, MandateRevokeResult, MandateSetupOutcome, MandateSetupRequest, MandateSetupStart, MandateStatusResult } from '../models/mandate.model';
|
|
3
|
+
/**
|
|
4
|
+
* Optional capability of a payment provider: recurring payments (mandates).
|
|
5
|
+
*
|
|
6
|
+
* Implemented next to `IPaymentProvider` (`class X extends BasePaymentProvider implements
|
|
7
|
+
* IMandateProvider`); `IPaymentProvider` itself is unchanged. Call these methods through
|
|
8
|
+
* `CheckoutConfigurator`, which validates the inputs and normalizes the outcomes (fail closed).
|
|
9
|
+
*
|
|
10
|
+
* Rules for implementers:
|
|
11
|
+
* - Stateless: everything needed later is in the returned `MandatePendingState` / `Mandate`.
|
|
12
|
+
* - Identities (contract number, vault id, token id, order id) come from `pending` / `mandate` or
|
|
13
|
+
* from authenticated fields, never from query strings or unsigned callback fields.
|
|
14
|
+
* - `verified: true` only for outcomes authenticated by a MAC/signature checked by the library or
|
|
15
|
+
* by an authenticated server-to-server response.
|
|
16
|
+
* - Timeouts, 5xx, unparseable bodies and merchant-side refusals (401/403/429, auth/MAC errors,
|
|
17
|
+
* rate limiting) are `unknown`, never `failed`.
|
|
18
|
+
* - Append `mandate_ref` to `returnUrl`, `cancelUrl` and `notifyUrl` with `appendMandateRef`.
|
|
19
|
+
* - Never retry on your own.
|
|
20
|
+
*/
|
|
21
|
+
export interface IMandateProvider {
|
|
22
|
+
/** Starts a setup (customer present). The setup always includes the first charge. */
|
|
23
|
+
createMandate(request: MandateSetupRequest): Promise<MandateSetupStart>;
|
|
24
|
+
/**
|
|
25
|
+
* Idempotent: may be called twice (redirect + server notification) for the same pending state.
|
|
26
|
+
* Must also be safe to call again with an empty `input` (`{}`) at any time, including after a
|
|
27
|
+
* terminal outcome: apps re-run it from a job to resolve a first charge reported `unknown`. Re-read
|
|
28
|
+
* the setup server-to-server or replay the same idempotency keys; never start a second first
|
|
29
|
+
* charge. Without a way to re-read, return an unverified, non-terminal outcome.
|
|
30
|
+
*/
|
|
31
|
+
confirmMandate(pending: MandatePendingState, input: MandateCallbackInput): Promise<MandateSetupOutcome>;
|
|
32
|
+
/** Merchant-initiated charge (customer absent). Idempotent on `charge.chargeRef`. */
|
|
33
|
+
chargeMandate(mandate: Mandate, charge: ChargeRequest): Promise<ChargeResult>;
|
|
34
|
+
/** Re-reads usability from the provider when it can; otherwise returns verified: false. */
|
|
35
|
+
getMandate(mandate: Mandate): Promise<MandateStatusResult>;
|
|
36
|
+
revokeMandate(mandate: Mandate): Promise<MandateRevokeResult>;
|
|
37
|
+
}
|
|
38
|
+
/** True when `p` implements all five `IMandateProvider` methods. */
|
|
39
|
+
export declare function isMandateProvider(p: unknown): p is IPaymentProvider & IMandateProvider;
|
|
40
|
+
//# sourceMappingURL=mandate-provider.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandate-provider.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/mandate-provider.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EACL,aAAa,EACb,YAAY,EACZ,OAAO,EACP,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qFAAqF;IACrF,aAAa,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxE;;;;;;OAMG;IACH,cAAc,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxG,qFAAqF;IACrF,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9E,2FAA2F;IAC3F,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC3D,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC/D;AAUD,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,gBAAgB,GAAG,gBAAgB,CAItF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isMandateProvider = isMandateProvider;
|
|
4
|
+
const MANDATE_METHODS = [
|
|
5
|
+
'createMandate',
|
|
6
|
+
'confirmMandate',
|
|
7
|
+
'chargeMandate',
|
|
8
|
+
'getMandate',
|
|
9
|
+
'revokeMandate',
|
|
10
|
+
];
|
|
11
|
+
/** True when `p` implements all five `IMandateProvider` methods. */
|
|
12
|
+
function isMandateProvider(p) {
|
|
13
|
+
if (p === null || (typeof p !== 'object' && typeof p !== 'function'))
|
|
14
|
+
return false;
|
|
15
|
+
const candidate = p;
|
|
16
|
+
return MANDATE_METHODS.every((method) => typeof candidate[method] === 'function');
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=mandate-provider.interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandate-provider.interface.js","sourceRoot":"","sources":["../../src/interfaces/mandate-provider.interface.ts"],"names":[],"mappings":";;AA2DA,8CAIC;AAbD,MAAM,eAAe,GAAG;IACtB,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,YAAY;IACZ,eAAe;CACP,CAAC;AAEX,oEAAoE;AACpE,SAAgB,iBAAiB,CAAC,CAAU;IAC1C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACnF,MAAM,SAAS,GAAG,CAA4B,CAAC;IAC/C,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC,CAAC;AACpF,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CheckoutEventName } from '../events/checkout-event-bus';
|
|
1
2
|
/**
|
|
2
3
|
* Global configuration for CheckoutConfigurator.
|
|
3
4
|
*/
|
|
@@ -8,5 +9,20 @@ export interface CheckoutConfig {
|
|
|
8
9
|
* @default true
|
|
9
10
|
*/
|
|
10
11
|
emitEvents?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Receives an error raised while emitting an event after a mandate provider call has completed
|
|
14
|
+
* (`mandate.created`, `mandate.setup_failed` and the first `charge.*` from `confirmMandate`,
|
|
15
|
+
* `charge.*` from `chargeMandate`, `mandate.revoked` from `revokeMandate`). Usually a
|
|
16
|
+
* `CheckoutListenerError` (original value in `cause`).
|
|
17
|
+
*
|
|
18
|
+
* Those methods never reject because of a listener: money may already have moved, so the
|
|
19
|
+
* normalized result always reaches the caller and the error comes here instead. When this
|
|
20
|
+
* hook is not set, the error is logged with `console.error('[awesome-node-checkout]', err)`.
|
|
21
|
+
* An error thrown by the hook itself is logged and never rejects the method.
|
|
22
|
+
*
|
|
23
|
+
* Every other event, `mandate.setup_started` included, still propagates listener errors to the
|
|
24
|
+
* caller.
|
|
25
|
+
*/
|
|
26
|
+
onListenerError?: (err: unknown, event: CheckoutEventName) => void | Promise<void>;
|
|
11
27
|
}
|
|
12
28
|
//# sourceMappingURL=checkout-config.model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout-config.model.d.ts","sourceRoot":"","sources":["../../src/models/checkout-config.model.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"checkout-config.model.d.ts","sourceRoot":"","sources":["../../src/models/checkout-config.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpF"}
|
package/dist/models/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CheckoutErrorCode = 'PROVIDER_NOT_FOUND' | 'PROVIDER_ALREADY_REGISTERED' | 'PAYMENT_FAILED' | 'WEBHOOK_NOT_SUPPORTED' | 'REDIRECT_NOT_SUPPORTED' | 'TRANSACTION_NOT_FOUND' | 'INSECURE_CONFIGURATION' | 'INVALID_AMOUNT';
|
|
1
|
+
export type CheckoutErrorCode = 'PROVIDER_NOT_FOUND' | 'PROVIDER_ALREADY_REGISTERED' | 'PAYMENT_FAILED' | 'WEBHOOK_NOT_SUPPORTED' | 'REDIRECT_NOT_SUPPORTED' | 'TRANSACTION_NOT_FOUND' | 'INSECURE_CONFIGURATION' | 'INVALID_AMOUNT' | 'MANDATES_NOT_SUPPORTED' | 'INVALID_MANDATE_REQUEST';
|
|
2
2
|
export declare class CheckoutError extends Error {
|
|
3
3
|
readonly code: CheckoutErrorCode;
|
|
4
4
|
readonly provider?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/models/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,oBAAoB,GACpB,6BAA6B,GAC7B,gBAAgB,GAChB,uBAAuB,GACvB,wBAAwB,GACxB,uBAAuB,GACvB,wBAAwB,GACxB,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/models/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,oBAAoB,GACpB,6BAA6B,GAC7B,gBAAgB,GAChB,uBAAuB,GACvB,wBAAwB,GACxB,uBAAuB,GACvB,wBAAwB,GACxB,gBAAgB,GAChB,wBAAwB,GACxB,yBAAyB,CAAC;AAE9B,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,iBAAiB;aACvB,QAAQ,CAAC,EAAE,MAAM;gBAFjC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,iBAAiB,EACvB,QAAQ,CAAC,EAAE,MAAM,YAAA;CASpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/models/errors.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/models/errors.ts"],"names":[],"mappings":";;;AAYA,MAAa,aAAc,SAAQ,KAAK;IACtC,YACE,OAAe,EACC,IAAuB,EACvB,QAAiB;QAEjC,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAmB;QACvB,aAAQ,GAAR,QAAQ,CAAS;QAGjC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,qCAAqC;QACrC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;CACF;AAbD,sCAaC"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recurring payments (mandates).
|
|
3
|
+
*
|
|
4
|
+
* The library provides mandate primitives only (create, confirm, charge, get, revoke). The app
|
|
5
|
+
* owns scheduling, retries and dunning, subscription state, prices, VAT and invoices. Every
|
|
6
|
+
* object below is plain JSON: the app persists it and passes it back later, so a restart or a
|
|
7
|
+
* second instance loses nothing. The library keeps no mandate state in memory.
|
|
8
|
+
*/
|
|
9
|
+
/** `mandateRef`: 5-30 chars of `A-Z a-z 0-9 _ -` (Nexi `num_contratto` limits). */
|
|
10
|
+
export declare const MANDATE_REF_PATTERN: RegExp;
|
|
11
|
+
/**
|
|
12
|
+
* `orderId` of a setup and `chargeRef` of a charge: 2-30 chars of `A-Z a-z 0-9 -`, no
|
|
13
|
+
* underscore (Nexi `codiceTransazione` limits).
|
|
14
|
+
*/
|
|
15
|
+
export declare const CHARGE_REF_PATTERN: RegExp;
|
|
16
|
+
export interface MandateSetupRequest {
|
|
17
|
+
/** Fresh for EVERY setup attempt (never reuse one after a failed or abandoned setup). /^[A-Za-z0-9_-]{5,30}$/ (Nexi num_contratto limits). */
|
|
18
|
+
mandateRef: string;
|
|
19
|
+
/**
|
|
20
|
+
* Order code of the FIRST charge; also its chargeRef. Fresh for every setup attempt.
|
|
21
|
+
* /^[A-Za-z0-9-]{2,30}$/ (no underscore: Nexi codiceTransazione). Never pass it to
|
|
22
|
+
* `chargeMandate`: an `unknown` first charge is resolved by re-running `confirmMandate`.
|
|
23
|
+
*/
|
|
24
|
+
orderId: string;
|
|
25
|
+
/** First charge, major units; validated with toMinorUnits(amount, currency). */
|
|
26
|
+
amount: number;
|
|
27
|
+
/** ISO 4217 alpha-3. A provider may restrict it (Nexi: EUR only). */
|
|
28
|
+
currency: string;
|
|
29
|
+
/** Shown to the payer (PayPal vault description, Satispay reason). 1-127 chars. */
|
|
30
|
+
description: string;
|
|
31
|
+
/**
|
|
32
|
+
* Where the customer comes back after approving. With the Express adapter it must point to
|
|
33
|
+
* `<mount>/<provider>/mandate/callback`; the provider appends `mandate_ref`.
|
|
34
|
+
*/
|
|
35
|
+
returnUrl: string;
|
|
36
|
+
/** Where the customer comes back after cancelling. Same rule as `returnUrl`. */
|
|
37
|
+
cancelUrl: string;
|
|
38
|
+
/** Server-to-server notification URL, where supported (Nexi urlpost, Satispay callback_url). */
|
|
39
|
+
notifyUrl?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Persist verbatim; pass back to confirmMandate. JSON-serializable. Keep it after a terminal
|
|
43
|
+
* outcome consumed it while that outcome's `firstCharge` is `unknown`: it is the input of
|
|
44
|
+
* `confirmMandate(provider, pending, {})`, which resolves the first charge.
|
|
45
|
+
*/
|
|
46
|
+
export interface MandatePendingState {
|
|
47
|
+
provider: string;
|
|
48
|
+
mandateRef: string;
|
|
49
|
+
orderId: string;
|
|
50
|
+
amount: number;
|
|
51
|
+
currency: string;
|
|
52
|
+
/** Provider object created at setup: PayPal order id, Satispay authorization token id, Nexi codTrans. */
|
|
53
|
+
providerRef: string;
|
|
54
|
+
/** ISO 8601 */
|
|
55
|
+
createdAt: string;
|
|
56
|
+
}
|
|
57
|
+
export interface MandateSetupStart {
|
|
58
|
+
success: boolean;
|
|
59
|
+
/** Where to send the customer. */
|
|
60
|
+
approvalUrl?: string;
|
|
61
|
+
pending?: MandatePendingState;
|
|
62
|
+
error?: string;
|
|
63
|
+
raw?: unknown;
|
|
64
|
+
}
|
|
65
|
+
export type MandateStatus = 'active' | 'revoked';
|
|
66
|
+
/** Persist verbatim; pass back to chargeMandate / getMandate / revokeMandate. JSON-serializable. */
|
|
67
|
+
export interface Mandate {
|
|
68
|
+
provider: string;
|
|
69
|
+
mandateRef: string;
|
|
70
|
+
/**
|
|
71
|
+
* Nexi: num_contratto (= mandateRef). PayPal: vault payment token id. Satispay: authorization
|
|
72
|
+
* token id. Credential-like: never put it in logs, URLs or events (the library never does).
|
|
73
|
+
*/
|
|
74
|
+
providerMandateId: string;
|
|
75
|
+
status: MandateStatus;
|
|
76
|
+
/** ISO 8601 */
|
|
77
|
+
createdAt: string;
|
|
78
|
+
/** Provider-specific extra the provider needs at charge time (e.g. PayPal customer id). Never secrets. */
|
|
79
|
+
providerData?: Record<string, string>;
|
|
80
|
+
/** Hints from unsigned fields. Never use for authorization decisions. */
|
|
81
|
+
unverified?: {
|
|
82
|
+
cardExpiry?: string;
|
|
83
|
+
maskedPan?: string;
|
|
84
|
+
payerEmail?: string;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* - `succeeded`: the charge was authoritatively accepted (only with `verified: true`).
|
|
89
|
+
* - `failed`: the charge was authoritatively refused. Counts towards dunning; a retry is a NEW
|
|
90
|
+
* charge with a new `chargeRef`.
|
|
91
|
+
* - `unknown`: timeout, 5xx, unparseable body, merchant-side refusal (401/403/429, auth/MAC
|
|
92
|
+
* error, rate limit) or an unauthenticated "success". A `chargeMandate` charge: retry with the
|
|
93
|
+
* SAME `chargeRef`. The first charge of a setup (`chargeRef = orderId`): re-run
|
|
94
|
+
* `confirmMandate(provider, pending, {})`, never `chargeMandate` with the setup's `orderId`.
|
|
95
|
+
* - `requires_action`: the provider needs the customer (e.g. PayPal `PAYER_ACTION_REQUIRED`).
|
|
96
|
+
*/
|
|
97
|
+
export type ChargeStatus = 'succeeded' | 'failed' | 'unknown' | 'requires_action';
|
|
98
|
+
export interface ChargeRequest {
|
|
99
|
+
/** Idempotency key, unique per intended charge, stable across retries. /^[A-Za-z0-9-]{2,30}$/ (no underscore: Nexi codiceTransazione) */
|
|
100
|
+
chargeRef: string;
|
|
101
|
+
/** Major units; validated with toMinorUnits(amount, currency). */
|
|
102
|
+
amount: number;
|
|
103
|
+
currency: string;
|
|
104
|
+
description?: string;
|
|
105
|
+
}
|
|
106
|
+
export interface ChargeResult {
|
|
107
|
+
status: ChargeStatus;
|
|
108
|
+
/** true only for outcomes authenticated by MAC/signature or authenticated API response. */
|
|
109
|
+
verified: boolean;
|
|
110
|
+
chargeRef: string;
|
|
111
|
+
providerPaymentId?: string;
|
|
112
|
+
amount?: number;
|
|
113
|
+
currency?: string;
|
|
114
|
+
/** Set when the provider says the mandate is no longer usable (revoked, expired, contract KO). */
|
|
115
|
+
mandateUnusable?: boolean;
|
|
116
|
+
error?: string;
|
|
117
|
+
/** Provider decline/error code when available. */
|
|
118
|
+
providerCode?: string;
|
|
119
|
+
raw?: unknown;
|
|
120
|
+
}
|
|
121
|
+
export interface MandateSetupOutcome {
|
|
122
|
+
/** true when the mandate is active (first charge may still have failed: check firstCharge). */
|
|
123
|
+
success: boolean;
|
|
124
|
+
verified: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* true only when this outcome is final for the pending setup: verified AND either the mandate is
|
|
127
|
+
* active or the provider authoritatively refused it. Only a terminal outcome may consume the
|
|
128
|
+
* pending state. A non-terminal outcome (unverified, still pending, network error) must leave it
|
|
129
|
+
* in place so the genuine callback can still complete the setup.
|
|
130
|
+
*/
|
|
131
|
+
terminal: boolean;
|
|
132
|
+
mandate?: Mandate;
|
|
133
|
+
/**
|
|
134
|
+
* The first charge (`chargeRef = orderId`). It can be `unknown` on a terminal outcome, even with
|
|
135
|
+
* `success: true` (e.g. a PayPal capture still `PENDING`, a Satispay first payment that timed
|
|
136
|
+
* out). Resolve it by keeping the consumed pending state and re-running
|
|
137
|
+
* `confirmMandate(provider, pending, {})` from a job, never with `chargeMandate` and the setup's
|
|
138
|
+
* `orderId` (on PayPal that is a new order: a double charge or `DUPLICATE_INVOICE_ID`).
|
|
139
|
+
*/
|
|
140
|
+
firstCharge: ChargeResult;
|
|
141
|
+
error?: string;
|
|
142
|
+
raw?: unknown;
|
|
143
|
+
}
|
|
144
|
+
export interface MandateCallbackInput {
|
|
145
|
+
query?: Record<string, string>;
|
|
146
|
+
body?: Record<string, unknown>;
|
|
147
|
+
headers?: Record<string, string>;
|
|
148
|
+
context?: {
|
|
149
|
+
method?: string;
|
|
150
|
+
path?: string;
|
|
151
|
+
rawBody?: Buffer | string;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/** Result of `getMandate`: `verified: false` when the provider cannot re-read the mandate. */
|
|
155
|
+
export interface MandateStatusResult {
|
|
156
|
+
status: MandateStatus | 'unknown';
|
|
157
|
+
verified: boolean;
|
|
158
|
+
raw?: unknown;
|
|
159
|
+
}
|
|
160
|
+
/** Result of `revokeMandate`. Mark your own copy revoked whatever it says. */
|
|
161
|
+
export interface MandateRevokeResult {
|
|
162
|
+
revokedAtProvider: boolean;
|
|
163
|
+
error?: string;
|
|
164
|
+
raw?: unknown;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=mandate.model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandate.model.d.ts","sourceRoot":"","sources":["../../src/models/mandate.model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Recurring payments (mandates).
|
|
4
|
+
*
|
|
5
|
+
* The library provides mandate primitives only (create, confirm, charge, get, revoke). The app
|
|
6
|
+
* owns scheduling, retries and dunning, subscription state, prices, VAT and invoices. Every
|
|
7
|
+
* object below is plain JSON: the app persists it and passes it back later, so a restart or a
|
|
8
|
+
* second instance loses nothing. The library keeps no mandate state in memory.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.CHARGE_REF_PATTERN = exports.MANDATE_REF_PATTERN = void 0;
|
|
12
|
+
/** `mandateRef`: 5-30 chars of `A-Z a-z 0-9 _ -` (Nexi `num_contratto` limits). */
|
|
13
|
+
exports.MANDATE_REF_PATTERN = /^[A-Za-z0-9_-]{5,30}$/;
|
|
14
|
+
/**
|
|
15
|
+
* `orderId` of a setup and `chargeRef` of a charge: 2-30 chars of `A-Z a-z 0-9 -`, no
|
|
16
|
+
* underscore (Nexi `codiceTransazione` limits).
|
|
17
|
+
*/
|
|
18
|
+
exports.CHARGE_REF_PATTERN = /^[A-Za-z0-9-]{2,30}$/;
|
|
19
|
+
//# sourceMappingURL=mandate.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandate.model.js","sourceRoot":"","sources":["../../src/models/mandate.model.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,mFAAmF;AACtE,QAAA,mBAAmB,GAAG,uBAAuB,CAAC;AAE3D;;;GAGG;AACU,QAAA,kBAAkB,GAAG,sBAAsB,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { BasePaymentProvider } from '../../abstract/base-payment-provider.abstract';
|
|
2
2
|
import { PaymentRequest } from '../../models/payment-request.model';
|
|
3
3
|
import { PaymentResult, WebhookResult } from '../../models/payment-result.model';
|
|
4
|
+
import { IMandateProvider } from '../../interfaces/mandate-provider.interface';
|
|
5
|
+
import { ChargeRequest, ChargeResult, Mandate, MandateCallbackInput, MandatePendingState, MandateRevokeResult, MandateSetupOutcome, MandateSetupRequest, MandateSetupStart, MandateStatusResult } from '../../models/mandate.model';
|
|
4
6
|
export interface NexiProviderConfig {
|
|
5
7
|
merchantId: string;
|
|
6
8
|
macKey: string;
|
|
@@ -8,20 +10,37 @@ export interface NexiProviderConfig {
|
|
|
8
10
|
group?: string;
|
|
9
11
|
/** @default 'sandbox' */
|
|
10
12
|
environment?: 'sandbox' | 'production';
|
|
13
|
+
/**
|
|
14
|
+
* Timeout of the recurring-payment and contract API calls (`pagamentoRicorrente`,
|
|
15
|
+
* `situazioneOrdine` replay guard, `dettagliContratto`, `cancellaContratto`), in ms.
|
|
16
|
+
* @default 30000
|
|
17
|
+
*/
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Mandates: contract type sent as `tipo_contratto` at setup (`S` scheduled, `U` unscheduled) and
|
|
21
|
+
* included in the setup MAC. Only needed when the terminal is enabled for both kinds.
|
|
22
|
+
*/
|
|
23
|
+
contractType?: 'S' | 'U';
|
|
11
24
|
}
|
|
12
25
|
/**
|
|
13
26
|
* Nexi eCommerce provider.
|
|
14
27
|
* Flow: `redirect` — builds a signed checkout URL, redirects the user to Nexi,
|
|
15
28
|
* then handles the POST-back via `handleRedirect`.
|
|
16
29
|
*
|
|
30
|
+
* Recurring payments (`IMandateProvider`): the setup is a hosted-page first payment that
|
|
31
|
+
* registers a contract (`num_contratto` = `mandateRef`, `tipo_servizio=paga_multi`,
|
|
32
|
+
* `tipo_richiesta=PP`); later charges use `pagamentoRicorrente`; `cancellaContratto` revokes.
|
|
33
|
+
* EUR only. See "Specifiche tecniche di integrazione con il gateway di pagamento XPay" v20.4.
|
|
34
|
+
*
|
|
17
35
|
* Note: Nexi XPay mandates SHA-1 for MAC computation. This is a requirement of
|
|
18
36
|
* the Nexi API and cannot be changed on the client side.
|
|
19
37
|
*/
|
|
20
|
-
export declare class NexiProvider extends BasePaymentProvider {
|
|
38
|
+
export declare class NexiProvider extends BasePaymentProvider implements IMandateProvider {
|
|
21
39
|
private readonly config;
|
|
22
40
|
readonly name = "nexi";
|
|
23
41
|
readonly flow: "redirect";
|
|
24
42
|
private readonly apiUrl;
|
|
43
|
+
private readonly timeoutMs;
|
|
25
44
|
constructor(config: NexiProviderConfig);
|
|
26
45
|
/**
|
|
27
46
|
* Computes the SHA-1 MAC required by Nexi to authenticate the payment request.
|
|
@@ -58,6 +77,57 @@ export declare class NexiProvider extends BasePaymentProvider {
|
|
|
58
77
|
*/
|
|
59
78
|
private verifyResponseMac;
|
|
60
79
|
private safeVerifyResponseMac;
|
|
80
|
+
/**
|
|
81
|
+
* Extracts the fields of a hosted-page outcome (redirect query or `urlpost` form). Missing
|
|
82
|
+
* fields are `''`; `codTrans` falls back to `fallbackCodTrans` when given. `mac` is returned as
|
|
83
|
+
* is, to be checked with `isValidHexMac`.
|
|
84
|
+
*/
|
|
85
|
+
private extractOutcomeFields;
|
|
86
|
+
/** True when the 7-field outcome MAC of `fields` is present and valid (constant time). */
|
|
87
|
+
private outcomeMacValid;
|
|
88
|
+
/** Constant-time comparison of a hex MAC against the expected SHA-1 hex digest. */
|
|
89
|
+
private hexMacEquals;
|
|
90
|
+
/**
|
|
91
|
+
* Verifies the standard XPay REST response MAC:
|
|
92
|
+
* `esito={esito}idOperazione={idOperazione}timeStamp={timeStamp}{macKey}`.
|
|
93
|
+
*/
|
|
94
|
+
private responseMacValid;
|
|
95
|
+
/**
|
|
96
|
+
* MAC policy of the recurring and contract APIs: a present `mac` must be valid whatever the
|
|
97
|
+
* `esito`; a missing one is tolerated only on `KO` (an error answer may carry none).
|
|
98
|
+
*/
|
|
99
|
+
private responseAuthentic;
|
|
100
|
+
/**
|
|
101
|
+
* Classifies a "Tabella Codici errore API Restful" code (pp. 883-885). A missing or
|
|
102
|
+
* non-numeric code is `merchant`: without a code nothing says the customer is at fault.
|
|
103
|
+
*/
|
|
104
|
+
private classifyApiError;
|
|
105
|
+
/** `errore.codice` / `errore.messaggio` of a response, when present. */
|
|
106
|
+
private apiError;
|
|
107
|
+
/**
|
|
108
|
+
* Computes the MAC of `pagamentoRicorrente` (p. 191). `scadenza` is not sent, so it is in the
|
|
109
|
+
* string with an empty value, as the manual requires:
|
|
110
|
+
* `apiKey=…numeroContratto=…codiceTransazione=…importo=…divisa=978scadenza=timeStamp=…{macKey}`.
|
|
111
|
+
*/
|
|
112
|
+
private generateRecurringMac;
|
|
113
|
+
/**
|
|
114
|
+
* POSTs a JSON body to an XPay REST endpoint with the configured timeout. Never throws; the
|
|
115
|
+
* error never contains the response body.
|
|
116
|
+
*/
|
|
117
|
+
private postApi;
|
|
118
|
+
/**
|
|
119
|
+
* Reads `situazioneOrdine` for `codTrans` (same request as `getPaymentDetails`) and classifies
|
|
120
|
+
* the raw response, over every report entry for `codTrans`:
|
|
121
|
+
* - `paid`: some entry shows the money was taken (`NEXI_CHARGED_STATUSES`: paid, partly captured,
|
|
122
|
+
* refunded or partly refunded);
|
|
123
|
+
* - `pending`: otherwise, some entry is in progress (`In Corso`), has an unrecognised `stato`, or
|
|
124
|
+
* has none. Fail safe: such a code may still be charged, so it is never reported as refused;
|
|
125
|
+
* - `refused`: every entry is a clear refusal (`Negato`, `Annullato`, `Non Creato`);
|
|
126
|
+
* - `absent`: OK with no matching report entry, or KO "not found" 2/13;
|
|
127
|
+
* - `error`: anything else (HTTP, network, timeout, non-JSON, bad MAC, a missing MAC on OK, no
|
|
128
|
+
* `report` array, any other KO).
|
|
129
|
+
*/
|
|
130
|
+
private lookupTransaction;
|
|
61
131
|
createPayment(request: PaymentRequest): Promise<PaymentResult>;
|
|
62
132
|
/**
|
|
63
133
|
* Validates the POST-back data from Nexi.
|
|
@@ -81,5 +151,59 @@ export declare class NexiProvider extends BasePaymentProvider {
|
|
|
81
151
|
* The outcome MAC is mandatory and verified over all 7 fields to ensure authenticity.
|
|
82
152
|
*/
|
|
83
153
|
handleRedirect(query: Record<string, string>): Promise<PaymentResult>;
|
|
154
|
+
/**
|
|
155
|
+
* Starts a contract registration: a hosted-page first payment with `num_contratto` =
|
|
156
|
+
* `mandateRef`, `tipo_servizio=paga_multi`, `tipo_richiesta=PP` (pp. 59-65), charging the first
|
|
157
|
+
* period. `codTrans` is `orderId`. EUR only. `mandate_ref` is appended to `url`, `url_back` and
|
|
158
|
+
* `urlpost`.
|
|
159
|
+
*/
|
|
160
|
+
createMandate(request: MandateSetupRequest): Promise<MandateSetupStart>;
|
|
161
|
+
/**
|
|
162
|
+
* Confirms a setup from the hosted-page outcome: the redirect on `url` (GET query) or the
|
|
163
|
+
* `urlpost` notification (form POST). Pure function of its inputs, hence idempotent.
|
|
164
|
+
*
|
|
165
|
+
* - The 7-field outcome MAC must be valid, and the MAC-covered `codTrans`, `importo` and
|
|
166
|
+
* `divisa` must match `pending`; otherwise the outcome is unverified and non-terminal (a forged
|
|
167
|
+
* callback never consumes the pending state). The unsigned `num_contratto`, when present, must
|
|
168
|
+
* be `pending.mandateRef` (and `tipo_servizio` / `tipo_richiesta`, when present, `paga_multi` /
|
|
169
|
+
* `PP`); the contract number used is always `pending.mandateRef`.
|
|
170
|
+
* - `esito=OK` with `num_contratto`: active mandate, first charge `succeeded` (terminal). An OK
|
|
171
|
+
* without `num_contratto` is unverified and non-terminal (no contract may exist).
|
|
172
|
+
* - `esito` `KO`, `ANNULLO` or `ERRORE`: no mandate, first charge `failed` (terminal). Start a
|
|
173
|
+
* new setup with a fresh `mandateRef` and `orderId`: a `codTrans` is never reused. This
|
|
174
|
+
* requires a terminal that allows a single payment attempt per `codTrans`: on a terminal
|
|
175
|
+
* configured for up to 3 attempts (manual, pp. 32-33), a KO then an OK arrive for the same
|
|
176
|
+
* `codTrans`, and the OK finds the pending state already consumed.
|
|
177
|
+
* - Any other `esito` (e.g. a pending one) is unverified and non-terminal: it may still turn OK.
|
|
178
|
+
*
|
|
179
|
+
* An empty input (`{}`) has no MAC, so a re-confirm is unverified and non-terminal: Nexi never
|
|
180
|
+
* reports a terminal outcome with an `unknown` first charge.
|
|
181
|
+
*/
|
|
182
|
+
confirmMandate(pending: MandatePendingState, input: MandateCallbackInput): Promise<MandateSetupOutcome>;
|
|
183
|
+
/**
|
|
184
|
+
* Merchant-initiated charge with `pagamentoRicorrente` (pp. 188-193), EUR only.
|
|
185
|
+
* `codiceTransazione` is `charge.chargeRef`, so `refundPayment(chargeRef, amount)` refunds it.
|
|
186
|
+
*
|
|
187
|
+
* Replay guard: `situazioneOrdine` is read first. A transaction that took the money (paid,
|
|
188
|
+
* partly captured, refunded or partly refunded) is returned as `succeeded` without charging
|
|
189
|
+
* again, with its `stato` in `raw`; one that only Nexi refused (`Negato`, `Annullato`,
|
|
190
|
+
* `Non Creato`) is `failed` (a dunning retry needs a new `chargeRef`: Nexi's own retries of a
|
|
191
|
+
* code after a KO are not used); one still in progress (`In Corso`) or with an unrecognised
|
|
192
|
+
* `stato` is `unknown`, and so is a lookup error: nothing is charged. A Nexi "transaction
|
|
193
|
+
* already present" (9) is re-read.
|
|
194
|
+
* Merchant-side errors (credentials, MAC, technical) are `unknown`, never `failed`.
|
|
195
|
+
*/
|
|
196
|
+
chargeMandate(mandate: Mandate, charge: ChargeRequest): Promise<ChargeResult>;
|
|
197
|
+
/**
|
|
198
|
+
* Re-reads the contract with `dettagliContratto` (pp. 851-853). `active` when it is listed and
|
|
199
|
+
* its first payment is not KO; `revoked` when its first payment is KO or Nexi answers "not
|
|
200
|
+
* found" or "invalid contract"; otherwise `unknown` (unverified).
|
|
201
|
+
*/
|
|
202
|
+
getMandate(mandate: Mandate): Promise<MandateStatusResult>;
|
|
203
|
+
/**
|
|
204
|
+
* Cancels the contract with `cancellaContratto` (pp. 838-840). "Not found" and "invalid
|
|
205
|
+
* contract" count as revoked: the contract is already gone.
|
|
206
|
+
*/
|
|
207
|
+
revokeMandate(mandate: Mandate): Promise<MandateRevokeResult>;
|
|
84
208
|
}
|
|
85
209
|
//# sourceMappingURL=nexi.provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nexi.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/nexi/nexi.provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAGpF,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGjF,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"nexi.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/nexi/nexi.provider.ts"],"names":[],"mappings":"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"}
|