@agent-cards/sdk 0.21.0 → 0.22.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 +47 -0
- package/PREFLIGHT.md +30 -0
- package/README.md +1070 -21
- package/dist/aci.d.ts +173 -0
- package/dist/aci.generated.d.ts +87 -0
- package/dist/aci.generated.js +306 -0
- package/dist/aci.js +371 -0
- package/dist/adyen-merchant-hosted.generated.d.ts +3 -3
- package/dist/adyen-merchant-hosted.generated.js +283 -49
- package/dist/agentcard.d.ts +9 -2
- package/dist/agentcard.js +4 -2
- package/dist/amadeus-checkout.generated.d.ts +57 -0
- package/dist/amadeus-checkout.generated.js +549 -0
- package/dist/amadeus.d.ts +41 -0
- package/dist/amadeus.js +81 -0
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/card-endpoint.d.ts +177 -0
- package/dist/card-endpoint.js +286 -0
- package/dist/card-fields.generated.d.ts +5 -3
- package/dist/card-fields.generated.js +284 -7
- package/dist/cdp.d.ts +5 -1
- package/dist/cdp.js +841 -135
- package/dist/client.d.ts +403 -19
- package/dist/client.js +949 -98
- package/dist/creditguard.generated.d.ts +79 -0
- package/dist/creditguard.generated.js +662 -0
- package/dist/cse-body.js +11 -1
- package/dist/datatrans.d.ts +96 -0
- package/dist/datatrans.generated.d.ts +64 -0
- package/dist/datatrans.generated.js +426 -0
- package/dist/datatrans.js +178 -0
- package/dist/elavon-converge.d.ts +37 -0
- package/dist/elavon-converge.generated.d.ts +49 -0
- package/dist/elavon-converge.generated.js +439 -0
- package/dist/elavon-converge.js +84 -0
- package/dist/eprotect.d.ts +152 -0
- package/dist/eprotect.generated.d.ts +77 -0
- package/dist/eprotect.generated.js +498 -0
- package/dist/eprotect.js +222 -0
- package/dist/hosted-form.d.ts +3 -2
- package/dist/hosted-form.js +3 -2
- package/dist/index.d.ts +17 -3
- package/dist/index.js +6 -1
- package/dist/juspay-gate.d.ts +82 -0
- package/dist/juspay-gate.js +126 -0
- package/dist/juspay.generated.d.ts +89 -0
- package/dist/juspay.generated.js +705 -0
- package/dist/lifecycle.d.ts +57 -6
- package/dist/lifecycle.js +119 -8
- package/dist/merchant-card-endpoints.generated.d.ts +63 -0
- package/dist/merchant-card-endpoints.generated.js +1103 -0
- package/dist/merchant-hosted.d.ts +4 -1
- package/dist/merchant-hosted.js +5 -2
- package/dist/merchant-session-probe.d.ts +48 -0
- package/dist/merchant-session-probe.js +53 -0
- package/dist/merchant-session.generated.d.ts +69 -0
- package/dist/merchant-session.generated.js +919 -0
- package/dist/payrails.d.ts +133 -0
- package/dist/payrails.generated.d.ts +73 -0
- package/dist/payrails.generated.js +596 -0
- package/dist/payrails.js +305 -0
- package/dist/pelecard.d.ts +32 -0
- package/dist/pelecard.generated.d.ts +32 -0
- package/dist/pelecard.generated.js +283 -0
- package/dist/pelecard.js +42 -0
- package/dist/pre-claim.d.ts +72 -2
- package/dist/pre-claim.js +857 -5
- package/dist/preflight-catalog.json +2218 -287
- package/dist/preflight-schemas.json +179 -6
- package/dist/preflight.generated.d.ts +1 -1
- package/dist/preflight.generated.js +233 -4
- package/dist/preparation.d.ts +5 -2
- package/dist/preparation.js +36 -10
- package/dist/prepared-processor.d.ts +84 -5
- package/dist/prepared-processor.js +147 -6
- package/dist/primer.d.ts +53 -0
- package/dist/primer.generated.d.ts +38 -0
- package/dist/primer.generated.js +624 -0
- package/dist/primer.js +82 -0
- package/dist/registry.d.ts +100 -8
- package/dist/registry.js +85 -11
- package/dist/shiji-sts.d.ts +144 -0
- package/dist/shiji-sts.generated.d.ts +72 -0
- package/dist/shiji-sts.generated.js +913 -0
- package/dist/shiji-sts.js +222 -0
- package/dist/stripe-checkout.generated.d.ts +1 -1
- package/dist/stripe-checkout.generated.js +699 -9
- package/dist/stripe-setup.d.ts +16 -0
- package/dist/stripe-setup.js +61 -0
- package/dist/substitutions.generated.js +187 -29
- package/dist/verifone.d.ts +68 -0
- package/dist/verifone.generated.d.ts +51 -0
- package/dist/verifone.generated.js +1401 -0
- package/dist/verifone.js +119 -0
- package/dist/voice-types.d.ts +27 -0
- package/dist/voice.d.ts +6 -1
- package/dist/voice.js +6 -1
- package/dist/wspay.d.ts +41 -0
- package/dist/wspay.generated.d.ts +41 -0
- package/dist/wspay.generated.js +370 -0
- package/dist/wspay.js +65 -0
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
+
// artifact-sha256: 6dfbdbf520cb1656f338b88088dde209111190a2cbd3e7767e0e1b6d5e15e5ed
|
|
4
|
+
// src/card-number-key.js
|
|
5
|
+
var CARD_NUMBER_KEY = /^(number|card_number|cardnumber|cardNum|card_num|pan)$/i;
|
|
6
|
+
// src/json-path.js
|
|
7
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
8
|
+
function isPlainObject(v) {
|
|
9
|
+
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
10
|
+
}
|
|
11
|
+
var MAX_PATH_STEPS = 16;
|
|
12
|
+
function isJsonPath(path) {
|
|
13
|
+
return Array.isArray(path) && path.length <= MAX_PATH_STEPS && path.every((step) => typeof step === "string" ? step.length > 0 && !FORBIDDEN_KEYS.has(step) : Number.isSafeInteger(step) && step >= 0);
|
|
14
|
+
}
|
|
15
|
+
function jsonAt(root, path) {
|
|
16
|
+
let node = root;
|
|
17
|
+
for (const step of path) {
|
|
18
|
+
if (typeof step === "string") {
|
|
19
|
+
if (!isPlainObject(node) || FORBIDDEN_KEYS.has(step) || !Object.prototype.hasOwnProperty.call(node, step))
|
|
20
|
+
return { found: false };
|
|
21
|
+
}
|
|
22
|
+
else if (!Array.isArray(node) || !Number.isSafeInteger(step) || step < 0 || step >= node.length) {
|
|
23
|
+
return { found: false };
|
|
24
|
+
}
|
|
25
|
+
node = node[step];
|
|
26
|
+
}
|
|
27
|
+
return { found: true, value: node };
|
|
28
|
+
}
|
|
29
|
+
function roundTrips(parsed, body) {
|
|
30
|
+
try {
|
|
31
|
+
return JSON.stringify(parsed) === body;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// src/elavon-converge.js
|
|
38
|
+
var CONVERGE_PROCESS_URLS = /* @__PURE__ */ Object.freeze([
|
|
39
|
+
"https://api.convergepay.com/hosted-payments/service/payment/hpp/process",
|
|
40
|
+
"https://api.demo.convergepay.com/hosted-payments/service/payment/hpp/process"
|
|
41
|
+
]);
|
|
42
|
+
var TOP_LEVEL_KEYS = /* @__PURE__ */ Object.freeze(["paymentType", "paymentData", "context", "captchaToken", "shippingSameAsBilling"]);
|
|
43
|
+
var WALLET_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
44
|
+
"ssl_ewallet",
|
|
45
|
+
"googlepay_authmethod",
|
|
46
|
+
"ssl_google_pay",
|
|
47
|
+
"ssl_applepay_web",
|
|
48
|
+
"ssl_dsrp_cryptogram",
|
|
49
|
+
"ssl_visapayload",
|
|
50
|
+
"ssl_ewallet_shipping"
|
|
51
|
+
]);
|
|
52
|
+
var SERVICE_FEE_FIELDS = /* @__PURE__ */ Object.freeze(["ssl_service_fee_agree", "ssl_service_fee_amount", "ssl_service_fee_percent"]);
|
|
53
|
+
var THREE_DS_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
54
|
+
"ssl_transaction_type",
|
|
55
|
+
"ssl_eci_ind",
|
|
56
|
+
"ssl_3dsecure_value",
|
|
57
|
+
"ssl_dir_server_tran_id",
|
|
58
|
+
"ssl_xid",
|
|
59
|
+
"ssl_program_protocol"
|
|
60
|
+
]);
|
|
61
|
+
var THREE_DS_PREFIXES = /* @__PURE__ */ Object.freeze(["ssl_3ds_", "ssl_fsg_"]);
|
|
62
|
+
var SURCHARGE_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
63
|
+
"ssl_credit_surcharge_agree",
|
|
64
|
+
"ssl_credit_surcharge_amount",
|
|
65
|
+
"bypass_credit_surcharge",
|
|
66
|
+
"ssl_amount_subtotal",
|
|
67
|
+
"ssl_total_amount",
|
|
68
|
+
"ssl_surcharge_fee_total"
|
|
69
|
+
]);
|
|
70
|
+
var RECURRING_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
71
|
+
"recurring",
|
|
72
|
+
"installment",
|
|
73
|
+
"ssl_billing_cycle",
|
|
74
|
+
"ssl_next_payment_date",
|
|
75
|
+
"ssl_total_installments",
|
|
76
|
+
"ssl_skip_payment",
|
|
77
|
+
"ssl_recurring_id",
|
|
78
|
+
"ssl_recurring_batch_count",
|
|
79
|
+
"ssl_installment_id"
|
|
80
|
+
]);
|
|
81
|
+
var CARD_SAVING_FLAGS = /* @__PURE__ */ Object.freeze(["ssl_get_token", "ssl_add_token"]);
|
|
82
|
+
var CREDENTIAL_FIELDS = /* @__PURE__ */ Object.freeze(["ssl_account_id", "ssl_merchant_id", "ssl_user_id", "ssl_pin", "ssl_vendor_id"]);
|
|
83
|
+
var AMOUNT_ADD_ON_FIELDS = /* @__PURE__ */ Object.freeze(["ssl_tip_amount", "ssl_cashback_amount"]);
|
|
84
|
+
var CARD_NUMBER = /^\d{12,19}$/;
|
|
85
|
+
var EXPIRY_MMYY = /^(0[1-9]|1[0-2])\d{2}$/;
|
|
86
|
+
var CVC = /^\d{3,4}$/;
|
|
87
|
+
var AMOUNT = /^(\d{1,13})(?:\.(\d{1,2}))?$/;
|
|
88
|
+
var isRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
89
|
+
var owns = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
90
|
+
var refuse = (code) => Object.freeze({ verdict: "refuse", code });
|
|
91
|
+
var CARD = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
92
|
+
var CONTINUE = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
93
|
+
function parseConvergeBody(body) {
|
|
94
|
+
if (typeof body !== "string" || body === "" || body.length > 131072)
|
|
95
|
+
return null;
|
|
96
|
+
let parsed;
|
|
97
|
+
try {
|
|
98
|
+
parsed = JSON.parse(body);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
if (!isRecord(parsed) || JSON.stringify(parsed) !== body)
|
|
104
|
+
return null;
|
|
105
|
+
return parsed;
|
|
106
|
+
}
|
|
107
|
+
function convergeAmountCents(value) {
|
|
108
|
+
const text2 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
|
|
109
|
+
const m = typeof text2 === "string" ? AMOUNT.exec(text2) : null;
|
|
110
|
+
if (!m)
|
|
111
|
+
return null;
|
|
112
|
+
const cents = Number(m[1]) * 100 + Number(((m[2] ?? "") + "00").slice(0, 2));
|
|
113
|
+
return Number.isSafeInteger(cents) && cents > 0 ? cents : null;
|
|
114
|
+
}
|
|
115
|
+
function convergeBodyVerdict(body) {
|
|
116
|
+
const parsed = parseConvergeBody(body);
|
|
117
|
+
if (parsed === null || !Object.keys(parsed).every((key) => TOP_LEVEL_KEYS.includes(key)))
|
|
118
|
+
return refuse("converge_body_malformed");
|
|
119
|
+
const data = parsed.paymentData;
|
|
120
|
+
if (!isRecord(data))
|
|
121
|
+
return refuse("converge_body_malformed");
|
|
122
|
+
const type = parsed.paymentType;
|
|
123
|
+
if (type === "ELECTRONICCHECK" || type === "FINANCING") {
|
|
124
|
+
return owns(data, "ssl_card_number") ? refuse("converge_payment_type_refused") : CONTINUE;
|
|
125
|
+
}
|
|
126
|
+
if (type === "DEBITCARD") {
|
|
127
|
+
return refuse(typeof data.ssl_transaction_type === "string" && /DISBURSEMENT/i.test(data.ssl_transaction_type) ? "converge_push_to_card_refused" : "converge_debit_card_refused");
|
|
128
|
+
}
|
|
129
|
+
if (type === "GIFTCARD")
|
|
130
|
+
return refuse("converge_gift_card_refused");
|
|
131
|
+
if (type !== "CREDITCARD")
|
|
132
|
+
return refuse("converge_payment_type_refused");
|
|
133
|
+
const keys = Object.keys(data);
|
|
134
|
+
if (CREDENTIAL_FIELDS.some((key) => owns(data, key)))
|
|
135
|
+
return refuse("converge_credential_refused");
|
|
136
|
+
if (WALLET_FIELDS.some((key) => owns(data, key)))
|
|
137
|
+
return refuse("converge_wallet_refused");
|
|
138
|
+
if (owns(parsed, "captchaToken"))
|
|
139
|
+
return refuse("converge_captcha_refused");
|
|
140
|
+
if (SERVICE_FEE_FIELDS.some((key) => owns(data, key)))
|
|
141
|
+
return refuse("converge_service_fee_refused");
|
|
142
|
+
if (THREE_DS_FIELDS.some((key) => owns(data, key)) || keys.some((key) => THREE_DS_PREFIXES.some((prefix) => key.startsWith(prefix))))
|
|
143
|
+
return refuse("converge_3ds_follow_up_refused");
|
|
144
|
+
if (SURCHARGE_FIELDS.some((key) => owns(data, key)))
|
|
145
|
+
return refuse("converge_surcharge_refused");
|
|
146
|
+
if (AMOUNT_ADD_ON_FIELDS.some((key) => owns(data, key)))
|
|
147
|
+
return refuse("converge_amount_add_on_refused");
|
|
148
|
+
if (owns(data, "ssl_token") || CARD_SAVING_FLAGS.some((key) => owns(data, key) && !(typeof data[key] === "string" && /^n$/i.test(data[key])))) {
|
|
149
|
+
return refuse("converge_card_saving_refused");
|
|
150
|
+
}
|
|
151
|
+
if (RECURRING_FIELDS.some((key) => owns(data, key)))
|
|
152
|
+
return refuse("converge_recurring_refused");
|
|
153
|
+
if (owns(data, "ssl_transaction_currency") && !(typeof data.ssl_transaction_currency === "string" && /^usd$/i.test(data.ssl_transaction_currency))) {
|
|
154
|
+
return refuse("converge_currency_refused");
|
|
155
|
+
}
|
|
156
|
+
if (convergeAmountCents(data.ssl_amount) === null)
|
|
157
|
+
return refuse("converge_amount_missing");
|
|
158
|
+
if (typeof parsed.context !== "string" || parsed.context === "")
|
|
159
|
+
return refuse("converge_context_missing");
|
|
160
|
+
if (owns(parsed, "shippingSameAsBilling") && typeof parsed.shippingSameAsBilling !== "boolean")
|
|
161
|
+
return refuse("converge_body_malformed");
|
|
162
|
+
if (!owns(data, "ssl_card_number") || data.ssl_card_number === "" || data.ssl_card_number === null)
|
|
163
|
+
return refuse("converge_card_missing");
|
|
164
|
+
if (typeof data.ssl_card_number !== "string" || !CARD_NUMBER.test(data.ssl_card_number) || typeof data.ssl_exp_date !== "string" || !EXPIRY_MMYY.test(data.ssl_exp_date) || typeof data.ssl_cvv2cvc2 !== "string" || !CVC.test(data.ssl_cvv2cvc2))
|
|
165
|
+
return refuse("converge_card_malformed");
|
|
166
|
+
return CARD;
|
|
167
|
+
}
|
|
168
|
+
function isConvergeProcessUrl(url) {
|
|
169
|
+
if (typeof url !== "string")
|
|
170
|
+
return false;
|
|
171
|
+
let parsed;
|
|
172
|
+
try {
|
|
173
|
+
parsed = new URL(url);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
return parsed.href === url && CONVERGE_PROCESS_URLS.includes(parsed.href);
|
|
179
|
+
}
|
|
180
|
+
// src/amadeus-body.js
|
|
181
|
+
var AMADEUS_CARD_MOPID = /^creditcard[0-9]*$/;
|
|
182
|
+
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
183
|
+
var owns2 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
184
|
+
var holdsPan = (mopdata) => record(mopdata) && owns2(mopdata, "pan") && mopdata.pan !== null && mopdata.pan !== "";
|
|
185
|
+
function amadeusBodyKind(body) {
|
|
186
|
+
let value;
|
|
187
|
+
try {
|
|
188
|
+
value = typeof body === "string" ? JSON.parse(body) : void 0;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return "card";
|
|
192
|
+
}
|
|
193
|
+
if (!record(value))
|
|
194
|
+
return "card";
|
|
195
|
+
if (value.action === "add") {
|
|
196
|
+
const entries = Array.isArray(value.data) ? value.data : [value.data];
|
|
197
|
+
return entries.some((entry) => record(entry) && typeof entry.mopid === "string" && AMADEUS_CARD_MOPID.test(entry.mopid) && holdsPan(entry.mopdata)) ? "card" : "other";
|
|
198
|
+
}
|
|
199
|
+
if (value.action === "store")
|
|
200
|
+
return record(value.data) && holdsPan(value.data.mopdata) ? "card" : "other";
|
|
201
|
+
return "other";
|
|
202
|
+
}
|
|
203
|
+
// src/card-fields.js
|
|
204
|
+
function processorGate(recognizer, url, body) {
|
|
205
|
+
if (!recognizer || recognizer.psp !== "elavon_converge")
|
|
206
|
+
return null;
|
|
207
|
+
if (url !== void 0 && !isConvergeProcessUrl(url))
|
|
208
|
+
return { verdict: "refuse", code: "converge_url_refused" };
|
|
209
|
+
return convergeBodyVerdict(body);
|
|
210
|
+
}
|
|
211
|
+
function carriesCardFields(recognizer, body) {
|
|
212
|
+
const gate = processorGate(recognizer, void 0, body);
|
|
213
|
+
if (gate !== null)
|
|
214
|
+
return gate.verdict === "card";
|
|
215
|
+
if (recognizer && recognizer.encoding === "json") {
|
|
216
|
+
const claimed = carriesJsonCardFields(recognizer.jsonCardFields, body, DECLARED_PATHS_ONLY.has(recognizer.psp));
|
|
217
|
+
return claimed && recognizer.psp === "amadeus_checkout" ? amadeusBodyKind(body) === "card" : claimed;
|
|
218
|
+
}
|
|
219
|
+
const fields = recognizer && recognizer.cardFields;
|
|
220
|
+
if (!Array.isArray(fields) || fields.length === 0)
|
|
221
|
+
return true;
|
|
222
|
+
if (recognizer.encoding !== "form")
|
|
223
|
+
return true;
|
|
224
|
+
if (typeof body !== "string" || body === "")
|
|
225
|
+
return false;
|
|
226
|
+
const anyCase = recognizer.caseInsensitiveFormKeys === true;
|
|
227
|
+
const wanted = anyCase ? fields.map((field) => String(field).toLowerCase()) : fields;
|
|
228
|
+
for (const chunk of body.split("&")) {
|
|
229
|
+
const eq = chunk.indexOf("=");
|
|
230
|
+
if (eq <= 0 || eq === chunk.length - 1)
|
|
231
|
+
continue;
|
|
232
|
+
let key;
|
|
233
|
+
try {
|
|
234
|
+
key = decodeURIComponent(chunk.slice(0, eq).replace(/\+/g, " "));
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (wanted.includes(anyCase ? key.trim().toLowerCase() : key))
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
var DECLARED_PATHS_ONLY = /* @__PURE__ */ new Set(["primer", "pelecard", "creditguard", "payrails"]);
|
|
245
|
+
function carriesJsonCardFields(paths, body, declaredOnly) {
|
|
246
|
+
if (!Array.isArray(paths) || paths.length === 0 || !paths.every((path) => isJsonPath(path) && path.length > 0))
|
|
247
|
+
return true;
|
|
248
|
+
if (declaredOnly)
|
|
249
|
+
return declaredPathHoldsCard(paths, body);
|
|
250
|
+
let parsed;
|
|
251
|
+
try {
|
|
252
|
+
parsed = typeof body === "string" ? JSON.parse(body) : void 0;
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
if (!isPlainObject(parsed))
|
|
258
|
+
return true;
|
|
259
|
+
if (paths.some((path) => {
|
|
260
|
+
const at = jsonAt(parsed, path);
|
|
261
|
+
return at.found && (typeof at.value === "string" && at.value !== "" || typeof at.value === "number");
|
|
262
|
+
}))
|
|
263
|
+
return true;
|
|
264
|
+
const declared = /* @__PURE__ */ new Set();
|
|
265
|
+
for (const path of paths) {
|
|
266
|
+
const last = path[path.length - 1];
|
|
267
|
+
if (typeof last === "string")
|
|
268
|
+
declared.add(last.toLowerCase());
|
|
269
|
+
}
|
|
270
|
+
return namesCardNumber(parsed, declared);
|
|
271
|
+
}
|
|
272
|
+
function declaredPathHoldsCard(paths, body) {
|
|
273
|
+
if (typeof body !== "string" || body === "")
|
|
274
|
+
return false;
|
|
275
|
+
let parsed;
|
|
276
|
+
try {
|
|
277
|
+
parsed = JSON.parse(body);
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
return paths.some((path) => {
|
|
283
|
+
const at = jsonAt(parsed, path);
|
|
284
|
+
return at.found && (typeof at.value === "string" && at.value !== "" || typeof at.value === "number");
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
function namesCardNumber(root, declared) {
|
|
288
|
+
const pending = [root];
|
|
289
|
+
while (pending.length > 0) {
|
|
290
|
+
const node = pending.pop();
|
|
291
|
+
const named = !Array.isArray(node);
|
|
292
|
+
for (const key of Object.keys(node)) {
|
|
293
|
+
if (named) {
|
|
294
|
+
const name = key.slice(key.lastIndexOf(".") + 1).toLowerCase();
|
|
295
|
+
if (declared.has(name) || CARD_NUMBER_KEY.test(name) || name.endsWith("cardnumber"))
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
const value = node[key];
|
|
299
|
+
if (value !== null && typeof value === "object")
|
|
300
|
+
pending.push(value);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
// src/primer.js
|
|
306
|
+
var PRIMER_PCI_HOSTS = /* @__PURE__ */ Object.freeze(["sdk.api.primer.io", "sdk.api.sandbox.primer.io"]);
|
|
307
|
+
var PRIMER_TOKENIZE_PATH = "/payment-instruments";
|
|
308
|
+
var PRIMER_REFUSAL_REASONS = /* @__PURE__ */ Object.freeze(["unsupported", "keep_on_file", "unsupported_sdk", "network_mismatch"]);
|
|
309
|
+
var PRIMER_PROVABLE_NETWORKS = /* @__PURE__ */ Object.freeze(["VISA", "MASTERCARD", "AMEX"]);
|
|
310
|
+
var UNSUPPORTED_REFUSAL = "Refusing to pay: unsupported Primer card request.";
|
|
311
|
+
var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the card on file without your consent. Nothing was sent.";
|
|
312
|
+
var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
|
|
313
|
+
var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
|
|
314
|
+
var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
|
|
315
|
+
var BODY_LIMIT = 16384;
|
|
316
|
+
var RESPONSE_LIMIT = 32768;
|
|
317
|
+
var ROOT_KEYS = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
|
|
318
|
+
var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
|
|
319
|
+
var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
|
|
320
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
321
|
+
var owns3 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
322
|
+
var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
323
|
+
var text = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
324
|
+
var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
325
|
+
var panLike = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
|
|
326
|
+
var plain = (value, max) => text(value, max) && !panLike(value);
|
|
327
|
+
var MONTH = /^(?:0[1-9]|1[0-2])$/;
|
|
328
|
+
var YEAR = /^20[0-9]{2}$/;
|
|
329
|
+
var NETWORK = /^[A-Z][A-Z_]{1,31}$/;
|
|
330
|
+
function isPrimerTokenizeUrl(url, method = "POST") {
|
|
331
|
+
if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
332
|
+
return false;
|
|
333
|
+
let parsed;
|
|
334
|
+
try {
|
|
335
|
+
parsed = new URL(url);
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
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
|
+
}
|
|
342
|
+
function judgeBody(body) {
|
|
343
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT)
|
|
344
|
+
return null;
|
|
345
|
+
let value;
|
|
346
|
+
try {
|
|
347
|
+
value = JSON.parse(body);
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
if (!record2(value) || !roundTrips(value, body))
|
|
353
|
+
return null;
|
|
354
|
+
if (!Object.keys(value).every((key) => ROOT_KEYS.includes(key)) || !owns3(value, "paymentInstrument"))
|
|
355
|
+
return null;
|
|
356
|
+
const instrument = value.paymentInstrument;
|
|
357
|
+
if (!record2(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns3(instrument, key)))
|
|
358
|
+
return null;
|
|
359
|
+
if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH, instrument.expirationMonth) || !exact(YEAR, instrument.expirationYear))
|
|
360
|
+
return null;
|
|
361
|
+
if (owns3(instrument, "cardholderName") && instrument.cardholderName !== null && !plain(instrument.cardholderName, 256) || owns3(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact(NETWORK, instrument.preferredNetwork) || owns3(value, "userDescription") && value.userDescription !== null && !plain(value.userDescription, 256) || owns3(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns3(value, "paymentFlow") && value.paymentFlow !== "VAULT")
|
|
362
|
+
return null;
|
|
363
|
+
return { value, keepOnFile: owns3(value, "tokenType") || owns3(value, "paymentFlow") };
|
|
364
|
+
}
|
|
365
|
+
function primerBodyRefusal(body) {
|
|
366
|
+
const judged = judgeBody(body);
|
|
367
|
+
if (!judged)
|
|
368
|
+
return "unsupported";
|
|
369
|
+
return judged.keepOnFile ? "keep_on_file" : null;
|
|
370
|
+
}
|
|
371
|
+
function isPrimerNewCardBody(body) {
|
|
372
|
+
return primerBodyRefusal(body) === null;
|
|
373
|
+
}
|
|
374
|
+
function primerKeepOnFileRequested(body) {
|
|
375
|
+
const judged = judgeBody(body);
|
|
376
|
+
return judged ? judged.keepOnFile : null;
|
|
377
|
+
}
|
|
378
|
+
var CARD_GATE = /* @__PURE__ */ Object.freeze({ psp: "primer", encoding: "json", jsonCardFields: [["paymentInstrument", "number"]] });
|
|
379
|
+
var CONTENT_TYPE = /^application\/json(?:;\s*charset=utf-8)?$/i;
|
|
380
|
+
var LEGACY_SDK_VERSION = /^v2\.[0-9]{1,3}\.[0-9]{1,3}$/;
|
|
381
|
+
var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
|
|
382
|
+
var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
383
|
+
var API_VERSION = /^2\.[0-9]{1,2}$/;
|
|
384
|
+
function readHeaders(headers) {
|
|
385
|
+
if (!record2(headers))
|
|
386
|
+
return null;
|
|
387
|
+
const folded = /* @__PURE__ */ new Map();
|
|
388
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
389
|
+
const lower = name.toLowerCase();
|
|
390
|
+
if (folded.has(lower) || typeof value !== "string")
|
|
391
|
+
return null;
|
|
392
|
+
folded.set(lower, value);
|
|
393
|
+
}
|
|
394
|
+
return folded;
|
|
395
|
+
}
|
|
396
|
+
function headersRefusal(headers) {
|
|
397
|
+
const folded = readHeaders(headers);
|
|
398
|
+
if (!folded)
|
|
399
|
+
return "unsupported";
|
|
400
|
+
const version = folded.get("primer-sdk-version");
|
|
401
|
+
if (typeof version !== "string")
|
|
402
|
+
return "unsupported";
|
|
403
|
+
if (!exact(LEGACY_SDK_VERSION, version))
|
|
404
|
+
return "unsupported_sdk";
|
|
405
|
+
if (!exact(CONTENT_TYPE, folded.get("content-type")) || !exact(CLIENT_TOKEN, folded.get("primer-client-token")) || folded.has("primer-sdk-client") && folded.get("primer-sdk-client") !== "WEB" || folded.has("x-api-version") && !exact(API_VERSION, folded.get("x-api-version")) || folded.has("primer-sdk-checkout-session-id") && !exact(REQUEST_ID, folded.get("primer-sdk-checkout-session-id")) || folded.has("x-request-id") && !exact(REQUEST_ID, folded.get("x-request-id")))
|
|
406
|
+
return "unsupported";
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
function classifyPrimerRequest(url, method, body, headers) {
|
|
410
|
+
if (method !== "POST" || !onTokenizePath(url))
|
|
411
|
+
return null;
|
|
412
|
+
if (typeof body !== "string")
|
|
413
|
+
return "unsupported";
|
|
414
|
+
if (!carriesCardFields(CARD_GATE, body))
|
|
415
|
+
return null;
|
|
416
|
+
if (!isPrimerTokenizeUrl(url))
|
|
417
|
+
return "unsupported";
|
|
418
|
+
return headersRefusal(headers) ?? primerBodyRefusal(body) ?? "card";
|
|
419
|
+
}
|
|
420
|
+
function onTokenizePath(url) {
|
|
421
|
+
if (typeof url !== "string")
|
|
422
|
+
return false;
|
|
423
|
+
try {
|
|
424
|
+
const parsed = new URL(url);
|
|
425
|
+
return PRIMER_PCI_HOSTS.includes(parsed.hostname.replace(/\.$/, "")) && parsed.pathname.toLowerCase() === PRIMER_TOKENIZE_PATH;
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function primerTokenizeRefusal(request) {
|
|
432
|
+
if (!record2(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
|
|
433
|
+
return "unsupported";
|
|
434
|
+
return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
|
|
435
|
+
}
|
|
436
|
+
function isPrimerTokenizeRequest(request) {
|
|
437
|
+
return primerTokenizeRefusal(request) === null;
|
|
438
|
+
}
|
|
439
|
+
function primerRefusalMessage(reason) {
|
|
440
|
+
if (reason === "keep_on_file")
|
|
441
|
+
return KEEP_ON_FILE_REFUSAL;
|
|
442
|
+
if (reason === "unsupported_sdk")
|
|
443
|
+
return UNSUPPORTED_SDK_REFUSAL;
|
|
444
|
+
if (reason === "network_mismatch")
|
|
445
|
+
return NETWORK_MISMATCH_REFUSAL;
|
|
446
|
+
return UNSUPPORTED_REFUSAL;
|
|
447
|
+
}
|
|
448
|
+
function primerCardNetwork(number) {
|
|
449
|
+
if (!digits(number, 12, 19))
|
|
450
|
+
return null;
|
|
451
|
+
const two = Number(number.slice(0, 2));
|
|
452
|
+
const four = Number(number.slice(0, 4));
|
|
453
|
+
if (number[0] === "4")
|
|
454
|
+
return "VISA";
|
|
455
|
+
if (two >= 51 && two <= 55 || four >= 2221 && four <= 2720)
|
|
456
|
+
return "MASTERCARD";
|
|
457
|
+
if (two === 34 || two === 37)
|
|
458
|
+
return "AMEX";
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
function primerNetworkRefusal(body, card) {
|
|
462
|
+
const judged = judgeBody(body);
|
|
463
|
+
if (!judged)
|
|
464
|
+
return "unsupported";
|
|
465
|
+
const preferred = judged.value.paymentInstrument.preferredNetwork;
|
|
466
|
+
if (preferred === void 0 || preferred === null)
|
|
467
|
+
return null;
|
|
468
|
+
const network = primerCardNetwork(card && card.number);
|
|
469
|
+
return network !== null && network === preferred ? null : "network_mismatch";
|
|
470
|
+
}
|
|
471
|
+
function injectPrimerCard(body, card) {
|
|
472
|
+
const judged = judgeBody(body);
|
|
473
|
+
if (!judged)
|
|
474
|
+
throw new Error(UNSUPPORTED_REFUSAL);
|
|
475
|
+
if (judged.keepOnFile)
|
|
476
|
+
throw new Error(KEEP_ON_FILE_REFUSAL);
|
|
477
|
+
const month = card && (Number.isInteger(card.month) || digits(card.month, 1, 2)) ? Number(card.month) : NaN;
|
|
478
|
+
const year = card && (Number.isInteger(card.year) || digits(card.year, 2, 4)) ? Number(card.year) : NaN;
|
|
479
|
+
if (!card || !digits(card.number, 12, 19) || !(month >= 1 && month <= 12) || !(year >= 0 && year <= 99 || year >= 2e3 && year <= 2099) || !digits(card.cvc, 3, 4)) {
|
|
480
|
+
throw new Error(FILL_REFUSAL);
|
|
481
|
+
}
|
|
482
|
+
if (primerNetworkRefusal(body, card) !== null)
|
|
483
|
+
throw new Error(NETWORK_MISMATCH_REFUSAL);
|
|
484
|
+
const instrument = judged.value.paymentInstrument;
|
|
485
|
+
instrument.number = card.number;
|
|
486
|
+
instrument.cvv = card.cvc;
|
|
487
|
+
instrument.expirationMonth = String(month).padStart(2, "0");
|
|
488
|
+
instrument.expirationYear = String(year < 100 ? 2e3 + year : year);
|
|
489
|
+
const where = ["paymentInstrument.number", "paymentInstrument.cvv", "paymentInstrument.expirationMonth", "paymentInstrument.expirationYear"];
|
|
490
|
+
if (typeof instrument.cardholderName === "string" && typeof card.name === "string" && card.name.trim() !== "" && plain(card.name, 256)) {
|
|
491
|
+
instrument.cardholderName = card.name;
|
|
492
|
+
where.push("paymentInstrument.cardholderName");
|
|
493
|
+
}
|
|
494
|
+
return { body: JSON.stringify(judged.value), where };
|
|
495
|
+
}
|
|
496
|
+
var TOKEN = /^[A-Za-z0-9_-]{8,256}$/;
|
|
497
|
+
var ERROR_ID = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
|
|
498
|
+
var CODE = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
499
|
+
var NETWORK_NAME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
500
|
+
var RESPONSE_MONTH = /^(?:0?[1-9]|1[0-2])$/;
|
|
501
|
+
var RESPONSE_YEAR = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
502
|
+
var PROTOCOL = /^[0-9]{1,2}(?:\.[0-9]{1,2}){0,2}$/;
|
|
503
|
+
var BIN_KEYS = [
|
|
504
|
+
"network",
|
|
505
|
+
"issuerCountryCode",
|
|
506
|
+
"issuerName",
|
|
507
|
+
"issuerCurrencyCode",
|
|
508
|
+
"regionalRestriction",
|
|
509
|
+
"accountNumberType",
|
|
510
|
+
"accountFundingType",
|
|
511
|
+
"prepaidReloadableIndicator",
|
|
512
|
+
"productUsageType",
|
|
513
|
+
"productCode",
|
|
514
|
+
"productName"
|
|
515
|
+
];
|
|
516
|
+
function readAnswer(body) {
|
|
517
|
+
if (typeof body !== "string" || body === "" || body.length > RESPONSE_LIMIT)
|
|
518
|
+
return null;
|
|
519
|
+
try {
|
|
520
|
+
const value = JSON.parse(body);
|
|
521
|
+
return record2(value) ? value : null;
|
|
522
|
+
}
|
|
523
|
+
catch {
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
var tokenValue = (value) => exact(TOKEN, value) && !panLike(value);
|
|
528
|
+
var optional = (value, key, check) => !owns3(value, key) || value[key] === null || check(value[key]);
|
|
529
|
+
function cardDetails(data) {
|
|
530
|
+
if (!record2(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
|
|
531
|
+
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", record2))
|
|
533
|
+
return null;
|
|
534
|
+
const safe = { last4Digits: data.last4Digits };
|
|
535
|
+
for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
|
|
536
|
+
if (owns3(data, key) && data[key] !== null)
|
|
537
|
+
safe[key] = data[key];
|
|
538
|
+
}
|
|
539
|
+
if (record2(data.binData)) {
|
|
540
|
+
const bin = {};
|
|
541
|
+
for (const key of BIN_KEYS) {
|
|
542
|
+
if (!owns3(data.binData, key) || data.binData[key] === null)
|
|
543
|
+
continue;
|
|
544
|
+
if (!plain(data.binData[key], 128))
|
|
545
|
+
return null;
|
|
546
|
+
bin[key] = data.binData[key];
|
|
547
|
+
}
|
|
548
|
+
safe.binData = bin;
|
|
549
|
+
}
|
|
550
|
+
return safe;
|
|
551
|
+
}
|
|
552
|
+
function threeDsSummary(value) {
|
|
553
|
+
if (value === void 0 || value === null)
|
|
554
|
+
return null;
|
|
555
|
+
if (!record2(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
|
+
return void 0;
|
|
557
|
+
const safe = { responseCode: value.responseCode };
|
|
558
|
+
for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
|
|
559
|
+
if (owns3(value, key) && value[key] !== null)
|
|
560
|
+
safe[key] = value[key];
|
|
561
|
+
}
|
|
562
|
+
return safe;
|
|
563
|
+
}
|
|
564
|
+
function rebuildToken(value) {
|
|
565
|
+
if (!tokenValue(value.token) || !optional(value, "analyticsId", tokenValue) || value.tokenType !== "SINGLE_USE" || value.paymentInstrumentType !== "PAYMENT_CARD" || value.vaultData !== void 0 && value.vaultData !== null)
|
|
566
|
+
return null;
|
|
567
|
+
const details = cardDetails(value.paymentInstrumentData);
|
|
568
|
+
const threeDs = threeDsSummary(value.threeDSecureAuthentication);
|
|
569
|
+
if (!details || threeDs === void 0)
|
|
570
|
+
return null;
|
|
571
|
+
const safe = { token: value.token };
|
|
572
|
+
if (owns3(value, "analyticsId") && value.analyticsId !== null)
|
|
573
|
+
safe.analyticsId = value.analyticsId;
|
|
574
|
+
safe.tokenType = "SINGLE_USE";
|
|
575
|
+
safe.paymentInstrumentType = "PAYMENT_CARD";
|
|
576
|
+
safe.paymentInstrumentData = details;
|
|
577
|
+
safe.threeDSecureAuthentication = threeDs;
|
|
578
|
+
safe.vaultData = null;
|
|
579
|
+
return safe;
|
|
580
|
+
}
|
|
581
|
+
function primerErrorId(body) {
|
|
582
|
+
const value = readAnswer(body);
|
|
583
|
+
const id = value && record2(value.error) ? value.error.errorId : null;
|
|
584
|
+
return exact(ERROR_ID, id) && !panLike(id) ? id : null;
|
|
585
|
+
}
|
|
586
|
+
function matchesCard(details, card) {
|
|
587
|
+
const number = card && typeof card.number === "string" ? card.number : "";
|
|
588
|
+
if (details.last4Digits !== number.slice(-4))
|
|
589
|
+
return false;
|
|
590
|
+
if (details.first6Digits !== void 0 && details.first6Digits !== number.slice(0, 6))
|
|
591
|
+
return false;
|
|
592
|
+
if (details.expirationMonth !== void 0 && Number(details.expirationMonth) !== Number(card.month))
|
|
593
|
+
return false;
|
|
594
|
+
return details.expirationYear === void 0 || Number(details.expirationYear) % 100 === Number(card.year) % 100;
|
|
595
|
+
}
|
|
596
|
+
function primerResponseOutcome(status, body, card) {
|
|
597
|
+
if (status >= 400 && status < 500)
|
|
598
|
+
return { outcome: "refused", code: primerErrorId(body) ?? `http_${status}` };
|
|
599
|
+
if (status !== 200 && status !== 201)
|
|
600
|
+
return { outcome: "unknown", reason: "primer_status_unconfirmed" };
|
|
601
|
+
const value = readAnswer(body);
|
|
602
|
+
if (!value)
|
|
603
|
+
return { outcome: "unknown", reason: "primer_unreadable" };
|
|
604
|
+
if (value.tokenType === "MULTI_USE" || value.vaultData !== void 0 && value.vaultData !== null) {
|
|
605
|
+
const minted = typeof value.token === "string" && value.token !== "";
|
|
606
|
+
return { outcome: "unknown", reason: minted ? "primer_card_kept" : "primer_unexpected_response" };
|
|
607
|
+
}
|
|
608
|
+
const safe = rebuildToken(value);
|
|
609
|
+
if (!safe)
|
|
610
|
+
return { outcome: "unknown", reason: "primer_unexpected_response" };
|
|
611
|
+
if (card && !matchesCard(safe.paymentInstrumentData, card))
|
|
612
|
+
return { outcome: "unknown", reason: "primer_token_mismatch" };
|
|
613
|
+
return { outcome: "approved" };
|
|
614
|
+
}
|
|
615
|
+
function sanitizePrimerResponse(body) {
|
|
616
|
+
if (primerResponseOutcome(200, body).outcome !== "approved")
|
|
617
|
+
throw new Error("Invalid Primer tokenization response.");
|
|
618
|
+
return JSON.stringify(rebuildToken(readAnswer(body)));
|
|
619
|
+
}
|
|
620
|
+
function primerFacts(status, body) {
|
|
621
|
+
const verdict = primerResponseOutcome(status, body);
|
|
622
|
+
return { outcome: verdict.outcome, refusalCode: verdict.outcome === "refused" ? verdict.code : null };
|
|
623
|
+
}
|
|
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 };
|