@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
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { ApiModule } from './api-module.js';
|
|
2
|
+
import { stripePaymentIntentConfirmRequest } from './requests.js';
|
|
3
|
+
import { AgentcardError } from './api-types.js';
|
|
4
|
+
/** Your server's words for withdrawing a purchase (`approvals.cancel`); anything else is refused before any call. */
|
|
5
|
+
export const CANCEL_REASONS = ['person_closed_sheet', 'person_changed_mind', 'business_cancelled'];
|
|
6
|
+
/** How long `awaitResult` waits when the call names no `timeout_ms`. */
|
|
7
|
+
const AWAIT_RESULT_TIMEOUT_MS = 60_000;
|
|
8
|
+
/**
|
|
9
|
+
* The sandbox request: a first run's purchase, naming no processor. Under a sandbox client
|
|
10
|
+
* `approvals.create({ request: 'sandbox' })` sends this; the sandbox completes it without reaching any
|
|
11
|
+
* processor. A live client refuses it before any call (`sandbox_request_in_live`).
|
|
12
|
+
*/
|
|
13
|
+
export const SANDBOX_REQUEST = stripePaymentIntentConfirmRequest({
|
|
14
|
+
origin: 'https://sandbox.agentcard.sh',
|
|
15
|
+
intent: { id: 'pi_sandbox', client_secret: 'pi_sandbox_secret_sandbox', publishable_key: 'pk_test_sandbox' },
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* The origin a paused request pays from, when its `origin` header is one Agentcard admits as `checkout_origin`
|
|
19
|
+
* (an exact https origin, or http://localhost for a local run); null otherwise.
|
|
20
|
+
*/
|
|
21
|
+
function checkoutOriginOf(request) {
|
|
22
|
+
const header = Object.entries(request.headers ?? {}).find(([k]) => k.toLowerCase() === 'origin')?.[1];
|
|
23
|
+
if (typeof header !== 'string')
|
|
24
|
+
return null;
|
|
25
|
+
try {
|
|
26
|
+
const u = new URL(header);
|
|
27
|
+
return u.origin === header && !u.username && !u.password && (u.protocol === 'https:' || (u.protocol === 'http:' && u.hostname === 'localhost')) ? header : null;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** The paying card as the API names it, read for its type; null for null or anything that is not one. */
|
|
34
|
+
function cardOf(v) {
|
|
35
|
+
if (!v || typeof v !== 'object')
|
|
36
|
+
return null;
|
|
37
|
+
const c = v;
|
|
38
|
+
if (typeof c.id !== 'string' || !c.id)
|
|
39
|
+
return null;
|
|
40
|
+
return { id: c.id, name: typeof c.name === 'string' ? c.name : '', last4: typeof c.last4 === 'string' ? c.last4 : null, brand: typeof c.brand === 'string' ? c.brand : null, reason: typeof c.reason === 'string' ? c.reason : null };
|
|
41
|
+
}
|
|
42
|
+
/** The choosable cards as the API lists them; a list only, every entry a card. */
|
|
43
|
+
function cardsOf(v) {
|
|
44
|
+
if (!Array.isArray(v))
|
|
45
|
+
return undefined;
|
|
46
|
+
const out = [];
|
|
47
|
+
for (const raw of v) {
|
|
48
|
+
const card = cardOf(raw);
|
|
49
|
+
if (!card)
|
|
50
|
+
continue;
|
|
51
|
+
const c = raw;
|
|
52
|
+
out.push({ ...card, recommended: c.recommended === true, ...(c.auto_approve === true ? { auto_approve: true } : {}) });
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
/** The fields a read carries beside its status, typed, and nothing the row does not carry. */
|
|
57
|
+
function fieldsOf(a) {
|
|
58
|
+
const out = {};
|
|
59
|
+
if ('request_id' in a)
|
|
60
|
+
out.request_id = a.request_id ?? null;
|
|
61
|
+
if ('external_user_id' in a)
|
|
62
|
+
out.external_user_id = a.external_user_id ?? null;
|
|
63
|
+
if (typeof a.interval === 'number')
|
|
64
|
+
out.interval = a.interval;
|
|
65
|
+
if (typeof a.poll_interval_ms === 'number')
|
|
66
|
+
out.poll_interval_ms = a.poll_interval_ms;
|
|
67
|
+
if (typeof a.expires_at === 'string')
|
|
68
|
+
out.expires_at = a.expires_at;
|
|
69
|
+
if ('terminal_reason' in a)
|
|
70
|
+
out.terminal_reason = a.terminal_reason ?? null;
|
|
71
|
+
if (typeof a.execution_mode === 'string')
|
|
72
|
+
out.execution_mode = a.execution_mode;
|
|
73
|
+
if (typeof a.execution_reason === 'string')
|
|
74
|
+
out.execution_reason = a.execution_reason;
|
|
75
|
+
if (typeof a.execution_detail === 'string')
|
|
76
|
+
out.execution_detail = a.execution_detail;
|
|
77
|
+
if ('card' in a)
|
|
78
|
+
out.card = cardOf(a.card);
|
|
79
|
+
const cards = cardsOf(a.cards);
|
|
80
|
+
if (cards)
|
|
81
|
+
out.cards = cards;
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
/** A purchase as one read answers it: the status, what approved it, the request fields and the settlement. */
|
|
85
|
+
function resultOf(a) {
|
|
86
|
+
// The settlement as the API carries it (the same object as on the finishing webhook), read defensively: an object
|
|
87
|
+
// with a status word, or null when there is nothing to read back; absent from an older API.
|
|
88
|
+
const settlement = 'settlement' in a
|
|
89
|
+
? (a.settlement && typeof a.settlement === 'object' && typeof a.settlement.status === 'string' ? a.settlement : null)
|
|
90
|
+
: undefined;
|
|
91
|
+
// The API answers the link as `approvalUrl` on its reads; `approval_url` is read too.
|
|
92
|
+
const approvalUrl = typeof a.approval_url === 'string' ? a.approval_url : typeof a.approvalUrl === 'string' ? a.approvalUrl : undefined;
|
|
93
|
+
return {
|
|
94
|
+
...(typeof a.id === 'string' ? { id: a.id } : {}),
|
|
95
|
+
status: a.status,
|
|
96
|
+
...(typeof a.approved_with === 'string' ? { approved_with: a.approved_with } : {}),
|
|
97
|
+
...fieldsOf(a),
|
|
98
|
+
...(settlement === undefined ? {} : { settlement }),
|
|
99
|
+
...(approvalUrl && a.status === 'awaiting_approval' ? { approval_url: approvalUrl } : {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** A random idempotency key for one create, so a retried call makes one purchase. */
|
|
103
|
+
function idempotencyKey() {
|
|
104
|
+
const c = globalThis.crypto;
|
|
105
|
+
if (c?.randomUUID)
|
|
106
|
+
return c.randomUUID();
|
|
107
|
+
return 'ik_' + Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
108
|
+
}
|
|
109
|
+
/** `agentcard.approvals`: constructed by the client, never on its own. */
|
|
110
|
+
export class ApprovalsModule extends ApiModule {
|
|
111
|
+
clientIsSandbox;
|
|
112
|
+
constructor(t, clientIsSandbox) {
|
|
113
|
+
super(t);
|
|
114
|
+
this.clientIsSandbox = clientIsSandbox;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Creates the purchase, paused for the person's approval on Agentcard's page, for the person `user_id`
|
|
118
|
+
* names. `execution_mode: 'autopilot'` means the person's rule took it and no approval follows.
|
|
119
|
+
* `request: 'sandbox'` is the first-run form: under a sandbox client (`sandbox: true`, an `sk_test_`
|
|
120
|
+
* credential, or a mode the token exchange named) it sends the sandbox request; a live client refuses it
|
|
121
|
+
* before the create leaves (`sandbox_request_in_live`). Every create carries an idempotency key, so a
|
|
122
|
+
* retried call makes one purchase.
|
|
123
|
+
*/
|
|
124
|
+
async create(input) {
|
|
125
|
+
const user = input.user_id;
|
|
126
|
+
if (typeof user !== 'string' || !user)
|
|
127
|
+
throw new AgentcardError('not_connected', 'Name user_id: a person connected to your client. Refused before any call.');
|
|
128
|
+
let request;
|
|
129
|
+
if (input.request === 'sandbox') {
|
|
130
|
+
// A client that was not named sandbox may still learn it from the token exchange; the create itself has not left.
|
|
131
|
+
if (!this.clientIsSandbox())
|
|
132
|
+
await this.t.bearer();
|
|
133
|
+
if (!this.clientIsSandbox())
|
|
134
|
+
throw new AgentcardError('sandbox_request_in_live', "request: 'sandbox' is for a sandbox client. Under live credentials build the processor's request (checkout.requests.build) or hand over the request a browser purchase paused on. Refused before any call.");
|
|
135
|
+
request = SANDBOX_REQUEST;
|
|
136
|
+
}
|
|
137
|
+
else if (input.request && typeof input.request === 'object' && typeof input.request.url === 'string') {
|
|
138
|
+
request = input.request;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
throw new AgentcardError('invalid_request', "request must be a paused request ({ url, method, headers, body }) or 'sandbox'. Refused before any call.");
|
|
142
|
+
}
|
|
143
|
+
// The origin the purchase is paid from goes in the create (Agentcard keeps no `origin` header from the paused
|
|
144
|
+
// request), so a rule the person confirmed can take it; named on the call, else the paused request's own.
|
|
145
|
+
const checkoutOrigin = input.checkout_origin ?? checkoutOriginOf(request);
|
|
146
|
+
const body = await this.request('/v2/checkout/authorizations', {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
body: {
|
|
149
|
+
user, merchant: input.merchant, amount: input.amount, currency: input.currency, psp: input.psp ?? 'stripe', mode: input.mode ?? 'token', request,
|
|
150
|
+
...(input.return_url ? { return_url: input.return_url } : {}), ...(checkoutOrigin ? { checkout_origin: checkoutOrigin } : {}), ...(input.card_id ? { card_id: input.card_id } : {}),
|
|
151
|
+
},
|
|
152
|
+
headers: { 'idempotency-key': input.idempotency_key ?? idempotencyKey() },
|
|
153
|
+
});
|
|
154
|
+
const approvalUrl = body.approval_url ?? body.approvalUrl;
|
|
155
|
+
return {
|
|
156
|
+
id: body.id, status: body.status, ...fieldsOf(body),
|
|
157
|
+
...(approvalUrl ? { approval_url: approvalUrl } : {}), ...(typeof body.return_url === 'string' ? { return_url: body.return_url } : {}),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* One read of a purchase, with no wait: its status, what approved it, the request fields and the settlement
|
|
162
|
+
* once it finished. The way to ask "is it decided yet?" from a handler that cannot wait; `awaitResult` is the
|
|
163
|
+
* way to wait. `slow_down` is waited out.
|
|
164
|
+
*/
|
|
165
|
+
async get(authorizationId) {
|
|
166
|
+
const a = await this.read(`/v2/checkout/authorizations/${encodeURIComponent(authorizationId)}`);
|
|
167
|
+
return resultOf(a);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Withdraws a purchase that still awaits the person, in your server's own words: the person closed the
|
|
171
|
+
* page (`person_closed_sheet`), the person changed their mind (`person_changed_mind`), or a reason of your
|
|
172
|
+
* own (`business_cancelled`). The purchase reads `status: 'cancelled'` from then on, and the reason is its
|
|
173
|
+
* `terminal_reason` on every read and on the `checkout_authorization.cancelled` webhook. Idempotent: a
|
|
174
|
+
* purchase already withdrawn answers what it became. One the person already approved cannot be withdrawn
|
|
175
|
+
* (`409 already_finalized` once it finished, `409 outcome_unknown` while the card is with the processor).
|
|
176
|
+
*/
|
|
177
|
+
async cancel(authorizationId, opts) {
|
|
178
|
+
const reason = opts?.reason;
|
|
179
|
+
if (!CANCEL_REASONS.includes(reason))
|
|
180
|
+
throw new AgentcardError('invalid_cancel_reason', `reason must be one of ${CANCEL_REASONS.join(', ')}.`);
|
|
181
|
+
const body = await this.request(`/v2/checkout/authorizations/${encodeURIComponent(authorizationId)}/cancel`, { method: 'POST', body: { reason } });
|
|
182
|
+
const stamped = CANCEL_REASONS.includes(body.reason) ? body.reason : reason;
|
|
183
|
+
return { id: body.id ?? authorizationId, status: 'cancelled', reason: stamped, terminal_reason: (typeof body.terminal_reason === 'string' ? body.terminal_reason : stamped), request_id: body.request_id ?? null };
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Polls the purchase until it leaves `awaiting_approval`; `{ status: 'timeout' }` at the deadline (60 s unless
|
|
187
|
+
* `timeout_ms` names another). The first read's `interval` (seconds) is the least this waits between reads, and
|
|
188
|
+
* a `slow_down` answer backs off to the interval it names and keeps polling.
|
|
189
|
+
*/
|
|
190
|
+
async awaitResult(authorizationId, opts = {}) {
|
|
191
|
+
let intervalMs;
|
|
192
|
+
const timeoutMs = opts.timeout_ms ?? AWAIT_RESULT_TIMEOUT_MS;
|
|
193
|
+
const deadline = Date.now() + timeoutMs;
|
|
194
|
+
return this.poll(async () => {
|
|
195
|
+
let a;
|
|
196
|
+
try {
|
|
197
|
+
// The shared read waits out slow_down up to this call's deadline; past it the refusal is the poll
|
|
198
|
+
// loop's cue to space its next read by the interval named, and the deadline reads `timeout`.
|
|
199
|
+
a = await this.read(`/v2/checkout/authorizations/${encodeURIComponent(authorizationId)}`, { deadline, onInterval: (ms) => { intervalMs = ms; } });
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (err instanceof AgentcardError && err.code === 'slow_down')
|
|
203
|
+
return undefined;
|
|
204
|
+
throw err;
|
|
205
|
+
}
|
|
206
|
+
if (typeof a.interval === 'number')
|
|
207
|
+
intervalMs = a.interval * 1000;
|
|
208
|
+
if (a.status === 'awaiting_approval')
|
|
209
|
+
return undefined;
|
|
210
|
+
return resultOf(a);
|
|
211
|
+
}, timeoutMs, () => ({ status: 'timeout' }), () => intervalMs);
|
|
212
|
+
}
|
|
213
|
+
}
|
package/dist/buy.d.ts
CHANGED
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The buy module of the SDK: `agentcard.buy.*`. The Purchase API from the
|
|
3
|
-
* same client the
|
|
3
|
+
* same client the checkout module uses: one pair of client credentials, one
|
|
4
4
|
* token. A business asks for a cart on behalf of a person it connected,
|
|
5
5
|
* confirms the cart by its hash, and, when it already holds an approval the
|
|
6
|
-
* person gave
|
|
6
|
+
* person gave, names that approval on the confirm so the API places
|
|
7
7
|
* against it and asks the person for nothing a second time (decision 234).
|
|
8
|
-
* With `approval: 'voice'` the confirm asks the API to mint the purchase's
|
|
9
|
-
* own approval instead of an approval page, the business runs the key word
|
|
10
|
-
* in its app on that id, and the same confirm placed again completes the
|
|
11
|
-
* order (decision 237).
|
|
12
8
|
*
|
|
13
9
|
* Every call names `user_id`, the person the connect exchange returned, so a
|
|
14
10
|
* server serving many people never buys for the wrong one. A person who is
|
|
15
11
|
* not connected to this client is refused with `user_not_connected`.
|
|
16
12
|
*/
|
|
17
13
|
import { ApiModule, type ApiTransport } from './api-module.js';
|
|
18
|
-
import { AgentcardError } from './
|
|
19
|
-
/** Where a turn stands. `needs_input` is the common case: a question, or a cart waiting for its confirm; `
|
|
20
|
-
export type BuyStatus = 'needs_input' | '
|
|
21
|
-
/** How a confirm that pays with the person's own card asks them: `page`, Agentcard's approval page on `approval_url` (the default); `voice`, the key word inside your app on the purchase's own `authorization_id`. */
|
|
22
|
-
export type BuyApproval = 'voice' | 'page';
|
|
23
|
-
/** The two ways a purchase approved by voice ends without an order: the person declined it, or the approval ran out before a confirm placed against it. */
|
|
24
|
-
export type BuyVoiceDeclineCode = 'voice_declined' | 'approval_expired';
|
|
25
|
-
/** The one refusal a store makes under `approval: 'voice'`: its connector cannot place under a voice verdict, and the business takes its own path. A 409, as `BuyError.code`. */
|
|
26
|
-
export declare const VOICE_EXECUTION_UNSUPPORTED = "voice_execution_unsupported";
|
|
14
|
+
import { AgentcardError } from './api-types.js';
|
|
15
|
+
/** Where a turn stands. `needs_input` is the common case: a question, or a cart waiting for its confirm; `approved_not_charged` is a sandbox browser checkout the person approved, where the card was never sent to the store. */
|
|
16
|
+
export type BuyStatus = 'needs_input' | 'order_placed' | 'partially_placed' | 'declined' | 'approved_not_charged';
|
|
27
17
|
/** One line of a cart as the API shows it; `product_id` is the merchant's id for the line, null on a cart recorded before it was kept. */
|
|
28
18
|
export interface BuyCartLine {
|
|
29
19
|
name: string;
|
|
@@ -50,7 +40,10 @@ export interface BuyCart {
|
|
|
50
40
|
/** The store the cart is at, when one is known: for `retail`, the retailer every line is at. Null otherwise. */
|
|
51
41
|
store: BuyStore | null;
|
|
52
42
|
items: BuyCartLine[];
|
|
53
|
-
|
|
43
|
+
/** Fees on top of the items, or null while the store has not quoted them (`serviceFeesStatus` says which). */
|
|
44
|
+
serviceFeesCents: number | null;
|
|
45
|
+
/** `known` when `serviceFeesCents` is the quoted amount, `pending` before the store quotes its fees, `unknown` otherwise. */
|
|
46
|
+
serviceFeesStatus: 'known' | 'pending' | 'unknown';
|
|
54
47
|
tipCents: number;
|
|
55
48
|
totalCents: number;
|
|
56
49
|
approvedCeilingCents: number | null;
|
|
@@ -78,11 +71,10 @@ export interface BuyPaymentSource {
|
|
|
78
71
|
* The typed outcome of a checkout attempt, every field null when no checkout
|
|
79
72
|
* ran on the call. `decline_code` is a refusal's machine code
|
|
80
73
|
* (`authorization_not_approved`, `authorization_mismatch`,
|
|
81
|
-
* `authorization_spent`, `user_not_connected`,
|
|
82
|
-
*
|
|
74
|
+
* `authorization_spent`, `user_not_connected`, a gate's or a merchant's
|
|
75
|
+
* code); `approval_url` is
|
|
83
76
|
* where the person approves when the confirm paused for one;
|
|
84
|
-
* `authorization_id` is the approval the order was placed against
|
|
85
|
-
* `needs_approval` turn, the one the person is about to give by voice.
|
|
77
|
+
* `authorization_id` is the approval the order was placed against.
|
|
86
78
|
*/
|
|
87
79
|
export interface BuyOutcome {
|
|
88
80
|
order_id: string | null;
|
|
@@ -226,30 +218,7 @@ export type BuyDeclined = BuyTurn & {
|
|
|
226
218
|
status: 'declined';
|
|
227
219
|
};
|
|
228
220
|
/** True for a turn the API declined; `decline_code` says why (it is null when the loop refused in prose only). */
|
|
229
|
-
export declare function isBuyDeclined(turn: BuyTurn
|
|
230
|
-
/** A confirm under `approval: 'voice'` waiting for the person: `authorization_id` is the purchase's own approval, minted by the API, for `voice.challengeForHost`. `isBuyNeedsApproval` narrows to it. */
|
|
231
|
-
export type BuyNeedsApproval = BuyTurn & {
|
|
232
|
-
status: 'needs_approval';
|
|
233
|
-
authorization_id: string;
|
|
234
|
-
};
|
|
235
|
-
/** True for a confirm waiting for the person's verdict by voice; `authorization_id` is the id your app runs the key word on. */
|
|
236
|
-
export declare function isBuyNeedsApproval(turn: BuyTurn | BuyVoiceUnsupported): turn is BuyNeedsApproval;
|
|
237
|
-
/**
|
|
238
|
-
* The store's refusal to place under a voice verdict, as `buy.approveByVoice`
|
|
239
|
-
* returns it instead of throwing: `status: 'voice_execution_unsupported'`,
|
|
240
|
-
* the conversation, the approval the API had minted when it had, and the
|
|
241
|
-
* `BuyError` as the confirm raised it. The business takes its own path.
|
|
242
|
-
*/
|
|
243
|
-
export interface BuyVoiceUnsupported {
|
|
244
|
-
status: typeof VOICE_EXECUTION_UNSUPPORTED;
|
|
245
|
-
conversation_id: string;
|
|
246
|
-
authorization_id: string | null;
|
|
247
|
-
error: BuyError;
|
|
248
|
-
}
|
|
249
|
-
/** True when the store could not place under a voice verdict; `error` is the refusal. */
|
|
250
|
-
export declare function isBuyVoiceUnsupported(turn: BuyTurn | BuyVoiceUnsupported): turn is BuyVoiceUnsupported;
|
|
251
|
-
/** What `buy.approveByVoice` returns: the final turn (`order_placed`, `declined`, or `needs_approval` when the verdict was still out on the retry), or the store's refusal to run under a voice verdict. */
|
|
252
|
-
export type BuyVoiceTurn = BuyTurn | BuyVoiceUnsupported;
|
|
221
|
+
export declare function isBuyDeclined(turn: BuyTurn): turn is BuyDeclined;
|
|
253
222
|
/** An order a conversation placed, from the ledger. */
|
|
254
223
|
export interface BuyOrder {
|
|
255
224
|
order_id: string | null;
|
|
@@ -318,9 +287,8 @@ export interface BuyConfirmInput {
|
|
|
318
287
|
/** The hash of the cart the person saw (`turn.cart.hash`), or several carts' hashes to place each as its own order. */
|
|
319
288
|
confirm: string | string[];
|
|
320
289
|
/**
|
|
321
|
-
* An approval the business already holds for this purchase, `cauth_
|
|
322
|
-
*
|
|
323
|
-
* approved. The API places the cart against it and asks the person for
|
|
290
|
+
* An approval the business already holds for this purchase, `cauth_…`.
|
|
291
|
+
* The API places the cart against it and asks the person for
|
|
324
292
|
* nothing a second time. Sent only when named.
|
|
325
293
|
*/
|
|
326
294
|
authorization_id?: string;
|
|
@@ -328,16 +296,6 @@ export interface BuyConfirmInput {
|
|
|
328
296
|
delivery_address?: BuyDeliveryAddress;
|
|
329
297
|
/** `'vault'`: pay with the person's own stored card; the confirm pauses with an `approval_url` until they approve. */
|
|
330
298
|
payment_source?: 'vault';
|
|
331
|
-
/**
|
|
332
|
-
* How the person approves a confirm that pays with their own card. `page`
|
|
333
|
-
* (the default, and today's behaviour): the API answers `declined` with the
|
|
334
|
-
* `approval_url` they approve on. `voice`: the API mints the purchase's
|
|
335
|
-
* own approval and answers `needs_approval` with its `authorization_id`;
|
|
336
|
-
* your app runs the key word on it (`voice.challengeForHost(id)`), and the
|
|
337
|
-
* same confirm sent again places the order, or answers `declined` with
|
|
338
|
-
* `voice_declined` or `approval_expired`. Sent only when named.
|
|
339
|
-
*/
|
|
340
|
-
approval?: BuyApproval;
|
|
341
299
|
/**
|
|
342
300
|
* On a repeat confirm of a browser cart waiting for the person's approval,
|
|
343
301
|
* hold up to 25 seconds and answer the moment they decide, instead of
|
|
@@ -348,28 +306,6 @@ export interface BuyConfirmInput {
|
|
|
348
306
|
/** How long this call waits for the turn. Default 130 seconds. */
|
|
349
307
|
timeout_ms?: number;
|
|
350
308
|
}
|
|
351
|
-
/** `buy.approveByVoice`: the cart, the person, and the approval your app runs on the id the API mints. */
|
|
352
|
-
export interface BuyApproveByVoiceInput {
|
|
353
|
-
/** The person the connect exchange returned. Required on every call. */
|
|
354
|
-
user_id: string;
|
|
355
|
-
/** The conversation the cart was shown in. */
|
|
356
|
-
conversation_id: string;
|
|
357
|
-
/** The hash of the cart the person saw (`turn.cart.hash`), or several carts' hashes. */
|
|
358
|
-
confirm: string | string[];
|
|
359
|
-
/** The delivery address the cart was built for, when the ask named one. */
|
|
360
|
-
delivery_address?: BuyDeliveryAddress;
|
|
361
|
-
/**
|
|
362
|
-
* Your app's approval: given the `authorization_id` the API minted (and the
|
|
363
|
-
* `needs_approval` turn it rode on), mint the key word with
|
|
364
|
-
* `voice.challengeForHost(authorizationId)`, hand the bundle to the app,
|
|
365
|
-
* and resolve once the verdict is in (`voice.awaitResult`, or the app's
|
|
366
|
-
* own word). The confirm is sent again when this resolves; a rejection is
|
|
367
|
-
* thrown as it came and nothing is placed.
|
|
368
|
-
*/
|
|
369
|
-
challenge: (authorizationId: string, turn: BuyNeedsApproval) => Promise<void>;
|
|
370
|
-
/** How long each confirm waits for its turn. Default 130 seconds. */
|
|
371
|
-
timeout_ms?: number;
|
|
372
|
-
}
|
|
373
309
|
/** `buy.conversation`: one read of where a conversation stands. */
|
|
374
310
|
export interface BuyConversationInput {
|
|
375
311
|
/** The person the connect exchange returned. Required on every call. */
|
|
@@ -381,11 +317,10 @@ export interface BuyConversationInput {
|
|
|
381
317
|
* API's (`user_not_connected`, `authorization_not_approved`,
|
|
382
318
|
* `authorization_mismatch`, `authorization_spent`, `turn_in_progress`,
|
|
383
319
|
* `delivery_address_changed`, `cart_changed`, `nothing_to_confirm`,
|
|
384
|
-
* `conversation_not_found`, `conversation_closed
|
|
385
|
-
* `voice_execution_unsupported`) or the client's own before any call
|
|
320
|
+
* `conversation_not_found`, `conversation_closed`) or the client's own before any call
|
|
386
321
|
* (`not_connected`, `invalid_ask`, `invalid_cart_hash`,
|
|
387
|
-
* `invalid_authorization_id`, `invalid_payment_source`,
|
|
388
|
-
* `missing_conversation_id
|
|
322
|
+
* `invalid_authorization_id`, `invalid_payment_source`,
|
|
323
|
+
* `missing_conversation_id`). `carts` carries the
|
|
389
324
|
* carts as they stand when the refusal named them, so a confirm of a changed
|
|
390
325
|
* cart reads the fresh hash from the error.
|
|
391
326
|
*/
|
|
@@ -416,8 +351,8 @@ export declare class BuyModule extends ApiModule {
|
|
|
416
351
|
ask(input: BuyAskInput): Promise<BuyTurn>;
|
|
417
352
|
/**
|
|
418
353
|
* Places the cart the person saw, by its hash, for the person `user_id`
|
|
419
|
-
* names. With `authorization_id`, the approval the person already gave
|
|
420
|
-
*
|
|
354
|
+
* names. With `authorization_id`, the approval the person already gave
|
|
355
|
+
* for this purchase, the API places against that approval and asks
|
|
421
356
|
* for nothing a second time; the answer carries `authorization_id` back.
|
|
422
357
|
* Without it the confirm runs as before: the person's rules, or the
|
|
423
358
|
* approval the API asks for on `approval_url`. A cart that changed since
|
|
@@ -427,22 +362,6 @@ export declare class BuyModule extends ApiModule {
|
|
|
427
362
|
* `authorization_spent`, and nothing is charged.
|
|
428
363
|
*/
|
|
429
364
|
confirm(input: BuyConfirmInput): Promise<BuyTurn>;
|
|
430
|
-
/**
|
|
431
|
-
* The whole approval by voice, for a business whose app holds the person:
|
|
432
|
-
* confirms the cart with the person's own card and `approval: 'voice'`,
|
|
433
|
-
* hands the `authorization_id` the API minted to your `challenge` (your
|
|
434
|
-
* app runs the key word on it; you resolve when the verdict is in), then
|
|
435
|
-
* sends the same confirm again and returns what it answered:
|
|
436
|
-
* `order_placed` with `order_id`, `declined` with `voice_declined` or
|
|
437
|
-
* `approval_expired`, or `needs_approval` again when the verdict was still
|
|
438
|
-
* out. A store whose connector cannot place under a voice verdict is
|
|
439
|
-
* returned as `status: 'voice_execution_unsupported'`, not thrown, so the
|
|
440
|
-
* business falls back to its own path; every other refusal throws as
|
|
441
|
-
* `buy.confirm` does. A first confirm the API completes without asking (a
|
|
442
|
-
* rule took it, or it declined outright) is returned as it came and
|
|
443
|
-
* `challenge` is never called. Two confirms at most; nothing is polled.
|
|
444
|
-
*/
|
|
445
|
-
approveByVoice(input: BuyApproveByVoiceInput): Promise<BuyVoiceTurn>;
|
|
446
365
|
/**
|
|
447
366
|
* One read of a conversation, with no wait: whether a turn is still
|
|
448
367
|
* running, the last checkout attempt, every order it placed from the
|
package/dist/buy.js
CHANGED
|
@@ -1,39 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The buy module of the SDK: `agentcard.buy.*`. The Purchase API from the
|
|
3
|
-
* same client the
|
|
3
|
+
* same client the checkout module uses: one pair of client credentials, one
|
|
4
4
|
* token. A business asks for a cart on behalf of a person it connected,
|
|
5
5
|
* confirms the cart by its hash, and, when it already holds an approval the
|
|
6
|
-
* person gave
|
|
6
|
+
* person gave, names that approval on the confirm so the API places
|
|
7
7
|
* against it and asks the person for nothing a second time (decision 234).
|
|
8
|
-
* With `approval: 'voice'` the confirm asks the API to mint the purchase's
|
|
9
|
-
* own approval instead of an approval page, the business runs the key word
|
|
10
|
-
* in its app on that id, and the same confirm placed again completes the
|
|
11
|
-
* order (decision 237).
|
|
12
8
|
*
|
|
13
9
|
* Every call names `user_id`, the person the connect exchange returned, so a
|
|
14
10
|
* server serving many people never buys for the wrong one. A person who is
|
|
15
11
|
* not connected to this client is refused with `user_not_connected`.
|
|
16
12
|
*/
|
|
17
13
|
import { ApiModule } from './api-module.js';
|
|
18
|
-
import { AgentcardError } from './
|
|
19
|
-
/** The one refusal a store makes under `approval: 'voice'`: its connector cannot place under a voice verdict, and the business takes its own path. A 409, as `BuyError.code`. */
|
|
20
|
-
export const VOICE_EXECUTION_UNSUPPORTED = 'voice_execution_unsupported';
|
|
14
|
+
import { AgentcardError } from './api-types.js';
|
|
21
15
|
/** True for a turn the API declined; `decline_code` says why (it is null when the loop refused in prose only). */
|
|
22
16
|
export function isBuyDeclined(turn) { return turn.status === 'declined'; }
|
|
23
|
-
/** True for a confirm waiting for the person's verdict by voice; `authorization_id` is the id your app runs the key word on. */
|
|
24
|
-
export function isBuyNeedsApproval(turn) { return turn.status === 'needs_approval' && typeof turn.authorization_id === 'string'; }
|
|
25
|
-
/** True when the store could not place under a voice verdict; `error` is the refusal. */
|
|
26
|
-
export function isBuyVoiceUnsupported(turn) { return turn.status === VOICE_EXECUTION_UNSUPPORTED; }
|
|
27
17
|
/**
|
|
28
18
|
* A refusal from the Purchase API, as an `AgentcardError` whose `code` is the
|
|
29
19
|
* API's (`user_not_connected`, `authorization_not_approved`,
|
|
30
20
|
* `authorization_mismatch`, `authorization_spent`, `turn_in_progress`,
|
|
31
21
|
* `delivery_address_changed`, `cart_changed`, `nothing_to_confirm`,
|
|
32
|
-
* `conversation_not_found`, `conversation_closed
|
|
33
|
-
* `voice_execution_unsupported`) or the client's own before any call
|
|
22
|
+
* `conversation_not_found`, `conversation_closed`) or the client's own before any call
|
|
34
23
|
* (`not_connected`, `invalid_ask`, `invalid_cart_hash`,
|
|
35
|
-
* `invalid_authorization_id`, `invalid_payment_source`,
|
|
36
|
-
* `missing_conversation_id
|
|
24
|
+
* `invalid_authorization_id`, `invalid_payment_source`,
|
|
25
|
+
* `missing_conversation_id`). `carts` carries the
|
|
37
26
|
* carts as they stand when the refusal named them, so a confirm of a changed
|
|
38
27
|
* cart reads the fresh hash from the error.
|
|
39
28
|
*/
|
|
@@ -69,13 +58,21 @@ function cartOf(v) {
|
|
|
69
58
|
merchant_name: typeof c.merchant_name === 'string' ? c.merchant_name : c.merchant,
|
|
70
59
|
store: storeOf(c.store),
|
|
71
60
|
items: Array.isArray(c.items) ? c.items : [],
|
|
72
|
-
|
|
61
|
+
...feesOf(c),
|
|
73
62
|
tipCents: typeof c.tipCents === 'number' ? c.tipCents : 0,
|
|
74
63
|
totalCents: typeof c.totalCents === 'number' ? c.totalCents : 0,
|
|
75
64
|
approvedCeilingCents: typeof c.approvedCeilingCents === 'number' ? c.approvedCeilingCents : null,
|
|
76
65
|
hash: c.hash,
|
|
77
66
|
};
|
|
78
67
|
}
|
|
68
|
+
/** A pending or unreadable fee stays null with its status, so it never reads as a genuine zero. */
|
|
69
|
+
function feesOf(c) {
|
|
70
|
+
const amount = typeof c.serviceFeesCents === 'number' ? c.serviceFeesCents : null;
|
|
71
|
+
const status = c.merchantFeesPending === true || c.serviceFeesStatus === 'pending' ? 'pending'
|
|
72
|
+
: (c.serviceFeesStatus === undefined || c.serviceFeesStatus === 'known')
|
|
73
|
+
&& amount !== null && Number.isSafeInteger(amount) && amount >= 0 ? 'known' : 'unknown';
|
|
74
|
+
return { serviceFeesCents: status === 'known' ? amount : null, serviceFeesStatus: status };
|
|
75
|
+
}
|
|
79
76
|
function storeOf(v) {
|
|
80
77
|
if (!v || typeof v !== 'object')
|
|
81
78
|
return null;
|
|
@@ -113,7 +110,7 @@ function outcomeOf(a) {
|
|
|
113
110
|
authorization_id: str(a.authorization_id),
|
|
114
111
|
};
|
|
115
112
|
}
|
|
116
|
-
const STATUSES = new Set(['needs_input', '
|
|
113
|
+
const STATUSES = new Set(['needs_input', 'order_placed', 'partially_placed', 'declined', 'approved_not_charged']);
|
|
117
114
|
function statusOf(v) { return typeof v === 'string' && STATUSES.has(v) ? v : 'needs_input'; }
|
|
118
115
|
function placementsOf(v) {
|
|
119
116
|
if (!Array.isArray(v))
|
|
@@ -215,8 +212,8 @@ export class BuyModule extends ApiModule {
|
|
|
215
212
|
}
|
|
216
213
|
/**
|
|
217
214
|
* Places the cart the person saw, by its hash, for the person `user_id`
|
|
218
|
-
* names. With `authorization_id`, the approval the person already gave
|
|
219
|
-
*
|
|
215
|
+
* names. With `authorization_id`, the approval the person already gave
|
|
216
|
+
* for this purchase, the API places against that approval and asks
|
|
220
217
|
* for nothing a second time; the answer carries `authorization_id` back.
|
|
221
218
|
* Without it the confirm runs as before: the person's rules, or the
|
|
222
219
|
* approval the API asks for on `approval_url`. A cart that changed since
|
|
@@ -232,11 +229,9 @@ export class BuyModule extends ApiModule {
|
|
|
232
229
|
if (hashes.length === 0 || hashes.some((h) => typeof h !== 'string' || !CART_HASH.test(h)))
|
|
233
230
|
refuse('invalid_cart_hash', 'confirm must be a cart hash from a previous turn (turn.cart.hash), or a list of them.');
|
|
234
231
|
if (input.authorization_id !== undefined && (typeof input.authorization_id !== 'string' || !/^cauth_/.test(input.authorization_id)))
|
|
235
|
-
refuse('invalid_authorization_id', 'authorization_id must be the approval
|
|
232
|
+
refuse('invalid_authorization_id', 'authorization_id must be the approval you hold for this purchase (cauth_…).');
|
|
236
233
|
if (input.payment_source !== undefined && input.payment_source !== 'vault')
|
|
237
234
|
refuse('invalid_payment_source', "payment_source must be 'vault' when named.");
|
|
238
|
-
if (input.approval !== undefined && input.approval !== 'voice' && input.approval !== 'page')
|
|
239
|
-
refuse('invalid_approval', "approval must be 'voice' or 'page' when named.");
|
|
240
235
|
const body = {
|
|
241
236
|
user_id,
|
|
242
237
|
conversation_id,
|
|
@@ -244,60 +239,10 @@ export class BuyModule extends ApiModule {
|
|
|
244
239
|
...(input.authorization_id ? { authorization_id: input.authorization_id } : {}),
|
|
245
240
|
...(input.delivery_address ? { delivery_address: input.delivery_address } : {}),
|
|
246
241
|
...(input.payment_source ? { payment_source: input.payment_source } : {}),
|
|
247
|
-
...(input.approval ? { approval: input.approval } : {}),
|
|
248
242
|
...(input.wait === true ? { wait: true } : {}),
|
|
249
243
|
};
|
|
250
244
|
return this.turn(body, input.timeout_ms);
|
|
251
245
|
}
|
|
252
|
-
/**
|
|
253
|
-
* The whole approval by voice, for a business whose app holds the person:
|
|
254
|
-
* confirms the cart with the person's own card and `approval: 'voice'`,
|
|
255
|
-
* hands the `authorization_id` the API minted to your `challenge` (your
|
|
256
|
-
* app runs the key word on it; you resolve when the verdict is in), then
|
|
257
|
-
* sends the same confirm again and returns what it answered:
|
|
258
|
-
* `order_placed` with `order_id`, `declined` with `voice_declined` or
|
|
259
|
-
* `approval_expired`, or `needs_approval` again when the verdict was still
|
|
260
|
-
* out. A store whose connector cannot place under a voice verdict is
|
|
261
|
-
* returned as `status: 'voice_execution_unsupported'`, not thrown, so the
|
|
262
|
-
* business falls back to its own path; every other refusal throws as
|
|
263
|
-
* `buy.confirm` does. A first confirm the API completes without asking (a
|
|
264
|
-
* rule took it, or it declined outright) is returned as it came and
|
|
265
|
-
* `challenge` is never called. Two confirms at most; nothing is polled.
|
|
266
|
-
*/
|
|
267
|
-
async approveByVoice(input) {
|
|
268
|
-
if (typeof input?.challenge !== 'function')
|
|
269
|
-
refuse('invalid_challenge', 'Name challenge: the function that runs the key word in your app on the authorization_id and resolves when the verdict is in.');
|
|
270
|
-
const confirm = {
|
|
271
|
-
user_id: input.user_id, conversation_id: input.conversation_id, confirm: input.confirm,
|
|
272
|
-
...(input.delivery_address ? { delivery_address: input.delivery_address } : {}),
|
|
273
|
-
payment_source: 'vault', approval: 'voice', ...(input.timeout_ms !== undefined ? { timeout_ms: input.timeout_ms } : {}),
|
|
274
|
-
};
|
|
275
|
-
const unsupported = (err, authorization_id) => err instanceof BuyError && err.code === VOICE_EXECUTION_UNSUPPORTED ? { status: VOICE_EXECUTION_UNSUPPORTED, conversation_id: err.conversation_id ?? input.conversation_id, authorization_id, error: err } : null;
|
|
276
|
-
let first;
|
|
277
|
-
try {
|
|
278
|
-
first = await this.confirm(confirm);
|
|
279
|
-
}
|
|
280
|
-
catch (err) {
|
|
281
|
-
const u = unsupported(err, null);
|
|
282
|
-
if (u)
|
|
283
|
-
return u;
|
|
284
|
-
throw err;
|
|
285
|
-
}
|
|
286
|
-
if (first.status !== 'needs_approval')
|
|
287
|
-
return first;
|
|
288
|
-
if (!isBuyNeedsApproval(first))
|
|
289
|
-
refuse('missing_authorization_id', 'The API asked for an approval by voice but named no authorization_id to run it on.');
|
|
290
|
-
await input.challenge(first.authorization_id, first);
|
|
291
|
-
try {
|
|
292
|
-
return await this.confirm(confirm);
|
|
293
|
-
}
|
|
294
|
-
catch (err) {
|
|
295
|
-
const u = unsupported(err, first.authorization_id);
|
|
296
|
-
if (u)
|
|
297
|
-
return u;
|
|
298
|
-
throw err;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
246
|
/**
|
|
302
247
|
* One read of a conversation, with no wait: whether a turn is still
|
|
303
248
|
* running, the last checkout attempt, every order it placed from the
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Written by scripts/generate-capabilities.mjs from capabilities.json. Do not edit; git ignores it.
|
|
2
2
|
/** capabilities.json's list, sorted; client.ts exports it as SUPPORTED_CAPABILITIES. */
|
|
3
|
-
export const DECLARED_CAPABILITIES = ["aci_split_card.v1", "amadeus_checkout_actions.v1", "aps_custom_merchant_page", "authorize_net_dpm_form", "barion_hosted_payment_page", "capture_context", "clover_card_token", "comgate_hosted_payment_page", "converge_hpp_process", "creditguard_pps_process", "cybersource_sa_token_create", "datatrans_secure_fields_tokenize", "ekashu_hosted_payment_page", "eximbay_hosted_payment_page", "fastspring_card_payment", "fiserv_card_capture", "gmo_shared_pk", "gopay_card_form", "gravy_session_fields_put", "hipay_vault_token", "juspay_txns.v1", "lyra_krypton_payment", "makecommerce_card_frame", "midtrans_card_token", "moneris_hosted_tokenization", "nexi_checkout_pay", "omise_card_token", "openpay_tokenizer", "paddle_tokenex_pay", "paddle_vgs_cards", "pay_nl_card_token", "payfast_card_pay", "paygent_token", "paymob_checkout_pay", "paymongo_checkout_pay", "paypal_card_fields", "payrails_device_encrypt", "payrexx_card_frame", "paytrail_hosted_payment_page", "payu_latam_webcheckout_card", "pelecard_transaction", "pin_payments_card_token", "poynt_collect_nonce", "primer_payment_instruments", "przelewy24_hosted_payment_page", "quickpay_hosted_payment_page", "redsys_hosted_payment_page", "revolut_card_field", "sbps_token_jsonp", "shiji_sts_pinned_key", "sumup_checkout_process", "tap_card_sdk_token", "toast_pinned_key", "tokenex_iframe_tokenize", "transbank_webpay_hosted_payment_page", "twoc2p_secure_pay", "verifone_card_capture", "wix_payments_tokenize", "worldline_mycheckout_form", "worldpay_eprotect_jsonp", "wspay_confirm", "xendit_card_token"];
|
|
3
|
+
export const DECLARED_CAPABILITIES = ["aci_split_card.v1", "amadeus_checkout_actions.v1", "aps_custom_merchant_page", "authorize_net_dpm_form", "barion_hosted_payment_page", "bluesnap_hosted_payment_fields", "capture_context", "clover_card_token", "comgate_hosted_payment_page", "converge_hpp_process", "creditguard_pps_process", "cybersource_sa_token_create", "datatrans_secure_fields_tokenize", "ekashu_hosted_payment_page", "eximbay_hosted_payment_page", "fastspring_card_payment", "fiserv_card_capture", "gmo_shared_pk", "gopay_card_form", "gravy_session_fields_put", "hipay_vault_token", "iyzico_checkout_form", "juspay_txns.v1", "lyra_krypton_payment", "makecommerce_card_frame", "midtrans_card_token", "moneris_hosted_tokenization", "nexi_checkout_pay", "oceanpayment_hosted_payment_page", "omise_card_token", "openpay_tokenizer", "paddle_tokenex_pay", "paddle_vgs_cards", "pay_nl_card_token", "payfast_card_pay", "paygent_token", "paymentwall_card_token", "paymob_checkout_pay", "paymongo_checkout_pay", "paypal_card_fields", "payplug_hosted_payment_page", "payrails_device_encrypt", "payrexx_card_frame", "paytrail_hosted_payment_page", "payu_latam_webcheckout_card", "pelecard_transaction", "pin_payments_card_token", "poynt_collect_nonce", "primer_payment_instruments", "processout_card_token", "przelewy24_hosted_payment_page", "quickpay_hosted_payment_page", "redsys_hosted_payment_page", "revolut_card_field", "sbps_token_jsonp", "shiji_sts_pinned_key", "sumup_checkout_process", "tap_card_sdk_token", "toast_pinned_key", "tokenex_iframe_tokenize", "transbank_webpay_hosted_payment_page", "twoc2p_secure_pay", "usaepay_payment_key", "verifone_card_capture", "vtex_payments_card_payment", "wix_payments_tokenize", "worldline_mycheckout_form", "worldpay_eprotect_jsonp", "wspay_confirm", "xendit_card_token"];
|