@agent-cards/sdk 0.23.28 → 0.24.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 +58 -0
- package/PREFLIGHT.md +7 -1
- package/README.md +137 -99
- package/dist/aci.d.ts +52 -22
- package/dist/aci.js +79 -15
- package/dist/adyen-merchant-hosted.generated.d.ts +1 -1
- package/dist/adyen-merchant-hosted.generated.js +459 -21
- package/dist/agent-amount.generated.js +1 -1
- package/dist/agentcard.d.ts +4 -5
- package/dist/agentcard.js +4 -5
- package/dist/amadeus.d.ts +9 -3
- package/dist/amadeus.js +33 -4
- package/dist/api-module.d.ts +1 -7
- package/dist/api-module.js +3 -5
- package/dist/{voice-retry.js → api-retry.js} +1 -1
- package/dist/api-types.d.ts +53 -0
- package/dist/{voice-types.js → api-types.js} +7 -2
- package/dist/approvals.d.ts +166 -0
- package/dist/approvals.js +213 -0
- package/dist/buy.d.ts +20 -101
- package/dist/buy.js +19 -74
- package/dist/capabilities.generated.js +1 -1
- package/dist/card-fields.generated.js +1398 -106
- package/dist/cdp.d.ts +3 -13
- package/dist/cdp.js +231 -175
- package/dist/client.d.ts +104 -22
- package/dist/client.js +215 -40
- package/dist/creditguard.generated.d.ts +4 -4
- package/dist/datatrans.generated.js +22 -1
- package/dist/elavon-converge.generated.js +5 -3
- package/dist/hold.d.ts +8 -0
- package/dist/hold.js +43 -2
- package/dist/hosted-entry.js +2 -0
- package/dist/index.d.ts +9 -15
- package/dist/index.js +6 -10
- package/dist/lifecycle.d.ts +9 -61
- package/dist/lifecycle.js +24 -10
- package/dist/merchant-card-endpoints.generated.d.ts +6 -1
- package/dist/merchant-card-endpoints.generated.js +344 -19
- package/dist/merchant-hosted.d.ts +8 -1
- package/dist/nike-order.d.ts +51 -0
- package/dist/nike-order.js +81 -0
- package/dist/oceanpayment.d.ts +38 -0
- package/dist/oceanpayment.js +70 -0
- package/dist/paddle-tokenex.generated.js +105 -10
- package/dist/payplug.d.ts +41 -0
- package/dist/payplug.js +71 -0
- package/dist/payrails.generated.js +27 -7
- package/dist/pre-claim.d.ts +9 -0
- package/dist/pre-claim.js +86 -7
- package/dist/preflight-capabilities.generated.d.ts +0 -4
- package/dist/preflight-capabilities.generated.js +0 -5
- package/dist/preflight-catalog.json +46 -5
- package/dist/preflight-playwright.d.ts +2 -2
- package/dist/preflight-playwright.js +63 -14
- package/dist/preflight-schemas.json +4 -0
- package/dist/preflight.generated.d.ts +0 -4
- package/dist/preflight.generated.js +24 -1
- package/dist/prepared-processor.d.ts +18 -5
- package/dist/prepared-processor.js +48 -8
- package/dist/primer.generated.js +1418 -120
- package/dist/processout.generated.d.ts +61 -0
- package/dist/processout.generated.js +577 -0
- package/dist/requests.js +1 -1
- package/dist/shiji-sts.generated.js +105 -10
- package/dist/stripe-checkout.generated.js +1405 -234
- package/dist/substitutions.generated.js +460 -26
- package/dist/tap-payments.generated.js +105 -10
- package/dist/twoc2p.generated.js +105 -10
- package/dist/url-masks/bluesnap.d.ts +2 -0
- package/dist/url-masks/bluesnap.js +15 -0
- package/dist/url-masks/oceanpayment.d.ts +2 -0
- package/dist/url-masks/oceanpayment.js +13 -0
- package/dist/url-masks/payplug.d.ts +2 -0
- package/dist/url-masks/payplug.js +13 -0
- package/dist/url-masks/vtex_payments.d.ts +2 -0
- package/dist/url-masks/vtex_payments.js +12 -0
- package/dist/url-masks.generated.d.ts +1 -1
- package/dist/url-masks.generated.js +6 -2
- package/dist/verifone.generated.js +42 -2
- package/dist/vtex-payments.generated.d.ts +127 -0
- package/dist/vtex-payments.generated.js +544 -0
- package/dist/webhooks.d.ts +2 -2
- package/dist/webhooks.js +2 -2
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +6 -8
- package/dist/languages.d.ts +0 -23
- package/dist/languages.js +0 -76
- package/dist/voice-pkce.d.ts +0 -49
- package/dist/voice-pkce.js +0 -147
- package/dist/voice-stream.generated.d.ts +0 -118
- package/dist/voice-stream.generated.js +0 -170
- package/dist/voice-types.d.ts +0 -735
- package/dist/voice.d.ts +0 -373
- package/dist/voice.js +0 -815
- package/readme.test.mjs +0 -53
- /package/dist/{voice-retry.d.ts → api-retry.d.ts} +0 -0
package/dist/hold.js
CHANGED
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
// - Any request whose body carries the placeholder card number (`placeholderNumbers`): a store's own card post or
|
|
18
18
|
// an unknown processor. The browser only ever holds the placeholder, so a body with its digits is a card request
|
|
19
19
|
// wherever it goes. In sandbox it may be released unchanged (it carries the documented test number only).
|
|
20
|
+
// - With `placeholderNumbers`, any request whose body carries a card a processor's frame encrypted in the page
|
|
21
|
+
// (Adyen's encryptedCardNumber, Braintree's legacy CSE, Worldline Connect's encryptedCustomerInput) sent to the
|
|
22
|
+
// merchant's own server instead of the processor (encryptedCardHoldRule). Held, then only cancelled.
|
|
20
23
|
// The hold records the processor and the endpoint (origin and path, any path credential masked), never a body or a
|
|
21
24
|
// header.
|
|
22
25
|
import { redactUrl } from './client.js';
|
|
@@ -54,6 +57,36 @@ export function placeholderHoldRule(numbers, deadlineMs = HOLD_DEFAULT_DEADLINE_
|
|
|
54
57
|
patterns: PLACEHOLDER_RESOURCE_TYPES.map((resourceType) => ({ urlPattern: '*', resourceType })),
|
|
55
58
|
};
|
|
56
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* A card a processor's own frame encrypted in the page, sent on inside the merchant's own request (its order or payment
|
|
62
|
+
* step) instead of to the processor: the placeholder's digits never appear, so placeholderHoldRule cannot see it, and
|
|
63
|
+
* no recogniser matches the merchant's URL. Adyen's card component on Salesforce Commerce, Magento and other Advanced
|
|
64
|
+
* (non-Sessions) integrations posts `encryptedCardNumber` (a JWE, `eyJ...`, or the legacy `adyenjs_0_1_...`) to the
|
|
65
|
+
* store's CheckoutServices-SubmitPayment / PlaceOrder: ca.coach.com's PlaceOrder answered 200 with no hold on
|
|
66
|
+
* 2026-10-23. Also caught: Braintree's legacy client-side encryption (`$bt4|javascript_...`) and Worldline/Ingenico
|
|
67
|
+
* Connect's `encryptedCustomerInput`. Matched in JSON, escaped JSON, URL-encoded and form bodies. Held, then only
|
|
68
|
+
* cancelled: no release can answer a request the vault never encrypted for.
|
|
69
|
+
*/
|
|
70
|
+
const Q = '(?:\\\\?"|%22|%5C%22|\\\\u0022)?';
|
|
71
|
+
const SEP = '\\s*(?::|%3A|=)\\s*';
|
|
72
|
+
// A multipart field: the name's closing quote, the part's remaining header lines, a blank line, then the value.
|
|
73
|
+
// The value is read on its own line only: never across a line break, and never a boundary line (`--...`), so an empty
|
|
74
|
+
// field followed by a long boundary is not a card.
|
|
75
|
+
const PART = '"?[^\\r\\n]{0,80}\\r?\\n(?:[^\\r\\n]{1,200}\\r?\\n){0,4}\\r?\\n[ \\t]*(?!--)';
|
|
76
|
+
const ENCRYPTED_CARD_BODY = new RegExp([
|
|
77
|
+
`encryptedCardNumber${Q}${SEP}${Q}\\s*(?:eyJ|adyenjs_|[A-Za-z0-9+/_$|.-]{40})`,
|
|
78
|
+
`encryptedCardNumber${PART}(?:eyJ|adyenjs_|[A-Za-z0-9+/_$|.-]{40})`,
|
|
79
|
+
`encryptedCustomerInput${PART}[A-Za-z0-9+/_.-]{40}`,
|
|
80
|
+
'adyenjs_0_[0-9]+_[0-9]+(?:\\$|%24)',
|
|
81
|
+
'\\$bt[0-9]\\|javascript_|%24bt[0-9](?:\\||%7C)javascript_',
|
|
82
|
+
`encryptedCustomerInput${Q}${SEP}${Q}\\s*[A-Za-z0-9+/_.-]{40}`,
|
|
83
|
+
].join('|'), 'i');
|
|
84
|
+
export function encryptedCardHoldRule(deadlineMs = HOLD_DEFAULT_DEADLINE_MS) {
|
|
85
|
+
return {
|
|
86
|
+
psp: 'encrypted_card', match: /^[a-z]+:\/\//i, body: ENCRYPTED_CARD_BODY, kind: 'store_card_post', deadlineMs, methods: ['POST', 'PUT', 'PATCH'],
|
|
87
|
+
patterns: PLACEHOLDER_RESOURCE_TYPES.map((resourceType) => ({ urlPattern: '*', resourceType })),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
57
90
|
/** The hold-only rule a request is a card request under, or null. */
|
|
58
91
|
export function matchHoldOnlyRule(request, rules) {
|
|
59
92
|
for (const rule of rules) {
|
|
@@ -127,11 +160,15 @@ export class HoldGate {
|
|
|
127
160
|
this.sandbox = sandbox;
|
|
128
161
|
this.emit = emit;
|
|
129
162
|
const placeholder = options.placeholderNumbers?.length ? placeholderHoldRule(options.placeholderNumbers) : null;
|
|
130
|
-
|
|
163
|
+
// A page the vault types its placeholder into is watched for every card leaving it, encrypted or not; the
|
|
164
|
+
// encrypted-card rule shares the placeholder rule's patterns, so it pauses nothing more. It comes first: a body
|
|
165
|
+
// carrying both the placeholder and an encrypted card is the encrypted card's, and is never continued.
|
|
166
|
+
this.rules = [BOLT_HOLD_RULE, ...(placeholder ? [encryptedCardHoldRule(), placeholder] : [])];
|
|
131
167
|
}
|
|
132
168
|
get state() { return this._state; }
|
|
133
169
|
get held() { return this._held ? { ...this._held } : null; }
|
|
134
170
|
get refused() { return this._refused; }
|
|
171
|
+
get covers() { return this.rules.map((r) => r.psp); }
|
|
135
172
|
/** Fetch patterns the hold-only rules need beside the registry's. */
|
|
136
173
|
patterns() { return this.rules.flatMap((r) => r.patterns); }
|
|
137
174
|
deadlineFor(psp, rule) {
|
|
@@ -245,7 +282,11 @@ export class HoldGate {
|
|
|
245
282
|
let settle;
|
|
246
283
|
const settled = new Promise((resolve) => { settle = resolve; });
|
|
247
284
|
if (!held.replayable) {
|
|
248
|
-
|
|
285
|
+
// Only the plain placeholder post may be sent on in sandbox: an encrypted card inside a merchant's own order or
|
|
286
|
+
// payment request (encrypted_card) is the order itself, and is never continued in any mode.
|
|
287
|
+
if (held.psp === 'encrypted_card')
|
|
288
|
+
return fail('encrypted_card_post');
|
|
289
|
+
if (held.kind === 'store_card_post' && held.psp === 'placeholder_card' && input.continuePlaceholder && this.sandbox) {
|
|
249
290
|
this.decide({ kind: 'continue', settle });
|
|
250
291
|
this.emit('card_request_released', { psp: held.psp, continued: true, amount: input.amount, currency: input.currency.toLowerCase(), upTo: !!input.upTo });
|
|
251
292
|
return settled;
|
package/dist/hosted-entry.js
CHANGED
|
@@ -18,11 +18,13 @@ import { PRZELEWY24_PSP, isPrzelewy24EntryUrl } from './przelewy24.js';
|
|
|
18
18
|
import { COMGATE_PSP, isComgateEntryUrl } from './comgate.js';
|
|
19
19
|
import { TRANSBANK_PSP, isTransbankEntryUrl } from './transbank.js';
|
|
20
20
|
import { BARION_PSP, isBarionEntryUrl } from './barion.js';
|
|
21
|
+
import { PAYPLUG_PSP, isPayplugEntryUrl } from './payplug.js';
|
|
21
22
|
const HOSTED_GET_ENTRIES = new Map([
|
|
22
23
|
[PRZELEWY24_PSP, isPrzelewy24EntryUrl],
|
|
23
24
|
[COMGATE_PSP, isComgateEntryUrl],
|
|
24
25
|
[TRANSBANK_PSP, isTransbankEntryUrl],
|
|
25
26
|
[BARION_PSP, isBarionEntryUrl],
|
|
27
|
+
[PAYPLUG_PSP, isPayplugEntryUrl],
|
|
26
28
|
]);
|
|
27
29
|
/** Whether this processor's hosted page is entered with a GET this build reads exactly. */
|
|
28
30
|
export function hasHostedGetEntry(psp) {
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type { SecureAcceptanceCheckoutRefusal, SecureAcceptanceUnknownReason } f
|
|
|
14
14
|
export type { PausedRequest, ReplayResponse, TokenReplay, CseReplay, MerchantHostedReplay, VerifoneReplay, HostedFormReplay, CardEndpointReplay, DeviceEncryptReplay, AmountAuthority, AuthorizeInput, VaultClientOptions, AgentcardOptions, AdyenTestPlatformRefusal, MerchantTotalRefusal, PrepareCheckoutOptions, PrepareCheckoutInput, PreparedCheckout, RazorpayProcessorError, RuntimeCancelReason, ExecutionMetadata, PlaceholderCard, } from './client.js';
|
|
15
15
|
export type { MicroformField, MicroformSidecar } from './cybersource-flex.js';
|
|
16
16
|
export { attachToCdp, attachToPlaywright, corsHeadersFor, corsDecision, withCorsHeaders } from './cdp.js';
|
|
17
|
-
export { BOLT_HOLD_RULE, HOLD_DEADLINES_MS, HOLD_DEFAULT_DEADLINE_MS, HOLD_DEADLINE_MARGIN_MS, HoldAnsweredError, HoldEndedError, matchHoldOnlyRule, placeholderHoldRule } from './hold.js';
|
|
17
|
+
export { BOLT_HOLD_RULE, HOLD_DEADLINES_MS, HOLD_DEFAULT_DEADLINE_MS, HOLD_DEADLINE_MARGIN_MS, HoldAnsweredError, HoldEndedError, matchHoldOnlyRule, placeholderHoldRule, encryptedCardHoldRule } from './hold.js';
|
|
18
18
|
export type { CardRequestHold, HeldCardRequest, HoldOnlyRule, HoldOptions, HoldReleaseInput, HoldReleaseOutcome, HoldState } from './hold.js';
|
|
19
19
|
export { CheckoutAttachmentError } from './attachment.js';
|
|
20
20
|
export { EbanxFollowUpError } from './ebanx.js';
|
|
@@ -28,7 +28,7 @@ export { substituteEncryptedFields, SubstitutionError } from './substitute.js';
|
|
|
28
28
|
export { PaddleCheckoutWatch, type PaddleCheckoutAnswer, type PaddleCheckoutCapture } from './paddle-checkout-watch.js';
|
|
29
29
|
export type { Substitutions } from './substitute.js';
|
|
30
30
|
export { classifyDeclaredMerchantRequest, classifyMerchantRequest, substituteMerchantHostedBody } from './merchant-hosted.js';
|
|
31
|
-
export type { MerchantProfile, MerchantProfileStatus, MerchantRequestVerdict, MerchantHostedSubstitutions, MerchantHostedFact, JsonPathStep, SandboxMerchantDeclaration } from './merchant-hosted.js';
|
|
31
|
+
export type { MerchantProfile, MerchantProfileStatus, MerchantRequestVerdict, MerchantHostedSubstitutions, MerchantHostedFact, JsonPathStep, JsonTextStep, ProfilePathStep, SandboxMerchantDeclaration } from './merchant-hosted.js';
|
|
32
32
|
export { MerchantExchangeLog, merchantAmountExchanges, merchantAmountFromResponses, merchantChargeReport, merchantProfilePricedBySource, merchantTotalAtRelease, MERCHANT_EXCHANGES_MAX, } from './merchant-total.js';
|
|
33
33
|
export type { MerchantAmountCard, MerchantExchange, MerchantRequestSeen, MerchantTotalApproved, MerchantTotalCapture, MerchantTotalScope } from './merchant-total.js';
|
|
34
34
|
export { substituteFiservEnvelope } from './fiserv.js';
|
|
@@ -39,21 +39,15 @@ export type { HostedFormSubmittedPageInput, SyntheticPage } from './hosted-form.
|
|
|
39
39
|
export { BUILTIN_REGISTRY, cardUrlPatterns, findRecognizer, isLoopbackUrl, LOOPBACK_URL_PATTERNS } from './registry.js';
|
|
40
40
|
export type { Recognizer, CheckoutMode, RecognizerOptions } from './registry.js';
|
|
41
41
|
export type { PayrailsSidecar, PayrailsUnsupportedReason } from './payrails.js';
|
|
42
|
-
export type { CheckoutController, CheckoutState, MerchantResult, MerchantPaymentConfirmation, UserAction, LifecycleOptions, PaymentEndpointGuard
|
|
42
|
+
export type { CheckoutController, CheckoutState, MerchantResult, MerchantPaymentConfirmation, UserAction, LifecycleOptions, PaymentEndpointGuard } from './lifecycle.js';
|
|
43
43
|
export { RequestRegistry, BUILTIN_REQUEST_BUILDERS, stripePaymentIntentConfirm, stripePaymentIntentConfirmRequest, stripeCardTokenRequest, stripePaymentMethodRequest } from './requests.js';
|
|
44
44
|
export type { RequestBuilder, BuildInput, MintedIntent } from './requests.js';
|
|
45
|
-
export { VoiceModule, checkoutOriginOf, CANCEL_REASONS, bundleOf, streamAddress, SANDBOX_REQUEST } from './voice.js';
|
|
46
|
-
export type { VoiceOptions, VoiceTransport } from './voice.js';
|
|
47
45
|
export type { ApiTransport } from './api-module.js';
|
|
48
|
-
export { BuyModule, BuyError, isBuyDeclined,
|
|
49
|
-
export type { BuyStatus,
|
|
50
|
-
export {
|
|
51
|
-
export type {
|
|
46
|
+
export { BuyModule, BuyError, isBuyDeclined, BUY_TURN_TIMEOUT_MS } from './buy.js';
|
|
47
|
+
export type { BuyStatus, BuyCart, BuyCartLine, BuyDeliveryAddress, BuyPaymentSource, BuyOutcome, BuyPlacement, BuyCatalog, BuyUnmatched, BuyTurn, BuyDeclined, BuyOrder, BuyLastCheckout, BuyConversation, BuyAskInput, BuyConfirmInput, BuyConversationInput, BuyCheckoutHandoff, BuyOpenOffer, BuyBrowserCheckout, BuyApiAmount, } from './buy.js';
|
|
48
|
+
export { ApprovalsModule, CANCEL_REASONS, SANDBOX_REQUEST } from './approvals.js';
|
|
49
|
+
export type { CreateAuthorizationInput, Authorization, AuthorizationResult, AuthorizationFields, Cancelled, PayingCard, ChoosableCard } from './approvals.js';
|
|
52
50
|
export { verifyWebhook, signWebhook, parseWebhookEvent, parseSignatureHeader, isCheckoutAuthorizationEvent, isVaultEvent, CHECKOUT_AUTHORIZATION_EVENT_TYPES, VAULT_EVENT_TYPES } from './webhooks.js';
|
|
53
51
|
export type { WebhookEvent, AgentcardEvent, CheckoutAuthorizationEvent, CheckoutAuthorizationEventType, CheckoutAuthorizationEventData, VaultEvent, VaultEventType, VaultEventData, OtherEvent, VerifyWebhookOptions } from './webhooks.js';
|
|
54
|
-
export {
|
|
55
|
-
export type {
|
|
56
|
-
export { AgentcardError } from './voice-types.js';
|
|
57
|
-
export type { Lang, VoiceAsk, ApprovalPosture, Action, ConnectInput, ConnectResult, Connected, Person, Proposed, Done, ActionState, CreateAuthorizationInput, AuthorizationStatus, Authorization, VoiceResetInput, VoiceChallenge, AuthorizationResult, Verdict, AuthorizationDetail, Exchanged, ExchangeInput, Revoked, TerminalReason, DeliveryChannel, InteractionEvidence, Intent, ApprovalRequestFields, CancelReason, Cancelled, Settlement, SessionState, ReturnLink, VoiceResetOutcome, VaultSessionStep, HostApprovalBundle, AppVoiceKeyDescription, HardwareAttestation, RegisteredAppVoiceKey, RevokedAppVoiceKey, PayingCard, ChoosableCard, } from './voice-types.js';
|
|
58
|
-
export { openStream, streamBuffer } from './voice-stream.generated.js';
|
|
59
|
-
export type { Hearing, StreamFormat, StreamHandle, StreamInput, StreamVerdict, ChannelKind } from './voice-stream.generated.js';
|
|
52
|
+
export { AgentcardError } from './api-types.js';
|
|
53
|
+
export type { AuthorizationStatus, TerminalReason, CancelReason, Settlement } from './api-types.js';
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export { Agentcard, Agentcard as VaultClient, CheckoutModule } from './agentcard
|
|
|
4
4
|
export { CardEncryptedError, UnsupportedModeError, UnsupportedCapabilityError, PreparationRequiredError, AmountRequiredError, PageAmountRequiredError, ApprovalTimeoutError, ApprovalDeclinedError, AmountMismatchError, PresetRefusedError, PRESET_REFUSAL_REASONS, IntentNotConfirmableError, ProcessorRefusedError, CheckoutApiError, CheckoutAuthError, redactUrl, SUPPORTED_MODES, SUPPORTED_CAPABILITIES, PaymentOutcomeUnknownError, CheckoutCancelledError, CheckoutPreparationError, AdyenTestPlatformRefusedError, MerchantTotalError, PlaceholderCardError, } from './client.js';
|
|
5
5
|
export { CONVERGE_REFUSAL_REASONS } from './elavon-converge.js';
|
|
6
6
|
export { attachToCdp, attachToPlaywright, corsHeadersFor, corsDecision, withCorsHeaders } from './cdp.js';
|
|
7
|
-
export { BOLT_HOLD_RULE, HOLD_DEADLINES_MS, HOLD_DEFAULT_DEADLINE_MS, HOLD_DEADLINE_MARGIN_MS, HoldAnsweredError, HoldEndedError, matchHoldOnlyRule, placeholderHoldRule } from './hold.js';
|
|
7
|
+
export { BOLT_HOLD_RULE, HOLD_DEADLINES_MS, HOLD_DEFAULT_DEADLINE_MS, HOLD_DEADLINE_MARGIN_MS, HoldAnsweredError, HoldEndedError, matchHoldOnlyRule, placeholderHoldRule, encryptedCardHoldRule } from './hold.js';
|
|
8
8
|
export { CheckoutAttachmentError } from './attachment.js';
|
|
9
9
|
// EBANX after its card token: why a send an approved token request covers got no answer from the cardholder's device.
|
|
10
10
|
export { EbanxFollowUpError } from './ebanx.js';
|
|
@@ -22,14 +22,10 @@ export { hostedFormSubmittedPage, HOSTED_FORM_SUBMITTED_OUTCOME } from './hosted
|
|
|
22
22
|
export { BUILTIN_REGISTRY, cardUrlPatterns, findRecognizer, isLoopbackUrl, LOOPBACK_URL_PATTERNS } from './registry.js';
|
|
23
23
|
// The request builders: `agentcard.checkout.requests`, and the shipped builders as functions.
|
|
24
24
|
export { RequestRegistry, BUILTIN_REQUEST_BUILDERS, stripePaymentIntentConfirm, stripePaymentIntentConfirmRequest, stripeCardTokenRequest, stripePaymentMethodRequest } from './requests.js';
|
|
25
|
-
// The
|
|
26
|
-
export {
|
|
27
|
-
// The
|
|
28
|
-
export {
|
|
29
|
-
// Languages are data: `agentcard.voice.languages()` lists them, and a tag not on the list is refused before any call.
|
|
30
|
-
export { Languages } from './languages.js';
|
|
25
|
+
// The buy module: `agentcard.buy.*` (the Purchase API from the same client: ask, confirm against an approval the business holds, read a conversation).
|
|
26
|
+
export { BuyModule, BuyError, isBuyDeclined, BUY_TURN_TIMEOUT_MS } from './buy.js';
|
|
27
|
+
// The approvals module: `agentcard.approvals.*` (a purchase your server creates, approved on Agentcard's page).
|
|
28
|
+
export { ApprovalsModule, CANCEL_REASONS, SANDBOX_REQUEST } from './approvals.js';
|
|
31
29
|
// Webhooks: verified and typed.
|
|
32
30
|
export { verifyWebhook, signWebhook, parseWebhookEvent, parseSignatureHeader, isCheckoutAuthorizationEvent, isVaultEvent, CHECKOUT_AUTHORIZATION_EVENT_TYPES, VAULT_EVENT_TYPES } from './webhooks.js';
|
|
33
|
-
export {
|
|
34
|
-
export { AgentcardError } from './voice-types.js';
|
|
35
|
-
export { openStream, streamBuffer } from './voice-stream.generated.js';
|
|
31
|
+
export { AgentcardError } from './api-types.js';
|
package/dist/lifecycle.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CheckoutPreparationError, type PrepareCheckoutOptions, type PreparedCheckout, type ReplayResponse } from './client.js';
|
|
2
2
|
import type { CheckoutMode } from './registry.js';
|
|
3
3
|
import type { PayrailsUnsupportedReason } from './payrails.js';
|
|
4
|
-
import type { Substitutions } from './substitute.js';
|
|
5
4
|
import type { GmoUnsupportedReason } from './gmo.js';
|
|
6
5
|
import type { ShijiStsUnsupportedReason } from './shiji-sts.js';
|
|
7
6
|
import type { PaddleVgsPayRefusal } from './paddle-vgs-pay.js';
|
|
@@ -54,64 +53,8 @@ export interface LifecycleOptions {
|
|
|
54
53
|
/** Hold further card requests after handoff until the merchant result is reconciled. Default false for compatibility. */
|
|
55
54
|
requireMerchantResult?: boolean;
|
|
56
55
|
}
|
|
57
|
-
/**
|
|
58
|
-
* A browser purchase paused for the business to create: what
|
|
59
|
-
* `attachToCdp(…, { pauseOnly: true })` hands `onPaused`. The business creates
|
|
60
|
-
* the authorization from `request` (`voice.authorizations.create` with its
|
|
61
|
-
* posture, user and return link), reads the result, and calls
|
|
62
|
-
* `controller.resume(result)`.
|
|
63
|
-
*/
|
|
64
|
-
export interface PausedCheckout {
|
|
65
|
-
/** The card request the page sent, as the create takes it. */
|
|
66
|
-
request: {
|
|
67
|
-
url: string;
|
|
68
|
-
method: string;
|
|
69
|
-
headers: Record<string, string>;
|
|
70
|
-
body: string;
|
|
71
|
-
};
|
|
72
|
-
/** The recogniser that claimed the request, by its processor name (`stripe`); null when the pause named none. Nothing to re-match. */
|
|
73
|
-
recognizer: string | null;
|
|
74
|
-
/** The checkout page's origin (`https://shop.example`), when the browser exposed it; what `checkout_origin` names. */
|
|
75
|
-
page_origin?: string;
|
|
76
|
-
controller: CheckoutController;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* The authorization as the business read it, handed to `controller.resume`
|
|
80
|
-
* : `voice.awaitResult`'s answer as it is, or any object with
|
|
81
|
-
* these fields. `approved` with `response` replays the processor's answer into
|
|
82
|
-
* the page (`token`); with `substitutions` the page's own request continues
|
|
83
|
-
* with the ciphertext (`cse`); with `submitted_at` the paused navigation is
|
|
84
|
-
* answered as a hosted form submitted on the device. A terminal status
|
|
85
|
-
* (`declined`, `cancelled`, `expired`, `timeout`) fails the page's request
|
|
86
|
-
* with nothing charged.
|
|
87
|
-
*/
|
|
88
|
-
export interface ResumeResult {
|
|
89
|
-
id?: string;
|
|
90
|
-
status: string;
|
|
91
|
-
mode?: string;
|
|
92
|
-
response?: {
|
|
93
|
-
status: number;
|
|
94
|
-
headers: Record<string, string>;
|
|
95
|
-
body: string;
|
|
96
|
-
};
|
|
97
|
-
/**
|
|
98
|
-
* The read's `processor_context`, as the API serves it. A Paddle VGS read carries the approved card's
|
|
99
|
-
* details here, which the frame's /pay names; without them the stored card's id is never handed to the page.
|
|
100
|
-
*/
|
|
101
|
-
processor_context?: unknown;
|
|
102
|
-
substitutions?: Substitutions;
|
|
103
|
-
submitted_at?: string;
|
|
104
|
-
execution_mode?: string;
|
|
105
|
-
terminal_reason?: string | null;
|
|
106
|
-
approved_with?: string | null;
|
|
107
|
-
}
|
|
108
56
|
export interface CheckoutController {
|
|
109
57
|
getState(): Readonly<CheckoutState>;
|
|
110
|
-
/**
|
|
111
|
-
* Answer the paused card request with the authorization the business created and read (* `attachToCdp(…, { pauseOnly: true })` only). Resolves once the page has its answer, or the request is
|
|
112
|
-
* failed for a terminal status; rejects when no request is paused or the read is not final.
|
|
113
|
-
*/
|
|
114
|
-
resume(result: ResumeResult): Promise<void>;
|
|
115
58
|
/** Await device consent before the caller starts the first native Pay action. One use per attachment. */
|
|
116
59
|
prepare(options: PrepareCheckoutOptions): Promise<PreparedCheckout>;
|
|
117
60
|
/**
|
|
@@ -163,6 +106,7 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
163
106
|
private stripeContinuedReason;
|
|
164
107
|
private approvedPaymentMethod;
|
|
165
108
|
private ownedShopOrderId;
|
|
109
|
+
private orderRefusal;
|
|
166
110
|
private readonly handoffs;
|
|
167
111
|
private reconciliation;
|
|
168
112
|
/**
|
|
@@ -172,7 +116,6 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
172
116
|
private followUpsOut;
|
|
173
117
|
private preparationHandler?;
|
|
174
118
|
private preparationUsed;
|
|
175
|
-
private resumeHandler;
|
|
176
119
|
private holdHandle;
|
|
177
120
|
readonly abort: AbortController;
|
|
178
121
|
constructor(options: LifecycleOptions);
|
|
@@ -183,9 +126,6 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
183
126
|
setHold(hold: CardRequestHold): void;
|
|
184
127
|
get hold(): CardRequestHold | null;
|
|
185
128
|
release(input: HoldReleaseInput): Promise<HoldReleaseOutcome>;
|
|
186
|
-
/** The transport's hand while one request is paused for the business; null once it is answered. */
|
|
187
|
-
setResumeHandler(handler: ((result: ResumeResult) => Promise<void>) | null): void;
|
|
188
|
-
resume(result: ResumeResult): Promise<void>;
|
|
189
129
|
preparing(): void;
|
|
190
130
|
preparationCreated(preparationId: string): void;
|
|
191
131
|
prepared(preparation: PreparedCheckout): void;
|
|
@@ -293,6 +233,14 @@ export declare class CheckoutLifecycle implements CheckoutController {
|
|
|
293
233
|
* state keeps it, and only the hold changes.
|
|
294
234
|
*/
|
|
295
235
|
unsupported(reason?: 'unrecognized_payment_endpoint' | 'merchant_profile_observe' | 'merchant_request_unsupported' | GmoUnsupportedReason | 'microform_unsupported' | 'juspay_request_unsupported' | 'merchant_card_endpoint_not_enabled' | 'merchant_card_endpoint_resend_refused' | 'creditguard_three_d_secure' | 'unsupported_primer_sdk' | 'unsupported_primer_request' | PayrailsUnsupportedReason | ShijiStsUnsupportedReason | 'processor_card_page' | 'unsupported_paypal_hosted_fields' | PaypalCardFormReason | 'unsupported_cybersource_secure_acceptance' | PaddleVgsPayRefusal | 'unsupported_ebanx_card_resend' | 'unsupported_payrexx_card_resend'): void;
|
|
236
|
+
/**
|
|
237
|
+
* Nike's order after its card was refused before it left (pre-claim.ts nikeOrderPreClaim): the card reached
|
|
238
|
+
* Nike's store and the order that would charge it never did, so a checkout still under way ends `failed` with
|
|
239
|
+
* the refusal's reason, nothing charged, and stays failed when the approval it was waiting on lands after the
|
|
240
|
+
* refusal (handedOff). A checkout that already ended keeps its state. Either way the attachment holds until the
|
|
241
|
+
* application starts another attempt.
|
|
242
|
+
*/
|
|
243
|
+
merchantOrderRefused(reason: string): void;
|
|
296
244
|
/**
|
|
297
245
|
* A card request that only a prepared checkout pays (an Adyen merchant
|
|
298
246
|
* profile's, or a Fiserv card capture) arrived with no preparation on this
|
package/dist/lifecycle.js
CHANGED
|
@@ -65,6 +65,8 @@ export class CheckoutLifecycle {
|
|
|
65
65
|
// The payment method a Stripe /v1/payment_methods approval returned: see approvedStripePaymentMethod.
|
|
66
66
|
approvedPaymentMethod = null;
|
|
67
67
|
ownedShopOrderId = null;
|
|
68
|
+
// The reason Nike's order was refused while this attempt was under way (merchantOrderRefused): its handoff keeps it failed.
|
|
69
|
+
orderRefusal = null;
|
|
68
70
|
// Every request this attachment handed the card to: see cardHandoffs().
|
|
69
71
|
handoffs = [];
|
|
70
72
|
reconciliation = null;
|
|
@@ -75,7 +77,6 @@ export class CheckoutLifecycle {
|
|
|
75
77
|
followUpsOut = 0;
|
|
76
78
|
preparationHandler;
|
|
77
79
|
preparationUsed = false;
|
|
78
|
-
resumeHandler = null;
|
|
79
80
|
holdHandle = null;
|
|
80
81
|
abort = new AbortController();
|
|
81
82
|
constructor(options) {
|
|
@@ -98,15 +99,6 @@ export class CheckoutLifecycle {
|
|
|
98
99
|
return Promise.reject(new Error('No card request hold: attach with hold: true.'));
|
|
99
100
|
return this.holdHandle.release(input);
|
|
100
101
|
}
|
|
101
|
-
/** The transport's hand while one request is paused for the business; null once it is answered. */
|
|
102
|
-
setResumeHandler(handler) { this.resumeHandler = handler; }
|
|
103
|
-
resume(result) {
|
|
104
|
-
if (!this.resumeHandler)
|
|
105
|
-
return Promise.reject(new Error('No card request is paused for the business to answer; attach with pauseOnly: true and wait for onPaused.'));
|
|
106
|
-
if (!result || typeof result !== 'object' || typeof result.status !== 'string')
|
|
107
|
-
return Promise.reject(new Error('resume takes the authorization as read: an object with a status.'));
|
|
108
|
-
return this.resumeHandler(result);
|
|
109
|
-
}
|
|
110
102
|
preparing() {
|
|
111
103
|
this.preparationUsed = true;
|
|
112
104
|
this.set({ status: 'awaiting_approval', authorizationId: null });
|
|
@@ -299,6 +291,20 @@ export class CheckoutLifecycle {
|
|
|
299
291
|
return; // do not hide an outstanding/completed payment behind a later unsupported request
|
|
300
292
|
this.set({ ...this.state, status: 'unsupported', reason });
|
|
301
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Nike's order after its card was refused before it left (pre-claim.ts nikeOrderPreClaim): the card reached
|
|
296
|
+
* Nike's store and the order that would charge it never did, so a checkout still under way ends `failed` with
|
|
297
|
+
* the refusal's reason, nothing charged, and stays failed when the approval it was waiting on lands after the
|
|
298
|
+
* refusal (handedOff). A checkout that already ended keeps its state. Either way the attachment holds until the
|
|
299
|
+
* application starts another attempt.
|
|
300
|
+
*/
|
|
301
|
+
merchantOrderRefused(reason) {
|
|
302
|
+
this.held = true;
|
|
303
|
+
if (this.cancelled || FINAL_STATUSES.has(this.state.status))
|
|
304
|
+
return;
|
|
305
|
+
this.orderRefusal = reason;
|
|
306
|
+
this.set({ ...this.state, status: 'failed', reason });
|
|
307
|
+
}
|
|
302
308
|
/**
|
|
303
309
|
* A card request that only a prepared checkout pays (an Adyen merchant
|
|
304
310
|
* profile's, or a Fiserv card capture) arrived with no preparation on this
|
|
@@ -410,6 +416,13 @@ export class CheckoutLifecycle {
|
|
|
410
416
|
if (this.merchantAborted)
|
|
411
417
|
return;
|
|
412
418
|
this.settled = true;
|
|
419
|
+
if (this.orderRefusal) {
|
|
420
|
+
// Nike's order was refused while this approval was on its way: the answer lands, and the checkout stays failed.
|
|
421
|
+
this.held = true;
|
|
422
|
+
this.set({ status: 'failed', authorizationId: replay.authorizationId, mode: replay.mode ?? 'token', reason: this.orderRefusal,
|
|
423
|
+
...(this.state.preparationId ? { preparationId: this.state.preparationId } : {}) });
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
413
426
|
if (this.ownedShopOrderId) {
|
|
414
427
|
this.held = true;
|
|
415
428
|
this.set({ status: 'completed', authorizationId: replay.authorizationId, mode: 'token', orderId: this.ownedShopOrderId });
|
|
@@ -600,6 +613,7 @@ export class CheckoutLifecycle {
|
|
|
600
613
|
throw new Error('This attachment delivered an unbound Stripe token; reconcile the merchant order and use a separately validated checkout flow.');
|
|
601
614
|
this.held = false;
|
|
602
615
|
this.merchantAborted = false;
|
|
616
|
+
this.orderRefusal = null;
|
|
603
617
|
this.set({ status: 'idle', authorizationId: null });
|
|
604
618
|
}
|
|
605
619
|
}
|
|
@@ -41,6 +41,11 @@ declare function merchantCardEndpointFactsRefusal(profile: any, facts: any, agen
|
|
|
41
41
|
code: any;
|
|
42
42
|
reason: any;
|
|
43
43
|
} | null;
|
|
44
|
+
declare var NIKE_ORDER: any;
|
|
45
|
+
declare var NIKE_ORDER_REFUSALS: any;
|
|
46
|
+
declare function nikeOrderHost(url: any): boolean;
|
|
47
|
+
declare function nikeOrderRequest(url: any, method: any): boolean;
|
|
48
|
+
declare function nikeOrderRefusal(url: any, method: any, body: any, approved: any): "body_unreadable" | "amount_mismatch" | "currency_mismatch" | "request_unrecognized" | "total_unreadable" | "currency_unreadable" | "approval_unknown" | null;
|
|
44
49
|
declare var MERCHANT_CARD_ENDPOINT_LIMITS: Readonly<{
|
|
45
50
|
bodyBytes: number;
|
|
46
51
|
answerBytes: number;
|
|
@@ -119,4 +124,4 @@ declare function merchantCardEndpointNavigationAnswer(profile: any, answer: any,
|
|
|
119
124
|
location: string;
|
|
120
125
|
reason?: undefined;
|
|
121
126
|
};
|
|
122
|
-
export { HILTON_CREATE_RESERVATION_DOCUMENTS, MERCHANT_CARD_ENDPOINT_CLIENT_TABLE, MERCHANT_CARD_ENDPOINT_FACTS_TEXT_MAX, MERCHANT_CARD_ENDPOINT_FACT_READERS, MERCHANT_CARD_ENDPOINT_LIMITS, MERCHANT_CARD_ENDPOINT_MODE, MERCHANT_CARD_ENDPOINT_PROFILES, MERCHANT_CARD_ENDPOINT_PSP, MERCHANT_CARD_ENDPOINT_RECOGNIZERS, SubstitutionError, assertMerchantCardEndpoint, encryptMerchantCardEndpointBody, encryptedMerchantEndpointRequest, matchMerchantCardEndpoint, matchMerchantCardEndpointResend, merchantCardEndpointAmount, merchantCardEndpointAnswer, merchantCardEndpointAnswerRefusal, merchantCardEndpointBodyRefusal, merchantCardEndpointById, merchantCardEndpointCarriesCard, merchantCardEndpointCheckoutKey, merchantCardEndpointEncrypts, merchantCardEndpointFactsRefusal, merchantCardEndpointFactsRole, merchantCardEndpointLive, merchantCardEndpointMatches, merchantCardEndpointNavigationAnswer, merchantCardEndpointPasses, merchantCardEndpointRecognizerById, merchantCardEndpointRequestOrigin, merchantCardEndpointSessionRefusal, merchantCardEndpointSessionTtl, merchantEndpointRequest, projectMerchantCardEndpointFacts, readMerchantCardEndpointFacts, responseCardLeak, substituteMerchantCardEndpoint, trustedMerchantCardEndpoint };
|
|
127
|
+
export { HILTON_CREATE_RESERVATION_DOCUMENTS, MERCHANT_CARD_ENDPOINT_CLIENT_TABLE, MERCHANT_CARD_ENDPOINT_FACTS_TEXT_MAX, MERCHANT_CARD_ENDPOINT_FACT_READERS, MERCHANT_CARD_ENDPOINT_LIMITS, MERCHANT_CARD_ENDPOINT_MODE, MERCHANT_CARD_ENDPOINT_PROFILES, MERCHANT_CARD_ENDPOINT_PSP, MERCHANT_CARD_ENDPOINT_RECOGNIZERS, NIKE_ORDER, NIKE_ORDER_REFUSALS, SubstitutionError, assertMerchantCardEndpoint, encryptMerchantCardEndpointBody, encryptedMerchantEndpointRequest, matchMerchantCardEndpoint, matchMerchantCardEndpointResend, merchantCardEndpointAmount, merchantCardEndpointAnswer, merchantCardEndpointAnswerRefusal, merchantCardEndpointBodyRefusal, merchantCardEndpointById, merchantCardEndpointCarriesCard, merchantCardEndpointCheckoutKey, merchantCardEndpointEncrypts, merchantCardEndpointFactsRefusal, merchantCardEndpointFactsRole, merchantCardEndpointLive, merchantCardEndpointMatches, merchantCardEndpointNavigationAnswer, merchantCardEndpointPasses, merchantCardEndpointRecognizerById, merchantCardEndpointRequestOrigin, merchantCardEndpointSessionRefusal, merchantCardEndpointSessionTtl, merchantEndpointRequest, nikeOrderHost, nikeOrderRefusal, nikeOrderRequest, projectMerchantCardEndpointFacts, readMerchantCardEndpointFacts, responseCardLeak, substituteMerchantCardEndpoint, trustedMerchantCardEndpoint };
|