@agent-cards/sdk 0.23.20 → 0.23.22
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 +55 -2
- package/PREFLIGHT.md +6 -0
- package/README.md +169 -5
- package/dist/amadeus-checkout.generated.d.ts +6 -1
- package/dist/amadeus-checkout.generated.js +26 -2
- package/dist/card-fields.generated.js +2341 -127
- package/dist/cdp.js +199 -28
- package/dist/client.d.ts +177 -9
- package/dist/client.js +387 -37
- package/dist/comgate.d.ts +50 -0
- package/dist/comgate.js +80 -0
- package/dist/creditguard.generated.js +4 -2
- package/dist/cse-body.js +11 -0
- package/dist/cybersource-secure-acceptance.generated.d.ts +1 -1
- package/dist/ebanx.d.ts +1 -1
- package/dist/ebanx.js +1 -1
- package/dist/eprotect.generated.d.ts +1 -1
- package/dist/eximbay.d.ts +46 -0
- package/dist/eximbay.js +69 -0
- package/dist/gmo.generated.js +7 -3
- package/dist/hipay.generated.d.ts +5 -5
- package/dist/hipay.generated.js +5 -2
- package/dist/hold.d.ts +1 -1
- package/dist/hold.js +10 -4
- package/dist/hosted-entry.d.ts +4 -0
- package/dist/hosted-entry.js +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/lifecycle.d.ts +9 -4
- package/dist/lifecycle.js +16 -4
- package/dist/paddle-tokenex.generated.js +7 -3
- package/dist/paygent.generated.d.ts +60 -0
- package/dist/paygent.generated.js +425 -0
- package/dist/payrails.generated.js +7 -3
- package/dist/payrexx.d.ts +91 -0
- package/dist/payrexx.generated.d.ts +91 -0
- package/dist/payrexx.generated.js +536 -0
- package/dist/payrexx.js +141 -0
- package/dist/pre-claim.d.ts +30 -1
- package/dist/pre-claim.js +257 -39
- package/dist/preflight-catalog.json +58 -0
- package/dist/preflight-schemas.json +4 -0
- package/dist/preflight.generated.js +26 -2
- package/dist/prepared-processor.d.ts +7 -2
- package/dist/prepared-processor.js +16 -2
- package/dist/primer.generated.js +2469 -255
- package/dist/przelewy24.d.ts +47 -0
- package/dist/przelewy24.js +88 -0
- package/dist/registry.d.ts +6 -5
- package/dist/registry.js +27 -7
- package/dist/shiji-sts.generated.js +7 -3
- package/dist/stripe-checkout.generated.js +896 -19
- package/dist/toast-seal.generated.d.ts +37 -0
- package/dist/toast-seal.generated.js +625 -0
- package/dist/toast.generated.d.ts +41 -0
- package/dist/toast.generated.js +113 -0
- package/dist/tokenex-iframe.d.ts +93 -0
- package/dist/tokenex-iframe.generated.d.ts +81 -0
- package/dist/tokenex-iframe.generated.js +403 -0
- package/dist/tokenex-iframe.js +195 -0
- package/dist/transbank.d.ts +45 -0
- package/dist/transbank.js +73 -0
- package/dist/twoc2p.generated.js +7 -3
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComGate's payment gateway (pay1 to pay4.comgate.cz, where most Czech and Slovak e-shops send the buyer), as this
|
|
3
|
+
* SDK reads it.
|
|
4
|
+
*
|
|
5
|
+
* The merchant's server creates the payment at ComGate and sends the buyer's browser to the gateway link ComGate
|
|
6
|
+
* answered with, https://payN.comgate.cz/init?id=<transaction id>, by a redirect or by setting the page's or a
|
|
7
|
+
* frame's location. That GET carries no card and nothing but the payment's id, and it is the one request a build
|
|
8
|
+
* that declares ComGate's capability pauses for ComGate (hosted-entry.ts): the cardholder's device then makes the
|
|
9
|
+
* gateway's own calls for that payment over the end-to-end TLS relay (payment-core processors/comgate.js). Only the
|
|
10
|
+
* link exactly as ComGate writes it is the entry; any other parameter would be handed on to the gateway's own
|
|
11
|
+
* route, which these rules never see.
|
|
12
|
+
*
|
|
13
|
+
* COMGATE_GATEWAY_HOSTS is payment-core's COMGATE_GATEWAY_HOSTS, and isComgateEntryUrl is payment-core's rule of
|
|
14
|
+
* the same name; hosted-entry.test.mjs pins both to payment-core on every case payment-core's own tests list.
|
|
15
|
+
*/
|
|
16
|
+
export declare const COMGATE_PSP = "comgate";
|
|
17
|
+
/** The dark-launch capability the API serves ComGate's recognizer behind (payment-core definitions.js). */
|
|
18
|
+
export declare const COMGATE_CAPABILITY = "comgate_hosted_payment_page";
|
|
19
|
+
/** The four gateway hosts ComGate's create answer names, each a host of its own entry. */
|
|
20
|
+
export declare const COMGATE_GATEWAY_HOSTS: readonly string[];
|
|
21
|
+
/**
|
|
22
|
+
* The hosts that take a card, or part of one, for ComGate: the gateway's API (payments.comgate.cz behind pay1 and pay2,
|
|
23
|
+
* payments-gcp.comgate.cz behind pay3 and pay4), where the gateway posts the card (/client/instructions/card-process,
|
|
24
|
+
* check-card) and ComGate's Web Checkout SDK posts its own (/checkout/provider/*, /checkout/card/check-card), and the
|
|
25
|
+
* card frames' hosts (sec.comgate.cz, sec-gcp.comgate.cz), which post the card's first digits to their /bin-checker.
|
|
26
|
+
* The card is already encrypted in ComGate's frame by then, so no body rule could see it: once ComGate is served, this
|
|
27
|
+
* build fails every request to these hosts but a GET, so the card the agent typed never reaches ComGate.
|
|
28
|
+
*/
|
|
29
|
+
export declare const COMGATE_CARD_HOSTS: readonly string[];
|
|
30
|
+
/** The Fetch.enable globs attachToCdp arms for the card hosts, only while ComGate is served (cdp.ts). */
|
|
31
|
+
export declare const COMGATE_CARD_PATTERNS: readonly string[];
|
|
32
|
+
/** Whether this URL is on one of ComGate's card hosts (https, no credentials, any port, a trailing dot or not). */
|
|
33
|
+
export declare function isComgateCardHost(url: string): boolean;
|
|
34
|
+
/** Whether this build's registry serves ComGate's entry: a company Agentcard turned ComGate on for, on a build that declares it. */
|
|
35
|
+
export declare function servesComgate(vault: {
|
|
36
|
+
isCardRequest(url: string, method?: string): boolean;
|
|
37
|
+
} | undefined): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Whether an adapter must hand this request to the pre-claim gates: it is on one of ComGate's card hosts and this
|
|
40
|
+
* build's registry serves ComGate. attachToPlaywright's route predicate asks this, as attachToCdp arms the hosts.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isArmedComgateUrl(vault: {
|
|
43
|
+
isCardRequest(url: string, method?: string): boolean;
|
|
44
|
+
} | undefined, url: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether a URL is ComGate's gateway link exactly as ComGate's create answer writes it: https, one of the four
|
|
47
|
+
* gateway hosts in lowercase, the default port, no credentials or fragment, the path /init, and a query of the one
|
|
48
|
+
* `id` parameter holding a transaction id. A string that parses to another spelling is not it.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isComgateEntryUrl(raw: unknown): boolean;
|
package/dist/comgate.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComGate's payment gateway (pay1 to pay4.comgate.cz, where most Czech and Slovak e-shops send the buyer), as this
|
|
3
|
+
* SDK reads it.
|
|
4
|
+
*
|
|
5
|
+
* The merchant's server creates the payment at ComGate and sends the buyer's browser to the gateway link ComGate
|
|
6
|
+
* answered with, https://payN.comgate.cz/init?id=<transaction id>, by a redirect or by setting the page's or a
|
|
7
|
+
* frame's location. That GET carries no card and nothing but the payment's id, and it is the one request a build
|
|
8
|
+
* that declares ComGate's capability pauses for ComGate (hosted-entry.ts): the cardholder's device then makes the
|
|
9
|
+
* gateway's own calls for that payment over the end-to-end TLS relay (payment-core processors/comgate.js). Only the
|
|
10
|
+
* link exactly as ComGate writes it is the entry; any other parameter would be handed on to the gateway's own
|
|
11
|
+
* route, which these rules never see.
|
|
12
|
+
*
|
|
13
|
+
* COMGATE_GATEWAY_HOSTS is payment-core's COMGATE_GATEWAY_HOSTS, and isComgateEntryUrl is payment-core's rule of
|
|
14
|
+
* the same name; hosted-entry.test.mjs pins both to payment-core on every case payment-core's own tests list.
|
|
15
|
+
*/
|
|
16
|
+
export const COMGATE_PSP = 'comgate';
|
|
17
|
+
/** The dark-launch capability the API serves ComGate's recognizer behind (payment-core definitions.js). */
|
|
18
|
+
export const COMGATE_CAPABILITY = 'comgate_hosted_payment_page';
|
|
19
|
+
/** The four gateway hosts ComGate's create answer names, each a host of its own entry. */
|
|
20
|
+
export const COMGATE_GATEWAY_HOSTS = Object.freeze(['pay1.comgate.cz', 'pay2.comgate.cz', 'pay3.comgate.cz', 'pay4.comgate.cz']);
|
|
21
|
+
const COMGATE_ENTRY_PATH = '/init';
|
|
22
|
+
// The id the gateway's router takes: three groups of four letters or digits.
|
|
23
|
+
const TRANS_ID = /^[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}$/;
|
|
24
|
+
/**
|
|
25
|
+
* The hosts that take a card, or part of one, for ComGate: the gateway's API (payments.comgate.cz behind pay1 and pay2,
|
|
26
|
+
* payments-gcp.comgate.cz behind pay3 and pay4), where the gateway posts the card (/client/instructions/card-process,
|
|
27
|
+
* check-card) and ComGate's Web Checkout SDK posts its own (/checkout/provider/*, /checkout/card/check-card), and the
|
|
28
|
+
* card frames' hosts (sec.comgate.cz, sec-gcp.comgate.cz), which post the card's first digits to their /bin-checker.
|
|
29
|
+
* The card is already encrypted in ComGate's frame by then, so no body rule could see it: once ComGate is served, this
|
|
30
|
+
* build fails every request to these hosts but a GET, so the card the agent typed never reaches ComGate.
|
|
31
|
+
*/
|
|
32
|
+
export const COMGATE_CARD_HOSTS = Object.freeze(['payments.comgate.cz', 'payments-gcp.comgate.cz', 'sec.comgate.cz', 'sec-gcp.comgate.cz']);
|
|
33
|
+
/** The Fetch.enable globs attachToCdp arms for the card hosts, only while ComGate is served (cdp.ts). */
|
|
34
|
+
export const COMGATE_CARD_PATTERNS = Object.freeze(COMGATE_CARD_HOSTS.map((host) => `*${host}*`));
|
|
35
|
+
// A gateway link, as ComGate writes one: the registry reads ComGate as served when it takes this as a GET entry.
|
|
36
|
+
const COMGATE_SAMPLE_ENTRY = 'https://pay1.comgate.cz/init?id=AAAA-BBBB-CCCC';
|
|
37
|
+
/** Whether this URL is on one of ComGate's card hosts (https, no credentials, any port, a trailing dot or not). */
|
|
38
|
+
export function isComgateCardHost(url) {
|
|
39
|
+
let parsed;
|
|
40
|
+
try {
|
|
41
|
+
parsed = new URL(url);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return parsed.protocol === 'https:' && !parsed.username && !parsed.password
|
|
47
|
+
&& COMGATE_CARD_HOSTS.includes(parsed.hostname.toLowerCase().replace(/\.$/, ''));
|
|
48
|
+
}
|
|
49
|
+
/** Whether this build's registry serves ComGate's entry: a company Agentcard turned ComGate on for, on a build that declares it. */
|
|
50
|
+
export function servesComgate(vault) {
|
|
51
|
+
return typeof vault?.isCardRequest === 'function' && vault.isCardRequest(COMGATE_SAMPLE_ENTRY, 'GET');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Whether an adapter must hand this request to the pre-claim gates: it is on one of ComGate's card hosts and this
|
|
55
|
+
* build's registry serves ComGate. attachToPlaywright's route predicate asks this, as attachToCdp arms the hosts.
|
|
56
|
+
*/
|
|
57
|
+
export function isArmedComgateUrl(vault, url) {
|
|
58
|
+
return isComgateCardHost(url) && servesComgate(vault);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Whether a URL is ComGate's gateway link exactly as ComGate's create answer writes it: https, one of the four
|
|
62
|
+
* gateway hosts in lowercase, the default port, no credentials or fragment, the path /init, and a query of the one
|
|
63
|
+
* `id` parameter holding a transaction id. A string that parses to another spelling is not it.
|
|
64
|
+
*/
|
|
65
|
+
export function isComgateEntryUrl(raw) {
|
|
66
|
+
if (typeof raw !== 'string' || raw.length > 256)
|
|
67
|
+
return false;
|
|
68
|
+
let url;
|
|
69
|
+
try {
|
|
70
|
+
url = new URL(raw);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
if (url.href !== raw || url.protocol !== 'https:' || url.port || url.username || url.password || url.hash)
|
|
76
|
+
return false;
|
|
77
|
+
if (!COMGATE_GATEWAY_HOSTS.includes(url.hostname) || url.pathname !== COMGATE_ENTRY_PATH)
|
|
78
|
+
return false;
|
|
79
|
+
return url.search.startsWith('?id=') && TRANS_ID.test(url.search.slice(4));
|
|
80
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
3
|
+
// artifact-sha256: 24cac2580feefe7d273b89de8e5b84e744e561fd258252f98008801750370460
|
|
4
4
|
// src/creditguard.js
|
|
5
5
|
var CREDITGUARD_PPS_HOSTS = Object.freeze(["pps.creditguard.co.il", "pps2.creditguard.co.il", "ppsuat.creditguard.co.il"]);
|
|
6
6
|
var CREDITGUARD_SANDBOX_HOST = "ppsuat.creditguard.co.il";
|
|
@@ -707,6 +707,7 @@ var THREE_DS_INIT_KEYS = Object.freeze([
|
|
|
707
707
|
"cvv",
|
|
708
708
|
"isGooglePayTxn",
|
|
709
709
|
"isPayboxTxn",
|
|
710
|
+
"recaptchaValue",
|
|
710
711
|
"useDcc",
|
|
711
712
|
"acsWindowSize",
|
|
712
713
|
"browserColorDepth",
|
|
@@ -837,6 +838,7 @@ function creditguardDeviceThreeDSInitRequest(processUrl, card, options = {}) {
|
|
|
837
838
|
cvv: parts.cvc,
|
|
838
839
|
isGooglePayTxn: false,
|
|
839
840
|
isPayboxTxn: false,
|
|
841
|
+
recaptchaValue: "",
|
|
840
842
|
useDcc: false,
|
|
841
843
|
acsWindowSize: "4",
|
|
842
844
|
browserColorDepth: browser.colorDepth,
|
|
@@ -887,7 +889,7 @@ function deviceStepBodyRefusal(step, txId, body) {
|
|
|
887
889
|
return "dcc";
|
|
888
890
|
if (value.txId !== txId)
|
|
889
891
|
return "txid_mismatch";
|
|
890
|
-
if (value.acsWindowSize !== "4" || value.browserHeader !== BROWSER_HEADER || value.browserJavascriptEnabled !== true)
|
|
892
|
+
if (value.recaptchaValue !== "" || value.acsWindowSize !== "4" || value.browserHeader !== BROWSER_HEADER || value.browserJavascriptEnabled !== true)
|
|
891
893
|
return "malformed_body";
|
|
892
894
|
try {
|
|
893
895
|
deviceBrowser({
|
package/dist/cse-body.js
CHANGED
|
@@ -4,6 +4,8 @@ import { substituteEncryptedFields } from './substitute.js';
|
|
|
4
4
|
import { substituteMerchantHostedBody } from './merchant-hosted.js';
|
|
5
5
|
import { fiservCapturePinId, isFiservCaptureHost, substituteFiservEnvelope } from './fiserv.js';
|
|
6
6
|
import { substituteVerifoneBody } from './verifone.js';
|
|
7
|
+
import { isToastHost } from './toast.generated.js';
|
|
8
|
+
import { substituteToastCardData } from './toast-seal.generated.js';
|
|
7
9
|
/**
|
|
8
10
|
* The cse continuation: the paused body with the vault's ciphertext in place
|
|
9
11
|
* of the dummy blobs. The adapters send it as postData ALONE. Chromium
|
|
@@ -44,6 +46,15 @@ export function cseBody(body, replay, url, preparation) {
|
|
|
44
46
|
}
|
|
45
47
|
if (isFiservCaptureHost(url))
|
|
46
48
|
throw new Error('Refusing to substitute: a Fiserv capture continues only through a prepared Fiserv approval.');
|
|
49
|
+
// A request on Toast's payments host takes only Toast's own swap: the device's sealed card written over
|
|
50
|
+
// the paused card.cardData and no other byte, refused unless the paused body is still the frame's guest
|
|
51
|
+
// card request and the card is sealed under the key payment-core pins (toast-seal.js substituteToastCardData).
|
|
52
|
+
if (isToastHost(url)) {
|
|
53
|
+
if (replay.kind !== undefined || replay.substitutions.at !== 'card' || (replay.substitutions.remove ?? []).length > 0) {
|
|
54
|
+
throw new Error('Refusing to substitute: the paused request is not the Toast card request the cardholder approved.');
|
|
55
|
+
}
|
|
56
|
+
return substituteToastCardData(url, body, replay.substitutions.fields);
|
|
57
|
+
}
|
|
47
58
|
// A merchant-hosted approval is written into the LIVE paused body, which must
|
|
48
59
|
// still be the body the API checked at create (merchant-hosted.ts).
|
|
49
60
|
if (replay.kind === 'merchant_hosted')
|
|
@@ -38,7 +38,7 @@ declare function isPreparedSecureAcceptanceRequest(url: any, method: any, body:
|
|
|
38
38
|
declare function secureAcceptanceMerchantEntry(profileId: any, merchantOrigin: any, entries?: any): any;
|
|
39
39
|
declare function secureAcceptanceMerchantRefusal(environment: any, profileId: any, merchantOrigin: any, accessKey: any, entries?: any): "unsupported_environment" | "invalid_profile_id" | "secure_acceptance_merchant_unreviewed" | "secure_acceptance_merchant_pending" | "secure_acceptance_access_key_unreviewed" | "secure_acceptance_merchant_observe" | null;
|
|
40
40
|
declare function secureAcceptanceCardType(number: any): "001" | "002" | "003" | "004" | null;
|
|
41
|
-
declare function secureAcceptanceCardRefusal(environment: any, card: any): "
|
|
41
|
+
declare function secureAcceptanceCardRefusal(environment: any, card: any): "invalid_card_number" | "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "live_host_refuses_documented_test_card" | "card_network_unsupported" | "invalid_expiry" | "invalid_cvn" | null;
|
|
42
42
|
declare function isSecureAcceptanceDeviceRequest(templateBody: any, deviceBody: any, environment: any): boolean;
|
|
43
43
|
declare function secureAcceptanceDeviceRequest(request: any, card: any, options: any): {
|
|
44
44
|
url: any;
|
package/dist/ebanx.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export declare class EbanxFollowUps {
|
|
|
75
75
|
stop(): void;
|
|
76
76
|
/**
|
|
77
77
|
* The approval the remembered token request went under, or null when none is remembered. The gate sends nothing
|
|
78
|
-
* unless the checkout's own state names this same approval (pre-claim.ts
|
|
78
|
+
* unless the checkout's own state names this same approval (pre-claim.ts followUpMaySend).
|
|
79
79
|
*/
|
|
80
80
|
get authorizationId(): string | null;
|
|
81
81
|
/**
|
package/dist/ebanx.js
CHANGED
|
@@ -108,7 +108,7 @@ export class EbanxFollowUps {
|
|
|
108
108
|
stop() { this.stopped = true; }
|
|
109
109
|
/**
|
|
110
110
|
* The approval the remembered token request went under, or null when none is remembered. The gate sends nothing
|
|
111
|
-
* unless the checkout's own state names this same approval (pre-claim.ts
|
|
111
|
+
* unless the checkout's own state names this same approval (pre-claim.ts followUpMaySend).
|
|
112
112
|
*/
|
|
113
113
|
get authorizationId() { return this.parent?.authorizationId ?? null; }
|
|
114
114
|
/**
|
|
@@ -81,7 +81,7 @@ declare function eprotectMerchantPin(paypageId: any, merchantOrigin: any, pins?:
|
|
|
81
81
|
declare function eprotectMerchantRefusal(environment: any, paypageId: any, merchantOrigin: any, pins?: any): "invalid_paypage_id" | "unsupported_environment" | "eprotect_merchant_unreviewed" | null;
|
|
82
82
|
declare function defaultRandom(bytes: any): void;
|
|
83
83
|
declare function eprotectEncrypt(text: any, key: any, random?: typeof defaultRandom): string;
|
|
84
|
-
declare function eprotectCardRefusal(environment: any, cardNumber: any): "
|
|
84
|
+
declare function eprotectCardRefusal(environment: any, cardNumber: any): "invalid_card_number" | "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "live_host_refuses_documented_test_card" | null;
|
|
85
85
|
declare function eprotectDeviceRequest(templateUrl: any, card: any, sessionKey: any, random?: typeof defaultRandom): {
|
|
86
86
|
url: string;
|
|
87
87
|
method: string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eximbay's payment window (secureapi.eximbay.com, the Korean gateway that takes foreign cards for Korean merchants),
|
|
3
|
+
* as this SDK reads it.
|
|
4
|
+
*
|
|
5
|
+
* The merchant's page posts a signed entry form, top-level or into a window it opens, to
|
|
6
|
+
* https://secureapi.eximbay.com/Gateway/BasicProcessor.krp (Eximbay's test host for a test merchant), and Eximbay
|
|
7
|
+
* answers with a page that posts itself, with the session's paramkey, into its window. That entry carries no card,
|
|
8
|
+
* and it is the one request this SDK pauses: the cardholder's device repeats it over the end-to-end TLS relay and
|
|
9
|
+
* fills the card into the window Eximbay returns to it (payment-core processors/eximbay.js). Everything else the
|
|
10
|
+
* agent's browser posts to Eximbay follows the entry and leads to a card: the step that opens the window
|
|
11
|
+
* (/Gateway/BasicProcessor/230/NewGlobalStep1.jsp), the window's amount query and card lookup, which carries the
|
|
12
|
+
* card's first eight digits (controll/checkApprvJson.do, controll/checkCardBin.do), its card post
|
|
13
|
+
* (controll/checkApprv.jsp) and its other posts. This SDK aborts every one of them in a page it watches, so a
|
|
14
|
+
* placeholder card never reaches Eximbay from one. attachToCdp watches a window the merchant's page opens once it has
|
|
15
|
+
* armed that window. Eximbay's popup integration opens the window and posts the entry into it at once, so that entry
|
|
16
|
+
* can leave before the window is armed; the window's next post, the step, is then aborted like any other, and the
|
|
17
|
+
* checkout reads unsupported. attachToPlaywright routes the page alone, never a window it opens.
|
|
18
|
+
*
|
|
19
|
+
* EXIMBAY_HOSTS is payment-core's EXIMBAY_HOSTS, and isEximbayEntry takes the URLs payment-core's isEximbayEntryUrl
|
|
20
|
+
* takes; eximbay.test.mjs pins both to payment-core.
|
|
21
|
+
*/
|
|
22
|
+
export declare const EXIMBAY_PSP = "eximbay";
|
|
23
|
+
/** The dark-launch capability the API serves Eximbay's recognizer behind (payment-core definitions.js). */
|
|
24
|
+
export declare const EXIMBAY_CAPABILITY = "eximbay_hosted_payment_page";
|
|
25
|
+
/** The live host and Eximbay's test host, which serves the same window for a test merchant. */
|
|
26
|
+
export declare const EXIMBAY_HOSTS: readonly string[];
|
|
27
|
+
/** Whether this URL is on one of Eximbay's two hosts. */
|
|
28
|
+
export declare function isEximbayHost(url: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* The only request on Eximbay's hosts that is the merchant's entry: a POST to the entry path, written exactly as a
|
|
31
|
+
* browser posts a form to it, with no port, query or fragment (payment-core isEximbayEntryUrl takes those two strings
|
|
32
|
+
* only). The entry the SDK pauses; every other POST there is aborted.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isEximbayEntry(url: string, method: string): boolean;
|
|
35
|
+
/** The entry URL on the same Eximbay host, which the registry recognizes when this build is armed for Eximbay, or null. */
|
|
36
|
+
export declare function eximbayEntryUrl(url: string): string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Whether an adapter must hand this request to the pre-claim gates: it is on an Eximbay host and this build's registry
|
|
39
|
+
* serves Eximbay's entry there. The step, the window's lookups and its card post are not the entry, so the registry's
|
|
40
|
+
* card-request test does not name them; the CDP adapter still pauses them through the recognizer's host pattern, and
|
|
41
|
+
* attachToPlaywright's route predicate asks this, so both adapters show the gates every request to Eximbay once
|
|
42
|
+
* Eximbay is armed.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isArmedEximbayUrl(vault: {
|
|
45
|
+
isCardRequest(url: string, method?: string): boolean;
|
|
46
|
+
}, url: string): boolean;
|
package/dist/eximbay.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eximbay's payment window (secureapi.eximbay.com, the Korean gateway that takes foreign cards for Korean merchants),
|
|
3
|
+
* as this SDK reads it.
|
|
4
|
+
*
|
|
5
|
+
* The merchant's page posts a signed entry form, top-level or into a window it opens, to
|
|
6
|
+
* https://secureapi.eximbay.com/Gateway/BasicProcessor.krp (Eximbay's test host for a test merchant), and Eximbay
|
|
7
|
+
* answers with a page that posts itself, with the session's paramkey, into its window. That entry carries no card,
|
|
8
|
+
* and it is the one request this SDK pauses: the cardholder's device repeats it over the end-to-end TLS relay and
|
|
9
|
+
* fills the card into the window Eximbay returns to it (payment-core processors/eximbay.js). Everything else the
|
|
10
|
+
* agent's browser posts to Eximbay follows the entry and leads to a card: the step that opens the window
|
|
11
|
+
* (/Gateway/BasicProcessor/230/NewGlobalStep1.jsp), the window's amount query and card lookup, which carries the
|
|
12
|
+
* card's first eight digits (controll/checkApprvJson.do, controll/checkCardBin.do), its card post
|
|
13
|
+
* (controll/checkApprv.jsp) and its other posts. This SDK aborts every one of them in a page it watches, so a
|
|
14
|
+
* placeholder card never reaches Eximbay from one. attachToCdp watches a window the merchant's page opens once it has
|
|
15
|
+
* armed that window. Eximbay's popup integration opens the window and posts the entry into it at once, so that entry
|
|
16
|
+
* can leave before the window is armed; the window's next post, the step, is then aborted like any other, and the
|
|
17
|
+
* checkout reads unsupported. attachToPlaywright routes the page alone, never a window it opens.
|
|
18
|
+
*
|
|
19
|
+
* EXIMBAY_HOSTS is payment-core's EXIMBAY_HOSTS, and isEximbayEntry takes the URLs payment-core's isEximbayEntryUrl
|
|
20
|
+
* takes; eximbay.test.mjs pins both to payment-core.
|
|
21
|
+
*/
|
|
22
|
+
export const EXIMBAY_PSP = 'eximbay';
|
|
23
|
+
/** The dark-launch capability the API serves Eximbay's recognizer behind (payment-core definitions.js). */
|
|
24
|
+
export const EXIMBAY_CAPABILITY = 'eximbay_hosted_payment_page';
|
|
25
|
+
/** The live host and Eximbay's test host, which serves the same window for a test merchant. */
|
|
26
|
+
export const EXIMBAY_HOSTS = Object.freeze(['secureapi.eximbay.com', 'secureapi.test.eximbay.com']);
|
|
27
|
+
const ENTRY_PATH = '/Gateway/BasicProcessor.krp';
|
|
28
|
+
/** The Eximbay host a URL is on (https, no credentials, any port, any letter case, a trailing dot or not), or null. */
|
|
29
|
+
function eximbayHost(raw) {
|
|
30
|
+
let url;
|
|
31
|
+
try {
|
|
32
|
+
url = new URL(raw);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (url.protocol !== 'https:' || url.username || url.password)
|
|
38
|
+
return null;
|
|
39
|
+
const host = url.hostname.toLowerCase().replace(/\.$/, '');
|
|
40
|
+
return EXIMBAY_HOSTS.includes(host) ? host : null;
|
|
41
|
+
}
|
|
42
|
+
/** Whether this URL is on one of Eximbay's two hosts. */
|
|
43
|
+
export function isEximbayHost(url) {
|
|
44
|
+
return eximbayHost(url) !== null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The only request on Eximbay's hosts that is the merchant's entry: a POST to the entry path, written exactly as a
|
|
48
|
+
* browser posts a form to it, with no port, query or fragment (payment-core isEximbayEntryUrl takes those two strings
|
|
49
|
+
* only). The entry the SDK pauses; every other POST there is aborted.
|
|
50
|
+
*/
|
|
51
|
+
export function isEximbayEntry(url, method) {
|
|
52
|
+
return String(method).toUpperCase() === 'POST' && EXIMBAY_HOSTS.some((host) => url === `https://${host}${ENTRY_PATH}`);
|
|
53
|
+
}
|
|
54
|
+
/** The entry URL on the same Eximbay host, which the registry recognizes when this build is armed for Eximbay, or null. */
|
|
55
|
+
export function eximbayEntryUrl(url) {
|
|
56
|
+
const host = eximbayHost(url);
|
|
57
|
+
return host === null ? null : `https://${host}${ENTRY_PATH}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether an adapter must hand this request to the pre-claim gates: it is on an Eximbay host and this build's registry
|
|
61
|
+
* serves Eximbay's entry there. The step, the window's lookups and its card post are not the entry, so the registry's
|
|
62
|
+
* card-request test does not name them; the CDP adapter still pauses them through the recognizer's host pattern, and
|
|
63
|
+
* attachToPlaywright's route predicate asks this, so both adapters show the gates every request to Eximbay once
|
|
64
|
+
* Eximbay is armed.
|
|
65
|
+
*/
|
|
66
|
+
export function isArmedEximbayUrl(vault, url) {
|
|
67
|
+
const entry = eximbayEntryUrl(url);
|
|
68
|
+
return entry !== null && vault.isCardRequest(entry, 'POST');
|
|
69
|
+
}
|
package/dist/gmo.generated.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
3
|
+
// artifact-sha256: a65199bcbf0b67546130fb4f2c12ba72c8f51a2ff5b4e3054e2bfcc29b06f95d
|
|
4
4
|
// src/sha256.js
|
|
5
5
|
var K = /* @__PURE__ */ new Uint32Array([
|
|
6
6
|
1116352408,
|
|
@@ -153,6 +153,9 @@ var typedArrayName = Object.getOwnPropertyDescriptor(TYPED_ARRAY, Symbol.toStrin
|
|
|
153
153
|
function parseRsaPublicKey(key) {
|
|
154
154
|
const spki = key && typeof key === "object" ? key.spki : void 0;
|
|
155
155
|
const pin = key && typeof key === "object" ? key.sha256 : void 0;
|
|
156
|
+
const named = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "exponent") ? key.exponent : void 0;
|
|
157
|
+
if (named !== void 0 && named !== 17)
|
|
158
|
+
throw refuse("key");
|
|
156
159
|
if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
|
|
157
160
|
throw refuse("key");
|
|
158
161
|
if (typeof pin !== "string" || !SHA256_HEX.test(pin))
|
|
@@ -188,9 +191,10 @@ function parseRsaPublicKey(key) {
|
|
|
188
191
|
if (!MODULUS_BYTES.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
|
|
189
192
|
throw refuse("key");
|
|
190
193
|
const e = exponent.bytes;
|
|
191
|
-
|
|
194
|
+
const expected = named === 17 ? [17] : [1, 0, 1];
|
|
195
|
+
if (e.length !== expected.length || !expected.every((byte, i) => e[i] === byte))
|
|
192
196
|
throw refuse("key");
|
|
193
|
-
return Object.freeze({ n: toBigInt(n), e: 65537n, size: n.length });
|
|
197
|
+
return Object.freeze({ n: toBigInt(n), e: named === 17 ? 17n : 65537n, size: n.length });
|
|
194
198
|
}
|
|
195
199
|
function rsaesPkcs1v15Encrypt(key, message, random) {
|
|
196
200
|
const { n, e, size } = parseRsaPublicKey(key);
|
|
@@ -25,11 +25,11 @@ declare function hipayUsername(headers: any): string | null;
|
|
|
25
25
|
declare function hipayRequestRefusal(request: any): any;
|
|
26
26
|
declare function isPreparedHipayRequest(url: any, method: any, body: any, environment: any, headers: any): boolean;
|
|
27
27
|
declare function hipayPinOriginUsable(origin: any): boolean;
|
|
28
|
-
declare var HIPAY_MERCHANT_PINS: readonly
|
|
29
|
-
declare function hipayOriginPin(merchantOrigin: any, pins?: readonly
|
|
30
|
-
declare function hipayPreparationRefusal(environment: any, merchantOrigin: any, pins?: readonly
|
|
31
|
-
declare function hipayMerchantPin(merchantOrigin: any, username: any, pins?: readonly
|
|
32
|
-
declare function hipayMerchantRefusal(environment: any, merchantOrigin: any, username: any, pins?: readonly
|
|
28
|
+
declare var HIPAY_MERCHANT_PINS: readonly any[];
|
|
29
|
+
declare function hipayOriginPin(merchantOrigin: any, pins?: readonly any[]): any;
|
|
30
|
+
declare function hipayPreparationRefusal(environment: any, merchantOrigin: any, pins?: readonly any[]): "unsupported_environment" | "hipay_merchant_unreviewed" | null;
|
|
31
|
+
declare function hipayMerchantPin(merchantOrigin: any, username: any, pins?: readonly any[]): any;
|
|
32
|
+
declare function hipayMerchantRefusal(environment: any, merchantOrigin: any, username: any, pins?: readonly any[]): "hipay_headers_refused" | "unsupported_environment" | "hipay_merchant_unreviewed" | null;
|
|
33
33
|
declare function hipayRefusalMessage(code: any): any;
|
|
34
34
|
declare function injectHipayCard(body: any, card: any): {
|
|
35
35
|
body: string;
|
package/dist/hipay.generated.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
3
|
+
// artifact-sha256: e8cb1ddfc6c8937f5126197b90d8261da8b07c9c68df1decb261052e8a2fabc1
|
|
4
4
|
// src/hipay.js
|
|
5
5
|
var HIPAY_PSP = "hipay";
|
|
6
6
|
var HIPAY_CAPABILITY = "hipay_vault_token";
|
|
@@ -168,7 +168,10 @@ function hipayPinOriginUsable(origin) {
|
|
|
168
168
|
const host = typeof origin === "string" ? PIN_ORIGIN.exec(origin) : null;
|
|
169
169
|
return !!host && !HIPAY_DOMAIN.test(host[1]);
|
|
170
170
|
}
|
|
171
|
-
var
|
|
171
|
+
var pin = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), usernames: Object.freeze([...fields.usernames]) });
|
|
172
|
+
var HIPAY_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
173
|
+
pin({ id: "happybulle", merchant: "HappyBulle", origins: ["https://www.happybulle.com"], usernames: ["94683309.secure-gateway.hipay-tpp.com"] })
|
|
174
|
+
]);
|
|
172
175
|
var usablePin = (entry) => !!entry && Array.isArray(entry.origins) && Array.isArray(entry.usernames) && entry.origins.length > 0 && entry.usernames.length > 0 && entry.origins.every(hipayPinOriginUsable) && entry.usernames.every((name) => hipayUsernameEnvironment(name) === "production");
|
|
173
176
|
function hipayOriginPin(merchantOrigin, pins = HIPAY_MERCHANT_PINS) {
|
|
174
177
|
if (typeof merchantOrigin !== "string" || !Array.isArray(pins) || !hipayPinOriginUsable(merchantOrigin))
|
package/dist/hold.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ export interface HoldOptions {
|
|
|
55
55
|
export interface HeldCardRequest {
|
|
56
56
|
/** The processor, by the recogniser's name (`braintree`), `bolt`, or `placeholder_card`; null when unnamed. */
|
|
57
57
|
psp: string | null;
|
|
58
|
-
/** Origin and path only. */
|
|
58
|
+
/** Origin and path only, with any credential a processor writes into the path masked (redactUrl). */
|
|
59
59
|
endpoint: string;
|
|
60
60
|
kind: 'tokenize' | 'store_card_post' | 'card_request';
|
|
61
61
|
/** Whether a release can answer it: a recogniser the SDK pays, never Bolt or a store's own card post. */
|
package/dist/hold.js
CHANGED
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
// - Any request whose body carries the placeholder card number (`placeholderNumbers`): a store's own card post or
|
|
18
18
|
// an unknown processor. The browser only ever holds the placeholder, so a body with its digits is a card request
|
|
19
19
|
// wherever it goes. In sandbox it may be released unchanged (it carries the documented test number only).
|
|
20
|
-
// The hold records the processor and the endpoint (origin and path), never a body or a
|
|
20
|
+
// The hold records the processor and the endpoint (origin and path, any path credential masked), never a body or a
|
|
21
|
+
// header.
|
|
22
|
+
import { redactUrl } from './client.js';
|
|
21
23
|
/**
|
|
22
24
|
* Bolt's embedded card frame (connect.bolt.com credit-card-input): a POST of `{ payload, nonce, public_key }` JSON,
|
|
23
25
|
* the card boxed to Bolt's key, to `<base>/token` or `<base>/token/cvv`, with a 20 s timeout and retries.
|
|
@@ -87,14 +89,18 @@ export class HoldAnsweredError extends Error {
|
|
|
87
89
|
this.name = 'HoldAnsweredError';
|
|
88
90
|
}
|
|
89
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* A held request's origin and path as redactUrl reads them, so a credential a processor writes into the path (GoPay's
|
|
94
|
+
* card form token, a PayMongo session) never reaches an event or onHeld.
|
|
95
|
+
*/
|
|
90
96
|
function endpointOf(url) {
|
|
91
97
|
try {
|
|
92
|
-
|
|
93
|
-
return `${u.origin}${u.pathname}`;
|
|
98
|
+
new URL(url);
|
|
94
99
|
}
|
|
95
100
|
catch {
|
|
96
|
-
return String(url).slice(0, 120);
|
|
101
|
+
return redactUrl(String(url)).slice(0, 120);
|
|
97
102
|
}
|
|
103
|
+
return redactUrl(url);
|
|
98
104
|
}
|
|
99
105
|
function validTotal(t) {
|
|
100
106
|
const v = t;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Whether this processor's hosted page is entered with a GET this build reads exactly. */
|
|
2
|
+
export declare function hasHostedGetEntry(psp: string): boolean;
|
|
3
|
+
/** Whether `url` is exactly the GET entry of this processor's hosted page (false for a processor with none). */
|
|
4
|
+
export declare function isHostedGetEntry(psp: string, url: string): boolean;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hosted payment pages whose entry is a plain GET: the processors whose merchant sends the buyer's browser to the
|
|
3
|
+
* processor's own page with a link (a redirect, or a page or frame location set by script) rather than a form post.
|
|
4
|
+
*
|
|
5
|
+
* Such an entry carries no card. The cardholder's device takes it over (mode hosted_form): it makes the processor's
|
|
6
|
+
* own calls for the payment the link names, and the paused navigation gets this SDK's submitted_on_device notice.
|
|
7
|
+
* A GET recognizer otherwise reads as a card request carried in the URL (Worldpay eProtect's registration), which
|
|
8
|
+
* this build completes only for a grammar it checks, so a hosted page joins this table with the exact link
|
|
9
|
+
* payment-core's resolveRecognizerForUrl admits for it, and nothing else: a URL the table does not admit is never
|
|
10
|
+
* paused, as the API would refuse it, and the page's own request goes on unchanged.
|
|
11
|
+
*
|
|
12
|
+
* Each rule is dark on its own: a processor is paused only once the API serves its recognizer, which it does only
|
|
13
|
+
* for a build that declares the processor's capability (client.ts SUPPORTED_CAPABILITIES) and a company Agentcard
|
|
14
|
+
* turned the processor on for. A rule listed here for a processor this build does not declare pauses nothing.
|
|
15
|
+
*/
|
|
16
|
+
import { PRZELEWY24_PSP, isPrzelewy24EntryUrl } from './przelewy24.js';
|
|
17
|
+
import { COMGATE_PSP, isComgateEntryUrl } from './comgate.js';
|
|
18
|
+
import { TRANSBANK_PSP, isTransbankEntryUrl } from './transbank.js';
|
|
19
|
+
const HOSTED_GET_ENTRIES = new Map([
|
|
20
|
+
[PRZELEWY24_PSP, isPrzelewy24EntryUrl],
|
|
21
|
+
[COMGATE_PSP, isComgateEntryUrl],
|
|
22
|
+
[TRANSBANK_PSP, isTransbankEntryUrl],
|
|
23
|
+
]);
|
|
24
|
+
/** Whether this processor's hosted page is entered with a GET this build reads exactly. */
|
|
25
|
+
export function hasHostedGetEntry(psp) {
|
|
26
|
+
return HOSTED_GET_ENTRIES.has(psp);
|
|
27
|
+
}
|
|
28
|
+
/** Whether `url` is exactly the GET entry of this processor's hosted page (false for a processor with none). */
|
|
29
|
+
export function isHostedGetEntry(psp, url) {
|
|
30
|
+
const rule = HOSTED_GET_ENTRIES.get(psp);
|
|
31
|
+
return !!rule && typeof url === 'string' && rule(url) === true;
|
|
32
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export type { CheckoutAttachOptions } from './agentcard.js';
|
|
|
3
3
|
export { CardEncryptedError, UnsupportedModeError, UnsupportedCapabilityError, PreparationRequiredError, AmountRequiredError, PageAmountRequiredError, ApprovalTimeoutError, ApprovalDeclinedError, AmountMismatchError, PresetRefusedError, PRESET_REFUSAL_REASONS, IntentNotConfirmableError, ProcessorRefusedError, CheckoutApiError, CheckoutAuthError, redactUrl, SUPPORTED_MODES, SUPPORTED_CAPABILITIES, PaymentOutcomeUnknownError, CheckoutCancelledError, CheckoutPreparationError, AdyenTestPlatformRefusedError, MerchantTotalError, PlaceholderCardError, } from './client.js';
|
|
4
4
|
export type { GmoUnsupportedReason } from './gmo.js';
|
|
5
5
|
export type { DatatransRefusalReason } from './datatrans.js';
|
|
6
|
+
export type { TokenexIframeRefusalReason } from './tokenex-iframe.js';
|
|
6
7
|
export type { PelecardRefusalReason } from './pelecard.js';
|
|
7
8
|
export type { PrimerUnsupportedReason, PrimerBlockedReason } from './primer.js';
|
|
8
9
|
export { CONVERGE_REFUSAL_REASONS } from './elavon-converge.js';
|
package/dist/lifecycle.d.ts
CHANGED
|
@@ -159,6 +159,7 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
159
159
|
private stripeContinuationChecks;
|
|
160
160
|
/** The handoff in progress is WSPay's 3-D Secure step; see handedOff. */
|
|
161
161
|
private wspayChallenge;
|
|
162
|
+
private heldBeforeHandoff;
|
|
162
163
|
private stripeContinuedReason;
|
|
163
164
|
private approvedPaymentMethod;
|
|
164
165
|
private ownedShopOrderId;
|
|
@@ -191,7 +192,8 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
191
192
|
preparationFailed(error: CheckoutPreparationError): void;
|
|
192
193
|
isBlocked(): boolean;
|
|
193
194
|
/**
|
|
194
|
-
* An EBANX send left for the cardholder's device under this attachment's approval (pre-claim.ts ebanxFollowUp
|
|
195
|
+
* An EBANX or Payrexx send left for the cardholder's device under this attachment's approval (pre-claim.ts ebanxFollowUp,
|
|
196
|
+
* payrexxFollowUp). Until
|
|
195
197
|
* the returned function runs, once the send's answer reached the page or the send failed, reconcile() and
|
|
196
198
|
* retryAfterMerchantFailure() throw, as they do while a card request is active: a confirm may still pay. The returned
|
|
197
199
|
* function settles the send once, however often it runs.
|
|
@@ -200,7 +202,7 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
200
202
|
/** Whether a reconcile() is still waiting on the application's merchant resolver; pre-claim.ts claims no EBANX send then. */
|
|
201
203
|
isReconciling(): boolean;
|
|
202
204
|
/**
|
|
203
|
-
* Whether an EBANX send this attachment claimed is still out (followUpStarted). Both adapters refuse a new card
|
|
205
|
+
* Whether an EBANX or Payrexx send this attachment claimed is still out (followUpStarted). Both adapters refuse a new card
|
|
204
206
|
* request meanwhile, as they do while an approval is outstanding: a confirm that may pay is never hidden behind
|
|
205
207
|
* another payment's state.
|
|
206
208
|
*/
|
|
@@ -284,10 +286,13 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
284
286
|
* paddle-vgs-pay.ts reasons), or the typed card that EBANX's 3-D Secure calls or
|
|
285
287
|
* its hosted page's confirm send again after the token, when no approved token
|
|
286
288
|
* request on this attachment covers that send or the cardholder's device did not
|
|
287
|
-
* send it (unsupported_ebanx_card_resend, ebanx.ts)
|
|
289
|
+
* send it (unsupported_ebanx_card_resend, ebanx.ts), or the typed card Payrexx's card
|
|
290
|
+
* frame sends again for a 3-D Secure step when no approved card request on this
|
|
291
|
+
* attachment covers that send or the cardholder's device did not send it
|
|
292
|
+
* (unsupported_payrexx_card_resend, payrexx.ts): once an approval exists the
|
|
288
293
|
* state keeps it, and only the hold changes.
|
|
289
294
|
*/
|
|
290
|
-
unsupported(reason?: 'unrecognized_payment_endpoint' | 'merchant_profile_observe' | 'merchant_request_unsupported' | GmoUnsupportedReason | 'microform_unsupported' | 'juspay_request_unsupported' | 'merchant_card_endpoint_not_enabled' | 'merchant_card_endpoint_resend_refused' | 'creditguard_three_d_secure' | 'unsupported_primer_sdk' | 'unsupported_primer_request' | PayrailsUnsupportedReason | ShijiStsUnsupportedReason | 'processor_card_page' | 'unsupported_paypal_hosted_fields' | PaypalCardFormReason | 'unsupported_cybersource_secure_acceptance' | PaddleVgsPayRefusal | 'unsupported_ebanx_card_resend'): void;
|
|
295
|
+
unsupported(reason?: 'unrecognized_payment_endpoint' | 'merchant_profile_observe' | 'merchant_request_unsupported' | GmoUnsupportedReason | 'microform_unsupported' | 'juspay_request_unsupported' | 'merchant_card_endpoint_not_enabled' | 'merchant_card_endpoint_resend_refused' | 'creditguard_three_d_secure' | 'unsupported_primer_sdk' | 'unsupported_primer_request' | PayrailsUnsupportedReason | ShijiStsUnsupportedReason | 'processor_card_page' | 'unsupported_paypal_hosted_fields' | PaypalCardFormReason | 'unsupported_cybersource_secure_acceptance' | PaddleVgsPayRefusal | 'unsupported_ebanx_card_resend' | 'unsupported_payrexx_card_resend'): void;
|
|
291
296
|
/**
|
|
292
297
|
* A card request that only a prepared checkout pays (an Adyen merchant
|
|
293
298
|
* profile's, or a Fiserv card capture) arrived with no preparation on this
|
package/dist/lifecycle.js
CHANGED
|
@@ -57,6 +57,9 @@ export class CheckoutLifecycle {
|
|
|
57
57
|
stripeContinuationChecks = 0;
|
|
58
58
|
/** The handoff in progress is WSPay's 3-D Secure step; see handedOff. */
|
|
59
59
|
wspayChallenge = false;
|
|
60
|
+
// Whether the attachment held when the handoff in progress began (prepareHandoff): a hold raised after that, while
|
|
61
|
+
// the answer was still landing, survives handedOff.
|
|
62
|
+
heldBeforeHandoff = false;
|
|
60
63
|
// What the continuation that went through confirmed: a payment, or a card save.
|
|
61
64
|
stripeContinuedReason = 'stripe_payment_continued';
|
|
62
65
|
// The payment method a Stripe /v1/payment_methods approval returned: see approvedStripePaymentMethod.
|
|
@@ -120,7 +123,8 @@ export class CheckoutLifecycle {
|
|
|
120
123
|
}
|
|
121
124
|
isBlocked() { return this.held || this.cancelled; }
|
|
122
125
|
/**
|
|
123
|
-
* An EBANX send left for the cardholder's device under this attachment's approval (pre-claim.ts ebanxFollowUp
|
|
126
|
+
* An EBANX or Payrexx send left for the cardholder's device under this attachment's approval (pre-claim.ts ebanxFollowUp,
|
|
127
|
+
* payrexxFollowUp). Until
|
|
124
128
|
* the returned function runs, once the send's answer reached the page or the send failed, reconcile() and
|
|
125
129
|
* retryAfterMerchantFailure() throw, as they do while a card request is active: a confirm may still pay. The returned
|
|
126
130
|
* function settles the send once, however often it runs.
|
|
@@ -136,7 +140,7 @@ export class CheckoutLifecycle {
|
|
|
136
140
|
/** Whether a reconcile() is still waiting on the application's merchant resolver; pre-claim.ts claims no EBANX send then. */
|
|
137
141
|
isReconciling() { return this.reconciliation !== null; }
|
|
138
142
|
/**
|
|
139
|
-
* Whether an EBANX send this attachment claimed is still out (followUpStarted). Both adapters refuse a new card
|
|
143
|
+
* Whether an EBANX or Payrexx send this attachment claimed is still out (followUpStarted). Both adapters refuse a new card
|
|
140
144
|
* request meanwhile, as they do while an approval is outstanding: a confirm that may pay is never hidden behind
|
|
141
145
|
* another payment's state.
|
|
142
146
|
*/
|
|
@@ -283,7 +287,10 @@ export class CheckoutLifecycle {
|
|
|
283
287
|
* paddle-vgs-pay.ts reasons), or the typed card that EBANX's 3-D Secure calls or
|
|
284
288
|
* its hosted page's confirm send again after the token, when no approved token
|
|
285
289
|
* request on this attachment covers that send or the cardholder's device did not
|
|
286
|
-
* send it (unsupported_ebanx_card_resend, ebanx.ts)
|
|
290
|
+
* send it (unsupported_ebanx_card_resend, ebanx.ts), or the typed card Payrexx's card
|
|
291
|
+
* frame sends again for a 3-D Secure step when no approved card request on this
|
|
292
|
+
* attachment covers that send or the cardholder's device did not send it
|
|
293
|
+
* (unsupported_payrexx_card_resend, payrexx.ts): once an approval exists the
|
|
287
294
|
* state keeps it, and only the hold changes.
|
|
288
295
|
*/
|
|
289
296
|
unsupported(reason = 'unrecognized_payment_endpoint') {
|
|
@@ -305,6 +312,7 @@ export class CheckoutLifecycle {
|
|
|
305
312
|
this.set({ ...this.state, status: 'failed', reason: 'preparation_required' });
|
|
306
313
|
}
|
|
307
314
|
prepareHandoff(replay, requestUrl) {
|
|
315
|
+
this.heldBeforeHandoff = this.held;
|
|
308
316
|
this.wspayChallenge = isWspayChallenge(requestUrl, replay);
|
|
309
317
|
this.handoffs.push(requestUrl);
|
|
310
318
|
if (replay.mode === 'token' && replay.executionMode === 'autopilot' && replay.shopOrderId) {
|
|
@@ -422,10 +430,14 @@ export class CheckoutLifecycle {
|
|
|
422
430
|
return;
|
|
423
431
|
}
|
|
424
432
|
const mismatch = (!replay.mode || replay.mode === 'token') && replay.amountVerified === false;
|
|
433
|
+
// A hold raised while the answer was still landing stands: the page may send its first follow-up the moment the
|
|
434
|
+
// answer lands, and an EBANX or Payrexx send that fails then stops the approval's follow-ups for good
|
|
435
|
+
// (pre-claim.ts), so a new card request must not reopen the checkout under an approval that cannot finish.
|
|
436
|
+
const heldDuringHandoff = this.held && !this.heldBeforeHandoff;
|
|
425
437
|
// A card endpoint answer means the merchant already holds the card: its page's own
|
|
426
438
|
// retry, or a step-up that sends the card again, is refused until the application
|
|
427
439
|
// reconciles the order, exactly as for a hosted form the device submitted.
|
|
428
|
-
this.held = !!this.options.requireMerchantResult || replay.mode === 'hosted_form' || replay.mode === 'card_endpoint' || mismatch || this.unboundStripeToken;
|
|
440
|
+
this.held = heldDuringHandoff || !!this.options.requireMerchantResult || replay.mode === 'hosted_form' || replay.mode === 'card_endpoint' || mismatch || this.unboundStripeToken;
|
|
429
441
|
if (mismatch)
|
|
430
442
|
this.stripeTokenPrepared = false;
|
|
431
443
|
this.set({ status: 'awaiting_merchant', authorizationId: replay.authorizationId, mode: replay.mode ?? 'token',
|