@agent-cards/checkout 0.19.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/README.md +6 -753
- package/cdp.d.ts +1 -0
- package/cdp.js +2 -0
- package/index.d.ts +1 -0
- package/index.js +2 -0
- package/package.json +33 -33
- package/playwright.d.ts +1 -0
- package/playwright.js +2 -0
- package/preflight.d.ts +1 -0
- package/preflight.js +2 -0
- package/CHANGELOG.md +0 -132
- package/PREFLIGHT.md +0 -312
- package/dist/adyen-merchant-hosted.generated.d.ts +0 -277
- package/dist/adyen-merchant-hosted.generated.js +0 -1902
- package/dist/adyen.generated.d.ts +0 -24
- package/dist/adyen.generated.js +0 -64
- package/dist/attachment.d.ts +0 -11
- package/dist/attachment.js +0 -50
- package/dist/braintree.d.ts +0 -2
- package/dist/braintree.generated.d.ts +0 -10
- package/dist/braintree.generated.js +0 -302
- package/dist/braintree.js +0 -2
- package/dist/builtin-registry.generated.d.ts +0 -2
- package/dist/builtin-registry.generated.js +0 -1
- package/dist/card-fields.generated.d.ts +0 -3
- package/dist/card-fields.generated.js +0 -46
- package/dist/cdp.d.ts +0 -192
- package/dist/cdp.js +0 -2393
- package/dist/checkout-com.generated.d.ts +0 -4
- package/dist/checkout-com.generated.js +0 -183
- package/dist/client.d.ts +0 -849
- package/dist/client.js +0 -1754
- package/dist/cse-body.d.ts +0 -25
- package/dist/cse-body.js +0 -41
- package/dist/fiserv.d.ts +0 -65
- package/dist/fiserv.generated.d.ts +0 -73
- package/dist/fiserv.generated.js +0 -830
- package/dist/fiserv.js +0 -104
- package/dist/hosted-form.d.ts +0 -44
- package/dist/hosted-form.js +0 -78
- package/dist/index.d.ts +0 -18
- package/dist/index.js +0 -10
- package/dist/lifecycle.d.ts +0 -179
- package/dist/lifecycle.js +0 -395
- package/dist/mercado-checkout.d.ts +0 -20
- package/dist/mercado-checkout.generated.d.ts +0 -52
- package/dist/mercado-checkout.generated.js +0 -198
- package/dist/mercado-checkout.js +0 -108
- package/dist/merchant-handoff.d.ts +0 -54
- package/dist/merchant-handoff.js +0 -100
- package/dist/merchant-hosted.d.ts +0 -140
- package/dist/merchant-hosted.js +0 -170
- package/dist/merchant-total-watch.d.ts +0 -115
- package/dist/merchant-total-watch.js +0 -268
- package/dist/merchant-total.d.ts +0 -257
- package/dist/merchant-total.js +0 -383
- package/dist/owned-shop.generated.d.ts +0 -24
- package/dist/owned-shop.generated.js +0 -108
- package/dist/paysafe.generated.d.ts +0 -12
- package/dist/paysafe.generated.js +0 -87
- package/dist/playwright.d.ts +0 -3
- package/dist/playwright.js +0 -3
- package/dist/pre-claim.d.ts +0 -123
- package/dist/pre-claim.js +0 -386
- package/dist/preflight-capabilities.generated.d.ts +0 -1253
- package/dist/preflight-capabilities.generated.js +0 -1929
- package/dist/preflight-catalog.json +0 -4727
- package/dist/preflight-playwright.d.ts +0 -34
- package/dist/preflight-playwright.js +0 -355
- package/dist/preflight-schemas.json +0 -1122
- package/dist/preflight.d.ts +0 -1
- package/dist/preflight.generated.d.ts +0 -1965
- package/dist/preflight.generated.js +0 -570
- package/dist/preflight.js +0 -2
- package/dist/preparation.d.ts +0 -38
- package/dist/preparation.js +0 -191
- package/dist/prepared-processor.d.ts +0 -43
- package/dist/prepared-processor.js +0 -172
- package/dist/recurly.generated.d.ts +0 -1
- package/dist/recurly.generated.js +0 -87
- package/dist/registry.d.ts +0 -121
- package/dist/registry.js +0 -310
- package/dist/spreedly.generated.d.ts +0 -10
- package/dist/spreedly.generated.js +0 -332
- package/dist/stripe-checkout.d.ts +0 -81
- package/dist/stripe-checkout.generated.d.ts +0 -82
- package/dist/stripe-checkout.generated.js +0 -1093
- package/dist/stripe-checkout.js +0 -140
- package/dist/substitute.d.ts +0 -38
- package/dist/substitute.js +0 -23
- package/dist/substitutions.generated.d.ts +0 -11
- package/dist/substitutions.generated.js +0 -818
- package/examples/existing-browser.mjs +0 -63
- package/examples/preflight/classify-direct.mjs +0 -21
- package/examples/preflight/classify-kernel.mjs +0 -30
- package/examples/preflight/inspect-browser.mjs +0 -44
- package/examples/preflight/kernel-native/README.md +0 -112
- package/examples/preflight/kernel-native/documented-adapters.json +0 -113
- package/examples/preflight/kernel-native/inventory.json +0 -233
- package/examples/preflight/kernel-native/qualification.mjs +0 -182
- package/examples/preflight/kernel-profile.empty.json +0 -11
- package/examples/preflight/mollie-hosted.observations.json +0 -23
- package/examples/preflight/mollie-hosted.result.json +0 -103
- package/examples/preflight/stripe-script.direct.result.json +0 -92
- package/examples/preflight/stripe-script.observations.json +0 -16
- package/examples/preflight/stripe-script.result.json +0 -87
package/dist/stripe-checkout.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { classifyStripeCheckoutRequest, createStripeCheckoutTokenizationStub, encodeStripeCheckoutContext, isStripeCheckoutEndpoint, STRIPE_CHECKOUT_CONTEXT_HEADER, captureStripeCheckoutBilling, attachStripeCheckoutBilling, validateStripeCheckoutIdentity, stripeCheckoutValidationCode, STRIPE_CHECKOUT_VALIDATION_CODES, } from './stripe-checkout.generated.js';
|
|
2
|
-
class StripeCheckoutRejectionError extends Error {
|
|
3
|
-
stage;
|
|
4
|
-
reason;
|
|
5
|
-
phase;
|
|
6
|
-
validationCode;
|
|
7
|
-
constructor(message, stage, reason, phase, validationCode) {
|
|
8
|
-
super(message);
|
|
9
|
-
this.stage = stage;
|
|
10
|
-
this.reason = reason;
|
|
11
|
-
this.phase = phase;
|
|
12
|
-
this.validationCode = validationCode;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
export function stripeCheckoutReadinessError(reason) {
|
|
16
|
-
return new StripeCheckoutRejectionError('checkout_interception_not_ready', 'readiness', reason);
|
|
17
|
-
}
|
|
18
|
-
/** A valid competing request must not retire the request that already claimed this step. */
|
|
19
|
-
export class StripeCheckoutClaimConflictError extends StripeCheckoutRejectionError {
|
|
20
|
-
constructor(phase) {
|
|
21
|
-
super(phase === 'tokenization' ? 'Native Stripe Checkout preparation is already claimed.'
|
|
22
|
-
: 'Native Stripe Checkout confirmation is already claimed.', 'claim', phase === 'tokenization' ? 'duplicate_tokenization' : 'duplicate_confirmation', phase);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/** The two native browser requests belong to one attachment and one grant.
|
|
26
|
-
* Processor rules and form transformations live in the generated shared core.
|
|
27
|
-
* The local stub contains no selected-card data and starts no authorization.
|
|
28
|
-
*/
|
|
29
|
-
export class StripeCheckoutGate {
|
|
30
|
-
state = 'fresh';
|
|
31
|
-
billing;
|
|
32
|
-
binding;
|
|
33
|
-
constructor(options) {
|
|
34
|
-
if (!options.stripeCheckout)
|
|
35
|
-
return;
|
|
36
|
-
const { sessionId, publishableKey, environment } = options.stripeCheckout;
|
|
37
|
-
validateStripeCheckoutIdentity({ environment, sessionId, publishableKey });
|
|
38
|
-
if (options.executionMode !== 'autopilot' || !/^apg_[A-Za-z0-9_-]{1,128}(?![\s\S])/.test(options.grantId ?? '')
|
|
39
|
-
|| !Number.isSafeInteger(options.amount) || Number(options.amount) <= 0 || options.currency !== 'usd')
|
|
40
|
-
throw new Error('Native Stripe Checkout requires a mode-bound session, grant and numeric USD amount.');
|
|
41
|
-
this.binding = Object.freeze({ environment, sessionId, publishableKey, amountCents: options.amount,
|
|
42
|
-
syntheticPaymentMethodId: `pm_agentcard_checkout_${crypto.randomUUID().replaceAll('-', '')}` });
|
|
43
|
-
}
|
|
44
|
-
matches(url) { return !!this.binding && isStripeCheckoutEndpoint(url); }
|
|
45
|
-
isEnabled() { return !!this.binding; }
|
|
46
|
-
isPrepared() { return this.state !== 'fresh'; }
|
|
47
|
-
invalidate() { this.state = 'stopped'; this.billing = undefined; }
|
|
48
|
-
/** Observability only: this endpoint label never participates in a payment decision. */
|
|
49
|
-
describeRejection(error, rawUrl, stage, phase = 'unknown') {
|
|
50
|
-
let family = 'other';
|
|
51
|
-
try {
|
|
52
|
-
const url = new URL(rawUrl);
|
|
53
|
-
if (url.origin === 'https://api.stripe.com' && url.pathname === '/v1/payment_methods')
|
|
54
|
-
family = 'payment_methods';
|
|
55
|
-
else if (isStripeCheckoutEndpoint(rawUrl))
|
|
56
|
-
family = 'payment_page_confirm';
|
|
57
|
-
}
|
|
58
|
-
catch { /* No untrusted URL or parser error leaves this method. */ }
|
|
59
|
-
const fallback = {
|
|
60
|
-
request_read: 'request_unavailable', classification: 'request_validation_failed', claim: 'preparation_unavailable',
|
|
61
|
-
readiness: 'readiness_unavailable', document: 'document_unavailable', stub_response: 'stub_response_failed',
|
|
62
|
-
};
|
|
63
|
-
const rejection = error instanceof StripeCheckoutRejectionError ? error : undefined;
|
|
64
|
-
const reason = rejection?.reason ?? fallback[stage];
|
|
65
|
-
return { version: 1, processor: 'stripe', endpoint_family: family,
|
|
66
|
-
phase: rejection?.phase ?? phase, stage: rejection?.stage ?? stage, reason,
|
|
67
|
-
...(reason === 'request_validation_failed' ? { validation_code: rejection?.validationCode ?? STRIPE_CHECKOUT_VALIDATION_CODES.unclassified } : {}),
|
|
68
|
-
gate_state: this.state, disposition: error instanceof StripeCheckoutClaimConflictError ? 'active_claim_preserved' : 'checkout_stopped' };
|
|
69
|
-
}
|
|
70
|
-
assertClaim(step) {
|
|
71
|
-
if (this.state !== (step.phase === 'tokenization' ? 'stubbed' : 'submitted'))
|
|
72
|
-
throw new StripeCheckoutRejectionError('Native Stripe Checkout preparation is unavailable.', 'claim', 'claim_invalidated', step.phase);
|
|
73
|
-
}
|
|
74
|
-
/** Check the actual top-level hosted document before preparing either step. */
|
|
75
|
-
assertDocument(raw) {
|
|
76
|
-
if (!this.binding)
|
|
77
|
-
return;
|
|
78
|
-
const url = new URL(raw);
|
|
79
|
-
if (url.origin !== 'https://checkout.stripe.com' || url.username || url.password
|
|
80
|
-
|| ![`/c/pay/${this.binding.sessionId}`, `/pay/${this.binding.sessionId}`, `/g/pay/${this.binding.sessionId}`, `/f/pay/${this.binding.sessionId}`].includes(url.pathname)) {
|
|
81
|
-
this.invalidate();
|
|
82
|
-
throw new StripeCheckoutRejectionError('Native Stripe Checkout document changed.', 'document', 'document_changed');
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
claim(request) {
|
|
86
|
-
if (!this.binding)
|
|
87
|
-
return null;
|
|
88
|
-
if (request.method.toUpperCase() !== 'POST')
|
|
89
|
-
return null;
|
|
90
|
-
let phase;
|
|
91
|
-
try {
|
|
92
|
-
phase = classifyStripeCheckoutRequest(request, this.binding);
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
throw new StripeCheckoutRejectionError('stripe_checkout_rejected', 'classification', 'request_validation_failed', 'unknown', stripeCheckoutValidationCode(error));
|
|
96
|
-
}
|
|
97
|
-
if (!phase)
|
|
98
|
-
return null;
|
|
99
|
-
const diagnosticPhase = phase.phase === 'tokenization' ? 'tokenization' : phase.phase === 'final' ? 'final' : 'unknown';
|
|
100
|
-
if (Object.keys(request.headers).some(name => name.toLowerCase() === STRIPE_CHECKOUT_CONTEXT_HEADER))
|
|
101
|
-
throw new StripeCheckoutRejectionError('Native Stripe Checkout already carries a context.', 'claim', 'context_already_present', diagnosticPhase);
|
|
102
|
-
if (phase.phase === 'tokenization') {
|
|
103
|
-
if (this.state === 'stubbed' || this.state === 'submitted')
|
|
104
|
-
throw new StripeCheckoutClaimConflictError('tokenization');
|
|
105
|
-
if (this.state !== 'fresh')
|
|
106
|
-
throw new StripeCheckoutRejectionError('Native Stripe Checkout preparation is unavailable.', 'claim', 'preparation_unavailable', 'tokenization');
|
|
107
|
-
this.state = 'stopped';
|
|
108
|
-
let response;
|
|
109
|
-
try {
|
|
110
|
-
this.billing = captureStripeCheckoutBilling(request, this.binding);
|
|
111
|
-
response = createStripeCheckoutTokenizationStub(request, this.binding);
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
const code = stripeCheckoutValidationCode(error);
|
|
115
|
-
if (code !== STRIPE_CHECKOUT_VALIDATION_CODES.unclassified)
|
|
116
|
-
throw new StripeCheckoutRejectionError('stripe_checkout_rejected', 'classification', 'request_validation_failed', 'tokenization', code);
|
|
117
|
-
throw new StripeCheckoutRejectionError('stripe_checkout_rejected', 'stub_response', 'stub_response_failed', 'tokenization');
|
|
118
|
-
}
|
|
119
|
-
this.state = 'stubbed';
|
|
120
|
-
return { phase: 'tokenization', response };
|
|
121
|
-
}
|
|
122
|
-
if (phase.phase === 'final' && this.state === 'submitted')
|
|
123
|
-
throw new StripeCheckoutClaimConflictError('final');
|
|
124
|
-
if (phase.phase !== 'final' || this.state !== 'stubbed')
|
|
125
|
-
throw new StripeCheckoutRejectionError('Native Stripe Checkout has no matching prepared request.', 'claim', 'preparation_missing', diagnosticPhase);
|
|
126
|
-
let final;
|
|
127
|
-
try {
|
|
128
|
-
final = attachStripeCheckoutBilling(request, this.billing, this.binding);
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
this.invalidate();
|
|
132
|
-
throw new StripeCheckoutRejectionError('stripe_checkout_rejected', 'classification', 'request_validation_failed', 'final', stripeCheckoutValidationCode(error));
|
|
133
|
-
}
|
|
134
|
-
this.state = 'submitted';
|
|
135
|
-
this.billing = undefined;
|
|
136
|
-
return { phase: 'final', request: { ...final, headers: { ...final.headers,
|
|
137
|
-
[STRIPE_CHECKOUT_CONTEXT_HEADER]: encodeStripeCheckoutContext({ version: 1,
|
|
138
|
-
session_id: this.binding.sessionId, synthetic_payment_method_id: this.binding.syntheticPaymentMethodId }) } } };
|
|
139
|
-
}
|
|
140
|
-
}
|
package/dist/substitute.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The cse half of a replay: put the vault's ciphertext into the paused body.
|
|
3
|
-
*
|
|
4
|
-
* On a client-side-encrypted processor (Adyen) the cardholder's device does
|
|
5
|
-
* not call the processor. It encrypts the card under the processor's public
|
|
6
|
-
* key and reports the ciphertext; the paused request then continues from the
|
|
7
|
-
* agent's own browser with those blobs in place of the dummy ones. Everything
|
|
8
|
-
* else in the body (session data, risk data, browser info, origin) stays the
|
|
9
|
-
* browser's own, so the processor's origin allowlist and risk checks see the
|
|
10
|
-
* request they expected.
|
|
11
|
-
*
|
|
12
|
-
* Deliberately narrow: only keys that ALREADY exist as strings at the named
|
|
13
|
-
* path are overwritten. A key is never added, a sibling is touched only when
|
|
14
|
-
* the API names it in `remove` (Adyen's `brand`, which adyen-web derived from
|
|
15
|
-
* the dummy digits the agent typed: left in place it describes the wrong card
|
|
16
|
-
* and Adyen refuses the mismatch), and a body that does not carry the fields
|
|
17
|
-
* is refused rather than guessed at.
|
|
18
|
-
*/
|
|
19
|
-
export interface Substitutions {
|
|
20
|
-
encoding: 'json';
|
|
21
|
-
/** Dotted path to the object that holds the fields, e.g. `paymentMethod`. */
|
|
22
|
-
at: string;
|
|
23
|
-
/** Field name -> ciphertext, exactly as the vault reported it. */
|
|
24
|
-
fields: Record<string, string>;
|
|
25
|
-
/**
|
|
26
|
-
* Sibling keys at `at` to delete when present (never an error when absent):
|
|
27
|
-
* values the page SDK derived from the agent's dummy card that would
|
|
28
|
-
* contradict the swapped ciphertext. Served by the API per processor.
|
|
29
|
-
*/
|
|
30
|
-
remove?: string[];
|
|
31
|
-
}
|
|
32
|
-
declare class SubstitutionErrorShape extends Error {
|
|
33
|
-
constructor(message: string);
|
|
34
|
-
}
|
|
35
|
-
export type SubstitutionError = SubstitutionErrorShape;
|
|
36
|
-
export declare const SubstitutionError: typeof SubstitutionErrorShape;
|
|
37
|
-
export declare const substituteEncryptedFields: (body: string, sub: Substitutions) => string;
|
|
38
|
-
export {};
|
package/dist/substitute.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The cse half of a replay: put the vault's ciphertext into the paused body.
|
|
3
|
-
*
|
|
4
|
-
* On a client-side-encrypted processor (Adyen) the cardholder's device does
|
|
5
|
-
* not call the processor. It encrypts the card under the processor's public
|
|
6
|
-
* key and reports the ciphertext; the paused request then continues from the
|
|
7
|
-
* agent's own browser with those blobs in place of the dummy ones. Everything
|
|
8
|
-
* else in the body (session data, risk data, browser info, origin) stays the
|
|
9
|
-
* browser's own, so the processor's origin allowlist and risk checks see the
|
|
10
|
-
* request they expected.
|
|
11
|
-
*
|
|
12
|
-
* Deliberately narrow: only keys that ALREADY exist as strings at the named
|
|
13
|
-
* path are overwritten. A key is never added, a sibling is touched only when
|
|
14
|
-
* the API names it in `remove` (Adyen's `brand`, which adyen-web derived from
|
|
15
|
-
* the dummy digits the agent typed: left in place it describes the wrong card
|
|
16
|
-
* and Adyen refuses the mismatch), and a body that does not carry the fields
|
|
17
|
-
* is refused rather than guessed at.
|
|
18
|
-
*/
|
|
19
|
-
// The implementation is bundled from the internal core; the published SDK
|
|
20
|
-
// keeps its existing public types and does not require another package at runtime.
|
|
21
|
-
import { substituteEncryptedFields as sharedSubstitute, SubstitutionError as SharedSubstitutionError, } from './substitutions.generated.js';
|
|
22
|
-
export const SubstitutionError = SharedSubstitutionError;
|
|
23
|
-
export const substituteEncryptedFields = sharedSubstitute;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
declare var SubstitutionError: {
|
|
2
|
-
new (message: any): {
|
|
3
|
-
name: string;
|
|
4
|
-
message: string;
|
|
5
|
-
stack?: string;
|
|
6
|
-
cause?: unknown;
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
declare function substituteEncryptedFields(body: any, sub: any): string;
|
|
10
|
-
declare function substituteMerchantHosted(body: any, sub: any, opts: any): string;
|
|
11
|
-
export { SubstitutionError, substituteEncryptedFields, substituteMerchantHosted };
|