@agent-cards/checkout 0.17.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/PREFLIGHT.md +4 -0
  3. package/README.md +106 -14
  4. package/dist/adyen-merchant-hosted.generated.d.ts +277 -0
  5. package/dist/adyen-merchant-hosted.generated.js +1902 -0
  6. package/dist/builtin-registry.generated.js +1 -1
  7. package/dist/card-fields.generated.d.ts +3 -0
  8. package/dist/card-fields.generated.js +46 -0
  9. package/dist/cdp.d.ts +6 -1
  10. package/dist/cdp.js +574 -220
  11. package/dist/client.d.ts +285 -5
  12. package/dist/client.js +590 -12
  13. package/dist/cse-body.d.ts +25 -0
  14. package/dist/cse-body.js +41 -0
  15. package/dist/fiserv.d.ts +65 -0
  16. package/dist/fiserv.generated.d.ts +73 -0
  17. package/dist/fiserv.generated.js +830 -0
  18. package/dist/fiserv.js +104 -0
  19. package/dist/index.d.ts +7 -2
  20. package/dist/index.js +5 -1
  21. package/dist/lifecycle.d.ts +38 -1
  22. package/dist/lifecycle.js +77 -5
  23. package/dist/merchant-handoff.d.ts +54 -0
  24. package/dist/merchant-handoff.js +100 -0
  25. package/dist/merchant-hosted.d.ts +140 -0
  26. package/dist/merchant-hosted.js +170 -0
  27. package/dist/merchant-total-watch.d.ts +115 -0
  28. package/dist/merchant-total-watch.js +268 -0
  29. package/dist/merchant-total.d.ts +257 -0
  30. package/dist/merchant-total.js +383 -0
  31. package/dist/pre-claim.d.ts +123 -0
  32. package/dist/pre-claim.js +386 -0
  33. package/dist/preflight-capabilities.generated.d.ts +1 -1
  34. package/dist/preflight-capabilities.generated.js +1 -1
  35. package/dist/preflight-catalog.json +133 -1
  36. package/dist/preflight-schemas.json +14 -2
  37. package/dist/preflight.generated.d.ts +1 -1
  38. package/dist/preflight.generated.js +15 -1
  39. package/dist/preparation.d.ts +13 -0
  40. package/dist/preparation.js +46 -9
  41. package/dist/prepared-processor.d.ts +36 -3
  42. package/dist/prepared-processor.js +53 -3
  43. package/dist/registry.d.ts +60 -0
  44. package/dist/registry.js +14 -0
  45. package/dist/stripe-checkout.generated.js +140 -20
  46. package/dist/substitutions.generated.d.ts +2 -1
  47. package/dist/substitutions.generated.js +758 -6
  48. package/examples/preflight/kernel-native/inventory.json +1 -1
  49. package/package.json +3 -3
package/dist/client.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { type CheckoutMode, type Recognizer } from './registry.js';
2
2
  import type { Substitutions } from './substitute.js';
3
+ import { type MerchantHostedSubstitutions, type MerchantProfile, type SandboxMerchantDeclaration } from './merchant-hosted.js';
4
+ import { type MerchantTotalApproved, type MerchantTotalCapture } from './merchant-total.js';
3
5
  import { type PreparationMode, type PreparationProcessor } from './prepared-processor.js';
