@agent-cards/checkout 0.18.0 → 0.19.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 +8 -0
- package/PREFLIGHT.md +4 -0
- package/README.md +91 -7
- package/dist/adyen-merchant-hosted.generated.d.ts +277 -0
- package/dist/adyen-merchant-hosted.generated.js +1902 -0
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/cdp.d.ts +4 -1
- package/dist/cdp.js +416 -217
- package/dist/client.d.ts +236 -5
- package/dist/client.js +514 -11
- package/dist/cse-body.d.ts +25 -0
- package/dist/cse-body.js +41 -0
- package/dist/fiserv.d.ts +65 -0
- package/dist/fiserv.generated.d.ts +73 -0
- package/dist/fiserv.generated.js +830 -0
- package/dist/fiserv.js +104 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +5 -1
- package/dist/lifecycle.d.ts +15 -1
- package/dist/lifecycle.js +28 -3
- package/dist/merchant-handoff.d.ts +54 -0
- package/dist/merchant-handoff.js +100 -0
- package/dist/merchant-hosted.d.ts +140 -0
- package/dist/merchant-hosted.js +170 -0
- package/dist/merchant-total-watch.d.ts +115 -0
- package/dist/merchant-total-watch.js +268 -0
- package/dist/merchant-total.d.ts +257 -0
- package/dist/merchant-total.js +383 -0
- package/dist/pre-claim.d.ts +123 -0
- package/dist/pre-claim.js +386 -0
- package/dist/preflight-catalog.json +132 -0
- package/dist/preflight-schemas.json +14 -2
- package/dist/preflight.generated.js +15 -1
- package/dist/preparation.d.ts +7 -0
- package/dist/preparation.js +33 -6
- package/dist/prepared-processor.d.ts +36 -3
- package/dist/prepared-processor.js +53 -3
- package/dist/registry.d.ts +45 -0
- package/dist/registry.js +14 -0
- package/dist/stripe-checkout.generated.js +96 -7
- package/dist/substitutions.generated.d.ts +2 -1
- package/dist/substitutions.generated.js +758 -6
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PreparedCheckout, ReplayResponse } from './client.js';
|
|
2
|
+
/**
|
|
3
|
+
* The cse continuation: the paused body with the vault's ciphertext in place
|
|
4
|
+
* of the dummy blobs. The adapters send it as postData ALONE. Chromium
|
|
5
|
+
* recomputes Content-Length for a continued request itself and refuses a
|
|
6
|
+
* header override that names it (Fetch.continueRequest answers -32602 "Unsafe
|
|
7
|
+
* header"), and that refusal would land after the cardholder approved, failing
|
|
8
|
+
* a paid-for request. Leaving `headers` off the command keeps every other
|
|
9
|
+
* header the browser's own, untouched, which is the point of continuing rather
|
|
10
|
+
* than fulfilling.
|
|
11
|
+
*
|
|
12
|
+
* The approval picks the substitution, not the URL alone. A Fiserv approval is
|
|
13
|
+
* always a prepared one (authorize() requires it), so its preparation names
|
|
14
|
+
* the processor and the key pin the cardholder approved. It continues only a
|
|
15
|
+
* request on Fiserv's capture hosts, and only when that capture's own pin (its
|
|
16
|
+
* envelope's key, pinned for its endpoint and its merchant) is the approved
|
|
17
|
+
* pin; then Fiserv's own substitution writes only the envelope's four members
|
|
18
|
+
* at source.encryptionData of the live paused body, and throws for a body that
|
|
19
|
+
* is not the capture Agentcard covers or an envelope under another key than
|
|
20
|
+
* the one the paused capture names (fiserv.ts). Any other approval never meets
|
|
21
|
+
* a Fiserv capture host. Every refusal throws before anything is sent.
|
|
22
|
+
*/
|
|
23
|
+
export declare function cseBody(body: string, replay: Extract<ReplayResponse, {
|
|
24
|
+
mode: 'cse';
|
|
25
|
+
}>, url: string, preparation: PreparedCheckout | undefined): string;
|
package/dist/cse-body.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// The body a cse approval continues, shared by both adapters (cdp.ts). Kept in its
|
|
2
|
+
// own module, outside the package's published entries, so its tests can reach it.
|
|
3
|
+
import { substituteEncryptedFields } from './substitute.js';
|
|
4
|
+
import { substituteMerchantHostedBody } from './merchant-hosted.js';
|
|
5
|
+
import { fiservCapturePinId, isFiservCaptureHost, substituteFiservEnvelope } from './fiserv.js';
|
|
6
|
+
/**
|
|
7
|
+
* The cse continuation: the paused body with the vault's ciphertext in place
|
|
8
|
+
* of the dummy blobs. The adapters send it as postData ALONE. Chromium
|
|
9
|
+
* recomputes Content-Length for a continued request itself and refuses a
|
|
10
|
+
* header override that names it (Fetch.continueRequest answers -32602 "Unsafe
|
|
11
|
+
* header"), and that refusal would land after the cardholder approved, failing
|
|
12
|
+
* a paid-for request. Leaving `headers` off the command keeps every other
|
|
13
|
+
* header the browser's own, untouched, which is the point of continuing rather
|
|
14
|
+
* than fulfilling.
|
|
15
|
+
*
|
|
16
|
+
* The approval picks the substitution, not the URL alone. A Fiserv approval is
|
|
17
|
+
* always a prepared one (authorize() requires it), so its preparation names
|
|
18
|
+
* the processor and the key pin the cardholder approved. It continues only a
|
|
19
|
+
* request on Fiserv's capture hosts, and only when that capture's own pin (its
|
|
20
|
+
* envelope's key, pinned for its endpoint and its merchant) is the approved
|
|
21
|
+
* pin; then Fiserv's own substitution writes only the envelope's four members
|
|
22
|
+
* at source.encryptionData of the live paused body, and throws for a body that
|
|
23
|
+
* is not the capture Agentcard covers or an envelope under another key than
|
|
24
|
+
* the one the paused capture names (fiserv.ts). Any other approval never meets
|
|
25
|
+
* a Fiserv capture host. Every refusal throws before anything is sent.
|
|
26
|
+
*/
|
|
27
|
+
export function cseBody(body, replay, url, preparation) {
|
|
28
|
+
if (preparation?.psp === 'fiserv') {
|
|
29
|
+
if (replay.kind === 'merchant_hosted' || !isFiservCaptureHost(url) || fiservCapturePinId(url, body) !== preparation.merchantProfile) {
|
|
30
|
+
throw new Error('Refusing to substitute: the paused request is not a Fiserv capture under the key pin the cardholder approved.');
|
|
31
|
+
}
|
|
32
|
+
return substituteFiservEnvelope(body, replay.substitutions);
|
|
33
|
+
}
|
|
34
|
+
if (isFiservCaptureHost(url))
|
|
35
|
+
throw new Error('Refusing to substitute: a Fiserv capture continues only through a prepared Fiserv approval.');
|
|
36
|
+
// A merchant-hosted approval is written into the LIVE paused body, which must
|
|
37
|
+
// still be the body the API checked at create (merchant-hosted.ts).
|
|
38
|
+
if (replay.kind === 'merchant_hosted')
|
|
39
|
+
return substituteMerchantHostedBody(body, replay);
|
|
40
|
+
return substituteEncryptedFields(body, replay.substitutions);
|
|
41
|
+
}
|
package/dist/fiserv.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Substitutions } from './substitute.js';
|
|
2
|
+
export type FiservEnvironment = 'production' | 'sandbox';
|
|
3
|
+
/** A Fiserv public key Agentcard reviewed: its id, the merchant a cardholder is shown, and the environment it pays in. */
|
|
4
|
+
export interface FiservKeyPin {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly merchant: string;
|
|
7
|
+
readonly environment: FiservEnvironment;
|
|
8
|
+
}
|
|
9
|
+
/** The card-capture endpoint per environment, exactly as the Secure Data Capture frame writes it. */
|
|
10
|
+
export declare const FISERV_CARD_CAPTURE_ENDPOINTS: Readonly<Record<FiservEnvironment, string>>;
|
|
11
|
+
/**
|
|
12
|
+
* Whether `url` is on one of the two card-capture hosts (connect.fiservapis.com and
|
|
13
|
+
* connect-cert.fiservapis.com), whatever its path or query. The registry's Fiserv
|
|
14
|
+
* recognizer lists exactly these hosts, so a card request on one of them is Fiserv's.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isFiservCaptureHost(url: string): boolean;
|
|
17
|
+
/** The pinned key with this id, in either environment, or null. */
|
|
18
|
+
export declare function fiservKeyPinById(id: unknown): FiservKeyPin | null;
|
|
19
|
+
/**
|
|
20
|
+
* The id of the pin a paused capture's card may be sealed under (its envelope's key,
|
|
21
|
+
* pinned for its endpoint's environment and for the merchant its body names), or null.
|
|
22
|
+
*/
|
|
23
|
+
export declare function fiservCapturePinId(url: string, body: string | null): string | null;
|
|
24
|
+
/** The card-capture endpoint a Fiserv preparation names for its environment. */
|
|
25
|
+
export declare function fiservPreparationUrl(environment: FiservEnvironment): string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether the SDK pauses this capture body for the cardholder, or refuses it when no
|
|
28
|
+
* preparation is ready: every body except the captures that carry no Vault card.
|
|
29
|
+
* Fastlane (PaymentToken), ACH (PaymentCheck), gift and EBT captures share the endpoint
|
|
30
|
+
* and continue untouched, each only in its exact source shape. A body not proven
|
|
31
|
+
* card-free (one the adapter could not read, one over 64 KiB, one that is not JSON, a
|
|
32
|
+
* PaymentCard with a plaintext card, a non-card type or category that also carries a card
|
|
33
|
+
* member) is judged as a card capture, so the agent's placeholder never continues to
|
|
34
|
+
* Fiserv on it.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isFiservPausableBody(body: string | null): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Whether this build pays the request only through a prepared checkout because it is
|
|
39
|
+
* Fiserv's: a recognizer named fiserv, or a request on one of Fiserv's capture hosts.
|
|
40
|
+
* The served entry says so too (preparationRequired); this build carries Fiserv's own
|
|
41
|
+
* rules, so it requires the preparation whatever the served registry says, and a
|
|
42
|
+
* registry that dropped the flag never opens an ordinary Fiserv authorization.
|
|
43
|
+
*/
|
|
44
|
+
export declare function requiresFiservPreparation(psp: string, url: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether a paused request is the capture a Fiserv preparation for `environment`
|
|
47
|
+
* consents to: that environment's endpoint exactly, the capture rules on the whole
|
|
48
|
+
* request, headers included, and an envelope under a key pinned for that environment
|
|
49
|
+
* and for the merchant the body names.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isPreparedFiservRequest(url: string, method: string, body: string | null, environment: FiservEnvironment, headers?: Record<string, string>): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Whether an approval's substitution is exactly Fiserv's envelope: `encoding` json,
|
|
54
|
+
* `at` source.encryptionData, the four members keyId, encryptedKey, encryptionBlock and
|
|
55
|
+
* aesIv in their exact shape under a pinned key, and nothing removed.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isFiservSubstitution(sub: unknown): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* The paused Fiserv capture with the approval's envelope written over the four members
|
|
60
|
+
* its source.encryptionData already carries, and every other byte the frame's own. It
|
|
61
|
+
* throws, writing nothing, for a body that is not the capture Agentcard covers, for any
|
|
62
|
+
* substitution but Fiserv's envelope, and for an envelope under another key than the one
|
|
63
|
+
* the paused capture names. Run this on a Fiserv approval, never substituteEncryptedFields.
|
|
64
|
+
*/
|
|
65
|
+
export declare function substituteFiservEnvelope(body: string, sub: Substitutions): string;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
declare var FISERV_CARD_CAPTURE_ENDPOINTS: Readonly<{
|
|
2
|
+
production: "https://connect.fiservapis.com/ch/payments-vas/v1/card-capture";
|
|
3
|
+
sandbox: "https://connect-cert.fiservapis.com/ch/payments-vas/v1/card-capture";
|
|
4
|
+
}>;
|
|
5
|
+
declare function fiservEnvironment(url: any): "production" | "sandbox" | undefined;
|
|
6
|
+
declare function isFiservCardCaptureUrl(url: any): boolean;
|
|
7
|
+
declare var FISERV_SIMULATOR_PANS: readonly string[];
|
|
8
|
+
declare var FISERV_ENVELOPE_CONSTANTS: Readonly<{
|
|
9
|
+
aesTagLength: 128;
|
|
10
|
+
encryptionType: "AES-GCM";
|
|
11
|
+
encryptionTarget: "MANUAL";
|
|
12
|
+
}>;
|
|
13
|
+
declare function fiservTimestampMs(text2: any): number;
|
|
14
|
+
declare var FISERV_KEY_PINS: any;
|
|
15
|
+
declare function fiservKeyPin(keyId: any, environment: any): any;
|
|
16
|
+
declare function isFiservPinnedKeyId(keyId: any): any;
|
|
17
|
+
declare function fiservKeyRefusal(keyId: any, environment: any, nowMs: any): "fiserv_key_unpinned" | "fiserv_key_inactive" | "fiserv_key_outside_validity" | null;
|
|
18
|
+
declare function parseFiservPublishedKey(text2: any): {
|
|
19
|
+
keyId: any;
|
|
20
|
+
encryptionType: any;
|
|
21
|
+
modulus: any;
|
|
22
|
+
encodedPublicKey: any;
|
|
23
|
+
validFrom: any;
|
|
24
|
+
validTo: any;
|
|
25
|
+
status: any;
|
|
26
|
+
symmetric: {
|
|
27
|
+
encryptionType: any;
|
|
28
|
+
modulus: any;
|
|
29
|
+
};
|
|
30
|
+
} | null;
|
|
31
|
+
declare function fiservPublishedKeyRefusal(text2: any, keyId: any, environment: any, nowMs: any): "fiserv_key_unpinned" | "fiserv_key_inactive" | "fiserv_key_outside_validity" | "fiserv_published_key_unreadable" | "fiserv_published_key_rotated" | "fiserv_published_key_mismatch" | null;
|
|
32
|
+
declare function sanitizeFiservCaptureResponse(text2: any): string;
|
|
33
|
+
declare function fiservCaptureCardMismatch(text2: any, card: any): boolean;
|
|
34
|
+
declare function fiservErrorIdentifiers(text2: any): {
|
|
35
|
+
code: any;
|
|
36
|
+
type: any;
|
|
37
|
+
};
|
|
38
|
+
declare function fiservCardCaptureRefusal(request: any): "fiserv_request_invalid" | "fiserv_endpoint_invalid" | "fiserv_body_invalid" | "fiserv_body_member_not_allowed" | "fiserv_source_not_encrypted_card" | "fiserv_envelope_invalid" | "fiserv_merchant_invalid" | "fiserv_transaction_details_invalid" | "fiserv_billing_address_invalid" | "fiserv_method_invalid" | "fiserv_headers_invalid" | "fiserv_header_not_allowed" | "fiserv_content_type_invalid" | "fiserv_auth_token_type_invalid" | "fiserv_merchant_header_mismatch" | "fiserv_terminal_header_mismatch" | "fiserv_header_value_invalid" | null;
|
|
39
|
+
declare function isFiservCardCaptureRequest(request: any): boolean;
|
|
40
|
+
declare function isFiservPausableBody(body: any): boolean;
|
|
41
|
+
declare function fiservTemplateKeyId(body: any): any;
|
|
42
|
+
declare function fiservCaptureMerchant(body: any): {
|
|
43
|
+
merchantId: any;
|
|
44
|
+
terminalId: any;
|
|
45
|
+
} | null;
|
|
46
|
+
declare function fiservCapturePin(capture: any): any;
|
|
47
|
+
declare function fiservCaptureKeyRefusal(capture: any, nowMs: any): string | null;
|
|
48
|
+
declare function fiservPreparationUrl(environment: any): any;
|
|
49
|
+
declare function isPreparedFiservRequest(url: any, method: any, body: any, environment: any, headers: any): boolean;
|
|
50
|
+
declare function encryptFiservCard(card: any, capture: any, facilities: any): Promise<{
|
|
51
|
+
keyId: string;
|
|
52
|
+
encryptedKey: string;
|
|
53
|
+
encryptionBlock: string;
|
|
54
|
+
aesIv: string;
|
|
55
|
+
aesTagLength: 128;
|
|
56
|
+
encryptionType: "AES-GCM";
|
|
57
|
+
encryptionTarget: "MANUAL";
|
|
58
|
+
}>;
|
|
59
|
+
declare var FISERV_SUBSTITUTION: Readonly<{
|
|
60
|
+
at: "source.encryptionData";
|
|
61
|
+
fields: readonly string[];
|
|
62
|
+
}>;
|
|
63
|
+
declare function fiservSubstitutionFieldsRefusal(fields: any): "fiserv_key_unpinned" | "fiserv_substitution_invalid" | "fiserv_substitution_fields_invalid" | null;
|
|
64
|
+
declare function fiservApprovedEnvelopeRefusal(fields: any, context: any): string | null;
|
|
65
|
+
declare function fiservSubstitutions(envelope: any): {
|
|
66
|
+
encoding: string;
|
|
67
|
+
at: "source.encryptionData";
|
|
68
|
+
fields: {
|
|
69
|
+
[k: string]: any;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
declare function substituteFiservEnvelope(body: any, sub: any): string;
|
|
73
|
+
export { FISERV_CARD_CAPTURE_ENDPOINTS, FISERV_ENVELOPE_CONSTANTS, FISERV_KEY_PINS, FISERV_SIMULATOR_PANS, FISERV_SUBSTITUTION, encryptFiservCard, fiservApprovedEnvelopeRefusal, fiservCaptureCardMismatch, fiservCaptureKeyRefusal, fiservCaptureMerchant, fiservCapturePin, fiservCardCaptureRefusal, fiservEnvironment, fiservErrorIdentifiers, fiservKeyPin, fiservKeyRefusal, fiservPreparationUrl, fiservPublishedKeyRefusal, fiservSubstitutionFieldsRefusal, fiservSubstitutions, fiservTemplateKeyId, fiservTimestampMs, isFiservCardCaptureRequest, isFiservCardCaptureUrl, isFiservPausableBody, isFiservPinnedKeyId, isPreparedFiservRequest, parseFiservPublishedKey, sanitizeFiservCaptureResponse, substituteFiservEnvelope };
|