@conto_finance/sdk 0.6.0-beta.2 → 0.6.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/README.md +48 -171
- package/dist/index.d.mts +92 -174
- package/dist/index.d.ts +92 -174
- package/dist/index.js +164 -261
- package/dist/index.mjs +159 -259
- package/package.json +3 -9
- package/dist/link-testing.d.mts +0 -49
- package/dist/link-testing.d.ts +0 -49
- package/dist/link-testing.js +0 -285
- package/dist/link-testing.mjs +0 -265
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @conto_finance/sdk
|
|
2
2
|
|
|
3
|
-
Conto is a buyer-side control layer. Integrate it in the agent owner's runtime or payment tools
|
|
4
|
-
|
|
3
|
+
Conto is a buyer-side control layer. Integrate it in the agent owner's runtime or payment tools.
|
|
4
|
+
The owner or budget holder sets policy before the agent pays.
|
|
5
5
|
See [buyer-side control](https://conto.finance/docs/introduction/concepts) for the authorization
|
|
6
6
|
and execution boundary.
|
|
7
7
|
|
|
@@ -66,16 +66,20 @@ Use `conto.checkout` when your agent runs its own checkout. Call Conto right bef
|
|
|
66
66
|
method opens and again right before the payment is submitted. Conto checks the agent's rules at
|
|
67
67
|
both points and holds the spend in between. Your checkout must stop whenever a call fails.
|
|
68
68
|
|
|
69
|
-
Checkout checkpoints need SDK 0.6.0
|
|
69
|
+
Checkout checkpoints need SDK 0.6.0 or later.
|
|
70
70
|
|
|
71
71
|
```typescript
|
|
72
|
-
|
|
72
|
+
let checkpoint = await conto.checkout.begin({
|
|
73
73
|
idempotencyKey: order.id,
|
|
74
74
|
merchant: { id: 'acme-retail', name: 'ACME Retail', checkoutUrl: page.url() },
|
|
75
75
|
amountMinor: 7900,
|
|
76
76
|
purpose: 'Drip coffee maker the shopper chose',
|
|
77
77
|
lineItems: [{ name: 'Drip coffee maker', quantity: 1, unitAmountMinor: 7900 }],
|
|
78
78
|
});
|
|
79
|
+
if (checkpoint.stage === 'AWAITING_APPROVAL') {
|
|
80
|
+
// The agent's rules need the owner. Throws if the owner rejects or the approval expires.
|
|
81
|
+
checkpoint = await conto.checkout.waitForApproval(checkpoint, { timeoutMs: 15 * 60_000 });
|
|
82
|
+
}
|
|
79
83
|
// Open Link. The buyer signs in and the final total appears.
|
|
80
84
|
|
|
81
85
|
const confirmed = await conto.checkout.confirm(checkpoint, {
|
|
@@ -87,8 +91,17 @@ const confirmed = await conto.checkout.confirm(checkpoint, {
|
|
|
87
91
|
await conto.checkout.reportOutcome(confirmed.id, { outcome: 'PAID', reference: orderNumber });
|
|
88
92
|
```
|
|
89
93
|
|
|
94
|
+
- Open the payment method only when the stage is `APPROVED`. When the rules require approval,
|
|
95
|
+
`begin()` returns `AWAITING_APPROVAL`, holds the spend, and asks the owner.
|
|
96
|
+
`waitForApproval()` resolves to the approved checkpoint, whose 30 minutes to confirm start at
|
|
97
|
+
the approval. It throws `CheckoutApprovalDeniedError`, `CheckoutApprovalExpiredError`, or
|
|
98
|
+
`CheckoutApprovalTimeoutError`. After a timeout the spend stays held until you cancel.
|
|
90
99
|
- If the final total differs from the approved one, `confirm()` starts a new checkpoint at the
|
|
91
|
-
final total, so the rules check the amount actually paid.
|
|
100
|
+
final total, so the rules check the amount actually paid. If that total needs approval,
|
|
101
|
+
`confirm()` throws `CheckoutApprovalPendingError`: wait with
|
|
102
|
+
`waitForApproval(error.checkpoint)`, then confirm the checkpoint it returns.
|
|
103
|
+
- `begin()` throws `CheckoutCheckpointClosedError` when its idempotency key belongs to a
|
|
104
|
+
checkpoint that already closed. Start a new purchase with a new key.
|
|
92
105
|
- `reportOutcome()` accepts `PAID`, `NOT_PAID`, or `UNKNOWN`. Until an outcome arrives, the spend
|
|
93
106
|
stays counted. Cancel an unconfirmed checkpoint with `conto.checkout.cancel(id)`.
|
|
94
107
|
- Conto records what your checkout reports and does not see the charge. For control at the
|
|
@@ -154,6 +167,16 @@ const result = await conto.payments.pay({
|
|
|
154
167
|
});
|
|
155
168
|
```
|
|
156
169
|
|
|
170
|
+
## Connected-card delivery
|
|
171
|
+
|
|
172
|
+
For an organization with connected cards enabled, `conto.connectedCards.draw()` returns a disposable
|
|
173
|
+
credential exactly once. Keep it in memory and use it at the mandate's merchant before
|
|
174
|
+
`credentialExpiresAt`. Never log or persist it. After receipt, call
|
|
175
|
+
`conto.connectedCards.acknowledgeDelivery(draw.requestId)`. Acknowledgement is idempotent and records
|
|
176
|
+
delivery only, not payment settlement. Replaying the original draw key cannot recover a lost
|
|
177
|
+
credential. Check the original outcome before requesting a replacement. Issued capacity stays
|
|
178
|
+
consumed even when checkout fails.
|
|
179
|
+
|
|
157
180
|
## Protocol Clients
|
|
158
181
|
|
|
159
182
|
`Conto` also exposes typed helpers for x402 and MPP service payments:
|
|
@@ -194,7 +217,7 @@ automatically. The record response then includes `policyBypass: true`, `bypassRe
|
|
|
194
217
|
`agentFrozen`.
|
|
195
218
|
|
|
196
219
|
For a Privy-managed EVM wallet, `conto.x402.pay` replaces `preAuthorize`. Pass the same fields
|
|
197
|
-
plus the accepted 402 requirements
|
|
220
|
+
plus the accepted 402 requirements. When approved, Conto signs the payment and returns the header
|
|
198
221
|
to retry with:
|
|
199
222
|
|
|
200
223
|
```typescript
|
|
@@ -220,82 +243,21 @@ The MPP client mirrors the same shape with `conto.mpp.preAuthorize`, `conto.mpp.
|
|
|
220
243
|
`conto.mpp.budget`, and `conto.mpp.services`. An MPP session grant is a ceiling: several
|
|
221
244
|
`record` calls with the same `sessionId` may draw it down until it is used up or expires.
|
|
222
245
|
|
|
223
|
-
## Stripe Link Checkout Commerce (test only)
|
|
224
|
-
|
|
225
|
-
`LINK_CHECKOUT` is test-only and works only with a merchant enrolled with Conto. It is not a
|
|
226
|
-
general merchant integration. It evaluates policy before creating an ordinary Stripe-hosted
|
|
227
|
-
Checkout Session with card and Link enabled. It needs no private Link SDK permission,
|
|
228
|
-
Link connection, saved payment-method ID, SPT, or LPT.
|
|
229
|
-
|
|
230
|
-
Commerce execution responses separate the provider-neutral `executionChannel`, optional
|
|
231
|
-
`checkoutMethod`, and optional `settlementRail` from the legacy provider and adapter identifiers.
|
|
232
|
-
For dynamic hosted Checkout, `checkoutMethod` remains absent until settlement observes Link or the
|
|
233
|
-
card fallback; callers must not treat the adapter name as proof that Link was selected.
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
let { execution } = await conto.beginCommerceExecution({
|
|
237
|
-
executionMethod: 'LINK_CHECKOUT',
|
|
238
|
-
idempotencyKey: crypto.randomUUID(),
|
|
239
|
-
amountMinor: 6400,
|
|
240
|
-
currency: 'USD',
|
|
241
|
-
category: 'OFFICE_SUPPLIES',
|
|
242
|
-
purpose: 'Office supplies',
|
|
243
|
-
counterparty: {
|
|
244
|
-
canonicalId: 'conto-demo-office-supply',
|
|
245
|
-
},
|
|
246
|
-
cart: {
|
|
247
|
-
lineItems: [{ name: 'Office supplies', quantity: 1, unitAmountMinor: 6400 }],
|
|
248
|
-
totals: [{ type: 'total', label: 'Total', amountMinor: 6400 }],
|
|
249
|
-
},
|
|
250
|
-
providerPresentation: {
|
|
251
|
-
approvalSummary: 'Buy office supplies from the configured merchant',
|
|
252
|
-
lineItemLabels: ['Office supplies'],
|
|
253
|
-
},
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
if (execution.status !== 'ACTION_REQUIRED' || !execution.approvalUrl) {
|
|
257
|
-
throw new Error('Stripe Checkout was not created safely');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (execution.executionAdapter !== 'LINK_CHECKOUT') {
|
|
261
|
-
throw new Error('Unexpected commerce execution adapter');
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Hand the temporary capability to a trusted interactive browser/UI. Do not log it.
|
|
265
|
-
await presentCheckoutActionSecurely(execution.approvalUrl);
|
|
266
|
-
|
|
267
|
-
while (execution.status === 'ACTION_REQUIRED' || execution.status === 'PROCESSING') {
|
|
268
|
-
({ execution } = await conto.refreshCommerceExecution(execution.id));
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (execution.status !== 'SETTLED' || execution.evidence.actualPaymentMethod !== 'LINK') {
|
|
272
|
-
throw new Error('This execution did not settle with Link');
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
Stripe decides whether Link appears and whether the customer chooses it. Card is an explicit
|
|
277
|
-
fallback, surfaced as `actualPaymentMethod: 'CARD'`; it is a valid payment but not Link evidence.
|
|
278
|
-
The read-only `getCommerceExecution` projection redacts action URLs; use the initial begin result or
|
|
279
|
-
the `payments:confirm` refresh path while action remains required.
|
|
280
|
-
The server resolves the exact merchant name, Stripe account, and return URLs from configuration, so
|
|
281
|
-
the caller cannot redirect the approved purchase. This path covers only that enrolled merchant's
|
|
282
|
-
Conto channel, not unrelated Checkout pages or the consumer's Link wallet. See
|
|
283
|
-
`docs/STRIPE_LINK_CHECKOUT_ADAPTER.md` for configuration, webhook, drill, and reconciliation
|
|
284
|
-
requirements.
|
|
285
|
-
|
|
286
246
|
## Agent checkout guard
|
|
287
247
|
|
|
288
248
|
For browser checkouts on supported rails (Link, card, Shop Pay, or PayPal), use
|
|
289
249
|
`runGuardedCheckout` with `executionMethod: 'BROWSER_CHECKOUT'`. Other rails and checkout flows are
|
|
290
250
|
not covered. It binds and atomically authorizes one exact Link, card,
|
|
291
251
|
Shop Pay, or PayPal browser action without requiring private provider integration. The
|
|
292
|
-
privileged browser executor must be available only through this wrapper
|
|
293
|
-
payment tool would bypass the control. Persist its stable dispatch attempt before calling the
|
|
294
|
-
one-use claim, the privileged callback, and finalization.
|
|
295
|
-
|
|
252
|
+
privileged browser executor must be available only through this wrapper. An unrestricted click or
|
|
253
|
+
payment tool would bypass the control. Persist its stable dispatch attempt before calling the
|
|
254
|
+
helper. The helper owns authorization, one-use claim, the privileged callback, and finalization.
|
|
255
|
+
The
|
|
256
|
+
[Stripe Link guide](https://conto.finance/docs/guides/stripe-link#make-the-check-enforceable)
|
|
257
|
+
describes the runtime boundary and includes an example.
|
|
296
258
|
|
|
297
259
|
Isolated browser processes can implement `PrivilegedBrowserCheckoutDriver` and use
|
|
298
|
-
`runGuardedCheckoutWithDriver
|
|
260
|
+
`runGuardedCheckoutWithDriver`. The agent model must receive only that guarded wrapper, never the
|
|
299
261
|
driver's `dispatch` primitive. Generate `action.targetFingerprint` with
|
|
300
262
|
`fingerprintBrowserCheckoutTarget` during inspection, then wrap the privileged target resolver with
|
|
301
263
|
`createVerifiedBrowserCheckoutDriver`. The wrapper re-hashes the current page, locator, accessible
|
|
@@ -305,7 +267,7 @@ the action's `targetUrl`, allowing Conto's origin trust policy to evaluate them
|
|
|
305
267
|
|
|
306
268
|
For Browserbase, use the first-class provider host. Its binding store must reject duplicate session
|
|
307
269
|
IDs and atomically revoke only an active record matching the supplied organization, agent, and
|
|
308
|
-
project. Store the credential-free binding durably
|
|
270
|
+
project. Store the credential-free binding durably, and never add the provider `connectUrl` to it.
|
|
309
271
|
|
|
310
272
|
```typescript
|
|
311
273
|
import {
|
|
@@ -357,15 +319,15 @@ export const POST = host.handler;
|
|
|
357
319
|
The Browserbase host exposes `handler`, `createSession`, `attachSession`, `observeSession`,
|
|
358
320
|
`liveViewForSession`, `releaseSession`, `detachSession`, and `close`. `observeSession` returns only a
|
|
359
321
|
bounded page origin/title and visible
|
|
360
|
-
link/button outline
|
|
322
|
+
link/button outline. It excludes full page text, DOM, form values, URL paths and queries,
|
|
361
323
|
screenshots, cookies, storage, and provider capabilities. It rechecks ownership and page identity
|
|
362
324
|
after observing.
|
|
363
325
|
`createSession` returns a session ID, active status, and expiry without a connection URL.
|
|
364
326
|
`liveViewForSession` is a privileged operator capability: expose it only behind separate human
|
|
365
327
|
authentication, never as an agent tool. A configured Context persists login state but must remain
|
|
366
|
-
server-side
|
|
328
|
+
server-side. Its durable binding store should prevent concurrent sessions from sharing one Context.
|
|
367
329
|
`releaseSession` atomically revokes Conto ownership before closing the local connection and asking
|
|
368
|
-
Browserbase to release the keep-alive session. Call it when the agent session ends
|
|
330
|
+
Browserbase to release the keep-alive session. Call it when the agent session ends. `close` only
|
|
369
331
|
closes local Playwright connections. `attachSession` accepts only a five-minute HMAC assertion
|
|
370
332
|
binding the exact provider project, Conto organization, agent, session, and expiry. Its matching
|
|
371
333
|
`detachSession` revokes Conto access and closes the local connection without releasing the
|
|
@@ -377,12 +339,12 @@ For another Playwright or secure CDP provider, use
|
|
|
377
339
|
exposes only `handler`, `observeSession`, `closeSession`, and `close`, keeping discovery, mutation
|
|
378
340
|
primitives, the target store, the Playwright page, and raw dispatch private.
|
|
379
341
|
Lower-level integrations can still compose `createGuardedPlaywrightCheckoutRuntime`, whose façade
|
|
380
|
-
exposes only `discover` and `run
|
|
342
|
+
exposes only `discover` and `run`. The raw driver is not returned. Target
|
|
381
343
|
registrations expire after ten minutes by default. The encrypted store persists only ciphertext
|
|
382
344
|
through a small durable blob port, so a runtime restart does not lose an approved
|
|
383
345
|
target or disclose its locator. `dispatchAttemptFor` must atomically return the same persisted ID for
|
|
384
346
|
the same checkout intent. The dispatch result classifies the browser outcome as `NEW_PAGE`,
|
|
385
|
-
`PAGE_NAVIGATION`, or `SAME_PAGE`, but always reports settlement as `UNVERIFIED
|
|
347
|
+
`PAGE_NAVIGATION`, or `SAME_PAGE`, but always reports settlement as `UNVERIFIED`. Only merchant or
|
|
386
348
|
provider evidence can prove payment. Never expose the page, target store, persisted registrations,
|
|
387
349
|
or provider-derived locator state to the model. The inert positional reference returned by
|
|
388
350
|
`observeSession` is the only locator intended for the model.
|
|
@@ -406,15 +368,15 @@ ambiguous-dispatch probes pass.
|
|
|
406
368
|
|
|
407
369
|
The probe runner belongs to the trusted integration host and must execute against an isolated
|
|
408
370
|
fixture session. A report does not remotely attest an untrusted host or discover tools omitted from
|
|
409
|
-
its inventory.
|
|
410
|
-
contract.
|
|
371
|
+
its inventory. The types exported from `@conto_finance/sdk/checkout-verifier` define the
|
|
372
|
+
manifest, probe, and status contract.
|
|
411
373
|
|
|
412
374
|
The HTTP handler implements the authenticated endpoint consumed by the optional
|
|
413
375
|
`guarded_browser_checkout` MCP tool. It accepts Web `Request` objects, so it can be mounted directly
|
|
414
376
|
in a compatible route or adapted to a Node server. It authenticates before reading the body,
|
|
415
377
|
rejects unknown fields and mismatched cart totals, performs discovery and guarded execution in one
|
|
416
378
|
request, and returns only minimized browser evidence. Use a dedicated random token of at least 32
|
|
417
|
-
characters
|
|
379
|
+
characters. The handler rejects Conto API keys.
|
|
418
380
|
|
|
419
381
|
Organization-specific proposal facts can be sent through the typed normalization call after an
|
|
420
382
|
owner or administrator registers the namespace schema:
|
|
@@ -435,60 +397,6 @@ const proposal = await conto.normalizeCommerceProposal({
|
|
|
435
397
|
Conto rejects unregistered namespaces and schema-invalid values before policy evaluation. Accepted
|
|
436
398
|
facts are bound to the schema revision and fingerprint returned on the normalized proposal.
|
|
437
399
|
|
|
438
|
-
## Stripe Link Sandbox Commerce
|
|
439
|
-
|
|
440
|
-
The gated Stripe Link sandbox surface uses the agent key for policy evaluation and execution. A
|
|
441
|
-
Link connection must first be created by its user and explicitly bound to the agent through the
|
|
442
|
-
authenticated session API. The agent SDK never receives the Link access token or payment artifact.
|
|
443
|
-
|
|
444
|
-
```typescript
|
|
445
|
-
const linkContext = await conto.listStripeLinkPaymentMethods(connectionId);
|
|
446
|
-
if (linkContext.organizationId !== expectedOrganizationId) {
|
|
447
|
-
throw new Error('Agent key belongs to the wrong Conto organization');
|
|
448
|
-
}
|
|
449
|
-
const { paymentMethods } = linkContext;
|
|
450
|
-
|
|
451
|
-
let { execution } = await conto.beginCommerceExecution({
|
|
452
|
-
connectionId,
|
|
453
|
-
paymentMethodId: paymentMethods[0].id,
|
|
454
|
-
executionMethod: 'STRIPE_PAYMENT_INTENT',
|
|
455
|
-
idempotencyKey: crypto.randomUUID(),
|
|
456
|
-
amountMinor: 6400,
|
|
457
|
-
currency: 'USD',
|
|
458
|
-
purpose: 'Office supplies',
|
|
459
|
-
counterparty: {
|
|
460
|
-
canonicalId: 'conto-demo-office-supply',
|
|
461
|
-
displayName: 'Conto Demo Office Supply',
|
|
462
|
-
},
|
|
463
|
-
cart: {
|
|
464
|
-
lineItems: [{ name: 'Office supplies', quantity: 1, unitAmountMinor: 6400 }],
|
|
465
|
-
totals: [{ type: 'total', label: 'Total', amountMinor: 6400 }],
|
|
466
|
-
},
|
|
467
|
-
providerPresentation: {
|
|
468
|
-
approvalSummary: 'Buy office supplies from Conto Demo Office Supply',
|
|
469
|
-
lineItemLabels: ['Office supplies'],
|
|
470
|
-
},
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
if (execution.status === 'AWAITING_APPROVAL') {
|
|
474
|
-
// Present execution.approvalUrl to the Link user, then poll with refresh.
|
|
475
|
-
({ execution } = await conto.refreshCommerceExecution(execution.id));
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
if (execution.status === 'READY') {
|
|
479
|
-
const result = await conto.executeCommerceExecution(execution.id);
|
|
480
|
-
console.log(result.execution.evidence, result.execution.evidenceFingerprint);
|
|
481
|
-
}
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
Use `getCommerceExecution(id)` for read-only reconciliation and
|
|
485
|
-
`cancelCommerceExecution(id)` to cancel a nonterminal execution. `beginCommerceExecution` safely
|
|
486
|
-
retries with its stable idempotency key, and `refreshCommerceExecution` safely retries observation.
|
|
487
|
-
Checkout execution and cancellation are not transport-retried.
|
|
488
|
-
The Stripe account and Link business-network profile are resolved from server-owned configuration;
|
|
489
|
-
an agent cannot supply or replace them. Use `executionMethod: 'MPP'` only for the optional,
|
|
490
|
-
configured MPP compatibility transport.
|
|
491
|
-
|
|
492
400
|
## Admin SDK Quick Start
|
|
493
401
|
|
|
494
402
|
`ContoAdmin` uses an organization API key (`conto_xxx...`), not an agent SDK key.
|
|
@@ -523,27 +431,6 @@ if (frozen) {
|
|
|
523
431
|
}
|
|
524
432
|
```
|
|
525
433
|
|
|
526
|
-
### Stripe Link Checkout readiness
|
|
527
|
-
|
|
528
|
-
Organization administrators can inspect the configured merchant Checkout adapter without calling
|
|
529
|
-
Stripe, then explicitly verify that Conto's configured credential resolves to its configured
|
|
530
|
-
merchant account:
|
|
531
|
-
|
|
532
|
-
```typescript
|
|
533
|
-
const { readiness } = await admin.paymentRails.getStripeLinkCheckoutReadiness();
|
|
534
|
-
|
|
535
|
-
if (readiness.canVerify && !readiness.checks.accountVerified) {
|
|
536
|
-
const verified = await admin.paymentRails.verifyStripeLinkCheckoutAccount();
|
|
537
|
-
console.log(verified.readiness.status, verified.readiness.verification);
|
|
538
|
-
}
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
The result contains only mode, booleans, safe status codes, timestamps, and scope statements. It
|
|
542
|
-
never contains merchant/account identifiers, URLs, credentials, hashes, Stripe objects, or raw
|
|
543
|
-
provider errors. Verification proves the configured account match only; Stripe still decides
|
|
544
|
-
whether Link is eligible, displayed, and selected at Checkout. The static GET is retry-safe; the
|
|
545
|
-
active POST verification is not automatically retried.
|
|
546
|
-
|
|
547
434
|
## What This Package Covers
|
|
548
435
|
|
|
549
436
|
- `Conto` for agent-scoped payment flows
|
|
@@ -556,7 +443,7 @@ active POST verification is not automatically retried.
|
|
|
556
443
|
The SDK automatically adds an idempotency key to wallet payment authorization
|
|
557
444
|
requests. Provide your own stable `idempotencyKey` when a retry may happen in
|
|
558
445
|
another process or job attempt. External-card approvals always require a stable
|
|
559
|
-
caller-supplied `idempotencyKey
|
|
446
|
+
caller-supplied `idempotencyKey`. Card approval and confirmation are safe to
|
|
560
447
|
retry. x402 and MPP pre-authorization calls issue a grant and reserve spend. A retry
|
|
561
448
|
with the same `paymentId` (x402) or `challengeId`/`credentialId` (MPP) returns the
|
|
562
449
|
same live grant instead of reserving again.
|
|
@@ -566,7 +453,7 @@ ambiguous failure can be reconciled safely.
|
|
|
566
453
|
Read-only calls retry transient network failures, `429`, and `5xx` responses. Financial execution
|
|
567
454
|
and other non-idempotent mutations are never retried automatically. If execution times out, call
|
|
568
455
|
`conto.payments.status(requestId)` before attempting it again. A
|
|
569
|
-
`reconciliation_required` status means the execution outcome is ambiguous
|
|
456
|
+
`reconciliation_required` status means the execution outcome is ambiguous. Do not resend the
|
|
570
457
|
payment until an operator has resolved it.
|
|
571
458
|
|
|
572
459
|
`ContoError` and `ContoAdminError` expose a stable error contract: `code`, `status`, `requestId`,
|
|
@@ -602,14 +489,4 @@ try {
|
|
|
602
489
|
|
|
603
490
|
MIT
|
|
604
491
|
|
|
605
|
-
Developer support: [support@conto.finance](mailto:support@conto.finance). Include the package version and request ID
|
|
606
|
-
|
|
607
|
-
### Connected-card delivery
|
|
608
|
-
|
|
609
|
-
For an organization with connected cards enabled, `conto.connectedCards.draw()` returns a disposable
|
|
610
|
-
credential exactly once. Keep it in memory and use it at the mandate's merchant before
|
|
611
|
-
`credentialExpiresAt`. Never log or persist it. After receipt, call
|
|
612
|
-
`conto.connectedCards.acknowledgeDelivery(draw.requestId)`. Acknowledgement is idempotent and records
|
|
613
|
-
delivery only, not payment settlement. Replaying the original draw key cannot recover a lost
|
|
614
|
-
credential; check the original outcome before requesting a replacement. Issued capacity stays
|
|
615
|
-
consumed even when checkout fails.
|
|
492
|
+
Developer support: [support@conto.finance](mailto:support@conto.finance). Include the package version and request ID. Never include API keys.
|