4
6
  export interface PausedRequest {
5
7
  url: string;
@@ -15,6 +17,27 @@ export interface PausedRequest {
15
17
  * is never paused) and sent on every create.
16
18
  */
17
19
  export declare const SUPPORTED_MODES: readonly CheckoutMode[];
20
+ /**
21
+ * Registry features this SDK honours, asked for on syncRegistry next to the
22
+ * modes. `card_fields`: it reads a recognizer's cardFields and claims only a
23
+ * request whose body carries the card, so the API may serve it recognizers
24
+ * whose endpoints also run without a card. `checkout_sessions`: it lets a
25
+ * request the recognizer marks as routine without a card (passWithoutCard)
26
+ * through ahead of its holds, so the API may serve Stripe's Checkout Session
27
+ * confirm, which hosted Checkout sends after an approval.
28
+ */
29
+ export declare const SUPPORTED_REGISTRY_FEATURES: readonly string[];
30
+ /**
31
+ * Dark-launch capabilities this build can finish. Sent on syncRegistry as
32
+ * ?capabilities= so the API also serves the recognizers gated behind one of
33
+ * these. `fiserv_card_capture`: Fiserv Commerce Hub's Secure Data Capture card
34
+ * capture, which this build pauses and pays only through a prepared checkout
35
+ * (pre-claim.ts, fiserv.ts). The API serves Fiserv's recognizer only to a build
36
+ * that lists it and only for a company Agentcard turned Fiserv on for, so an older
37
+ * SDK never pauses a capture it cannot finish and no SDK pauses one for a company
38
+ * Fiserv is off for; the API also refuses a Fiserv payment for every such company.
39
+ */
40
+ export declare const SUPPORTED_CAPABILITIES: readonly string[];
18
41
  /**
19
42
  * What the amount on an authorization IS: held to a Stripe PaymentIntent
20
43
  * (read back at create and before the replay), the parked form's own sum
@@ -84,14 +107,52 @@ export interface TokenReplay extends ExecutionMetadata {
84
107
  * (substituteEncryptedFields) and let the request CONTINUE from the browser
85
108
  * that paused it, so its session data, risk data and cookies stay its own.
86
109
  * The processor's answer then reaches the page as it normally would; the
87
- * merchant's order state is where the outcome shows up.
110
+ * merchant's order state is where the outcome shows up. A Fiserv card capture
111
+ * (a prepared checkout only) carries its envelope at `source.encryptionData`:
112
+ * write it with substituteFiservEnvelope, never substituteEncryptedFields.
88
113
  */
89
114
  export interface CseReplay extends ExecutionMetadata {
90
115
  mode: 'cse';
116
+ /** Absent on a processor-hosted cse approval; see MerchantHostedReplay. */
117
+ kind?: undefined;
91
118
  authorizationId: string;
92
119
  substitutions: Substitutions;
93
120
  amountAuthority?: AmountAuthority;
94
121
  }
122
+ /**
123
+ * The cse flow at an Adyen merchant's OWN endpoint (a reviewed merchant
124
+ * profile, see merchant-hosted.ts): the cardholder's device encrypted the card
125
+ * under the key Agentcard reviewed for that merchant, and nothing was sent. The
126
+ * paused request continues from this browser with the ciphertext written where
127
+ * the profile holds it (substituteMerchantHostedBody), and only when the live
128
+ * body still hashes to `bodySha256`, the body the API checked at create. The
129
+ * merchant's server charges the card and answers its own page; its order state is
130
+ * the outcome. Only a prepared checkout pays one, never Autopilot.
131
+ */
132
+ export interface MerchantHostedReplay extends ExecutionMetadata {
133
+ mode: 'cse';
134
+ kind: 'merchant_hosted';
135
+ authorizationId: string;
136
+ /** The reviewed merchant profile the approval pays. */
137
+ profile: string;
138
+ substitutions: MerchantHostedSubstitutions;
139
+ /** SHA-256 (lowercase hex) of the paused body the API checked at create. */
140
+ bodySha256: string;
141
+ /** When the API stops serving this ciphertext, if it said. */
142
+ substitutionsExpiresAt: string | null;
143
+ /** Present when the approval pays this client's own sandbox declaration (VaultClientOptions.sandboxMerchants). */
144
+ sandboxDeclaration?: Readonly<{
145
+ endpoint: string;
146
+ clientKey: string;
147
+ }>;
148
+ /**
149
+ * The merchant's own total this approval was created at, when its profile is priced by
150
+ * one: the adapters read it again at release (merchantTotalAtRelease) and hold the card
151
+ * request unless it is still this amount, then report what the merchant says it charged.
152
+ */
153
+ merchantTotal?: MerchantTotalApproved;
154
+ amountAuthority?: AmountAuthority;
155
+ }
95
156
  /**
96
157
  * The hosted_form flow (Tranzila): the cardholder's device rebuilt the
97
158
  * processor's own form with the real card and submitted it itself, top-level,
@@ -121,11 +182,25 @@ export interface HostedFormReplay extends ExecutionMetadata {
121
182
  amountAuthority?: AmountAuthority;
122
183
  }
123
184
  /** What authorize() resolves with; branch on `mode` (absent means token). */
124
- export type ReplayResponse = TokenReplay | CseReplay | HostedFormReplay;
185
+ export type ReplayResponse = TokenReplay | CseReplay | MerchantHostedReplay | HostedFormReplay;
125
186
  export interface PrepareCheckoutOptions {
126
187
  psp: PreparationProcessor;
127
188
  /** The processor environment, independent of your Agentcard client's mode. */
128
189
  environment: 'production' | 'sandbox' | 'shared';
190
+ /**
191
+ * An Adyen merchant that takes the card on its own server: the id of the
192
+ * profile Agentcard reviewed for it (psp 'adyen'; the environment is the
193
+ * profile's). The profile must be enabled on this client (syncRegistry); its
194
+ * card request is then the one request this preparation pays.
195
+ *
196
+ * A Fiserv checkout (psp 'fiserv'): the id of the key Agentcard pinned for the
197
+ * merchant, `agentcard_sandbox` in the sandbox environment. Required for Fiserv,
198
+ * and refused for every processor but Adyen and Fiserv. The cardholder is asked to
199
+ * approve a payment to the merchant that key belongs to, so the checkout's `merchant`
200
+ * must be that merchant's name (`Agentcard sandbox` for `agentcard_sandbox`), and the
201
+ * one card capture this preparation pays must carry an envelope under that key.
202
+ */
203
+ merchantProfile?: string;
129
204
  signal?: AbortSignal;
130
205
  }
131
206
  export interface PrepareCheckoutInput extends PrepareCheckoutOptions {
@@ -161,6 +236,13 @@ export interface PreparedCheckout {
161
236
  readonly checkoutKey: string;
162
237
  readonly paymentStatus: 'not_started';
163
238
  readonly amountAuthority: 'agent';
239
+ /** The reviewed merchant profile this preparation pays, or the Fiserv key pin it pays under; absent for a processor-hosted checkout. */
240
+ readonly merchantProfile?: string;
241
+ /** The declared test endpoint and key this preparation pays instead of the profile's (VaultClientOptions.sandboxMerchants). */
242
+ readonly sandboxDeclaration?: Readonly<{
243
+ endpoint: string;
244
+ clientKey: string;
245
+ }>;
164
246
  }
165
247
  export declare class CheckoutPreparationError extends Error {
166
248
  preparationId: string | null;
@@ -199,6 +281,8 @@ export interface AuthorizeInput extends ExecutionMetadata {
199
281
  amount: number;
200
282
  currency: string;
201
283
  };
284
+ /** Milliseconds from the caller's pay click until the SDK caught the card request, measured on one clock. */
285
+ payToInterceptMs?: number;
202
286
  /**
203
287
  * WHICH stored card should pay — a vault card id from
204
288
  * GET /api/v2/vault_cards. The approval page preselects it (the human can
@@ -228,6 +312,13 @@ export interface AuthorizeInput extends ExecutionMetadata {
228
312
  onApprovalUrl?: (url: string) => void;
229
313
  /** One-use preparation returned by this client. Never resumes an older request. */
230
314
  preparation?: PreparedCheckout;
315
+ /**
316
+ * For a reviewed merchant profile priced by the merchant's own total: when the card
317
+ * request paused and the merchant responses this browser recorded (see
318
+ * merchant-total.ts). The adapters pass it; a runtime that intercepts on its own builds
319
+ * one from its network events, or the payment is refused before any create.
320
+ */
321
+ merchantTotal?: MerchantTotalCapture;
231
322
  }
232
323
  export declare class CardEncryptedError extends Error {
233
324
  psp: string;
@@ -242,6 +333,18 @@ export declare class UnsupportedModeError extends Error {
242
333
  mode: string;
243
334
  constructor(mode: string);
244
335
  }
336
+ /**
337
+ * The recognizer says this processor is preparation-required, and no preparation
338
+ * was passed. Its card may be sent only after the cardholder approved a
339
+ * prepare(): call prepareCheckout() (or the adapters' preparation gate) before
340
+ * this request is intercepted. Thrown locally before any create or prompt, and
341
+ * terminal (retrying the same paused request without preparing fails the same
342
+ * way). The API answers 409 preparation_required for the same case.
343
+ */
344
+ export declare class PreparationRequiredError extends Error {
345
+ psp: string;
346
+ constructor(psp: string);
347
+ }
245
348
  export declare class ApprovalTimeoutError extends Error {
246
349
  constructor(ms: number);
247
350
  }
@@ -276,13 +379,20 @@ export declare class ApprovalDeclinedError extends Error {
276
379
  * and quiet the page's retry exactly as for a person's "no"), so it extends
277
380
  * ApprovalDeclinedError: code that already handles declines keeps working,
278
381
  * and code that wants the numbers reads them here or branches on `code`.
382
+ *
383
+ * A merchant-hosted checkout (an Adyen merchant whose own server charges the card)
384
+ * has no processor read-back: its agent amount is held to the merchant's own
385
+ * checkout total, as the agent's browser read it, at stage 'create'. The SDK refuses
386
+ * that before any create, and the API refuses the same with 409 `amount_mismatch`, so a
387
+ * caller catches this one class either way; `amountSource` says whose number
388
+ * `actualCents` is, and the message names it.
279
389
  */
280
390
  export declare class AmountMismatchError extends ApprovalDeclinedError {
281
391
  /** The declined authorization, or null for a create-time refusal (no row exists). */
282
392
  authorizationId: string | null;
283
393
  /** What the user was asked to approve, smallest currency unit. */
284
394
  expectedCents: number;
285
- /** What the processor reported at the last check. */
395
+ /** What the processor (or the merchant, see `amountSource`) reported at the last check. */
286
396
  actualCents: number;
287
397
  /** ISO 4217 of the approved amount. */
288
398
  currency: string;
@@ -290,20 +400,32 @@ export declare class AmountMismatchError extends ApprovalDeclinedError {
290
400
  actualCurrency: string;
291
401
  /** Which check refused it. */
292
402
  stage: 'create' | 'pre_replay';
403
+ /**
404
+ * Whose number `actualCents` is: the processor's ('processor'), a merchant-hosted
405
+ * merchant's own checkout total ('merchant_total'), or the amount its card request
406
+ * names ('merchant_request').
407
+ */
408
+ readonly amountSource: 'processor' | 'merchant_total' | 'merchant_request';
293
409
  readonly code: "amount_mismatch";
294
410
  constructor(
295
411
  /** The declined authorization, or null for a create-time refusal (no row exists). */
296
412
  authorizationId: string | null,
297
413
  /** What the user was asked to approve, smallest currency unit. */
298
414
  expectedCents: number,
299
- /** What the processor reported at the last check. */
415
+ /** What the processor (or the merchant, see `amountSource`) reported at the last check. */
300
416
  actualCents: number,
301
417
  /** ISO 4217 of the approved amount. */
302
418
  currency: string,
303
419
  /** ISO 4217 the processor reported (differs only on a currency change). */
304
420
  actualCurrency?: string,
305
421
  /** Which check refused it. */
306
- stage?: 'create' | 'pre_replay');
422
+ stage?: 'create' | 'pre_replay',
423
+ /**
424
+ * Whose number `actualCents` is: the processor's ('processor'), a merchant-hosted
425
+ * merchant's own checkout total ('merchant_total'), or the amount its card request
426
+ * names ('merchant_request').
427
+ */
428
+ amountSource?: 'processor' | 'merchant_total' | 'merchant_request');
307
429
  }
308
430
  /**
309
431
  * The PaymentIntent behind this checkout can no longer be confirmed: it was
@@ -341,6 +463,55 @@ export declare class ProcessorRefusedError extends ApprovalDeclinedError {
341
463
  readonly processorError: RazorpayProcessorError | null;
342
464
  constructor(authorizationId: string, pspErrorCode: string | null, processorError?: RazorpayProcessorError | null);
343
465
  }
466
+ /** Why Agentcard refused a payment on Adyen's TEST platform; see AdyenTestPlatformRefusedError. */
467
+ export type AdyenTestPlatformRefusal = 'adyen_test_environment_refused' | 'adyen_test_platform_requires_documented_test_card';
468
+ /**
469
+ * Agentcard refused a payment on Adyen's TEST platform, where a test account can
470
+ * read whatever is encrypted under its key. Nothing was encrypted and nothing was
471
+ * charged. `code` says which rule:
472
+ * - 'adyen_test_environment_refused': a live checkout names Adyen's test host or
473
+ * a `test_` client key. Stage 'create': the API refused it before anyone was
474
+ * asked (`authorizationId` is null) and the page's next request is refused the
475
+ * same way, so the adapters stop intercepting. Stage 'pre_replay': the
476
+ * authorization was declined right before the card would have been encrypted.
477
+ * - 'adyen_test_platform_requires_documented_test_card': a test-mode checkout on
478
+ * Adyen's test platform, where the approval page encrypts only Adyen's
479
+ * documented test cards and the cardholder's card is not one.
480
+ * A decline in every structural sense, so it extends ApprovalDeclinedError.
481
+ */
482
+ export declare class AdyenTestPlatformRefusedError extends ApprovalDeclinedError {
483
+ readonly authorizationId: string | null;
484
+ readonly code: AdyenTestPlatformRefusal;
485
+ readonly stage: 'create' | 'pre_replay';
486
+ constructor(authorizationId: string | null, code: AdyenTestPlatformRefusal, stage: 'create' | 'pre_replay');
487
+ }
488
+ /** Why a merchant-hosted payment priced by the merchant's own total was refused; see MerchantTotalError. */
489
+ export type MerchantTotalRefusal = 'merchant_total_required' | 'merchant_total_refused' | 'merchant_total_changed' | 'merchant_total_stale';
490
+ /**
491
+ * A reviewed merchant's own checkout total could not stand behind this payment, so the
492
+ * card request was held and nothing was charged. The merchant's server picks what it
493
+ * charges, so a merchant-hosted payment is priced by the total the merchant's own
494
+ * checkout responses named in this browser (the profile's amount source), never by the
495
+ * agent's number alone. `code`:
496
+ * - 'merchant_total_required': no total was sent (stage 'sdk': this runtime recorded no
497
+ * merchant responses; stage 'create': the API got none);
498
+ * - 'merchant_total_refused': the responses do not confirm one total for this order
499
+ * (`reasonCode`: no_source when none was seen, stale, refused, unreadable,
500
+ * mismatch, unbound, invalid); stage 'sdk' before any create, 'create' by the API;
501
+ * - 'merchant_total_changed': stage 'release': between the approval and the moment the
502
+ * card would have gone out, the merchant's total moved, or a request that could move
503
+ * it had not answered. The approval is retired; the card never left this browser;
504
+ * - 'merchant_total_stale': stage 'runtime': the approval came after the total was too
505
+ * old for its profile, so the API withheld the card.
506
+ * A decline in every structural sense, so it extends ApprovalDeclinedError.
507
+ */
508
+ export declare class MerchantTotalError extends ApprovalDeclinedError {
509
+ readonly authorizationId: string | null;
510
+ readonly code: MerchantTotalRefusal;
511
+ readonly stage: 'sdk' | 'create' | 'release' | 'runtime';
512
+ readonly reasonCode: string | null;
513
+ constructor(authorizationId: string | null, code: MerchantTotalRefusal, stage: 'sdk' | 'create' | 'release' | 'runtime', reasonCode: string | null, reason: string);
514
+ }
344
515
  /**
345
516
  * A non-2xx from the Agentcard API, carrying the status so callers can tell a
346
517
  * misconfiguration from a blip. The adapters use this to decide whether
@@ -459,6 +630,11 @@ export interface VaultClientOptions {
459
630
  /** Override the PSP registry (tests, or pinning). Defaults to the hosted list. */
460
631
  registry?: Recognizer[];
461
632
  fetchImpl?: typeof fetch;
633
+ /** Receives contained reporting failures that do not change checkout behavior. */
634
+ onEvent?: (event: {
635
+ type: string;
636
+ detail?: unknown;
637
+ }) => void;
462
638
  pollIntervalMs?: number;
463
639
  /**
464
640
  * Waits before retrying a create the API answered 502 `amount_unverifiable`
@@ -467,6 +643,25 @@ export interface VaultClientOptions {
467
643
  * the error is thrown. Default [500, 1500]; [] disables retries.
468
644
  */
469
645
  unverifiableRetryDelaysMs?: number[];
646
+ /**
647
+ * Test mode only: run a merchant-hosted checkout against your own Adyen TEST
648
+ * account. Each entry arms your own endpoint as taking the card request of a
649
+ * profile Agentcard reviewed (its body rules), encrypted under your own Adyen
650
+ * TEST client key; prepare({ psp: 'adyen', environment: 'sandbox',
651
+ * merchantProfile: <that profile> }) then pays it. Declare them here, before any
652
+ * attach, so every adapter pauses the endpoint. The API accepts a declaration
653
+ * only from a test-mode client of an org Agentcard turned declarations on for,
654
+ * and the Vault encrypts only Adyen's documented test cards under a test_ key.
655
+ * Throws a TypeError at construction for a profile this build did not review, an
656
+ * endpoint the API would refuse (see declareSandboxMerchant) or a non-test key.
657
+ *
658
+ * On this client a declared profile id takes the place of the reviewed profile
659
+ * with that id: merchantProfile(id) and prepare({ merchantProfile: id }) name
660
+ * the declaration, so this client never prepares the reviewed merchant's own
661
+ * checkout. Nothing is lost on a test-mode client, which can never pay a
662
+ * reviewed profile on Adyen's live platform; use a separate client for that.
663
+ */
664
+ sandboxMerchants?: SandboxMerchantDeclaration[];
470
665
  }
471
666
  export declare class VaultClient {
472
667
  private readonly opts;
@@ -475,13 +670,49 @@ export declare class VaultClient {
475
670
  private readonly pollIntervalMs;
476
671
  private readonly unverifiableRetryDelaysMs;
477
672
  private registry;
673
+ /**
674
+ * The reviewed merchant profiles this client arms: every one this build reviewed,
675
+ * in 'observe' until a sync reads that the API enabled it (armServedProfiles).
676
+ */
677
+ private merchantProfiles;
678
+ /** This client's own sandbox declarations (sandboxMerchants), armed at construction, one per profile. */
679
+ private readonly declaredProfiles;
478
680
  private readonly preparations;
479
681
  private readonly usedPreparations;
480
682
  constructor(opts: VaultClientOptions);
481
683
  /** Refresh recognizers from the API so new PSPs work without a redeploy. */
482
684
  syncRegistry(): Promise<void>;
685
+ /**
686
+ * The reviewed Adyen merchant profile whose card endpoint (or a sibling of it,
687
+ * the same path under another query) this URL is, with its status on this
688
+ * client; null for any other URL. Every profile this build reviewed is armed,
689
+ * in 'observe' until a sync reads that the API enabled it. The adapters pause
690
+ * these requests and judge them with classifyMerchantRequest. A raw runtime
691
+ * that pauses one must never continue a card body there unless authorize()
692
+ * paid it.
693
+ */
694
+ merchantProfileOf(url: string): MerchantProfile | null;
695
+ /** The armed profile with this id, or null. A profile id this client declared (sandboxMerchants) names its declaration, in place of the reviewed profile. */
696
+ merchantProfile(id: string): MerchantProfile | null;
697
+ /**
698
+ * Fetch.enable globs for every armed merchant profile's endpoint and its
699
+ * siblings, for a raw CDP runtime to arm beside cardUrlPatterns(). Every profile
700
+ * this build reviewed is armed from the start, so these are the same before and
701
+ * after syncRegistry; a sync changes only a profile's status.
702
+ */
703
+ merchantProfileUrlPatterns(): string[];
483
704
  /** True when this request is a card tokenization we can take over. */
484
705
  isCardRequest(url: string, method?: string): boolean;
706
+ /**
707
+ * What happens to a card request (by URL) whose body carries no card: null
708
+ * when it carries one, so it is a card request as usual; 'continue' when the
709
+ * recognizer marks the endpoint as one where such requests are routine and
710
+ * never ours; 'refuse' otherwise, such as a Stripe confirmation paying with
711
+ * a method this checkout never approved. The adapters ask only after their
712
+ * holds, so a request that would reuse an approved token is refused there
713
+ * first. A body that could not be read is not judged here.
714
+ */
715
+ withoutCard(url: string, body: string | null | undefined): 'continue' | 'refuse' | null;
485
716
  /**
486
717
  * How the card would reach the processor on this request (`token`, `cse`
487
718
  * or `hosted_form`; absent on the entry means `token`), or null when the
@@ -506,6 +737,8 @@ export declare class VaultClient {
506
737
  prepareCheckout(input: PrepareCheckoutInput): Promise<PreparedCheckout>;
507
738
  /** Cancel only an unconsumed preparation; a bound request is reconciled separately. */
508
739
  cancelPreparation(id: string): Promise<void>;
740
+ observePreparation(id: string, guidance: 'presented_not_filled' | 'not_presented', reason?: string): Promise<void>;
741
+ reportDuplicateGuard(authorizationId: string): Promise<void>;
509
742
  /**
510
743
  * Hand us a paused tokenization request. We ask the cardholder to approve,
511
744
  * their device supplies the card and calls the merchant, and you get back the
@@ -539,6 +772,53 @@ export declare class VaultClient {
539
772
  cancelled: true;
540
773
  processor_request_started: boolean;
541
774
  }>;
775
+ /**
776
+ * Ask whether the page may pay with the Stripe card token an approval
777
+ * produced: a PaymentIntent confirm that carries no card and pays with
778
+ * exactly the approved payment method, card token, confirmation token or
779
+ * source. The API reads the payment from Stripe and answers only for the
780
+ * approved amount and currency on the same Stripe account; any other answer
781
+ * rejects with a CheckoutApiError whose code says why (for example
782
+ * `continuation_not_bound`, `amount_mismatch`). Nothing is charged here:
783
+ * the adapters continue the page's own request once this resolves.
784
+ */
785
+ checkStripeContinuation(authorizationId: string, request: {
786
+ url: string;
787
+ method: string;
788
+ headers: Record<string, string>;
789
+ body: string;
790
+ }): Promise<{
791
+ paymentIntentId: string;
792
+ amount: number;
793
+ currency: string;
794
+ }>;
795
+ /**
796
+ * After a merchant-hosted payment priced by the merchant's own total: what the merchant's
797
+ * confirmation says it charged (merchant-total.ts merchantChargeReport builds `report`
798
+ * from the responses this browser recorded after the card request). The API compares it
799
+ * with the approved amount and alerts Agentcard once when the merchant charged more, or
800
+ * in another currency. The adapters send it on their own; the verdict is 'equal',
801
+ * 'lower', 'higher', 'currency_mismatch', or 'unread' when no response read.
802
+ */
803
+ reportMerchantCharge(authorizationId: string, report: {
804
+ request: {
805
+ url: string;
806
+ method: string;
807
+ body: string;
808
+ };
809
+ responses: unknown[];
810
+ }): Promise<{
811
+ verdict: 'equal' | 'lower' | 'higher' | 'currency_mismatch' | 'unread';
812
+ alerted: boolean;
813
+ }>;
814
+ /**
815
+ * The merchant's own total for a paused card request whose reviewed profile is priced by
816
+ * one: the exchanges the adapter recorded (once every request that can move the total has
817
+ * answered), cut to what the profile's rules read, and the same reading the API makes.
818
+ * Refused with a MerchantTotalError before any create when nothing recorded them, one is
819
+ * still unanswered, or they do not confirm one total for this order.
820
+ */
821
+ private readMerchantTotal;
542
822
  /**
543
823
  * POST the create, with two typed twists: a 502 `amount_unverifiable`
544
824
  * (Stripe did not answer the read-back) is retried on a short backoff