@conto_finance/sdk 0.6.0-beta.1 → 0.6.0-beta.2

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/dist/index.js CHANGED
@@ -46,7 +46,7 @@ var require_package = __commonJS({
46
46
  "package.json"(exports2, module2) {
47
47
  module2.exports = {
48
48
  name: "@conto_finance/sdk",
49
- version: "0.6.0-beta.1",
49
+ version: "0.6.0-beta.2",
50
50
  description: "Conto SDK for AI agent payment authorization",
51
51
  main: "./dist/index.js",
52
52
  module: "./dist/index.mjs",
@@ -93,7 +93,7 @@ var require_package = __commonJS({
93
93
  dev: "tsup --watch",
94
94
  lint: "tsc --noEmit",
95
95
  test: "npm run lint && npm run test:contract && npm run test:consumer",
96
- "test:contract": "npm run build && node --test test/contract.test.mjs test/playwright.test.mjs test/browserbase.test.mjs test/checkout-verifier.test.mjs test/developer-experience.test.mjs test/link.test.mjs test/link-testing.test.mjs",
96
+ "test:contract": "npm run build && node --test test/contract.test.mjs test/playwright.test.mjs test/browserbase.test.mjs test/checkout-verifier.test.mjs test/developer-experience.test.mjs test/link.test.mjs test/link-testing.test.mjs test/checkout.test.mjs",
97
97
  "test:consumer": "npm run build && node --test test/consumer.test.mjs",
98
98
  "verify:release": "node scripts/verify-release.mjs",
99
99
  prepublishOnly: "npm run verify:release && npm run lint && npm run test:contract && npm run test:consumer"
@@ -159,6 +159,7 @@ __export(index_exports, {
159
159
  BrowserActionFinalizationPendingError: () => BrowserActionFinalizationPendingError,
160
160
  BrowserCheckoutTargetVerificationError: () => BrowserCheckoutTargetVerificationError,
161
161
  CardsClient: () => CardsClient,
162
+ CheckoutClient: () => CheckoutClient,
162
163
  ConnectedCardsClient: () => ConnectedCardsClient,
163
164
  Conto: () => Conto,
164
165
  ContoAdmin: () => ContoAdmin,
@@ -696,8 +697,11 @@ var AdminCardsClient = class {
696
697
  return this.client.request("GET", `/api/external-cards/requests${suffix ? `?${suffix}` : ""}`);
697
698
  }
698
699
  /**
699
- * Resolve a claimed execution after checking the customer's processor or
700
- * receipt. Resolving NOT_EXECUTED releases the reserved policy amount.
700
+ * @deprecated Resolution requires a signed-in user. SDK admin keys and
701
+ * organization API keys receive HTTP 403 INSUFFICIENT_PERMISSIONS from this
702
+ * endpoint. Have a signed-in organization owner or admin review the processor
703
+ * evidence and resolve the request through Conto's authenticated interface.
704
+ * Retained for source compatibility; this method does not bypass that restriction.
701
705
  */
702
706
  async resolveRequest(requestId, input) {
703
707
  return this.client.request(
@@ -1188,6 +1192,7 @@ var Conto = class {
1188
1192
  assertSecureBaseUrl(this.baseUrl);
1189
1193
  this.timeout = config.timeout || 3e4;
1190
1194
  this.link = new LinkClient(this, config.link);
1195
+ this.checkout = new CheckoutClient(this);
1191
1196
  this.payments = new PaymentsClient(this);
1192
1197
  this.cards = new CardsClient(this);
1193
1198
  this.connectedCards = new ConnectedCardsClient(this);
@@ -2147,17 +2152,147 @@ var MppClient = class {
2147
2152
  }
2148
2153
  };
2149
2154
  var index_default = Conto;
2150
- var _client, _defaults;
2155
+ function checkoutError(message, code = "INVALID_CHECKOUT_CHECKPOINT") {
2156
+ return new ContoError(message, { code, status: 0 });
2157
+ }
2158
+ function checkpointCart(amountMinor, lineItems, totals) {
2159
+ if (!Number.isSafeInteger(amountMinor) || amountMinor <= 0) {
2160
+ throw checkoutError("amountMinor must be a positive integer number of cents");
2161
+ }
2162
+ if (!Array.isArray(lineItems) || lineItems.length === 0) {
2163
+ throw checkoutError("Supply at least one line item");
2164
+ }
2165
+ return {
2166
+ lineItems,
2167
+ totals: totals ?? [{ type: "total", label: "Total", amountMinor }]
2168
+ };
2169
+ }
2170
+ var _client;
2171
+ var CheckoutClient = class {
2172
+ constructor(client) {
2173
+ __privateAdd(this, _client);
2174
+ __privateSet(this, _client, client);
2175
+ }
2176
+ /** First checkpoint. A ContoError means Conto did not approve: stop the checkout. */
2177
+ async begin(input) {
2178
+ const idempotencyKey = input.idempotencyKey?.trim();
2179
+ if (!idempotencyKey || idempotencyKey.length < 8 || idempotencyKey.length > 255) {
2180
+ throw checkoutError(
2181
+ "idempotencyKey must contain 8 to 255 characters",
2182
+ "INVALID_IDEMPOTENCY_KEY"
2183
+ );
2184
+ }
2185
+ if (input.currency !== void 0 && input.currency !== "USD") {
2186
+ throw checkoutError("Only USD checkouts are supported");
2187
+ }
2188
+ const result = await __privateGet(this, _client).request(
2189
+ "POST",
2190
+ "/api/sdk/checkout-checkpoints",
2191
+ {
2192
+ idempotencyKey,
2193
+ merchant: input.merchant,
2194
+ amountMinor: input.amountMinor,
2195
+ currency: "USD",
2196
+ purpose: input.purpose,
2197
+ ...input.category ? { category: input.category } : {},
2198
+ ...input.checkoutMethod ? { checkoutMethod: input.checkoutMethod } : {},
2199
+ cart: checkpointCart(input.amountMinor, input.lineItems, input.totals)
2200
+ },
2201
+ { idempotent: true }
2202
+ );
2203
+ return result.checkpoint;
2204
+ }
2205
+ /**
2206
+ * Second checkpoint, right before the payment is submitted. If the total
2207
+ * changed since begin() (tax or shipping, for example), this cancels the
2208
+ * approved checkpoint and starts a new one at the final total, so the agent's
2209
+ * rules see the amount actually being paid. Pay only if this resolves.
2210
+ */
2211
+ async confirm(checkpoint, input) {
2212
+ if (input.currency !== void 0 && input.currency !== "USD") {
2213
+ throw checkoutError("Only USD checkouts are supported");
2214
+ }
2215
+ if (!Number.isSafeInteger(input.amountMinor) || input.amountMinor <= 0) {
2216
+ throw checkoutError("amountMinor must be a positive integer number of cents");
2217
+ }
2218
+ let current = checkpoint;
2219
+ if (input.amountMinor !== checkpoint.amountMinor) {
2220
+ try {
2221
+ await this.cancel(checkpoint.id);
2222
+ } catch (error) {
2223
+ const closed = error instanceof ContoError && error.status === 409 && ["CANCELLED", "EXPIRED", "DENIED"].includes((await this.get(checkpoint.id)).stage);
2224
+ if (!closed) throw error;
2225
+ }
2226
+ current = await this.begin({
2227
+ idempotencyKey: `${checkpoint.idempotencyKey.slice(0, 200)}:final-${input.amountMinor}`,
2228
+ merchant: {
2229
+ id: checkpoint.merchant.id,
2230
+ name: checkpoint.merchant.name,
2231
+ checkoutUrl: checkpoint.merchant.checkoutUrl ?? ""
2232
+ },
2233
+ amountMinor: input.amountMinor,
2234
+ purpose: checkpoint.purpose,
2235
+ ...checkpoint.category ? { category: checkpoint.category } : {},
2236
+ checkoutMethod: checkpoint.checkoutMethod,
2237
+ lineItems: input.lineItems ?? checkpoint.cart.lineItems,
2238
+ totals: input.totals
2239
+ });
2240
+ }
2241
+ const result = await __privateGet(this, _client).request(
2242
+ "POST",
2243
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(current.id)}/confirm`,
2244
+ {
2245
+ amountMinor: input.amountMinor,
2246
+ currency: "USD",
2247
+ ...input.pageUrl ? { pageUrl: input.pageUrl } : {}
2248
+ },
2249
+ { idempotent: true }
2250
+ );
2251
+ return result.checkpoint;
2252
+ }
2253
+ /** Report what happened after a confirmed checkpoint. Safe to repeat with the same outcome. */
2254
+ async reportOutcome(checkpointId, input) {
2255
+ const result = await __privateGet(this, _client).request(
2256
+ "POST",
2257
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(checkpointId)}/outcome`,
2258
+ {
2259
+ outcome: input.outcome,
2260
+ ...input.reference ? { reference: input.reference } : {}
2261
+ },
2262
+ { idempotent: true }
2263
+ );
2264
+ return result.checkpoint;
2265
+ }
2266
+ /** Cancel a checkpoint that was not confirmed and release its spend. */
2267
+ async cancel(checkpointId) {
2268
+ const result = await __privateGet(this, _client).request(
2269
+ "POST",
2270
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(checkpointId)}/cancel`,
2271
+ {},
2272
+ { idempotent: true }
2273
+ );
2274
+ return result.checkpoint;
2275
+ }
2276
+ async get(checkpointId) {
2277
+ const result = await __privateGet(this, _client).request(
2278
+ "GET",
2279
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(checkpointId)}`
2280
+ );
2281
+ return result.checkpoint;
2282
+ }
2283
+ };
2284
+ _client = new WeakMap();
2285
+ var _client2, _defaults;
2151
2286
  var LinkClient = class {
2152
2287
  constructor(client, defaults) {
2153
- __privateAdd(this, _client);
2288
+ __privateAdd(this, _client2);
2154
2289
  __privateAdd(this, _defaults);
2155
- __privateSet(this, _client, client);
2290
+ __privateSet(this, _client2, client);
2156
2291
  __privateSet(this, _defaults, defaults ? { ...defaults } : void 0);
2157
2292
  }
2158
2293
  /** Inspect the configured live path. This is not a payment authorization or provider connectivity test. */
2159
2294
  async setup(input = {}) {
2160
- return __privateGet(this, _client).getLinkSetup({
2295
+ return __privateGet(this, _client2).getLinkSetup({
2161
2296
  connectionId: input.connectionId ?? __privateGet(this, _defaults)?.connectionId,
2162
2297
  paymentMethodId: input.paymentMethodId ?? __privateGet(this, _defaults)?.paymentMethodId,
2163
2298
  merchantId: input.merchantId
@@ -2165,7 +2300,7 @@ var LinkClient = class {
2165
2300
  }
2166
2301
  /** Read masked LIVE funding sources; never selects a source or initiates payment. */
2167
2302
  async paymentMethods(connectionId) {
2168
- return __privateGet(this, _client).listStripeLinkPaymentMethods(
2303
+ return __privateGet(this, _client2).listStripeLinkPaymentMethods(
2169
2304
  this.identifier(connectionId ?? __privateGet(this, _defaults)?.connectionId, "connectionId"),
2170
2305
  { mode: "LIVE" }
2171
2306
  );
@@ -2210,7 +2345,7 @@ var LinkClient = class {
2210
2345
  }
2211
2346
  );
2212
2347
  }
2213
- const result = await __privateGet(this, _client).beginCommerceExecution({
2348
+ const result = await __privateGet(this, _client2).beginCommerceExecution({
2214
2349
  executionMethod: "LINK_PAY_TOKEN",
2215
2350
  connectionId,
2216
2351
  paymentMethodId,
@@ -2237,25 +2372,25 @@ var LinkClient = class {
2237
2372
  */
2238
2373
  async resume(executionId) {
2239
2374
  const id = this.identifier(executionId, "executionId");
2240
- const current = await __privateGet(this, _client).getCommerceExecution(id);
2375
+ const current = await __privateGet(this, _client2).getCommerceExecution(id);
2241
2376
  this.assertLinkExecution(current);
2242
2377
  if (["AUTHORIZING", "AWAITING_APPROVAL", "ACTION_REQUIRED"].includes(current.execution.status)) {
2243
- return this.executeIfReady(await __privateGet(this, _client).refreshCommerceExecution(id));
2378
+ return this.executeIfReady(await __privateGet(this, _client2).refreshCommerceExecution(id));
2244
2379
  }
2245
2380
  return this.executeIfReady(current);
2246
2381
  }
2247
2382
  /** Observe and reconcile provider state. This method never submits a payment. */
2248
2383
  async status(executionId) {
2249
2384
  const id = this.identifier(executionId, "executionId");
2250
- this.assertLinkExecution(await __privateGet(this, _client).getCommerceExecution(id));
2251
- return this.result(await __privateGet(this, _client).refreshCommerceExecution(id));
2385
+ this.assertLinkExecution(await __privateGet(this, _client2).getCommerceExecution(id));
2386
+ return this.result(await __privateGet(this, _client2).refreshCommerceExecution(id));
2252
2387
  }
2253
2388
  /** Request cancellation of this existing Link payment; never retried automatically. */
2254
2389
  async cancel(executionId) {
2255
2390
  const id = this.identifier(executionId, "executionId");
2256
- this.assertLinkExecution(await __privateGet(this, _client).getCommerceExecution(id));
2391
+ this.assertLinkExecution(await __privateGet(this, _client2).getCommerceExecution(id));
2257
2392
  try {
2258
- return this.result(await __privateGet(this, _client).cancelCommerceExecution(id));
2393
+ return this.result(await __privateGet(this, _client2).cancelCommerceExecution(id));
2259
2394
  } catch (error) {
2260
2395
  throw new LinkPaymentExecutionError(id, error);
2261
2396
  }
@@ -2285,7 +2420,7 @@ var LinkClient = class {
2285
2420
  this.assertLinkExecution(result);
2286
2421
  if (result.execution.status !== "READY") return this.result(result);
2287
2422
  try {
2288
- return this.result(await __privateGet(this, _client).executeCommerceExecution(result.execution.id));
2423
+ return this.result(await __privateGet(this, _client2).executeCommerceExecution(result.execution.id));
2289
2424
  } catch (error) {
2290
2425
  throw new LinkPaymentExecutionError(result.execution.id, error);
2291
2426
  }
@@ -2315,13 +2450,14 @@ var LinkClient = class {
2315
2450
  };
2316
2451
  }
2317
2452
  };
2318
- _client = new WeakMap();
2453
+ _client2 = new WeakMap();
2319
2454
  _defaults = new WeakMap();
2320
2455
  // Annotate the CommonJS export names for ESM import in node:
2321
2456
  0 && (module.exports = {
2322
2457
  BrowserActionFinalizationPendingError,
2323
2458
  BrowserCheckoutTargetVerificationError,
2324
2459
  CardsClient,
2460
+ CheckoutClient,
2325
2461
  ConnectedCardsClient,
2326
2462
  Conto,
2327
2463
  ContoAdmin,
package/dist/index.mjs CHANGED
@@ -17,7 +17,7 @@ var require_package = __commonJS({
17
17
  "package.json"(exports, module) {
18
18
  module.exports = {
19
19
  name: "@conto_finance/sdk",
20
- version: "0.6.0-beta.1",
20
+ version: "0.6.0-beta.2",
21
21
  description: "Conto SDK for AI agent payment authorization",
22
22
  main: "./dist/index.js",
23
23
  module: "./dist/index.mjs",
@@ -64,7 +64,7 @@ var require_package = __commonJS({
64
64
  dev: "tsup --watch",
65
65
  lint: "tsc --noEmit",
66
66
  test: "npm run lint && npm run test:contract && npm run test:consumer",
67
- "test:contract": "npm run build && node --test test/contract.test.mjs test/playwright.test.mjs test/browserbase.test.mjs test/checkout-verifier.test.mjs test/developer-experience.test.mjs test/link.test.mjs test/link-testing.test.mjs",
67
+ "test:contract": "npm run build && node --test test/contract.test.mjs test/playwright.test.mjs test/browserbase.test.mjs test/checkout-verifier.test.mjs test/developer-experience.test.mjs test/link.test.mjs test/link-testing.test.mjs test/checkout.test.mjs",
68
68
  "test:consumer": "npm run build && node --test test/consumer.test.mjs",
69
69
  "verify:release": "node scripts/verify-release.mjs",
70
70
  prepublishOnly: "npm run verify:release && npm run lint && npm run test:contract && npm run test:consumer"
@@ -528,8 +528,11 @@ var AdminCardsClient = class {
528
528
  return this.client.request("GET", `/api/external-cards/requests${suffix ? `?${suffix}` : ""}`);
529
529
  }
530
530
  /**
531
- * Resolve a claimed execution after checking the customer's processor or
532
- * receipt. Resolving NOT_EXECUTED releases the reserved policy amount.
531
+ * @deprecated Resolution requires a signed-in user. SDK admin keys and
532
+ * organization API keys receive HTTP 403 INSUFFICIENT_PERMISSIONS from this
533
+ * endpoint. Have a signed-in organization owner or admin review the processor
534
+ * evidence and resolve the request through Conto's authenticated interface.
535
+ * Retained for source compatibility; this method does not bypass that restriction.
533
536
  */
534
537
  async resolveRequest(requestId, input) {
535
538
  return this.client.request(
@@ -1020,6 +1023,7 @@ var Conto = class {
1020
1023
  assertSecureBaseUrl(this.baseUrl);
1021
1024
  this.timeout = config.timeout || 3e4;
1022
1025
  this.link = new LinkClient(this, config.link);
1026
+ this.checkout = new CheckoutClient(this);
1023
1027
  this.payments = new PaymentsClient(this);
1024
1028
  this.cards = new CardsClient(this);
1025
1029
  this.connectedCards = new ConnectedCardsClient(this);
@@ -1979,17 +1983,147 @@ var MppClient = class {
1979
1983
  }
1980
1984
  };
1981
1985
  var index_default = Conto;
1982
- var _client, _defaults;
1986
+ function checkoutError(message, code = "INVALID_CHECKOUT_CHECKPOINT") {
1987
+ return new ContoError(message, { code, status: 0 });
1988
+ }
1989
+ function checkpointCart(amountMinor, lineItems, totals) {
1990
+ if (!Number.isSafeInteger(amountMinor) || amountMinor <= 0) {
1991
+ throw checkoutError("amountMinor must be a positive integer number of cents");
1992
+ }
1993
+ if (!Array.isArray(lineItems) || lineItems.length === 0) {
1994
+ throw checkoutError("Supply at least one line item");
1995
+ }
1996
+ return {
1997
+ lineItems,
1998
+ totals: totals ?? [{ type: "total", label: "Total", amountMinor }]
1999
+ };
2000
+ }
2001
+ var _client;
2002
+ var CheckoutClient = class {
2003
+ constructor(client) {
2004
+ __privateAdd(this, _client);
2005
+ __privateSet(this, _client, client);
2006
+ }
2007
+ /** First checkpoint. A ContoError means Conto did not approve: stop the checkout. */
2008
+ async begin(input) {
2009
+ const idempotencyKey = input.idempotencyKey?.trim();
2010
+ if (!idempotencyKey || idempotencyKey.length < 8 || idempotencyKey.length > 255) {
2011
+ throw checkoutError(
2012
+ "idempotencyKey must contain 8 to 255 characters",
2013
+ "INVALID_IDEMPOTENCY_KEY"
2014
+ );
2015
+ }
2016
+ if (input.currency !== void 0 && input.currency !== "USD") {
2017
+ throw checkoutError("Only USD checkouts are supported");
2018
+ }
2019
+ const result = await __privateGet(this, _client).request(
2020
+ "POST",
2021
+ "/api/sdk/checkout-checkpoints",
2022
+ {
2023
+ idempotencyKey,
2024
+ merchant: input.merchant,
2025
+ amountMinor: input.amountMinor,
2026
+ currency: "USD",
2027
+ purpose: input.purpose,
2028
+ ...input.category ? { category: input.category } : {},
2029
+ ...input.checkoutMethod ? { checkoutMethod: input.checkoutMethod } : {},
2030
+ cart: checkpointCart(input.amountMinor, input.lineItems, input.totals)
2031
+ },
2032
+ { idempotent: true }
2033
+ );
2034
+ return result.checkpoint;
2035
+ }
2036
+ /**
2037
+ * Second checkpoint, right before the payment is submitted. If the total
2038
+ * changed since begin() (tax or shipping, for example), this cancels the
2039
+ * approved checkpoint and starts a new one at the final total, so the agent's
2040
+ * rules see the amount actually being paid. Pay only if this resolves.
2041
+ */
2042
+ async confirm(checkpoint, input) {
2043
+ if (input.currency !== void 0 && input.currency !== "USD") {
2044
+ throw checkoutError("Only USD checkouts are supported");
2045
+ }
2046
+ if (!Number.isSafeInteger(input.amountMinor) || input.amountMinor <= 0) {
2047
+ throw checkoutError("amountMinor must be a positive integer number of cents");
2048
+ }
2049
+ let current = checkpoint;
2050
+ if (input.amountMinor !== checkpoint.amountMinor) {
2051
+ try {
2052
+ await this.cancel(checkpoint.id);
2053
+ } catch (error) {
2054
+ const closed = error instanceof ContoError && error.status === 409 && ["CANCELLED", "EXPIRED", "DENIED"].includes((await this.get(checkpoint.id)).stage);
2055
+ if (!closed) throw error;
2056
+ }
2057
+ current = await this.begin({
2058
+ idempotencyKey: `${checkpoint.idempotencyKey.slice(0, 200)}:final-${input.amountMinor}`,
2059
+ merchant: {
2060
+ id: checkpoint.merchant.id,
2061
+ name: checkpoint.merchant.name,
2062
+ checkoutUrl: checkpoint.merchant.checkoutUrl ?? ""
2063
+ },
2064
+ amountMinor: input.amountMinor,
2065
+ purpose: checkpoint.purpose,
2066
+ ...checkpoint.category ? { category: checkpoint.category } : {},
2067
+ checkoutMethod: checkpoint.checkoutMethod,
2068
+ lineItems: input.lineItems ?? checkpoint.cart.lineItems,
2069
+ totals: input.totals
2070
+ });
2071
+ }
2072
+ const result = await __privateGet(this, _client).request(
2073
+ "POST",
2074
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(current.id)}/confirm`,
2075
+ {
2076
+ amountMinor: input.amountMinor,
2077
+ currency: "USD",
2078
+ ...input.pageUrl ? { pageUrl: input.pageUrl } : {}
2079
+ },
2080
+ { idempotent: true }
2081
+ );
2082
+ return result.checkpoint;
2083
+ }
2084
+ /** Report what happened after a confirmed checkpoint. Safe to repeat with the same outcome. */
2085
+ async reportOutcome(checkpointId, input) {
2086
+ const result = await __privateGet(this, _client).request(
2087
+ "POST",
2088
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(checkpointId)}/outcome`,
2089
+ {
2090
+ outcome: input.outcome,
2091
+ ...input.reference ? { reference: input.reference } : {}
2092
+ },
2093
+ { idempotent: true }
2094
+ );
2095
+ return result.checkpoint;
2096
+ }
2097
+ /** Cancel a checkpoint that was not confirmed and release its spend. */
2098
+ async cancel(checkpointId) {
2099
+ const result = await __privateGet(this, _client).request(
2100
+ "POST",
2101
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(checkpointId)}/cancel`,
2102
+ {},
2103
+ { idempotent: true }
2104
+ );
2105
+ return result.checkpoint;
2106
+ }
2107
+ async get(checkpointId) {
2108
+ const result = await __privateGet(this, _client).request(
2109
+ "GET",
2110
+ `/api/sdk/checkout-checkpoints/${encodeURIComponent(checkpointId)}`
2111
+ );
2112
+ return result.checkpoint;
2113
+ }
2114
+ };
2115
+ _client = new WeakMap();
2116
+ var _client2, _defaults;
1983
2117
  var LinkClient = class {
1984
2118
  constructor(client, defaults) {
1985
- __privateAdd(this, _client);
2119
+ __privateAdd(this, _client2);
1986
2120
  __privateAdd(this, _defaults);
1987
- __privateSet(this, _client, client);
2121
+ __privateSet(this, _client2, client);
1988
2122
  __privateSet(this, _defaults, defaults ? { ...defaults } : void 0);
1989
2123
  }
1990
2124
  /** Inspect the configured live path. This is not a payment authorization or provider connectivity test. */
1991
2125
  async setup(input = {}) {
1992
- return __privateGet(this, _client).getLinkSetup({
2126
+ return __privateGet(this, _client2).getLinkSetup({
1993
2127
  connectionId: input.connectionId ?? __privateGet(this, _defaults)?.connectionId,
1994
2128
  paymentMethodId: input.paymentMethodId ?? __privateGet(this, _defaults)?.paymentMethodId,
1995
2129
  merchantId: input.merchantId
@@ -1997,7 +2131,7 @@ var LinkClient = class {
1997
2131
  }
1998
2132
  /** Read masked LIVE funding sources; never selects a source or initiates payment. */
1999
2133
  async paymentMethods(connectionId) {
2000
- return __privateGet(this, _client).listStripeLinkPaymentMethods(
2134
+ return __privateGet(this, _client2).listStripeLinkPaymentMethods(
2001
2135
  this.identifier(connectionId ?? __privateGet(this, _defaults)?.connectionId, "connectionId"),
2002
2136
  { mode: "LIVE" }
2003
2137
  );
@@ -2042,7 +2176,7 @@ var LinkClient = class {
2042
2176
  }
2043
2177
  );
2044
2178
  }
2045
- const result = await __privateGet(this, _client).beginCommerceExecution({
2179
+ const result = await __privateGet(this, _client2).beginCommerceExecution({
2046
2180
  executionMethod: "LINK_PAY_TOKEN",
2047
2181
  connectionId,
2048
2182
  paymentMethodId,
@@ -2069,25 +2203,25 @@ var LinkClient = class {
2069
2203
  */
2070
2204
  async resume(executionId) {
2071
2205
  const id = this.identifier(executionId, "executionId");
2072
- const current = await __privateGet(this, _client).getCommerceExecution(id);
2206
+ const current = await __privateGet(this, _client2).getCommerceExecution(id);
2073
2207
  this.assertLinkExecution(current);
2074
2208
  if (["AUTHORIZING", "AWAITING_APPROVAL", "ACTION_REQUIRED"].includes(current.execution.status)) {
2075
- return this.executeIfReady(await __privateGet(this, _client).refreshCommerceExecution(id));
2209
+ return this.executeIfReady(await __privateGet(this, _client2).refreshCommerceExecution(id));
2076
2210
  }
2077
2211
  return this.executeIfReady(current);
2078
2212
  }
2079
2213
  /** Observe and reconcile provider state. This method never submits a payment. */
2080
2214
  async status(executionId) {
2081
2215
  const id = this.identifier(executionId, "executionId");
2082
- this.assertLinkExecution(await __privateGet(this, _client).getCommerceExecution(id));
2083
- return this.result(await __privateGet(this, _client).refreshCommerceExecution(id));
2216
+ this.assertLinkExecution(await __privateGet(this, _client2).getCommerceExecution(id));
2217
+ return this.result(await __privateGet(this, _client2).refreshCommerceExecution(id));
2084
2218
  }
2085
2219
  /** Request cancellation of this existing Link payment; never retried automatically. */
2086
2220
  async cancel(executionId) {
2087
2221
  const id = this.identifier(executionId, "executionId");
2088
- this.assertLinkExecution(await __privateGet(this, _client).getCommerceExecution(id));
2222
+ this.assertLinkExecution(await __privateGet(this, _client2).getCommerceExecution(id));
2089
2223
  try {
2090
- return this.result(await __privateGet(this, _client).cancelCommerceExecution(id));
2224
+ return this.result(await __privateGet(this, _client2).cancelCommerceExecution(id));
2091
2225
  } catch (error) {
2092
2226
  throw new LinkPaymentExecutionError(id, error);
2093
2227
  }
@@ -2117,7 +2251,7 @@ var LinkClient = class {
2117
2251
  this.assertLinkExecution(result);
2118
2252
  if (result.execution.status !== "READY") return this.result(result);
2119
2253
  try {
2120
- return this.result(await __privateGet(this, _client).executeCommerceExecution(result.execution.id));
2254
+ return this.result(await __privateGet(this, _client2).executeCommerceExecution(result.execution.id));
2121
2255
  } catch (error) {
2122
2256
  throw new LinkPaymentExecutionError(result.execution.id, error);
2123
2257
  }
@@ -2147,12 +2281,13 @@ var LinkClient = class {
2147
2281
  };
2148
2282
  }
2149
2283
  };
2150
- _client = new WeakMap();
2284
+ _client2 = new WeakMap();
2151
2285
  _defaults = new WeakMap();
2152
2286
  export {
2153
2287
  BrowserActionFinalizationPendingError,
2154
2288
  BrowserCheckoutTargetVerificationError,
2155
2289
  CardsClient,
2290
+ CheckoutClient,
2156
2291
  ConnectedCardsClient,
2157
2292
  Conto,
2158
2293
  ContoAdmin,
@@ -1,9 +1,19 @@
1
- import { LinkPaymentResult, LinkSetupInput, LinkSetupResult, ListStripeLinkPaymentMethodsResult, LinkPaymentInput } from './index.mjs';
1
+ import { CommerceExecution, CommerceExecutionEvidence, LinkPaymentResult, LinkSetupInput, LinkSetupResult, ListStripeLinkPaymentMethodsResult, LinkPaymentInput } from './index.mjs';
2
2
 
3
3
  type LinkTestScenario = 'approved' | 'denied' | 'expired' | 'interrupted';
4
+ /** Evidence created by the local simulator. It is never a receipt. */
5
+ type SimulatedCommerceExecutionEvidence = CommerceExecutionEvidence & {
6
+ mode: 'SIMULATED';
7
+ };
8
+ /** Execution record created by the local simulator. It does not exist on any Conto server. */
9
+ type SimulatedCommerceExecution = CommerceExecution & {
10
+ mode: 'SIMULATED';
11
+ evidence: SimulatedCommerceExecutionEvidence;
12
+ };
4
13
  type SimulatedLinkPaymentResult = LinkPaymentResult & {
5
14
  mode: 'SIMULATED';
6
15
  settlementVerified: false;
16
+ execution: SimulatedCommerceExecution;
7
17
  };
8
18
  interface LinkTestOptions {
9
19
  scenario?: LinkTestScenario;
@@ -12,7 +22,9 @@ interface LinkTestOptions {
12
22
  }
13
23
  /**
14
24
  * Create an isolated in-memory test account with the same pay/resume/status API.
15
- * Approval is explicit through link.approve(), a test-only method. Nothing settles.
25
+ * Approval is explicit through link.approve(), a test-only method. Like the live
26
+ * API, an accepted submission is PROCESSING and only a later status() call
27
+ * reports SETTLED. No money moves, and every result has settlementVerified false.
16
28
  */
17
29
  declare function createLinkTestClient(options?: LinkTestOptions): {
18
30
  mode: "SIMULATED";
@@ -34,4 +46,4 @@ declare function createLinkTestClient(options?: LinkTestOptions): {
34
46
  };
35
47
  };
36
48
 
37
- export { type LinkTestOptions, type LinkTestScenario, type SimulatedLinkPaymentResult, createLinkTestClient };
49
+ export { type LinkTestOptions, type LinkTestScenario, type SimulatedCommerceExecution, type SimulatedCommerceExecutionEvidence, type SimulatedLinkPaymentResult, createLinkTestClient };
@@ -1,9 +1,19 @@
1
- import { LinkPaymentResult, LinkSetupInput, LinkSetupResult, ListStripeLinkPaymentMethodsResult, LinkPaymentInput } from './index.js';
1
+ import { CommerceExecution, CommerceExecutionEvidence, LinkPaymentResult, LinkSetupInput, LinkSetupResult, ListStripeLinkPaymentMethodsResult, LinkPaymentInput } from './index.js';
2
2
 
3
3
  type LinkTestScenario = 'approved' | 'denied' | 'expired' | 'interrupted';
4
+ /** Evidence created by the local simulator. It is never a receipt. */
5
+ type SimulatedCommerceExecutionEvidence = CommerceExecutionEvidence & {
6
+ mode: 'SIMULATED';
7
+ };
8
+ /** Execution record created by the local simulator. It does not exist on any Conto server. */
9
+ type SimulatedCommerceExecution = CommerceExecution & {
10
+ mode: 'SIMULATED';
11
+ evidence: SimulatedCommerceExecutionEvidence;
12
+ };
4
13
  type SimulatedLinkPaymentResult = LinkPaymentResult & {
5
14
  mode: 'SIMULATED';
6
15
  settlementVerified: false;
16
+ execution: SimulatedCommerceExecution;
7
17
  };
8
18
  interface LinkTestOptions {
9
19
  scenario?: LinkTestScenario;
@@ -12,7 +22,9 @@ interface LinkTestOptions {
12
22
  }
13
23
  /**
14
24
  * Create an isolated in-memory test account with the same pay/resume/status API.
15
- * Approval is explicit through link.approve(), a test-only method. Nothing settles.
25
+ * Approval is explicit through link.approve(), a test-only method. Like the live
26
+ * API, an accepted submission is PROCESSING and only a later status() call
27
+ * reports SETTLED. No money moves, and every result has settlementVerified false.
16
28
  */
17
29
  declare function createLinkTestClient(options?: LinkTestOptions): {
18
30
  mode: "SIMULATED";
@@ -34,4 +46,4 @@ declare function createLinkTestClient(options?: LinkTestOptions): {
34
46
  };
35
47
  };
36
48
 
37
- export { type LinkTestOptions, type LinkTestScenario, type SimulatedLinkPaymentResult, createLinkTestClient };
49
+ export { type LinkTestOptions, type LinkTestScenario, type SimulatedCommerceExecution, type SimulatedCommerceExecutionEvidence, type SimulatedLinkPaymentResult, createLinkTestClient };