@agent-cards/checkout 0.2.0 → 0.3.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 +25 -0
- package/README.md +191 -9
- package/dist/cdp.d.ts +73 -5
- package/dist/cdp.js +238 -25
- package/dist/client.d.ts +16 -4
- package/dist/client.js +132 -36
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -2
- package/dist/lifecycle.d.ts +91 -0
- package/dist/lifecycle.js +193 -0
- package/examples/existing-browser.mjs +63 -0
- package/package.json +6 -3
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Existing Kernel / Browserbase / custom Chromium session; does not create or close the provider's browser.
|
|
2
|
+
// Run: CHECKOUT_DRIVER=/absolute/path/to/instinct-driver.mjs node examples/existing-browser.mjs
|
|
3
|
+
// The driver owns the existing agent, its approved purchase and merchant-specific order verification.
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { chromium } from 'playwright-core';
|
|
6
|
+
import { VaultClient, attachToPlaywright } from '../dist/index.js';
|
|
7
|
+
|
|
8
|
+
const driverPath = process.env.CHECKOUT_DRIVER;
|
|
9
|
+
if (!driverPath?.startsWith('/')) throw new Error('CHECKOUT_DRIVER must name an absolute path to your integration module.');
|
|
10
|
+
const driver = await import(pathToFileURL(driverPath).href);
|
|
11
|
+
for (const method of ['prepareCheckout', 'submitCheckout', 'resolveMerchantResult', 'onUserAction', 'finishAfterPayment']) {
|
|
12
|
+
if (typeof driver[method] !== 'function') throw new Error(`Your driver must implement ${method}.`);
|
|
13
|
+
}
|
|
14
|
+
if (!process.env.CHECKOUT_CDP_URL) throw new Error('Set CHECKOUT_CDP_URL to your existing session connection URL. Never log it.');
|
|
15
|
+
for (const name of ['AGENTCARD_CLIENT_ID', 'AGENTCARD_CLIENT_SECRET']) {
|
|
16
|
+
if (!process.env[name]) throw new Error(`Set ${name} for your Agentcard organization.`);
|
|
17
|
+
}
|
|
18
|
+
const browser = await chromium.connectOverCDP(process.env.CHECKOUT_CDP_URL);
|
|
19
|
+
try {
|
|
20
|
+
const context = browser.contexts()[0];
|
|
21
|
+
if (!context) throw new Error('The provider returned no default browser context.');
|
|
22
|
+
const pages = context.pages();
|
|
23
|
+
const index = Number(process.env.CHECKOUT_PAGE_INDEX ?? 0);
|
|
24
|
+
const page = pages[index];
|
|
25
|
+
if (!page) throw new Error('CHECKOUT_PAGE_INDEX must select the existing agent checkout tab.');
|
|
26
|
+
|
|
27
|
+
const vault = new VaultClient({ clientId: process.env.AGENTCARD_CLIENT_ID, clientSecret: process.env.AGENTCARD_CLIENT_SECRET });
|
|
28
|
+
await vault.syncRegistry();
|
|
29
|
+
const checkout = await driver.prepareCheckout(page); // user, merchant, amountCents+currency, exact paymentEndpoints
|
|
30
|
+
const controller = await attachToPlaywright(page, {
|
|
31
|
+
...checkout,
|
|
32
|
+
vault,
|
|
33
|
+
requireMerchantResult: true,
|
|
34
|
+
onUserAction: action => driver.onUserAction(action, { page }),
|
|
35
|
+
resolveMerchantResult: state => driver.resolveMerchantResult({ page, state }),
|
|
36
|
+
// State has no PAN, replay body, approval capability, or provider connection URL.
|
|
37
|
+
onStateChange: state => console.log(JSON.stringify(state)),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Must return after dispatching the click; do not block on a navigation that awaits user approval.
|
|
41
|
+
await driver.submitCheckout(page);
|
|
42
|
+
const deadline = Date.now() + 15 * 60_000;
|
|
43
|
+
while (Date.now() < deadline) {
|
|
44
|
+
let state = controller.getState();
|
|
45
|
+
if (['awaiting_merchant', 'requires_user_action', 'outcome_unknown'].includes(state.status)) {
|
|
46
|
+
state = await controller.reconcile();
|
|
47
|
+
}
|
|
48
|
+
if (state.status === 'completed' && state.orderId) {
|
|
49
|
+
await driver.finishAfterPayment({ page, orderId: state.orderId });
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
if (['declined', 'timed_out', 'cancelled', 'unsupported', 'failed'].includes(state.status)) break;
|
|
53
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
54
|
+
}
|
|
55
|
+
if (controller.getState().status !== 'completed') {
|
|
56
|
+
controller.cancel(); // local stop only; reconcile any still-valid approval before creating a new one
|
|
57
|
+
process.exitCode = 2;
|
|
58
|
+
}
|
|
59
|
+
} finally {
|
|
60
|
+
// Disconnect this CDP client. The existing agent retains ownership of its provider session.
|
|
61
|
+
// Do not call page.close(), context.close(), or a provider session-delete API here.
|
|
62
|
+
await browser.close();
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-cards/checkout",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Let browser agents pay with the user's own card, without your infrastructure ever touching card data.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"dist",
|
|
15
|
-
"README.md"
|
|
15
|
+
"README.md",
|
|
16
|
+
"CHANGELOG.md",
|
|
17
|
+
"examples"
|
|
16
18
|
],
|
|
17
19
|
"publishConfig": {
|
|
18
20
|
"access": "public"
|
|
@@ -21,7 +23,8 @@
|
|
|
21
23
|
"_comment_build": "TypeScript is fetched rather than declared as a devDependency ON PURPOSE. This package ships zero dependencies, which is why pnpm writes no importer for it in the workspace lockfile; adding any dep here creates one, and an importer the lockfile has not been regenerated for fails every Vercel build with ERR_PNPM_OUTDATED_LOCKFILE. Pinned so the published output is reproducible.",
|
|
22
24
|
"build": "npx -y -p typescript@5.9.3 tsc",
|
|
23
25
|
"prepublishOnly": "pnpm build",
|
|
24
|
-
"test": "node test.mjs"
|
|
26
|
+
"test": "node test.mjs && node --test lifecycle.test.mjs",
|
|
27
|
+
"test:browser": "node browser.test.mjs && node stripe-browser.test.mjs"
|
|
25
28
|
},
|
|
26
29
|
"keywords": [
|
|
27
30
|
"payments",
|