@agent-cards/sdk 0.23.9 → 0.23.11
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 +48 -0
- package/PREFLIGHT.md +7 -5
- package/README.md +211 -102
- package/dist/aci.d.ts +7 -5
- package/dist/aci.generated.d.ts +2 -1
- package/dist/aci.generated.js +14 -4
- package/dist/aci.js +28 -7
- package/dist/amadeus-checkout.generated.js +2 -2
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/card-fields.generated.js +165 -10
- package/dist/cdp.js +86 -34
- package/dist/client.d.ts +73 -33
- package/dist/client.js +136 -45
- package/dist/creditguard.generated.d.ts +1 -1
- package/dist/creditguard.generated.js +1 -3
- package/dist/cse-body.d.ts +7 -6
- package/dist/cse-body.js +8 -7
- package/dist/datatrans.generated.js +8 -5
- package/dist/elavon-converge.d.ts +5 -2
- package/dist/elavon-converge.generated.js +9 -5
- package/dist/elavon-converge.js +8 -4
- package/dist/fiserv.d.ts +9 -5
- package/dist/fiserv.generated.d.ts +3 -3
- package/dist/fiserv.generated.js +50 -20
- package/dist/fiserv.js +10 -6
- package/dist/lifecycle.d.ts +9 -1
- package/dist/lifecycle.js +34 -0
- package/dist/payrails.d.ts +78 -18
- package/dist/payrails.generated.d.ts +12 -2
- package/dist/payrails.generated.js +213 -18
- package/dist/payrails.js +165 -44
- package/dist/pre-claim.d.ts +7 -0
- package/dist/pre-claim.js +98 -36
- package/dist/preflight-capabilities.generated.d.ts +0 -106
- package/dist/preflight-capabilities.generated.js +0 -153
- package/dist/preflight-catalog.json +61 -181
- package/dist/preflight-schemas.json +6 -6
- package/dist/preflight.generated.d.ts +0 -106
- package/dist/preflight.generated.js +27 -15
- package/dist/preparation.d.ts +2 -0
- package/dist/preparation.js +4 -2
- package/dist/prepared-processor.d.ts +19 -5
- package/dist/prepared-processor.js +21 -5
- package/dist/primer.generated.d.ts +5 -1
- package/dist/primer.generated.js +202 -34
- package/dist/registry.d.ts +18 -12
- package/dist/registry.js +11 -8
- package/dist/shiji-sts.d.ts +24 -22
- package/dist/shiji-sts.generated.d.ts +1 -1
- package/dist/shiji-sts.generated.js +12 -8
- package/dist/shiji-sts.js +49 -46
- package/dist/stripe-checkout.generated.js +157 -49
- package/dist/verifone.generated.js +192 -17
- package/dist/verifone.js +1 -1
- package/dist/worldline-mycheckout.d.ts +27 -0
- package/dist/worldline-mycheckout.generated.d.ts +29 -0
- package/dist/worldline-mycheckout.generated.js +162 -0
- package/dist/worldline-mycheckout.js +93 -0
- package/dist/wspay.d.ts +17 -16
- package/dist/wspay.generated.d.ts +6 -1
- package/dist/wspay.generated.js +13 -3
- package/dist/wspay.js +9 -11
- package/examples/preflight/kernel-native/README.md +1 -1
- package/examples/preflight/kernel-native/inventory.json +1 -19
- package/package.json +3 -3
|
@@ -20,6 +20,22 @@ export function preparationMode(psp) {
|
|
|
20
20
|
export function preparationRequestMethod(psp) {
|
|
21
21
|
return psp === 'worldpay_eprotect' ? 'GET' : 'POST';
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Whether a prepared checkout's approval outlives the page's own request, as an unprepared token
|
|
25
|
+
* approval does (cdp.ts survivesAbandonment): the page's next request for the same purchase, from
|
|
26
|
+
* the card frame that sent the first, is answered from it, with no second prompt. The approval stays
|
|
27
|
+
* that frame's (cdp.ts sameFrame): another frame's request is refused, and the frame's removal ends it.
|
|
28
|
+
*
|
|
29
|
+
* Bambora only. Custom Checkout's card frame fails its tokenization request 5 seconds after
|
|
30
|
+
* sending it, and a Pay button that runs the tokenization again sends the same placeholder and
|
|
31
|
+
* fields (WooCommerce's Bambora plugin shows the timeout, clears its token fields and lets Pay be
|
|
32
|
+
* clicked again). The cardholder's device answers with a token that pays nothing until the
|
|
33
|
+
* merchant's server charges it. Every other prepared checkout still answers only the request it
|
|
34
|
+
* was bound to.
|
|
35
|
+
*/
|
|
36
|
+
export function preparedApprovalAnswersRetry(psp) {
|
|
37
|
+
return psp === 'bambora';
|
|
38
|
+
}
|
|
23
39
|
/**
|
|
24
40
|
* Shared endpoint processors cannot attest test/live mode from their URL or key prefix.
|
|
25
41
|
* Adyen can: test and live are separate hosts and key prefixes. Fiserv's are separate
|
|
@@ -356,11 +372,11 @@ function secureAcceptanceClaimRefusal(requestUrl, body, headers, merchantOrigin,
|
|
|
356
372
|
/**
|
|
357
373
|
* The reason a claim reports for a request its preparation does not match. An Amadeus preparation
|
|
358
374
|
* names what payment-core's Amadeus check refused on its own environment's card URL, as
|
|
359
|
-
* `amadeus_<reason>`:
|
|
360
|
-
*
|
|
361
|
-
* `
|
|
362
|
-
*
|
|
363
|
-
*
|
|
375
|
+
* `amadeus_<reason>`: every Data Collection Page store is `amadeus_dcp_field_config_unreviewed`
|
|
376
|
+
* until a merchant's field config is reviewed, an add that keeps the card on file is
|
|
377
|
+
* `amadeus_card_on_file`, and a Host header that does not name the approved page is
|
|
378
|
+
* `amadeus_header_binding`. Everything else, another processor's request or the other
|
|
379
|
+
* environment's host included, is `checkout_changed`.
|
|
364
380
|
*/
|
|
365
381
|
export function preparedRequestRefusal(psp, environment, requestUrl, body, headers, merchantOrigin, currency) {
|
|
366
382
|
// A Secure Acceptance token create on the prepared environment's host names what payment-core's request
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
declare var PRIMER_PCI_HOSTS: readonly string[];
|
|
2
2
|
declare var PRIMER_TOKENIZE_PATH: string;
|
|
3
|
+
declare var PRIMER_SESSION_CARD_ON_FILE_POLICIES: readonly string[];
|
|
4
|
+
declare var PRIMER_SESSION_CARD_ON_FILE: string;
|
|
3
5
|
declare var PRIMER_REFUSAL_REASONS: readonly string[];
|
|
4
6
|
declare var PRIMER_PROVABLE_NETWORKS: readonly string[];
|
|
5
7
|
declare function isPrimerTokenizeUrl(url: any, method?: string): boolean;
|
|
@@ -9,6 +11,8 @@ declare function primerKeepOnFileRequested(body: any): boolean | null;
|
|
|
9
11
|
declare function classifyPrimerRequest(url: any, method: any, body: any, headers: any): "card" | "unsupported" | "keep_on_file" | "unsupported_sdk" | null;
|
|
10
12
|
declare function primerTokenizeRefusal(request: any): "unsupported" | "keep_on_file" | "unsupported_sdk" | null;
|
|
11
13
|
declare function isPrimerTokenizeRequest(request: any): boolean;
|
|
14
|
+
declare function primerCardOnFileDisclosure(url: any, policy?: string): boolean;
|
|
15
|
+
declare function primerCardOnFileRefusal(url: any, options: any, policy?: string): "unsupported" | "keep_on_file" | null;
|
|
12
16
|
declare function primerRefusalMessage(reason: any): string;
|
|
13
17
|
declare function primerCardNetwork(number: any): "VISA" | "AMEX" | "MASTERCARD" | null;
|
|
14
18
|
declare function primerNetworkRefusal(body: any, card: any): "unsupported" | "network_mismatch" | null;
|
|
@@ -35,4 +39,4 @@ declare function primerFacts(status: any, body: any): {
|
|
|
35
39
|
outcome: string;
|
|
36
40
|
refusalCode: any;
|
|
37
41
|
};
|
|
38
|
-
export { PRIMER_PCI_HOSTS, PRIMER_PROVABLE_NETWORKS, PRIMER_REFUSAL_REASONS, PRIMER_TOKENIZE_PATH, classifyPrimerRequest, injectPrimerCard, isPrimerNewCardBody, isPrimerTokenizeRequest, isPrimerTokenizeUrl, primerBodyRefusal, primerCardNetwork, primerErrorId, primerFacts, primerKeepOnFileRequested, primerNetworkRefusal, primerRefusalMessage, primerResponseOutcome, primerTokenizeRefusal, sanitizePrimerResponse };
|
|
42
|
+
export { PRIMER_PCI_HOSTS, PRIMER_PROVABLE_NETWORKS, PRIMER_REFUSAL_REASONS, PRIMER_SESSION_CARD_ON_FILE, PRIMER_SESSION_CARD_ON_FILE_POLICIES, PRIMER_TOKENIZE_PATH, classifyPrimerRequest, injectPrimerCard, isPrimerNewCardBody, isPrimerTokenizeRequest, isPrimerTokenizeUrl, primerBodyRefusal, primerCardNetwork, primerCardOnFileDisclosure, primerCardOnFileRefusal, primerErrorId, primerFacts, primerKeepOnFileRequested, primerNetworkRefusal, primerRefusalMessage, primerResponseOutcome, primerTokenizeRefusal, sanitizePrimerResponse };
|
package/dist/primer.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: 3f5ac5b4125cab96cc0851e9b1fe705aa96635e1df05b9216e951140fb47cd43
|
|
4
4
|
// src/card-number-key.js
|
|
5
5
|
var CARD_NUMBER_KEY = /^(number|card_number|cardnumber|cardNum|card_num|pan)$/i;
|
|
6
6
|
// src/json-path.js
|
|
@@ -37,7 +37,8 @@ function roundTrips(parsed, body) {
|
|
|
37
37
|
// src/elavon-converge.js
|
|
38
38
|
var CONVERGE_PROCESS_URLS = /* @__PURE__ */ Object.freeze([
|
|
39
39
|
"https://api.convergepay.com/hosted-payments/service/payment/hpp/process",
|
|
40
|
-
"https://api.demo.convergepay.com/hosted-payments/service/payment/hpp/process"
|
|
40
|
+
"https://api.demo.convergepay.com/hosted-payments/service/payment/hpp/process",
|
|
41
|
+
"https://www.convergepay.com/hosted-payments/service/payment/hpp/process"
|
|
41
42
|
]);
|
|
42
43
|
var TOP_LEVEL_KEYS = /* @__PURE__ */ Object.freeze(["paymentType", "paymentData", "context", "captchaToken", "shippingSameAsBilling"]);
|
|
43
44
|
var WALLET_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
@@ -78,15 +79,18 @@ var RECURRING_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
|
78
79
|
"ssl_recurring_batch_count",
|
|
79
80
|
"ssl_installment_id"
|
|
80
81
|
]);
|
|
82
|
+
var ONE_TIME_RECURRING_FLAG = "false";
|
|
81
83
|
var CARD_SAVING_FLAGS = /* @__PURE__ */ Object.freeze(["ssl_get_token", "ssl_add_token"]);
|
|
82
84
|
var CREDENTIAL_FIELDS = /* @__PURE__ */ Object.freeze(["ssl_account_id", "ssl_merchant_id", "ssl_user_id", "ssl_pin", "ssl_vendor_id"]);
|
|
83
85
|
var AMOUNT_ADD_ON_FIELDS = /* @__PURE__ */ Object.freeze(["ssl_tip_amount", "ssl_cashback_amount"]);
|
|
86
|
+
var SOLVED_CAPTCHA = /^[A-Za-z0-9_-]{1,4096}$/;
|
|
84
87
|
var CARD_NUMBER = /^\d{12,19}$/;
|
|
85
88
|
var EXPIRY_MMYY = /^(0[1-9]|1[0-2])\d{2}$/;
|
|
86
89
|
var CVC = /^\d{3,4}$/;
|
|
87
90
|
var AMOUNT = /^(\d{1,13})(?:\.(\d{1,2}))?$/;
|
|
88
91
|
var isRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
89
92
|
var owns = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
93
|
+
var recurringRequested = (data) => RECURRING_FIELDS.some((key) => owns(data, key) && !(key === "recurring" && data[key] === ONE_TIME_RECURRING_FLAG));
|
|
90
94
|
var refuse = (code) => Object.freeze({ verdict: "refuse", code });
|
|
91
95
|
var CARD = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
92
96
|
var CONTINUE = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
@@ -135,7 +139,7 @@ function convergeBodyVerdict(body) {
|
|
|
135
139
|
return refuse("converge_credential_refused");
|
|
136
140
|
if (WALLET_FIELDS.some((key) => owns(data, key)))
|
|
137
141
|
return refuse("converge_wallet_refused");
|
|
138
|
-
if (owns(parsed, "captchaToken"))
|
|
142
|
+
if (owns(parsed, "captchaToken") && !(typeof parsed.captchaToken === "string" && SOLVED_CAPTCHA.test(parsed.captchaToken)))
|
|
139
143
|
return refuse("converge_captcha_refused");
|
|
140
144
|
if (SERVICE_FEE_FIELDS.some((key) => owns(data, key)))
|
|
141
145
|
return refuse("converge_service_fee_refused");
|
|
@@ -148,7 +152,7 @@ function convergeBodyVerdict(body) {
|
|
|
148
152
|
if (owns(data, "ssl_token") || CARD_SAVING_FLAGS.some((key) => owns(data, key) && !(typeof data[key] === "string" && /^n$/i.test(data[key])))) {
|
|
149
153
|
return refuse("converge_card_saving_refused");
|
|
150
154
|
}
|
|
151
|
-
if (
|
|
155
|
+
if (recurringRequested(data))
|
|
152
156
|
return refuse("converge_recurring_refused");
|
|
153
157
|
if (owns(data, "ssl_transaction_currency") && !(typeof data.ssl_transaction_currency === "string" && /^usd$/i.test(data.ssl_transaction_currency))) {
|
|
154
158
|
return refuse("converge_currency_refused");
|
|
@@ -177,11 +181,155 @@ function isConvergeProcessUrl(url) {
|
|
|
177
181
|
}
|
|
178
182
|
return parsed.href === url && CONVERGE_PROCESS_URLS.includes(parsed.href);
|
|
179
183
|
}
|
|
180
|
-
// src/
|
|
181
|
-
var
|
|
184
|
+
// src/gravy.js
|
|
185
|
+
var GRAVY_PSP = "gravy";
|
|
186
|
+
var BODY_LIMIT = 4096;
|
|
187
|
+
var CARD_KEYS = /* @__PURE__ */ Object.freeze(["method", "number", "expiration_date", "security_code"]);
|
|
188
|
+
var ROOT_KEYS = /* @__PURE__ */ Object.freeze(["payment_method", "postal_code"]);
|
|
189
|
+
var CARD_NUMBER2 = /^[0-9]{12,19}$/;
|
|
190
|
+
var EXPIRY = /^(?:0[1-9]|1[0-2])\/[0-9]{2}$/;
|
|
191
|
+
var SECURITY_CODE = /^[0-9]{3,4}$/;
|
|
192
|
+
var POSTAL_CODE = /^[A-Za-z0-9 -]{0,16}$/;
|
|
193
|
+
var PAN_LIKE = /(?:[0-9][ _.:-]*){12,}/;
|
|
194
|
+
var EXPIRY_OR_CODE = /^(?:expiration_?date|expiry(?:_?date)?|exp_?date|card_?expiry|security_?code|cvc|cvc2|cvv|cvv2|cvd|card_?cvv|card_?cvc|verification_?value)$/i;
|
|
182
195
|
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
183
196
|
var owns2 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
184
|
-
|
|
197
|
+
function cardNamed(key) {
|
|
198
|
+
const name = key.slice(key.lastIndexOf(".") + 1);
|
|
199
|
+
return CARD_NUMBER_KEY.test(name) || /cardnumber$/i.test(name) || EXPIRY_OR_CODE.test(name);
|
|
200
|
+
}
|
|
201
|
+
function cardOutside(root) {
|
|
202
|
+
const pending = [];
|
|
203
|
+
for (const key of Object.keys(root)) {
|
|
204
|
+
const value = root[key];
|
|
205
|
+
if (key === "payment_method" && record(value)) {
|
|
206
|
+
for (const inner of Object.keys(value))
|
|
207
|
+
if (!CARD_KEYS.includes(inner))
|
|
208
|
+
pending.push([inner, value[inner]]);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
pending.push([key, value]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
while (pending.length > 0) {
|
|
215
|
+
const [key, value] = pending.pop();
|
|
216
|
+
if (key !== null && cardNamed(key))
|
|
217
|
+
return true;
|
|
218
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
219
|
+
if (PAN_LIKE.test(String(value)))
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
else if (Array.isArray(value)) {
|
|
223
|
+
for (const item of value)
|
|
224
|
+
pending.push([null, item]);
|
|
225
|
+
}
|
|
226
|
+
else if (record(value)) {
|
|
227
|
+
for (const inner of Object.keys(value))
|
|
228
|
+
pending.push([inner, value[inner]]);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
function readBody(body) {
|
|
234
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT)
|
|
235
|
+
return null;
|
|
236
|
+
let value;
|
|
237
|
+
try {
|
|
238
|
+
value = JSON.parse(body);
|
|
239
|
+
if (!record(value) || JSON.stringify(value) !== body)
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
var refuse2 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
248
|
+
var CARD2 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
249
|
+
function gravyBodyVerdict(body) {
|
|
250
|
+
const value = readBody(body);
|
|
251
|
+
if (value === null)
|
|
252
|
+
return refuse2("gravy_body_unsupported");
|
|
253
|
+
if (cardOutside(value))
|
|
254
|
+
return refuse2("gravy_card_outside_payment_method");
|
|
255
|
+
const card = value.payment_method;
|
|
256
|
+
if (!record(card) || card.method !== "card" || !CARD_KEYS.every((key) => owns2(card, key)))
|
|
257
|
+
return refuse2("gravy_new_card_missing");
|
|
258
|
+
if (!Object.keys(value).every((key) => ROOT_KEYS.includes(key)) || !Object.keys(card).every((key) => CARD_KEYS.includes(key)) || typeof card.number !== "string" || !CARD_NUMBER2.test(card.number) || typeof card.expiration_date !== "string" || !EXPIRY.test(card.expiration_date) || typeof card.security_code !== "string" || !SECURITY_CODE.test(card.security_code) || owns2(value, "postal_code") && (typeof value.postal_code !== "string" || !POSTAL_CODE.test(value.postal_code))) {
|
|
259
|
+
return refuse2("gravy_body_unsupported");
|
|
260
|
+
}
|
|
261
|
+
return CARD2;
|
|
262
|
+
}
|
|
263
|
+
// src/moneris.js
|
|
264
|
+
var MONERIS_PSP = "moneris";
|
|
265
|
+
var CARD_KEYS2 = /* @__PURE__ */ Object.freeze(["input_data", "input_exp", "input_cvd", "hpt_id", "hpt_ticket", "doTokenize"]);
|
|
266
|
+
var PARTIAL_KEYS = /* @__PURE__ */ Object.freeze([
|
|
267
|
+
["input_data", "hpt_id", "hpt_ticket", "doTokenize"],
|
|
268
|
+
["input_data", "input_exp", "hpt_id", "hpt_ticket", "doTokenize"],
|
|
269
|
+
["input_data", "input_cvd", "hpt_id", "hpt_ticket", "doTokenize"]
|
|
270
|
+
]);
|
|
271
|
+
var CARD_NUMBER3 = /^\d{12,19}$/;
|
|
272
|
+
var GROUPED_DIGITS = /^\d+(?: \d+)*$/;
|
|
273
|
+
var EXPIRY_MMYY2 = /^(0[1-9]|1[0-2])\d{2}$/;
|
|
274
|
+
var CVD = /^\d{3,4}$/;
|
|
275
|
+
var PROFILE_ID = /^ht[A-Za-z0-9]{1,64}$/;
|
|
276
|
+
var TICKET = /^tt[A-Za-z0-9]{1,128}$/;
|
|
277
|
+
var refuse3 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
278
|
+
var CARD3 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
279
|
+
function readPairs(body) {
|
|
280
|
+
if (typeof body !== "string" || body === "" || body.length > 4096)
|
|
281
|
+
return null;
|
|
282
|
+
const pairs = [];
|
|
283
|
+
for (const chunk of body.split("&")) {
|
|
284
|
+
const eq = chunk.indexOf("=");
|
|
285
|
+
if (eq <= 0)
|
|
286
|
+
return null;
|
|
287
|
+
pairs.push([chunk.slice(0, eq), chunk.slice(eq + 1)]);
|
|
288
|
+
}
|
|
289
|
+
return pairs;
|
|
290
|
+
}
|
|
291
|
+
var hasKeys = (pairs, keys) => pairs.length === keys.length && pairs.every(([key], at) => key === keys[at]);
|
|
292
|
+
function monerisBodyVerdict(body) {
|
|
293
|
+
const pairs = readPairs(body);
|
|
294
|
+
if (pairs === null)
|
|
295
|
+
return refuse3("moneris_body_malformed");
|
|
296
|
+
if (PARTIAL_KEYS.some((keys) => hasKeys(pairs, keys)))
|
|
297
|
+
return refuse3("moneris_partial_card");
|
|
298
|
+
if (!hasKeys(pairs, CARD_KEYS2))
|
|
299
|
+
return refuse3("moneris_body_malformed");
|
|
300
|
+
const [[, number], [, expiry], [, cvd], [, profile], [, ticket], [, tokenize]] = pairs;
|
|
301
|
+
if (!GROUPED_DIGITS.test(number) || !CARD_NUMBER3.test(number.replace(/ /g, "")) || !EXPIRY_MMYY2.test(expiry) || !CVD.test(cvd) || !PROFILE_ID.test(profile) || !TICKET.test(ticket) || tokenize !== "true")
|
|
302
|
+
return refuse3("moneris_body_malformed");
|
|
303
|
+
return CARD3;
|
|
304
|
+
}
|
|
305
|
+
var MONERIS_TOKENIZE_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
306
|
+
production: Object.freeze(["www3.moneris.com", "gateway.moneris.com"]),
|
|
307
|
+
sandbox: Object.freeze(["esqa.moneris.com"])
|
|
308
|
+
});
|
|
309
|
+
var MONERIS_TOKENIZE_PATH = "/HPPtoken/request.php";
|
|
310
|
+
function monerisTokenizeEnvironment(url) {
|
|
311
|
+
if (typeof url !== "string")
|
|
312
|
+
return null;
|
|
313
|
+
for (const environment of
|
|
314
|
+
/** @type {const} */
|
|
315
|
+
["production", "sandbox"]) {
|
|
316
|
+
if (MONERIS_TOKENIZE_HOSTS[environment].some((host) => url === `https://${host}${MONERIS_TOKENIZE_PATH}`))
|
|
317
|
+
return environment;
|
|
318
|
+
}
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
function isMonerisTokenizeUrl(url) {
|
|
322
|
+
return monerisTokenizeEnvironment(url) !== null;
|
|
323
|
+
}
|
|
324
|
+
var pin = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), profileIds: Object.freeze([...fields.profileIds]) });
|
|
325
|
+
var MONERIS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
326
|
+
pin({ id: "jack_org_raisin", merchant: "Jack.org", origins: ["https://jack.akaraisin.com"], profileIds: ["htL7TR9H7ICYN2B"] })
|
|
327
|
+
]);
|
|
328
|
+
// src/amadeus-body.js
|
|
329
|
+
var AMADEUS_CARD_MOPID = /^creditcard[0-9]*$/;
|
|
330
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
331
|
+
var owns3 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
332
|
+
var holdsPan = (mopdata) => record2(mopdata) && owns3(mopdata, "pan") && mopdata.pan !== null && mopdata.pan !== "";
|
|
185
333
|
function amadeusBodyKind(body) {
|
|
186
334
|
let value;
|
|
187
335
|
try {
|
|
@@ -190,18 +338,25 @@ function amadeusBodyKind(body) {
|
|
|
190
338
|
catch {
|
|
191
339
|
return "card";
|
|
192
340
|
}
|
|
193
|
-
if (!
|
|
341
|
+
if (!record2(value))
|
|
194
342
|
return "card";
|
|
195
343
|
if (value.action === "add") {
|
|
196
344
|
const entries = Array.isArray(value.data) ? value.data : [value.data];
|
|
197
|
-
return entries.some((entry) =>
|
|
345
|
+
return entries.some((entry) => record2(entry) && typeof entry.mopid === "string" && AMADEUS_CARD_MOPID.test(entry.mopid) && holdsPan(entry.mopdata)) ? "card" : "other";
|
|
198
346
|
}
|
|
199
347
|
if (value.action === "store")
|
|
200
|
-
return
|
|
348
|
+
return record2(value.data) && holdsPan(value.data.mopdata) ? "card" : "other";
|
|
201
349
|
return "other";
|
|
202
350
|
}
|
|
203
351
|
// src/card-fields.js
|
|
204
352
|
function processorGate(recognizer, url, body) {
|
|
353
|
+
if (recognizer && recognizer.psp === GRAVY_PSP)
|
|
354
|
+
return gravyBodyVerdict(body);
|
|
355
|
+
if (recognizer && recognizer.psp === MONERIS_PSP) {
|
|
356
|
+
if (url !== void 0 && !isMonerisTokenizeUrl(url))
|
|
357
|
+
return { verdict: "refuse", code: "moneris_url_refused" };
|
|
358
|
+
return monerisBodyVerdict(body);
|
|
359
|
+
}
|
|
205
360
|
if (!recognizer || recognizer.psp !== "elavon_converge")
|
|
206
361
|
return null;
|
|
207
362
|
if (url !== void 0 && !isConvergeProcessUrl(url))
|
|
@@ -305,6 +460,9 @@ function namesCardNumber(root, declared) {
|
|
|
305
460
|
// src/primer.js
|
|
306
461
|
var PRIMER_PCI_HOSTS = /* @__PURE__ */ Object.freeze(["sdk.api.primer.io", "sdk.api.sandbox.primer.io"]);
|
|
307
462
|
var PRIMER_TOKENIZE_PATH = "/payment-instruments";
|
|
463
|
+
var PRIMER_SESSION_CARD_ON_FILE_POLICIES = /* @__PURE__ */ Object.freeze(["refuse", "disclose"]);
|
|
464
|
+
var PRIMER_SESSION_CARD_ON_FILE = "disclose";
|
|
465
|
+
var LIVE_PCI_HOST = "sdk.api.primer.io";
|
|
308
466
|
var PRIMER_REFUSAL_REASONS = /* @__PURE__ */ Object.freeze(["unsupported", "keep_on_file", "unsupported_sdk", "network_mismatch"]);
|
|
309
467
|
var PRIMER_PROVABLE_NETWORKS = /* @__PURE__ */ Object.freeze(["VISA", "MASTERCARD", "AMEX"]);
|
|
310
468
|
var UNSUPPORTED_REFUSAL = "Refusing to pay: unsupported Primer card request.";
|
|
@@ -312,13 +470,13 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
|
|
|
312
470
|
var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
|
|
313
471
|
var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
|
|
314
472
|
var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
|
|
315
|
-
var
|
|
473
|
+
var BODY_LIMIT2 = 16384;
|
|
316
474
|
var RESPONSE_LIMIT = 32768;
|
|
317
|
-
var
|
|
475
|
+
var ROOT_KEYS2 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
|
|
318
476
|
var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
|
|
319
477
|
var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
|
|
320
|
-
var
|
|
321
|
-
var
|
|
478
|
+
var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
479
|
+
var owns4 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
322
480
|
var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
323
481
|
var text = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
324
482
|
var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
@@ -340,7 +498,7 @@ function isPrimerTokenizeUrl(url, method = "POST") {
|
|
|
340
498
|
return parsed.href === url && parsed.protocol === "https:" && !parsed.port && !parsed.username && !parsed.password && !parsed.search && !parsed.hash && PRIMER_PCI_HOSTS.includes(parsed.hostname) && parsed.pathname === PRIMER_TOKENIZE_PATH;
|
|
341
499
|
}
|
|
342
500
|
function judgeBody(body) {
|
|
343
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
501
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT2)
|
|
344
502
|
return null;
|
|
345
503
|
let value;
|
|
346
504
|
try {
|
|
@@ -349,18 +507,18 @@ function judgeBody(body) {
|
|
|
349
507
|
catch {
|
|
350
508
|
return null;
|
|
351
509
|
}
|
|
352
|
-
if (!
|
|
510
|
+
if (!record3(value) || !roundTrips(value, body))
|
|
353
511
|
return null;
|
|
354
|
-
if (!Object.keys(value).every((key) =>
|
|
512
|
+
if (!Object.keys(value).every((key) => ROOT_KEYS2.includes(key)) || !owns4(value, "paymentInstrument"))
|
|
355
513
|
return null;
|
|
356
514
|
const instrument = value.paymentInstrument;
|
|
357
|
-
if (!
|
|
515
|
+
if (!record3(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns4(instrument, key)))
|
|
358
516
|
return null;
|
|
359
517
|
if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH, instrument.expirationMonth) || !exact(YEAR, instrument.expirationYear))
|
|
360
518
|
return null;
|
|
361
|
-
if (
|
|
519
|
+
if (owns4(instrument, "cardholderName") && instrument.cardholderName !== null && !plain(instrument.cardholderName, 256) || owns4(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact(NETWORK, instrument.preferredNetwork) || owns4(value, "userDescription") && value.userDescription !== null && !plain(value.userDescription, 256) || owns4(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns4(value, "paymentFlow") && value.paymentFlow !== "VAULT")
|
|
362
520
|
return null;
|
|
363
|
-
return { value, keepOnFile:
|
|
521
|
+
return { value, keepOnFile: owns4(value, "tokenType") || owns4(value, "paymentFlow") };
|
|
364
522
|
}
|
|
365
523
|
function primerBodyRefusal(body) {
|
|
366
524
|
const judged = judgeBody(body);
|
|
@@ -382,7 +540,7 @@ var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
|
|
|
382
540
|
var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
383
541
|
var API_VERSION = /^2\.[0-9]{1,2}$/;
|
|
384
542
|
function readHeaders(headers) {
|
|
385
|
-
if (!
|
|
543
|
+
if (!record3(headers))
|
|
386
544
|
return null;
|
|
387
545
|
const folded = /* @__PURE__ */ new Map();
|
|
388
546
|
for (const [name, value] of Object.entries(headers)) {
|
|
@@ -429,13 +587,23 @@ function onTokenizePath(url) {
|
|
|
429
587
|
}
|
|
430
588
|
}
|
|
431
589
|
function primerTokenizeRefusal(request) {
|
|
432
|
-
if (!
|
|
590
|
+
if (!record3(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
|
|
433
591
|
return "unsupported";
|
|
434
592
|
return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
|
|
435
593
|
}
|
|
436
594
|
function isPrimerTokenizeRequest(request) {
|
|
437
595
|
return primerTokenizeRefusal(request) === null;
|
|
438
596
|
}
|
|
597
|
+
function primerCardOnFileDisclosure(url, policy = PRIMER_SESSION_CARD_ON_FILE) {
|
|
598
|
+
return policy === "disclose" && isPrimerTokenizeUrl(url) && new URL(url).hostname === LIVE_PCI_HOST;
|
|
599
|
+
}
|
|
600
|
+
function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_FILE) {
|
|
601
|
+
if (!isPrimerTokenizeUrl(url))
|
|
602
|
+
return "unsupported";
|
|
603
|
+
if (new URL(url).hostname !== LIVE_PCI_HOST)
|
|
604
|
+
return null;
|
|
605
|
+
return primerCardOnFileDisclosure(url, policy) && record3(options) && options.keepOnFile === true ? null : "keep_on_file";
|
|
606
|
+
}
|
|
439
607
|
function primerRefusalMessage(reason) {
|
|
440
608
|
if (reason === "keep_on_file")
|
|
441
609
|
return KEEP_ON_FILE_REFUSAL;
|
|
@@ -518,28 +686,28 @@ function readAnswer(body) {
|
|
|
518
686
|
return null;
|
|
519
687
|
try {
|
|
520
688
|
const value = JSON.parse(body);
|
|
521
|
-
return
|
|
689
|
+
return record3(value) ? value : null;
|
|
522
690
|
}
|
|
523
691
|
catch {
|
|
524
692
|
return null;
|
|
525
693
|
}
|
|
526
694
|
}
|
|
527
695
|
var tokenValue = (value) => exact(TOKEN, value) && !panLike(value);
|
|
528
|
-
var optional = (value, key, check) => !
|
|
696
|
+
var optional = (value, key, check) => !owns4(value, key) || value[key] === null || check(value[key]);
|
|
529
697
|
function cardDetails(data) {
|
|
530
|
-
if (!
|
|
698
|
+
if (!record3(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
|
|
531
699
|
return null;
|
|
532
|
-
if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData",
|
|
700
|
+
if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record3))
|
|
533
701
|
return null;
|
|
534
702
|
const safe = { last4Digits: data.last4Digits };
|
|
535
703
|
for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
|
|
536
|
-
if (
|
|
704
|
+
if (owns4(data, key) && data[key] !== null)
|
|
537
705
|
safe[key] = data[key];
|
|
538
706
|
}
|
|
539
|
-
if (
|
|
707
|
+
if (record3(data.binData)) {
|
|
540
708
|
const bin = {};
|
|
541
709
|
for (const key of BIN_KEYS) {
|
|
542
|
-
if (!
|
|
710
|
+
if (!owns4(data.binData, key) || data.binData[key] === null)
|
|
543
711
|
continue;
|
|
544
712
|
if (!plain(data.binData[key], 128))
|
|
545
713
|
return null;
|
|
@@ -552,11 +720,11 @@ function cardDetails(data) {
|
|
|
552
720
|
function threeDsSummary(value) {
|
|
553
721
|
if (value === void 0 || value === null)
|
|
554
722
|
return null;
|
|
555
|
-
if (!
|
|
723
|
+
if (!record3(value) || !exact(CODE, value.responseCode) || !optional(value, "reasonCode", (v) => exact(CODE, v)) || !optional(value, "reasonText", (v) => plain(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
|
|
556
724
|
return void 0;
|
|
557
725
|
const safe = { responseCode: value.responseCode };
|
|
558
726
|
for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
|
|
559
|
-
if (
|
|
727
|
+
if (owns4(value, key) && value[key] !== null)
|
|
560
728
|
safe[key] = value[key];
|
|
561
729
|
}
|
|
562
730
|
return safe;
|
|
@@ -569,7 +737,7 @@ function rebuildToken(value) {
|
|
|
569
737
|
if (!details || threeDs === void 0)
|
|
570
738
|
return null;
|
|
571
739
|
const safe = { token: value.token };
|
|
572
|
-
if (
|
|
740
|
+
if (owns4(value, "analyticsId") && value.analyticsId !== null)
|
|
573
741
|
safe.analyticsId = value.analyticsId;
|
|
574
742
|
safe.tokenType = "SINGLE_USE";
|
|
575
743
|
safe.paymentInstrumentType = "PAYMENT_CARD";
|
|
@@ -580,7 +748,7 @@ function rebuildToken(value) {
|
|
|
580
748
|
}
|
|
581
749
|
function primerErrorId(body) {
|
|
582
750
|
const value = readAnswer(body);
|
|
583
|
-
const id = value &&
|
|
751
|
+
const id = value && record3(value.error) ? value.error.errorId : null;
|
|
584
752
|
return exact(ERROR_ID, id) && !panLike(id) ? id : null;
|
|
585
753
|
}
|
|
586
754
|
function matchesCard(details, card) {
|
|
@@ -621,4 +789,4 @@ function primerFacts(status, body) {
|
|
|
621
789
|
const verdict = primerResponseOutcome(status, body);
|
|
622
790
|
return { outcome: verdict.outcome, refusalCode: verdict.outcome === "refused" ? verdict.code : null };
|
|
623
791
|
}
|
|
624
|
-
export { PRIMER_PCI_HOSTS, PRIMER_PROVABLE_NETWORKS, PRIMER_REFUSAL_REASONS, PRIMER_TOKENIZE_PATH, classifyPrimerRequest, injectPrimerCard, isPrimerNewCardBody, isPrimerTokenizeRequest, isPrimerTokenizeUrl, primerBodyRefusal, primerCardNetwork, primerErrorId, primerFacts, primerKeepOnFileRequested, primerNetworkRefusal, primerRefusalMessage, primerResponseOutcome, primerTokenizeRefusal, sanitizePrimerResponse };
|
|
792
|
+
export { PRIMER_PCI_HOSTS, PRIMER_PROVABLE_NETWORKS, PRIMER_REFUSAL_REASONS, PRIMER_SESSION_CARD_ON_FILE, PRIMER_SESSION_CARD_ON_FILE_POLICIES, PRIMER_TOKENIZE_PATH, classifyPrimerRequest, injectPrimerCard, isPrimerNewCardBody, isPrimerTokenizeRequest, isPrimerTokenizeUrl, primerBodyRefusal, primerCardNetwork, primerCardOnFileDisclosure, primerCardOnFileRefusal, primerErrorId, primerFacts, primerKeepOnFileRequested, primerNetworkRefusal, primerRefusalMessage, primerResponseOutcome, primerTokenizeRefusal, sanitizePrimerResponse };
|
package/dist/registry.d.ts
CHANGED
|
@@ -118,7 +118,9 @@ export interface Recognizer {
|
|
|
118
118
|
* names `authorize_net_dpm_form`, Pelecard names `pelecard_transaction`,
|
|
119
119
|
* Primer names `primer_payment_instruments`, Payrails names
|
|
120
120
|
* `payrails_device_encrypt`, Elavon Converge names `converge_hpp_process`,
|
|
121
|
-
* WSPay names `wspay_confirm
|
|
121
|
+
* WSPay names `wspay_confirm`, Shiji STS names `shiji_sts_pinned_key`, Gravy
|
|
122
|
+
* names `gravy_session_fields_put` and Moneris Hosted Tokenization names
|
|
123
|
+
* `moneris_hosted_tokenization`.
|
|
122
124
|
*/
|
|
123
125
|
capability?: string;
|
|
124
126
|
/**
|
|
@@ -165,13 +167,15 @@ export interface Recognizer {
|
|
|
165
167
|
/**
|
|
166
168
|
* The card request's shape when it is not a POST body. Worldpay eProtect
|
|
167
169
|
* declares `{ method: 'GET', cardIn: 'query', response: 'jsonp' }`: its card
|
|
168
|
-
* rides in the query of one JSONP <script> GET.
|
|
170
|
+
* rides in the query of one JSONP <script> GET. Gravy declares
|
|
171
|
+
* `{ method: 'PUT', cardIn: 'body', response: 'no_content' }`: its card rides in
|
|
172
|
+
* the JSON body of a PUT, as a POST's does. Absent means a POST. Carried
|
|
169
173
|
* verbatim by syncRegistry; isCardRequest reads `method` through
|
|
170
|
-
* recognizerRequestMethod,
|
|
171
|
-
* query this build can check.
|
|
174
|
+
* recognizerRequestMethod, pauses a PUT as it pauses a POST, and pauses a GET
|
|
175
|
+
* only for a processor whose exact query this build can check.
|
|
172
176
|
*/
|
|
173
177
|
request?: {
|
|
174
|
-
method: 'GET' | 'POST';
|
|
178
|
+
method: 'GET' | 'POST' | 'PUT';
|
|
175
179
|
cardIn?: string;
|
|
176
180
|
response?: string;
|
|
177
181
|
};
|
|
@@ -212,15 +216,17 @@ export declare function urlsOnProcessorHosts(url: string, rec: Recognizer, opts?
|
|
|
212
216
|
export declare function findRecognizer(url: string, registry?: Recognizer[], opts?: RecognizerOptions): Recognizer | null;
|
|
213
217
|
/**
|
|
214
218
|
* The HTTP method of a recognizer's card request, the rule payment-core's
|
|
215
|
-
* recognizerRequestMethod applies: GET only when the entry declares
|
|
216
|
-
* `request.method
|
|
217
|
-
* value that rode in over the wire as anything else never widens a
|
|
218
|
-
* recognizer.
|
|
219
|
+
* recognizerRequestMethod applies: GET or PUT only when the entry declares that
|
|
220
|
+
* `request.method` (Worldpay eProtect's GET, Gravy's PUT), POST for everything
|
|
221
|
+
* else, so a value that rode in over the wire as anything else never widens a
|
|
222
|
+
* POST recognizer.
|
|
219
223
|
*/
|
|
220
|
-
export declare function recognizerRequestMethod(rec: Pick<Recognizer, 'request'>): 'GET' | 'POST';
|
|
224
|
+
export declare function recognizerRequestMethod(rec: Pick<Recognizer, 'request'>): 'GET' | 'POST' | 'PUT';
|
|
221
225
|
/**
|
|
222
|
-
* Whether `method` is this recognizer's card request method for `url`. A
|
|
223
|
-
* carries the card in its
|
|
226
|
+
* Whether `method` is this recognizer's card request method for `url`. A PUT
|
|
227
|
+
* recognizer (Gravy) carries the card in its body as a POST one does, so its PUT
|
|
228
|
+
* pauses like a POST, and neither pauses in the other's method. A GET carries
|
|
229
|
+
* the card in its URL, so a GET recognizer is a card request only for a
|
|
224
230
|
* processor whose exact query this build checks (Worldpay eProtect, through
|
|
225
231
|
* payment-core's grammar); any other GET recognizer is nothing this build can
|
|
226
232
|
* complete and is never paused.
|
package/dist/registry.js
CHANGED
|
@@ -128,17 +128,20 @@ export function findRecognizer(url, registry = BUILTIN_REGISTRY, opts = {}) {
|
|
|
128
128
|
}
|
|
129
129
|
/**
|
|
130
130
|
* The HTTP method of a recognizer's card request, the rule payment-core's
|
|
131
|
-
* recognizerRequestMethod applies: GET only when the entry declares
|
|
132
|
-
* `request.method
|
|
133
|
-
* value that rode in over the wire as anything else never widens a
|
|
134
|
-
* recognizer.
|
|
131
|
+
* recognizerRequestMethod applies: GET or PUT only when the entry declares that
|
|
132
|
+
* `request.method` (Worldpay eProtect's GET, Gravy's PUT), POST for everything
|
|
133
|
+
* else, so a value that rode in over the wire as anything else never widens a
|
|
134
|
+
* POST recognizer.
|
|
135
135
|
*/
|
|
136
136
|
export function recognizerRequestMethod(rec) {
|
|
137
|
-
|
|
137
|
+
const method = rec?.request?.method;
|
|
138
|
+
return method === 'GET' || method === 'PUT' ? method : 'POST';
|
|
138
139
|
}
|
|
139
140
|
/**
|
|
140
|
-
* Whether `method` is this recognizer's card request method for `url`. A
|
|
141
|
-
* carries the card in its
|
|
141
|
+
* Whether `method` is this recognizer's card request method for `url`. A PUT
|
|
142
|
+
* recognizer (Gravy) carries the card in its body as a POST one does, so its PUT
|
|
143
|
+
* pauses like a POST, and neither pauses in the other's method. A GET carries
|
|
144
|
+
* the card in its URL, so a GET recognizer is a card request only for a
|
|
142
145
|
* processor whose exact query this build checks (Worldpay eProtect, through
|
|
143
146
|
* payment-core's grammar); any other GET recognizer is nothing this build can
|
|
144
147
|
* complete and is never paused.
|
|
@@ -147,7 +150,7 @@ export function isRecognizerRequest(rec, url, method) {
|
|
|
147
150
|
const expected = recognizerRequestMethod(rec);
|
|
148
151
|
if (typeof method !== 'string' || method.toUpperCase() !== expected)
|
|
149
152
|
return false;
|
|
150
|
-
return expected
|
|
153
|
+
return expected !== 'GET' || (rec.psp === EPROTECT_PSP && isEprotectTokenRequest(url, 'GET'));
|
|
151
154
|
}
|
|
152
155
|
/**
|
|
153
156
|
* True when this processor cannot be taken over on an ordinary authorization:
|