@agent-cards/sdk 0.21.0 → 0.23.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 +87 -2
- package/PREFLIGHT.md +32 -0
- package/README.md +1177 -23
- 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 +302 -56
- 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-facts.d.ts +96 -0
- package/dist/card-endpoint-facts.js +275 -0
- package/dist/card-endpoint-page.d.ts +54 -0
- package/dist/card-endpoint-page.js +69 -0
- package/dist/card-endpoint.d.ts +298 -0
- package/dist/card-endpoint.js +438 -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 +1155 -141
- package/dist/client.d.ts +456 -20
- package/dist/client.js +1072 -104
- package/dist/creditguard.generated.d.ts +79 -0
- package/dist/creditguard.generated.js +662 -0
- package/dist/cse-body.js +11 -1
- package/dist/cybersource-flex.d.ts +30 -0
- package/dist/cybersource-flex.generated.d.ts +27 -1
- package/dist/cybersource-flex.generated.js +42 -2
- package/dist/cybersource-flex.js +46 -0
- 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/ekashu.d.ts +35 -0
- package/dist/ekashu.js +55 -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 +60 -6
- package/dist/lifecycle.js +122 -8
- package/dist/merchant-card-endpoints.generated.d.ts +122 -0
- package/dist/merchant-card-endpoints.generated.js +4261 -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 +81 -2
- package/dist/pre-claim.js +1023 -5
- package/dist/preflight-catalog.json +2267 -288
- package/dist/preflight-schemas.json +183 -6
- package/dist/preflight.generated.d.ts +1 -1
- package/dist/preflight.generated.js +243 -4
- package/dist/preparation.d.ts +12 -3
- package/dist/preparation.js +63 -12
- 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 +764 -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 +1413 -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
package/dist/cse-body.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { substituteEncryptedFields } from './substitute.js';
|
|
4
4
|
import { substituteMerchantHostedBody } from './merchant-hosted.js';
|
|
5
5
|
import { fiservCapturePinId, isFiservCaptureHost, substituteFiservEnvelope } from './fiserv.js';
|
|
6
|
+
import { substituteVerifoneBody } from './verifone.js';
|
|
6
7
|
/**
|
|
7
8
|
* The cse continuation: the paused body with the vault's ciphertext in place
|
|
8
9
|
* of the dummy blobs. The adapters send it as postData ALONE. Chromium
|
|
@@ -25,8 +26,17 @@ import { fiservCapturePinId, isFiservCaptureHost, substituteFiservEnvelope } fro
|
|
|
25
26
|
* a Fiserv capture host. Every refusal throws before anything is sent.
|
|
26
27
|
*/
|
|
27
28
|
export function cseBody(body, replay, url, preparation) {
|
|
29
|
+
// A Verifone approval is always a prepared one for the profile it pays, and continues only the
|
|
30
|
+
// leg that profile reviewed, with the device's blob written into the LIVE paused body, which
|
|
31
|
+
// must still be the body the API checked at create (verifone.ts).
|
|
32
|
+
if (preparation?.psp === 'verifone' || replay.kind === 'verifone') {
|
|
33
|
+
if (replay.kind !== 'verifone' || preparation?.psp !== 'verifone' || preparation.merchantProfile !== replay.profile) {
|
|
34
|
+
throw new Error('Refusing to substitute: the paused request is not the Verifone card request the cardholder approved.');
|
|
35
|
+
}
|
|
36
|
+
return substituteVerifoneBody({ url, method: 'POST', body }, replay);
|
|
37
|
+
}
|
|
28
38
|
if (preparation?.psp === 'fiserv') {
|
|
29
|
-
if (replay.kind
|
|
39
|
+
if (replay.kind !== undefined || !isFiservCaptureHost(url) || fiservCapturePinId(url, body) !== preparation.merchantProfile) {
|
|
30
40
|
throw new Error('Refusing to substitute: the paused request is not a Fiserv capture under the key pin the cardholder approved.');
|
|
31
41
|
}
|
|
32
42
|
return substituteFiservEnvelope(body, replay.substitutions);
|
|
@@ -158,6 +158,8 @@ export declare class MicroformFrames {
|
|
|
158
158
|
/** A frame's committed document URL, fragment included. A URL that is not a field iframe's forgets the frame. */
|
|
159
159
|
observe(frameId: unknown, url: unknown): void;
|
|
160
160
|
forget(frameId: unknown): void;
|
|
161
|
+
/** The card Microform whose field documents this attachment recorded, for prepare({ tokenizeBeforePay: true }). */
|
|
162
|
+
loadedCard(): LoadedCardMicroform;
|
|
161
163
|
/**
|
|
162
164
|
* Judge a POST the frame `frameId` sent. When that frame is not on record, `reread` reads the
|
|
163
165
|
* pausing session's frame tree once (recording what it finds) and resolves to the frame's
|
|
@@ -173,6 +175,34 @@ export declare class MicroformFrames {
|
|
|
173
175
|
* request's frame could not be read at all.
|
|
174
176
|
*/
|
|
175
177
|
export declare function judgeMicroformFrameUrls(request: FlexRequest, issuingUrl: string | undefined, frameUrls: Iterable<string | undefined>, contexts: CaptureContexts): CybersourceFlexDecision | Promise<CybersourceFlexDecision>;
|
|
178
|
+
/**
|
|
179
|
+
* What prepare({ tokenizeBeforePay: true }) reads from the page before Pay: the one card Microform
|
|
180
|
+
* whose fields loaded, its capture context and its fields, or why there is none to read.
|
|
181
|
+
*/
|
|
182
|
+
export type LoadedCardMicroform = {
|
|
183
|
+
ok: true;
|
|
184
|
+
captureContext: string;
|
|
185
|
+
environment: string;
|
|
186
|
+
microform: {
|
|
187
|
+
version: string;
|
|
188
|
+
fields: MicroformField[];
|
|
189
|
+
};
|
|
190
|
+
} | {
|
|
191
|
+
ok: false;
|
|
192
|
+
reason: 'microform_not_loaded' | 'microform_ambiguous' | 'microform_unsupported';
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* The card Microform a page loaded, for prepare({ tokenizeBeforePay: true }): every committed card
|
|
196
|
+
* field-iframe document, grouped by capture context, microform id, version and host. One group of a
|
|
197
|
+
* reviewed version, with a card number field and at most a security code field, is the checkout the
|
|
198
|
+
* cardholder's device tokenizes before Pay. No group is `microform_not_loaded` (prepare once the card
|
|
199
|
+
* fields show), two or more are `microform_ambiguous`, and any other group is `microform_unsupported`.
|
|
200
|
+
* A check (eCheck) Microform carries no card and is not counted. Reads the frames only; the capture
|
|
201
|
+
* context is verified by prepareCheckout, the API and the device.
|
|
202
|
+
*/
|
|
203
|
+
export declare function loadedCardMicroform(frames: Iterable<MicroformFrame>): LoadedCardMicroform;
|
|
204
|
+
/** The Playwright adapter's read: every frame URL on the page (Playwright keeps the fragment in frame.url()). */
|
|
205
|
+
export declare function loadedCardMicroformFromUrls(urls: Iterable<string | undefined>): LoadedCardMicroform;
|
|
176
206
|
/**
|
|
177
207
|
* Whether a create's sidecar has the shape the API admits (routes/api/v2/checkout.ts
|
|
178
208
|
* createSchema): a capture context of 1 to 16384 characters, and a Microform version with a
|
|
@@ -89,4 +89,30 @@ declare function transientTokenFacts(status: any, body: any, verified: any, card
|
|
|
89
89
|
}>;
|
|
90
90
|
declare function cybersourceFlexPreparationUrl(environment: any): any;
|
|
91
91
|
declare function isPreparedCybersourceFlexRequest(url: any, method: any, body: any, environment: any, headers: any): boolean;
|
|
92
|
-
|
|
92
|
+
declare var CYBERSOURCE_FLEX_PRESEAL_TRIGGER: string;
|
|
93
|
+
declare function admitCybersourceFlexPreparation(prepared: any, { crypto, now }?: {}): Promise<Readonly<{
|
|
94
|
+
context: Readonly<{
|
|
95
|
+
raw: any;
|
|
96
|
+
signingKid: any;
|
|
97
|
+
environment: any;
|
|
98
|
+
origin: string;
|
|
99
|
+
path: string;
|
|
100
|
+
url: string;
|
|
101
|
+
jwk: Readonly<{
|
|
102
|
+
kty: "RSA";
|
|
103
|
+
n: any;
|
|
104
|
+
e: any;
|
|
105
|
+
kid: any;
|
|
106
|
+
}>;
|
|
107
|
+
modulusBytes: number;
|
|
108
|
+
index: any;
|
|
109
|
+
contextType: any;
|
|
110
|
+
allowedCardNetworks: readonly any[] | null;
|
|
111
|
+
targetOrigins: readonly any[];
|
|
112
|
+
iat: any;
|
|
113
|
+
exp: any;
|
|
114
|
+
}>;
|
|
115
|
+
fields: readonly string[];
|
|
116
|
+
}>>;
|
|
117
|
+
declare function sameCybersourceFlexPreparation(prepared: any, request: any): boolean;
|
|
118
|
+
export { CYBERSOURCE_FLEX_CAPTURE_CONTEXT_MAX_LENGTH, CYBERSOURCE_FLEX_CONTENT_TYPE, CYBERSOURCE_FLEX_PRESEAL_TRIGGER, CYBERSOURCE_FLEX_PSP, CYBERSOURCE_FLEX_REFUSAL_REASONS, CYBERSOURCE_FLEX_REVIEWED_IFRAME_VERSIONS, CYBERSOURCE_FLEX_RULES_SOURCE, CYBERSOURCE_FLEX_SIGNING_KEYS, CYBERSOURCE_FLEX_TEST_PANS, CYBERSOURCE_FLEX_TOKENS_URLS, CybersourceFlexError, admitCybersourceFlexPreparation, assertCybersourceFlexTemplate, buildCardPlaintext, cybersourceFlexEnvironment, flexHostEnvironment as cybersourceFlexHostEnvironment, cybersourceFlexPreparationUrl, cybersourceFlexRefusalCode, cybersourceFlexTemplateKid, detectCardTypes, isCybersourceFlexMediaType, isCybersourceFlexRequest, isCybersourceFlexTemplateBody, isCybersourceFlexTokenShape, isPreparedCybersourceFlexRequest, isVerifiedCaptureContext, parseMicroformFragment, sameCybersourceFlexPreparation, sealForContext, transientTokenFacts, transientTokenSigned, verifyCaptureContext };
|
|
@@ -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: a2baaac410b5aaa629b3d5031136f88645c7b45c67c3bbc154cad72de216a04e
|
|
4
4
|
// src/cybersource-flex-rules.js
|
|
5
5
|
var CYBERSOURCE_FLEX_RULES_SOURCE = Object.freeze({ version: "2.12.1", sha256: "8429ebae83e9745cd53ad8ff0d9ba69bee0087c1435ed0695a25444bed418327" });
|
|
6
6
|
var CYBERSOURCE_FLEX_RULES = [
|
|
@@ -686,4 +686,44 @@ function iframeHeaders(headers) {
|
|
|
686
686
|
function isPreparedCybersourceFlexRequest(url, method, body, environment, headers) {
|
|
687
687
|
return (environment === "production" || environment === "sandbox") && method === "POST" && cybersourceFlexEnvironment(url) === environment && iframeHeaders(headers) && isCybersourceFlexTemplateBody(body);
|
|
688
688
|
}
|
|
689
|
-
|
|
689
|
+
var CYBERSOURCE_FLEX_PRESEAL_TRIGGER = "number";
|
|
690
|
+
var isRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
691
|
+
function preparedLayout(microform) {
|
|
692
|
+
if (!isRecord(microform) || typeof microform.version !== "string" || !CYBERSOURCE_FLEX_REVIEWED_IFRAME_VERSIONS.includes(microform.version)) {
|
|
693
|
+
refuse("microform_version", "this payment's card field is not a Microform version this device can rebuild.");
|
|
694
|
+
}
|
|
695
|
+
if (Object.keys(microform).some((key) => key !== "version" && key !== "fields")) {
|
|
696
|
+
refuse("fields", "the Microform fields this payment loaded are not a card number field and an optional security code field.");
|
|
697
|
+
}
|
|
698
|
+
fieldSet(microform.fields, CYBERSOURCE_FLEX_PRESEAL_TRIGGER);
|
|
699
|
+
return Object.freeze(FIELD_TYPES.filter((field) => microform.fields.includes(field)));
|
|
700
|
+
}
|
|
701
|
+
async function admitCybersourceFlexPreparation(prepared, { crypto, now } = {}) {
|
|
702
|
+
if (!isRecord(prepared))
|
|
703
|
+
refuse("request", "malformed checkout preparation.");
|
|
704
|
+
const fields = preparedLayout(prepared.microform);
|
|
705
|
+
const { environment } = prepared;
|
|
706
|
+
if (environment !== "production" && environment !== "sandbox") {
|
|
707
|
+
refuse("environment_mismatch", "the preparation names no CyberSource environment.");
|
|
708
|
+
}
|
|
709
|
+
const context = await verifyCaptureContext(prepared.capture_context, { crypto, now });
|
|
710
|
+
if (context.environment !== environment || context.url !== CYBERSOURCE_FLEX_TOKENS_URLS[environment]) {
|
|
711
|
+
refuse("environment_mismatch", "the CyberSource test and live environments are mixed in this payment.");
|
|
712
|
+
}
|
|
713
|
+
return Object.freeze({ context, fields });
|
|
714
|
+
}
|
|
715
|
+
function sameCybersourceFlexPreparation(prepared, request) {
|
|
716
|
+
if (!isRecord(prepared) || !isRecord(request) || !isRecord(prepared.microform) || !isRecord(request.microform))
|
|
717
|
+
return false;
|
|
718
|
+
const context = prepared.capture_context;
|
|
719
|
+
if (typeof context !== "string" || context.length < 1 || context.length > CAPTURE_CONTEXT_MAX_LENGTH || request.capture_context !== context)
|
|
720
|
+
return false;
|
|
721
|
+
const one = prepared.microform;
|
|
722
|
+
const two = request.microform;
|
|
723
|
+
if (typeof one.version !== "string" || one.version !== two.version || !Array.isArray(one.fields) || !Array.isArray(two.fields))
|
|
724
|
+
return false;
|
|
725
|
+
const mine = new Set(one.fields);
|
|
726
|
+
const theirs = new Set(two.fields);
|
|
727
|
+
return mine.size === one.fields.length && theirs.size === two.fields.length && mine.size === theirs.size && [...mine].every((field) => theirs.has(field));
|
|
728
|
+
}
|
|
729
|
+
export { CYBERSOURCE_FLEX_CAPTURE_CONTEXT_MAX_LENGTH, CYBERSOURCE_FLEX_CONTENT_TYPE, CYBERSOURCE_FLEX_PRESEAL_TRIGGER, CYBERSOURCE_FLEX_PSP, CYBERSOURCE_FLEX_REFUSAL_REASONS, CYBERSOURCE_FLEX_REVIEWED_IFRAME_VERSIONS, CYBERSOURCE_FLEX_RULES_SOURCE, CYBERSOURCE_FLEX_SIGNING_KEYS, CYBERSOURCE_FLEX_TEST_PANS, CYBERSOURCE_FLEX_TOKENS_URLS, CybersourceFlexError, admitCybersourceFlexPreparation, assertCybersourceFlexTemplate, buildCardPlaintext, cybersourceFlexEnvironment, flexHostEnvironment as cybersourceFlexHostEnvironment, cybersourceFlexPreparationUrl, cybersourceFlexRefusalCode, cybersourceFlexTemplateKid, detectCardTypes, isCybersourceFlexMediaType, isCybersourceFlexRequest, isCybersourceFlexTemplateBody, isCybersourceFlexTokenShape, isPreparedCybersourceFlexRequest, isVerifiedCaptureContext, parseMicroformFragment, sameCybersourceFlexPreparation, sealForContext, transientTokenFacts, transientTokenSigned, verifyCaptureContext };
|
package/dist/cybersource-flex.js
CHANGED
|
@@ -222,6 +222,10 @@ export class MicroformFrames {
|
|
|
222
222
|
if (typeof frameId === 'string')
|
|
223
223
|
this.frames.delete(frameId);
|
|
224
224
|
}
|
|
225
|
+
/** The card Microform whose field documents this attachment recorded, for prepare({ tokenizeBeforePay: true }). */
|
|
226
|
+
loadedCard() {
|
|
227
|
+
return loadedCardMicroform(this.frames.values());
|
|
228
|
+
}
|
|
225
229
|
/**
|
|
226
230
|
* Judge a POST the frame `frameId` sent. When that frame is not on record, `reread` reads the
|
|
227
231
|
* pausing session's frame tree once (recording what it finds) and resolves to the frame's
|
|
@@ -251,6 +255,48 @@ export function judgeMicroformFrameUrls(request, issuingUrl, frameUrls, contexts
|
|
|
251
255
|
}
|
|
252
256
|
return judgeMicroformRequest(request, issuingUrl === undefined ? undefined : frameOf(issuingUrl), frames, contexts);
|
|
253
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* The card Microform a page loaded, for prepare({ tokenizeBeforePay: true }): every committed card
|
|
260
|
+
* field-iframe document, grouped by capture context, microform id, version and host. One group of a
|
|
261
|
+
* reviewed version, with a card number field and at most a security code field, is the checkout the
|
|
262
|
+
* cardholder's device tokenizes before Pay. No group is `microform_not_loaded` (prepare once the card
|
|
263
|
+
* fields show), two or more are `microform_ambiguous`, and any other group is `microform_unsupported`.
|
|
264
|
+
* A check (eCheck) Microform carries no card and is not counted. Reads the frames only; the capture
|
|
265
|
+
* context is verified by prepareCheckout, the API and the device.
|
|
266
|
+
*/
|
|
267
|
+
export function loadedCardMicroform(frames) {
|
|
268
|
+
const groups = new Map();
|
|
269
|
+
for (const frame of frames) {
|
|
270
|
+
if (frame.microformType !== 'card')
|
|
271
|
+
continue;
|
|
272
|
+
const key = JSON.stringify([frame.captureContext, frame.microformId, frame.version, frame.environment]);
|
|
273
|
+
const group = groups.get(key);
|
|
274
|
+
if (group)
|
|
275
|
+
group.types.add(frame.fieldType);
|
|
276
|
+
else
|
|
277
|
+
groups.set(key, { frame, types: new Set([frame.fieldType]) });
|
|
278
|
+
}
|
|
279
|
+
if (groups.size === 0)
|
|
280
|
+
return { ok: false, reason: 'microform_not_loaded' };
|
|
281
|
+
if (groups.size > 1)
|
|
282
|
+
return { ok: false, reason: 'microform_ambiguous' };
|
|
283
|
+
const [{ frame, types }] = [...groups.values()];
|
|
284
|
+
if (!frame.reviewed || !types.has('number') || [...types].some((type) => !MICROFORM_FIELDS.includes(type))) {
|
|
285
|
+
return { ok: false, reason: 'microform_unsupported' };
|
|
286
|
+
}
|
|
287
|
+
return { ok: true, captureContext: frame.captureContext, environment: frame.environment,
|
|
288
|
+
microform: { version: frame.version, fields: MICROFORM_FIELDS.filter((field) => types.has(field)) } };
|
|
289
|
+
}
|
|
290
|
+
/** The Playwright adapter's read: every frame URL on the page (Playwright keeps the fragment in frame.url()). */
|
|
291
|
+
export function loadedCardMicroformFromUrls(urls) {
|
|
292
|
+
const frames = [];
|
|
293
|
+
for (const url of urls) {
|
|
294
|
+
const frame = frameOf(url);
|
|
295
|
+
if (frame)
|
|
296
|
+
frames.push(frame);
|
|
297
|
+
}
|
|
298
|
+
return loadedCardMicroform(frames);
|
|
299
|
+
}
|
|
254
300
|
/**
|
|
255
301
|
* Whether a create's sidecar has the shape the API admits (routes/api/v2/checkout.ts
|
|
256
302
|
* createSchema): a capture context of 1 to 16384 characters, and a Microform version with a
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { DATATRANS_CARD_ON_FILE_REFUSED, DATATRANS_INVALID_REQUEST } from './datatrans.generated.js';
|
|
2
|
+
import type { ReplayResponse } from './client.js';
|
|
3
|
+
export declare const DATATRANS_PSP = "datatrans";
|
|
4
|
+
/** The dark-launch capability the API serves the datatrans recognizer behind. */
|
|
5
|
+
export declare const DATATRANS_CAPABILITY = "datatrans_secure_fields_tokenize";
|
|
6
|
+
/**
|
|
7
|
+
* Why the SDK refuses a Datatrans card post before anything is claimed, created or prompted. The
|
|
8
|
+
* API answers the same two codes at create, so a refusal here only saves the round trip:
|
|
9
|
+
* - `invalid_datatrans_request`: not a sound Secure Fields TOKENIZE card post. That covers
|
|
10
|
+
* another mode, a payment or 3-D Secure post (`transactionId`, `3D`, `dccSelected`), a key
|
|
11
|
+
* field.js never sends, a URL variant (a query, a case or dot spelling) or a content type that
|
|
12
|
+
* is not jQuery's form type. The cardholder's device could never fill it.
|
|
13
|
+
* - `datatrans_card_on_file_refused`: a sound post that asks PCI Proxy to keep the card on file
|
|
14
|
+
* (usage=REGISTRATION: a reusable alias plus a network token, so the merchant could charge the
|
|
15
|
+
* card again later), while the card-on-file policy the API served refuses that
|
|
16
|
+
* (datatransCardOnFilePolicy). British Airways's Nexus checkout sends it for every new card.
|
|
17
|
+
*/
|
|
18
|
+
export type DatatransRefusalReason = typeof DATATRANS_INVALID_REQUEST | typeof DATATRANS_CARD_ON_FILE_REFUSED;
|
|
19
|
+
/** True when the URL's host is one of Datatrans's two pay hosts. */
|
|
20
|
+
export declare function isDatatransHost(url: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The card-on-file policy this build applies to a Datatrans card post: the one the API served with
|
|
23
|
+
* the datatrans recognizer (Recognizer.cardOnFile, VaultClient.cardOnFilePolicy) when payment-core
|
|
24
|
+
* defines it (`refuse`, `disclose`, `agentcard_single_use`), and `refuse` for anything else, an entry
|
|
25
|
+
* that names none included. The decision is payment-core's DATATRANS_REGISTRATION_POLICY, which the
|
|
26
|
+
* API reads each time it serves the catalog and again at create, so a change to that one line
|
|
27
|
+
* reaches every build already published at its next syncRegistry(), with no SDK release.
|
|
28
|
+
*/
|
|
29
|
+
export declare function datatransCardOnFilePolicy(served: unknown): string;
|
|
30
|
+
/**
|
|
31
|
+
* The pause decision for a POST the registry recognized on a Datatrans pay host, by payment-core's
|
|
32
|
+
* classifyDatatransRequest under the card-on-file policy the API served (datatransCardOnFilePolicy):
|
|
33
|
+
* 'card' the exact card URL with jQuery's form type and a sound TOKENIZE card body: it pauses. A
|
|
34
|
+
* usage=REGISTRATION post is one too once the served policy allows card on file, and the
|
|
35
|
+
* API and the cardholder's device then apply that policy;
|
|
36
|
+
* a DatatransRefusalReason: it is refused in the browser;
|
|
37
|
+
* null no card in the body (a wallet, bank-account or CVV-only post) or not the card path:
|
|
38
|
+
* the SDK's ordinary handling decides, and such a post continues untouched.
|
|
39
|
+
*/
|
|
40
|
+
export declare function datatransPauseDecision(request: {
|
|
41
|
+
url: string;
|
|
42
|
+
headers: Record<string, string>;
|
|
43
|
+
body: string | null;
|
|
44
|
+
}, servedPolicy?: unknown): 'card' | DatatransRefusalReason | null;
|
|
45
|
+
/**
|
|
46
|
+
* How long an approved Datatrans answer is replayed to its own frame: the token's own lifetime
|
|
47
|
+
* (PCI Proxy keeps a tokenization readable for 30 minutes). Past it the stored transactionId names a
|
|
48
|
+
* token the merchant can no longer read, so a later post is a new question.
|
|
49
|
+
*/
|
|
50
|
+
export declare const DATATRANS_REPEAT_WINDOW_MS: number;
|
|
51
|
+
/**
|
|
52
|
+
* How long a stored answer waits for its form's next post. British Airways re-submits while the agent
|
|
53
|
+
* finishes the card form, right after the approved answer. A form that posts nothing for this long has
|
|
54
|
+
* moved on: the order was placed or abandoned, which the SDK cannot tell apart without reconcile(). Its
|
|
55
|
+
* next post is a new approval. Each answered re-submit restarts the wait, and the token's lifetime
|
|
56
|
+
* still ends every answer.
|
|
57
|
+
*/
|
|
58
|
+
export declare const DATATRANS_REPEAT_IDLE_MS: number;
|
|
59
|
+
/** A stored answer handed to a repeat, with the approval it came from. */
|
|
60
|
+
export interface DatatransRepeatAnswer {
|
|
61
|
+
authorizationId: string;
|
|
62
|
+
response: {
|
|
63
|
+
status: number;
|
|
64
|
+
headers: Record<string, string>;
|
|
65
|
+
body: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The approved Datatrans answers one attachment handed to a card post, per frame. `frame` is the
|
|
70
|
+
* adapter's identity for the request's frame (the CDP frameId, the Playwright Frame); a request
|
|
71
|
+
* whose frame is unknown is never remembered and never answered. Only an answer payment-core reads
|
|
72
|
+
* as approved ({transactionId, cardInfo}) is kept: an error answer leaves the next post a new
|
|
73
|
+
* question, so the page can try again.
|
|
74
|
+
*/
|
|
75
|
+
export declare class DatatransRepeats {
|
|
76
|
+
private readonly windowMs;
|
|
77
|
+
private readonly now;
|
|
78
|
+
private readonly idleMs;
|
|
79
|
+
private remembered;
|
|
80
|
+
constructor(windowMs?: number, now?: () => number, idleMs?: number);
|
|
81
|
+
/**
|
|
82
|
+
* Keep the answer a token replay handed to this card post, when Datatrans approved it. Called
|
|
83
|
+
* after the answer reached the browser, so it never throws: a failure here only leaves the
|
|
84
|
+
* page's next post a new question.
|
|
85
|
+
*/
|
|
86
|
+
remember(frame: unknown, url: string, body: string | null, replay: ReplayResponse): void;
|
|
87
|
+
/**
|
|
88
|
+
* The stored answer for a repeat of an answered card post from the same frame, or null. Only an
|
|
89
|
+
* answer from `authorizationId`, the approval the attachment is handing off now, is handed out,
|
|
90
|
+
* and every answer from another approval is dropped: a later authorization ends the window of
|
|
91
|
+
* every earlier one. An answer whose form stayed quiet past the idle bound is dropped too, and
|
|
92
|
+
* handing one out restarts that bound.
|
|
93
|
+
*/
|
|
94
|
+
answerFor(frame: unknown, url: string, body: string | null, authorizationId: string | null): DatatransRepeatAnswer | null;
|
|
95
|
+
private prune;
|
|
96
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
declare var DATATRANS_HOSTS: readonly string[];
|
|
2
|
+
declare var DATATRANS_TOKENIZE_PATH: string;
|
|
3
|
+
declare var DATATRANS_REFUSAL_REASONS: readonly string[];
|
|
4
|
+
declare var DATATRANS_INVALID_REQUEST: string;
|
|
5
|
+
declare var DATATRANS_CARD_ON_FILE_REFUSED: string;
|
|
6
|
+
declare var DATATRANS_REGISTRATION_POLICIES: readonly string[];
|
|
7
|
+
declare var DATATRANS_REGISTRATION_POLICY: string;
|
|
8
|
+
declare var DATATRANS_REVIEWED_MERCHANT_IDS: Readonly<{
|
|
9
|
+
"pay.datatrans.com": readonly never[];
|
|
10
|
+
"pay.sandbox.datatrans.com": readonly string[];
|
|
11
|
+
}>;
|
|
12
|
+
declare var DATATRANS_PAYMENT_METHODS: readonly string[];
|
|
13
|
+
declare var DATATRANS_TEST_PANS: readonly string[];
|
|
14
|
+
declare function encodeDatatransFormValue(value: any): string;
|
|
15
|
+
declare function parseDatatransForm(body: any): {
|
|
16
|
+
key: string;
|
|
17
|
+
value: string;
|
|
18
|
+
rawKey: string;
|
|
19
|
+
raw: string;
|
|
20
|
+
}[] | null;
|
|
21
|
+
declare function serializeDatatransForm(pairs: any): any;
|
|
22
|
+
declare function isDatatransTokenizeUrl(url: any, method?: string): boolean;
|
|
23
|
+
declare function datatransRegistrationRefusal(usage: any, card: any, policy?: string): "card_on_file" | null;
|
|
24
|
+
declare function datatransCardOnFileDisclosure(body: any, policy?: string): boolean;
|
|
25
|
+
declare function datatransBodyRefusal(body: any, card: any, policy?: string): "unsupported" | "card_on_file" | null;
|
|
26
|
+
declare function datatransMerchantId(body: any): string | null | undefined;
|
|
27
|
+
declare function classifyDatatransRequest(url: any, method: any, body: any, headers: any, policy?: string): "card" | "unsupported" | "card_on_file" | null;
|
|
28
|
+
declare function datatransTokenizeRefusal(request: any, card: any, policy?: string): "unsupported" | "card_on_file" | null;
|
|
29
|
+
declare function isDatatransTokenizeRequest(request: any, card: any): boolean;
|
|
30
|
+
declare function datatransMerchantRefusal(url: any, body: any, merchants?: Readonly<{
|
|
31
|
+
"pay.datatrans.com": readonly never[];
|
|
32
|
+
"pay.sandbox.datatrans.com": readonly string[];
|
|
33
|
+
}>): "unregistered_merchant" | null;
|
|
34
|
+
declare function datatransDeviceRefusal(request: any, card: any, policy?: string, merchants?: Readonly<{
|
|
35
|
+
"pay.datatrans.com": readonly never[];
|
|
36
|
+
"pay.sandbox.datatrans.com": readonly string[];
|
|
37
|
+
}>): "unsupported" | "card_on_file" | "brand_mismatch" | "unregistered_merchant" | null;
|
|
38
|
+
declare function datatransRefusalMessage(reason: any): string;
|
|
39
|
+
declare function datatransCardBrand(number: any): "VIS" | "ECA" | "AMX" | null;
|
|
40
|
+
declare function datatransBrandRefusal(body: any, card: any): "unsupported" | "brand_mismatch" | null;
|
|
41
|
+
declare function injectDatatransCard(body: any, card: any, policy?: string): {
|
|
42
|
+
body: string;
|
|
43
|
+
where: string[];
|
|
44
|
+
};
|
|
45
|
+
declare function datatransErrorCode(message: any): string | RegExp;
|
|
46
|
+
declare function datatransResponseOutcome(status: any, body: any, card: any): {
|
|
47
|
+
outcome: string;
|
|
48
|
+
reason: string;
|
|
49
|
+
code?: undefined;
|
|
50
|
+
} | {
|
|
51
|
+
outcome: string;
|
|
52
|
+
code: string | RegExp;
|
|
53
|
+
reason?: undefined;
|
|
54
|
+
} | {
|
|
55
|
+
outcome: string;
|
|
56
|
+
reason?: undefined;
|
|
57
|
+
code?: undefined;
|
|
58
|
+
};
|
|
59
|
+
declare function sanitizeDatatransTokenResponse(body: any): string;
|
|
60
|
+
declare function datatransFacts(status: any, body: any): {
|
|
61
|
+
outcome: string;
|
|
62
|
+
refusalCode: string | RegExp | null | undefined;
|
|
63
|
+
};
|
|
64
|
+
export { DATATRANS_CARD_ON_FILE_REFUSED, DATATRANS_HOSTS, DATATRANS_INVALID_REQUEST, DATATRANS_PAYMENT_METHODS, DATATRANS_REFUSAL_REASONS, DATATRANS_REGISTRATION_POLICIES, DATATRANS_REGISTRATION_POLICY, DATATRANS_REVIEWED_MERCHANT_IDS, DATATRANS_TEST_PANS, DATATRANS_TOKENIZE_PATH, classifyDatatransRequest, datatransBodyRefusal, datatransBrandRefusal, datatransCardBrand, datatransCardOnFileDisclosure, datatransDeviceRefusal, datatransErrorCode, datatransFacts, datatransMerchantId, datatransMerchantRefusal, datatransRefusalMessage, datatransRegistrationRefusal, datatransResponseOutcome, datatransTokenizeRefusal, encodeDatatransFormValue, injectDatatransCard, isDatatransTokenizeRequest, isDatatransTokenizeUrl, parseDatatransForm, sanitizeDatatransTokenResponse, serializeDatatransForm };
|