@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.
Files changed (106) hide show
  1. package/README.md +6 -753
  2. package/cdp.d.ts +1 -0
  3. package/cdp.js +2 -0
  4. package/index.d.ts +1 -0
  5. package/index.js +2 -0
  6. package/package.json +33 -33
  7. package/playwright.d.ts +1 -0
  8. package/playwright.js +2 -0
  9. package/preflight.d.ts +1 -0
  10. package/preflight.js +2 -0
  11. package/CHANGELOG.md +0 -132
  12. package/PREFLIGHT.md +0 -312
  13. package/dist/adyen-merchant-hosted.generated.d.ts +0 -277
  14. package/dist/adyen-merchant-hosted.generated.js +0 -1902
  15. package/dist/adyen.generated.d.ts +0 -24
  16. package/dist/adyen.generated.js +0 -64
  17. package/dist/attachment.d.ts +0 -11
  18. package/dist/attachment.js +0 -50
  19. package/dist/braintree.d.ts +0 -2
  20. package/dist/braintree.generated.d.ts +0 -10
  21. package/dist/braintree.generated.js +0 -302
  22. package/dist/braintree.js +0 -2
  23. package/dist/builtin-registry.generated.d.ts +0 -2
  24. package/dist/builtin-registry.generated.js +0 -1
  25. package/dist/card-fields.generated.d.ts +0 -3
  26. package/dist/card-fields.generated.js +0 -46
  27. package/dist/cdp.d.ts +0 -192
  28. package/dist/cdp.js +0 -2393
  29. package/dist/checkout-com.generated.d.ts +0 -4
  30. package/dist/checkout-com.generated.js +0 -183
  31. package/dist/client.d.ts +0 -849
  32. package/dist/client.js +0 -1754
  33. package/dist/cse-body.d.ts +0 -25
  34. package/dist/cse-body.js +0 -41
  35. package/dist/fiserv.d.ts +0 -65
  36. package/dist/fiserv.generated.d.ts +0 -73
  37. package/dist/fiserv.generated.js +0 -830
  38. package/dist/fiserv.js +0 -104
  39. package/dist/hosted-form.d.ts +0 -44
  40. package/dist/hosted-form.js +0 -78
  41. package/dist/index.d.ts +0 -18
  42. package/dist/index.js +0 -10
  43. package/dist/lifecycle.d.ts +0 -179
  44. package/dist/lifecycle.js +0 -395
  45. package/dist/mercado-checkout.d.ts +0 -20
  46. package/dist/mercado-checkout.generated.d.ts +0 -52
  47. package/dist/mercado-checkout.generated.js +0 -198
  48. package/dist/mercado-checkout.js +0 -108
  49. package/dist/merchant-handoff.d.ts +0 -54
  50. package/dist/merchant-handoff.js +0 -100
  51. package/dist/merchant-hosted.d.ts +0 -140
  52. package/dist/merchant-hosted.js +0 -170
  53. package/dist/merchant-total-watch.d.ts +0 -115
  54. package/dist/merchant-total-watch.js +0 -268
  55. package/dist/merchant-total.d.ts +0 -257
  56. package/dist/merchant-total.js +0 -383
  57. package/dist/owned-shop.generated.d.ts +0 -24
  58. package/dist/owned-shop.generated.js +0 -108
  59. package/dist/paysafe.generated.d.ts +0 -12
  60. package/dist/paysafe.generated.js +0 -87
  61. package/dist/playwright.d.ts +0 -3
  62. package/dist/playwright.js +0 -3
  63. package/dist/pre-claim.d.ts +0 -123
  64. package/dist/pre-claim.js +0 -386
  65. package/dist/preflight-capabilities.generated.d.ts +0 -1253
  66. package/dist/preflight-capabilities.generated.js +0 -1929
  67. package/dist/preflight-catalog.json +0 -4727
  68. package/dist/preflight-playwright.d.ts +0 -34
  69. package/dist/preflight-playwright.js +0 -355
  70. package/dist/preflight-schemas.json +0 -1122
  71. package/dist/preflight.d.ts +0 -1
  72. package/dist/preflight.generated.d.ts +0 -1965
  73. package/dist/preflight.generated.js +0 -570
  74. package/dist/preflight.js +0 -2
  75. package/dist/preparation.d.ts +0 -38
  76. package/dist/preparation.js +0 -191
  77. package/dist/prepared-processor.d.ts +0 -43
  78. package/dist/prepared-processor.js +0 -172
  79. package/dist/recurly.generated.d.ts +0 -1
  80. package/dist/recurly.generated.js +0 -87
  81. package/dist/registry.d.ts +0 -121
  82. package/dist/registry.js +0 -310
  83. package/dist/spreedly.generated.d.ts +0 -10
  84. package/dist/spreedly.generated.js +0 -332
  85. package/dist/stripe-checkout.d.ts +0 -81
  86. package/dist/stripe-checkout.generated.d.ts +0 -82
  87. package/dist/stripe-checkout.generated.js +0 -1093
  88. package/dist/stripe-checkout.js +0 -140
  89. package/dist/substitute.d.ts +0 -38
  90. package/dist/substitute.js +0 -23
  91. package/dist/substitutions.generated.d.ts +0 -11
  92. package/dist/substitutions.generated.js +0 -818
  93. package/examples/existing-browser.mjs +0 -63
  94. package/examples/preflight/classify-direct.mjs +0 -21
  95. package/examples/preflight/classify-kernel.mjs +0 -30
  96. package/examples/preflight/inspect-browser.mjs +0 -44
  97. package/examples/preflight/kernel-native/README.md +0 -112
  98. package/examples/preflight/kernel-native/documented-adapters.json +0 -113
  99. package/examples/preflight/kernel-native/inventory.json +0 -233
  100. package/examples/preflight/kernel-native/qualification.mjs +0 -182
  101. package/examples/preflight/kernel-profile.empty.json +0 -11
  102. package/examples/preflight/mollie-hosted.observations.json +0 -23
  103. package/examples/preflight/mollie-hosted.result.json +0 -103
  104. package/examples/preflight/stripe-script.direct.result.json +0 -92
  105. package/examples/preflight/stripe-script.observations.json +0 -16
  106. package/examples/preflight/stripe-script.result.json +0 -87
package/dist/lifecycle.js DELETED
@@ -1,395 +0,0 @@
1
- import { AdyenTestPlatformRefusedError, ApprovalDeclinedError, ApprovalTimeoutError, CheckoutCancelledError, CheckoutPreparationError, IntentNotConfirmableError, PaymentOutcomeUnknownError, ProcessorRefusedError } from './client.js';
2
- import { parseOwnedShopReceipt, OWNED_SHOP_SKU, OWNED_SHOP_AMOUNT_CENTS, OWNED_SHOP_CURRENCY } from './owned-shop.generated.js';
3
- /** How many times one approval's card-free Stripe confirmation may be checked before it is simply held. */
4
- export const MAX_STRIPE_CONTINUATION_CHECKS = 3;
5
- /** Shared by the raw CDP and Playwright transports. No browser ownership or payment execution lives here. */
6
- export class CheckoutLifecycle {
7
- options;
8
- state = { status: 'idle', authorizationId: null };
9
- held = false;
10
- active = false;
11
- cancelled = false;
12
- merchantAborted = false;
13
- unboundStripeToken = false;
14
- // The page's own confirmation paying with that token: see claimStripeContinuation.
15
- stripeTokenPrepared = false;
16
- stripeContinuation = 'none';
17
- stripeContinuationChecks = 0;
18
- ownedShopOrderId = null;
19
- reconciliation = null;
20
- preparationHandler;
21
- preparationUsed = false;
22
- abort = new AbortController();
23
- constructor(options) {
24
- this.options = options;
25
- }
26
- getState() {
27
- return { ...this.state, ...(this.state.confirmation ? { confirmation: { ...this.state.confirmation } } : {}) };
28
- }
29
- setPreparationHandler(handler) { this.preparationHandler = handler; }
30
- prepare(options) {
31
- if (!this.preparationHandler)
32
- return Promise.reject(new CheckoutPreparationError(null, 'transport_unavailable'));
33
- return this.preparationHandler(options);
34
- }
35
- preparing() {
36
- this.preparationUsed = true;
37
- this.set({ status: 'awaiting_approval', authorizationId: null });
38
- }
39
- preparationCreated(preparationId) { this.set({ ...this.state, preparationId }); }
40
- prepared(preparation) {
41
- this.set({ status: 'ready_to_submit', authorizationId: null, preparationId: preparation.id });
42
- }
43
- preparationFailed(error) {
44
- this.held = true;
45
- if (this.cancelled)
46
- return;
47
- this.set({ ...this.state, status: error.reason === 'expired' ? 'timed_out' : error.reason === 'cancelled' ? 'cancelled' : 'failed', reason: error.reason });
48
- }
49
- isBlocked() { return this.held || this.cancelled; }
50
- isCancelled() { return this.cancelled; }
51
- begin() {
52
- this.active = true;
53
- this.set({ status: 'awaiting_approval', authorizationId: null, ...(this.state.preparationId ? { preparationId: this.state.preparationId } : {}) });
54
- }
55
- end() { this.active = false; }
56
- set(state) {
57
- this.state = state;
58
- // Application telemetry must never interrupt a paused payment after it reaches the processor.
59
- try {
60
- Promise.resolve(this.options.onStateChange?.(this.getState())).catch(() => { });
61
- }
62
- catch { /* observer only */ }
63
- }
64
- approvalCreated(authorizationId) {
65
- this.set({ ...this.state, authorizationId });
66
- }
67
- approvalUrl(approvalUrl) {
68
- this.notify({ reason: 'approval', authorizationId: this.state.authorizationId, approvalUrl });
69
- }
70
- notify(action) {
71
- try {
72
- Promise.resolve(this.options.onUserAction?.(action)).catch(() => { });
73
- }
74
- catch { /* observer only */ }
75
- }
76
- cancel() {
77
- this.cancelled = true;
78
- this.held = true;
79
- this.abort.abort();
80
- this.set({ ...this.state, status: this.active || this.state.authorizationId ? 'outcome_unknown' : 'cancelled', reason: 'local_cancel' });
81
- }
82
- /** The exact browser request is gone; a late approval cannot reopen it. */
83
- merchantRequestAborted() {
84
- this.merchantAborted = true;
85
- this.held = true;
86
- this.set({ ...this.state, status: 'outcome_unknown', reason: 'merchant_request_aborted' });
87
- }
88
- /**
89
- * The page abandoned its card request (its own script timed out) while
90
- * the cardholder is still deciding. The approval stays pending and the
91
- * page's next matching request will be answered from it, so the status
92
- * stays `awaiting_approval`; the reason says the page has to ask again.
93
- * Not a hold: nothing is refused, and no card or token has moved.
94
- */
95
- merchantRequestLost() {
96
- this.set({ ...this.state, reason: 'merchant_request_lost' });
97
- }
98
- /**
99
- * The cardholder approved, and there is no live page request to hand the
100
- * answer to: the page gave up on its own request while they decided.
101
- * `ready_to_submit` is the state a prepared checkout uses for "consent in
102
- * hand, click Pay": the application's next Pay action produces the request
103
- * this approval answers, with no second prompt on the phone.
104
- */
105
- awaitingMerchantRetry(authorizationId) {
106
- this.set({ status: 'ready_to_submit', authorizationId, reason: 'awaiting_merchant_retry',
107
- ...(this.state.preparationId ? { preparationId: this.state.preparationId } : {}) });
108
- }
109
- /**
110
- * The page never asked again inside the retry wait and the API confirmed
111
- * the approval is retired: `declined`, like any other approval that ended
112
- * with nothing charged, and not held, because the next card request is a
113
- * new question (the cardholder is told to ask their agent to try again).
114
- * A retirement the API refused or did not confirm is an unknown outcome and
115
- * is reported through failed() instead, which holds.
116
- */
117
- merchantNeverRetried(authorizationId) {
118
- if (this.cancelled)
119
- return;
120
- this.set({ ...this.state, authorizationId, status: 'declined', reason: 'merchant_never_retried' });
121
- }
122
- /**
123
- * A card request this SDK cannot pay was aborted. `reason`: an unrecognized
124
- * declared payment endpoint (the default), a merchant profile Agentcard has not
125
- * turned on (merchant_profile_observe), or a card request the profile cannot
126
- * finish (merchant_request_unsupported).
127
- */
128
- unsupported(reason = 'unrecognized_payment_endpoint') {
129
- this.held = true;
130
- if (this.state.authorizationId)
131
- return; // do not hide an outstanding/completed payment behind a later unsupported request
132
- this.set({ ...this.state, status: 'unsupported', reason });
133
- }
134
- /**
135
- * A card request that only a prepared checkout pays (an Adyen merchant
136
- * profile's, or a Fiserv card capture) arrived with no preparation on this
137
- * attachment and was aborted before any pause, prompt or authorization.
138
- * Nothing is outstanding, so nothing is held; prepare() stays refused here, as
139
- * after any first card request.
140
- */
141
- preparationRequired() {
142
- if (this.cancelled || this.state.authorizationId)
143
- return;
144
- this.set({ ...this.state, status: 'failed', reason: 'preparation_required' });
145
- }
146
- prepareHandoff(replay, requestUrl) {
147
- if (replay.mode === 'token' && replay.executionMode === 'autopilot' && replay.shopOrderId) {
148
- let receipt;
149
- try {
150
- receipt = parseOwnedShopReceipt(JSON.parse(replay.body), {
151
- order_id: replay.shopOrderId, sku: OWNED_SHOP_SKU, amount: OWNED_SHOP_AMOUNT_CENTS, currency: OWNED_SHOP_CURRENCY,
152
- });
153
- }
154
- catch { /* An unrecognized response remains subject to the token continuation guard. */ }
155
- if (receipt) {
156
- this.ownedShopOrderId = receipt.order_id;
157
- this.held = true;
158
- return;
159
- }
160
- }
161
- // A tokenization approval has no authoritative PaymentIntent or amount
162
- // binding. Neither the first observed confirm nor the returned opaque
163
- // token can supply one. Hold even in compatibility mode: this attachment
164
- // must never turn that token into an unreviewed payment continuation.
165
- if (!replay.mode || replay.mode === 'token') {
166
- try {
167
- const url = new URL(requestUrl);
168
- if (url.origin === 'https://api.stripe.com' && ['/v1/payment_methods', '/v1/tokens', '/v1/sources', '/v1/confirmation_tokens'].includes(url.pathname)) {
169
- // Set before delivery: a lost browser acknowledgement must not reset
170
- // an already-issued token into a retryable authorization.
171
- this.unboundStripeToken = true;
172
- this.stripeTokenPrepared = true;
173
- this.held = true;
174
- }
175
- }
176
- catch { /* unknown URL cannot establish a token binding */ }
177
- }
178
- }
179
- /**
180
- * The approval a page's card-free Stripe confirmation may continue, or null.
181
- * Only once a Stripe tokenization is being handed to the page, and while
182
- * the checkout still awaits it (the page can send its confirmation before
183
- * the browser acknowledges the delivery) or the merchant; for one check at
184
- * a time and at most MAX_STRIPE_CONTINUATION_CHECKS checks. Reserves the check synchronously,
185
- * so two confirmations can never both continue: the caller settles it with
186
- * stripeContinuationChecked(). The hold stays on throughout.
187
- */
188
- claimStripeContinuation() {
189
- if (!this.stripeContinuationOpen() || this.stripeContinuation !== 'none'
190
- || this.stripeContinuationChecks >= MAX_STRIPE_CONTINUATION_CHECKS)
191
- return null;
192
- this.stripeContinuation = 'checking';
193
- this.stripeContinuationChecks++;
194
- return this.state.authorizationId;
195
- }
196
- /**
197
- * Settle a claimed check. True only when the API allowed it and the checkout
198
- * still awaits the merchant (nothing cancelled, aborted or reconciled it
199
- * while the API answered): the page's confirmation continues, and no later
200
- * one will.
201
- */
202
- stripeContinuationChecked(allowed) {
203
- if (this.stripeContinuation !== 'checking')
204
- return false;
205
- const proceed = allowed && this.stripeContinuationOpen();
206
- this.stripeContinuation = proceed ? 'continued' : 'none';
207
- if (proceed)
208
- this.set({ ...this.state, reason: 'stripe_payment_continued' });
209
- return proceed;
210
- }
211
- stripeContinuationOpen() {
212
- return this.stripeTokenPrepared && !this.cancelled && !this.merchantAborted && !!this.state.authorizationId
213
- && (this.state.status === 'awaiting_approval' || this.state.status === 'awaiting_merchant');
214
- }
215
- handedOff(replay) {
216
- if (this.merchantAborted)
217
- return;
218
- if (this.ownedShopOrderId) {
219
- this.held = true;
220
- this.set({ status: 'completed', authorizationId: replay.authorizationId, mode: 'token', orderId: this.ownedShopOrderId });
221
- return;
222
- }
223
- const mismatch = (!replay.mode || replay.mode === 'token') && replay.amountVerified === false;
224
- this.held = !!this.options.requireMerchantResult || replay.mode === 'hosted_form' || mismatch || this.unboundStripeToken;
225
- if (mismatch)
226
- this.stripeTokenPrepared = false;
227
- this.set({ status: 'awaiting_merchant', authorizationId: replay.authorizationId, mode: replay.mode ?? 'token',
228
- ...(this.state.preparationId ? { preparationId: this.state.preparationId } : {}),
229
- ...(mismatch ? { reason: 'charged_amount_mismatch' }
230
- : this.stripeContinuation === 'continued' ? { reason: 'stripe_payment_continued' }
231
- : this.unboundStripeToken ? { reason: 'stripe_tokenization_unbound' } : {}) });
232
- }
233
- failed(error, handoffStarted = false) {
234
- if (this.cancelled)
235
- return;
236
- if (this.merchantAborted) {
237
- this.merchantRequestAborted();
238
- return;
239
- }
240
- const authorizationId = error instanceof PaymentOutcomeUnknownError || error instanceof ProcessorRefusedError ? error.authorizationId : this.state.authorizationId;
241
- if (!handoffStarted && error instanceof PaymentOutcomeUnknownError && error.reason === 'autopilot_action_required') {
242
- this.held = true;
243
- this.set({ ...this.state, authorizationId, status: 'requires_user_action', reason: 'other' });
244
- this.notify({ reason: 'other', authorizationId });
245
- }
246
- else if (handoffStarted || error instanceof PaymentOutcomeUnknownError || error instanceof IntentNotConfirmableError) {
247
- this.held = true;
248
- this.set({ ...this.state, authorizationId, status: 'outcome_unknown', reason: error instanceof PaymentOutcomeUnknownError ? error.reason : error instanceof IntentNotConfirmableError ? 'intent_not_confirmable' : 'browser_handoff_failed' });
249
- }
250
- else if (error instanceof CheckoutCancelledError) {
251
- this.cancel();
252
- }
253
- else if (error instanceof CheckoutPreparationError) {
254
- this.preparationFailed(error);
255
- }
256
- else if (error instanceof ApprovalTimeoutError) {
257
- this.set({ ...this.state, status: 'timed_out', reason: 'approval_expired' });
258
- }
259
- else if (error instanceof ProcessorRefusedError) {
260
- // A rejected processor request is not proof that the merchant cannot
261
- // collect this payment. Keep native retries held until the application
262
- // checks the merchant and explicitly starts another attempt.
263
- this.held = true;
264
- this.set({ ...this.state, authorizationId, status: 'declined', reason: 'processor_refused' });
265
- }
266
- else if (error instanceof AdyenTestPlatformRefusedError) {
267
- // Agentcard's own rule, not a person's answer: refused at create before
268
- // anyone was asked, the checkout failed as it did before the error was
269
- // typed; declined before the card was sent, the authorization is declined.
270
- // Either way the reason names the rule.
271
- this.set({ ...this.state, status: error.stage === 'create' ? 'failed' : 'declined', reason: error.code });
272
- }
273
- else if (error instanceof ApprovalDeclinedError) {
274
- this.set({ ...this.state, status: 'declined', reason: 'approval_declined' });
275
- }
276
- else {
277
- this.set({ ...this.state, status: 'failed', reason: 'checkout_failed' });
278
- }
279
- }
280
- async requestUserAction(reason) {
281
- if (this.state.status === 'completed')
282
- return;
283
- this.held = true;
284
- this.set({ ...this.state, status: 'requires_user_action', reason });
285
- // Hooks deliver a link/live view owned by the integrator; the SDK does not invent challenge URLs.
286
- try {
287
- await this.options.onUserAction?.({ reason, authorizationId: this.state.authorizationId });
288
- }
289
- catch { /* observer only */ }
290
- }
291
- reconcile() {
292
- if (this.state.status === 'completed')
293
- return Promise.resolve(this.getState());
294
- if (this.reconciliation)
295
- return this.reconciliation;
296
- if (!this.options.resolveMerchantResult)
297
- return Promise.resolve(this.getState());
298
- if (this.active)
299
- throw new Error('Wait for the paused request to finish before reconciling the merchant order.');
300
- this.reconciliation = this.resolve().finally(() => { this.reconciliation = null; });
301
- return this.reconciliation;
302
- }
303
- async resolve() {
304
- let result;
305
- try {
306
- result = await this.options.resolveMerchantResult(this.getState());
307
- }
308
- catch {
309
- result = { status: 'unknown' };
310
- }
311
- if (!result || typeof result !== 'object' || Array.isArray(result))
312
- result = { status: 'unknown' };
313
- // The resolver is trusted application code: it must check the original
314
- // request, amount, currency, selected card and authoritative merchant
315
- // result. The SDK binds its explicit confirmation to this authorization;
316
- // it does not turn an HTTP response or a success URL into payment proof.
317
- const orderConfirmed = result.status === 'completed' && result.confirmation === undefined
318
- && typeof result.orderId === 'string' && result.orderId.length > 0;
319
- const paymentConfirmed = result.status === 'completed' && result.orderId === undefined
320
- && result.confirmation && typeof result.confirmation === 'object' && !Array.isArray(result.confirmation)
321
- && result.confirmation.kind === 'merchant_payment'
322
- && typeof this.state.authorizationId === 'string' && this.state.authorizationId.length > 0
323
- && result.confirmation.authorizationId === this.state.authorizationId;
324
- if (result.status === 'completed' && (orderConfirmed || paymentConfirmed)) {
325
- this.held = true;
326
- // Completion supersedes an earlier failure/challenge, while retaining
327
- // preparation and authorization context. Never copy arbitrary evidence
328
- // into public state or release the hold on additional payment requests.
329
- const { reason: _previousReason, orderId: _previousOrder, confirmation: _previousConfirmation, ...context } = this.state;
330
- this.set({ ...context, status: 'completed', ...(orderConfirmed
331
- ? { orderId: result.orderId }
332
- : { confirmation: { kind: 'merchant_payment', authorizationId: this.state.authorizationId } }) });
333
- }
334
- else if (result.status === 'failed') {
335
- // Keep the guard armed until the application deliberately starts another attempt.
336
- this.held = true;
337
- this.set({ ...this.state, status: 'failed', reason: 'merchant_confirmed_failure' });
338
- }
339
- else if (result.status === 'requires_user_action') {
340
- await this.requestUserAction(result.reason);
341
- }
342
- else {
343
- this.held = true;
344
- this.set({ ...this.state, status: result.status === 'pending' ? 'awaiting_merchant' : 'outcome_unknown', reason: 'merchant_not_confirmed' });
345
- }
346
- return this.getState();
347
- }
348
- retryAfterMerchantFailure(result) {
349
- if (this.ownedShopOrderId)
350
- throw new Error('This shop payment already has a receipt; another payment is not permitted.');
351
- if (this.preparationUsed)
352
- throw new Error('Prepared checkouts are single use. Reconcile this attempt and create a new attachment.');
353
- if (this.active || this.reconciliation)
354
- throw new Error('Cannot start another attempt while payment or reconciliation is in progress.');
355
- if (this.cancelled)
356
- throw new Error('This attachment was cancelled; attach again after reconciling the merchant order.');
357
- if (result?.status !== 'failed')
358
- throw new Error('A merchant-confirmed failure is required before retrying.');
359
- if (this.state.status === 'completed')
360
- throw new Error('This order is already complete. Use a new attachment for another order.');
361
- if (this.unboundStripeToken)
362
- throw new Error('This attachment delivered an unbound Stripe token; reconcile the merchant order and use a separately validated checkout flow.');
363
- this.held = false;
364
- this.merchantAborted = false;
365
- this.set({ status: 'idle', authorizationId: null });
366
- }
367
- }
368
- export function paymentEndpointGuards(input = []) {
369
- const guards = input.map((guard) => {
370
- const origin = new URL(guard.origin);
371
- if (!['http:', 'https:'].includes(origin.protocol) || origin.origin !== guard.origin
372
- || !guard.pathname.startsWith('/') || /[?#*]/.test(guard.pathname)) {
373
- throw new Error('Payment endpoint guards require a canonical http(s) origin and an exact path without wildcards or query strings.');
374
- }
375
- const methods = (guard.methods ?? ['POST', 'PUT', 'PATCH']).map((method) => method.toUpperCase());
376
- if (!methods.length || methods.some((method) => !['POST', 'PUT', 'PATCH', 'DELETE'].includes(method))) {
377
- throw new Error('Payment endpoint guards can only block explicit mutation methods.');
378
- }
379
- return { ...guard, methods };
380
- });
381
- return {
382
- patterns: guards.map((guard) => `${guard.origin}${guard.pathname}*`),
383
- matches(raw, method) {
384
- let url;
385
- try {
386
- url = new URL(raw);
387
- }
388
- catch {
389
- return false;
390
- }
391
- return guards.some((guard) => url.origin === guard.origin && url.pathname === guard.pathname
392
- && (method === undefined || guard.methods.includes(method.toUpperCase())));
393
- },
394
- };
395
- }
@@ -1,20 +0,0 @@
1
- import type { ReplayResponse } from './client.js';
2
- /** Capture only the native Checkout Pro configuration. A late configuration,
3
- * navigation or repeated token cannot replace the context of an issued token.
4
- * Final payment requests retain the attachment's existing payment guards.
5
- */
6
- export declare class MercadoCheckoutGate {
7
- private context;
8
- private started;
9
- private stopped;
10
- private sequence;
11
- private associatedFlow;
12
- private association;
13
- matches(url: string): boolean;
14
- requiresDocument(url: string, method: string): boolean;
15
- invalidate(): void;
16
- configuration(url: string, method: string, body: string, readDocument: () => Promise<string>): Promise<boolean>;
17
- claimToken(url: string, method: string, documentUrl: string): unknown;
18
- arm(replay: ReplayResponse, tokenUrl: string): Promise<void>;
19
- associationBody(url: string, method: string, body: string, documentUrl: string): string | undefined;
20
- }
@@ -1,52 +0,0 @@
1
- declare var MERCADO_CHECKOUT_ORIGIN: string;
2
- declare var MERCADO_CONFIGURATION_URL: string;
3
- declare var MERCADO_CHECKOUT_PATTERN: string;
4
- declare function mercadoCheckoutDocument(raw: any): {
5
- flowId: string;
6
- preferenceId: string | null;
7
- query: string;
8
- };
9
- declare function parseMercadoCheckoutContext(value: any): any;
10
- declare function captureMercadoCheckoutContext(url: any, method: any, body: any, documentUrl: any): any;
11
- declare function isMercadoTokenRequest(url: any, method: any): boolean;
12
- declare function mercadoDigest(value: any): Promise<string>;
13
- declare function mercadoContextDigest(context: any, tokenUrl: any): Promise<string>;
14
- declare function prepareMercadoConfiguration(context: any, card: any): {
15
- url: string;
16
- body: string;
17
- };
18
- declare function parseMercadoConfiguration(value: any): {
19
- paymentMethodId: any;
20
- paymentTypeId: any;
21
- paymentMethodName: any;
22
- issuerId: string;
23
- issuerName: any;
24
- };
25
- declare function createMercadoProcessorContext(configuration: any, context: any, tokenUrl: any, tokenBody: any): Promise<{
26
- paymentMethodId: any;
27
- paymentTypeId: any;
28
- paymentMethodName: any;
29
- issuerId: string;
30
- issuerName: any;
31
- version: number;
32
- psp: string;
33
- source: string;
34
- contextDigest: string;
35
- tokenDigest: string;
36
- }>;
37
- declare function validateMercadoProcessorContext(value: any, context: any, tokenUrl: any, tokenBody: any): Promise<any>;
38
- declare function createMercadoAssociationGate({ context, tokenUrl, tokenBody, processorContext }: {
39
- context: any;
40
- tokenUrl: any;
41
- tokenBody: any;
42
- processorContext: any;
43
- }): Promise<{
44
- take({ url, method, body, documentUrl }: {
45
- url: any;
46
- method: any;
47
- body: any;
48
- documentUrl: any;
49
- }): string;
50
- readonly claimed: boolean;
51
- }>;
52
- export { MERCADO_CHECKOUT_ORIGIN, MERCADO_CHECKOUT_PATTERN, MERCADO_CONFIGURATION_URL, captureMercadoCheckoutContext, createMercadoAssociationGate, createMercadoProcessorContext, isMercadoTokenRequest, mercadoCheckoutDocument, mercadoContextDigest, mercadoDigest, parseMercadoCheckoutContext, parseMercadoConfiguration, prepareMercadoConfiguration, validateMercadoProcessorContext };