T08 · Lab
Commerce checkout agent lab
Scaffold multi-provider commerce.checkout (Shopify, Stripe, Zinc demo map), walk the template, run the smoke.
Outcome: Scaffold paybond-commerce-checkout-agent and complete sandbox commerce.checkout with bind-injected tenant/intent.
Learning view: objectives and extras expanded. Switch for commands only.
Mental model
Kit is authorize → prove → release for checkout. Multi-provider = providers map under one commerce.checkout — not a buy-proxy.
You will be able to
You will be able to
- Scaffold commerce-checkout-agent in TypeScript or Python
- Explain tenant/intent come from session bind, not tool args
- Run a sandbox commerce.checkout smoke under the shopping policy
Prerequisites
Prerequisites
- · First guarded spend and policy and limits recommended
- · Sandbox API key via paybond login
Kit stays the control layer
Paybond is authorize → prove → release → receipt for agent commerce — not a buy-anything HTTP proxy. commerce.checkout is multi-provider: pass a map of adapters and route by provider while session binding injects tenant / intent (tenantId / intentId). Prefer the Shopify-only helper when you never leave Shopify; use the multi-provider instrument when one tool must settle via more than one merchant adapter.
Sandbox demo adapters: the cards below are the three first-party sandbox adapters this lab registers. Multi-provider means one commerce.checkout tool plus a providers map—not a single-merchant limit. Register the subset your agent needs.
Shopify
Sandbox UCP / storefront mock executor
Stripe
Sandbox PaymentIntent-shaped mock
Zinc
Offline sandbox retailer mock
Scaffold the lab
Step 1 of 3
Init commerce-checkout-agent (TypeScript)
Copies kit/ts/templates/paybond-commerce-checkout-agent into your project.
Goal: Start from the kit-maintained template instead of wiring provider files by hand.
Run this
paybond init --template commerce-checkout-agentExample response
Created paybond-commerce-checkout-agent/ src/index.ts paybond.policy.yaml package.json .env.exampleYou should see: src/index.ts and paybond.policy.yaml exist in the scaffold directory.
Note: Python twin: paybond init --template commerce-checkout-agent --language python
Step 2 of 3
Login and install
Copy env template if needed, then sandbox auth and npm deps.
Goal: Attach a sandbox key and install deps before multi-provider instrument runs.
Run this
cp .env.example .env.local paybond login npm installExample response
Logged in to sandbox. Wrote .env.local (mode 0600). added packages from @paybond/kit readyYou should see: PAYBOND_API_KEY is set and npm install completes.
Note: Without a global CLI: npx -p @paybond/kit paybond login
Step 3 of 3
Smoke
End-to-end authorize → commerce.checkout → evidence without a live merchant network.
Goal: Prove the shopping policy + commerce.checkout path once the lab files are in place.
Run this
npm run smokeExample response
{ "authorized": true, "operation": "commerce.checkout", "requested_spend_cents": 4500, "settled_cost_cents": 4500, "status": "released" }You should see: Smoke JSON settles without tenant IDs in tool args.
Note: Or npm start after npm run build for the demo main() path.
Template walkthrough
Source of truth: kit/ts/templates/paybond-commerce-checkout-agent/. Select a file to preview the concepts you will edit first.
Map Shopify, Stripe, and Zinc under one commerce.checkout tool; bind tenant/intent from the run.
src/index.ts
import {
createShopifyCommerceProvider,
createStripeCommerceProvider,
createZincCommerceProvider,
instrumentCommerceCheckout,
} from "@paybond/kit/commerce";
import { createPaybondClient } from "./paybond.config.js";
const paybond = await createPaybondClient();
const zinc = createZincCommerceProvider({
mode: "sandbox",
sandboxOrderIdPrefix: "zinc_sandbox_",
});
// also shopify / stripe mock executors (see template)
const instrumented = await instrumentCommerceCheckout(paybond, {
policy: "./paybond.policy.yaml",
// Sandbox demo registers Shopify, Stripe, Zinc — example multi-provider map
providers: { shopify, stripe, zinc },
defaultProvider: "zinc",
sandbox: true,
framework: "generic",
});
// Tenant / intent from sandbox bind — never tool args
instrumented.bindingRef.tenantId = instrumented.run.tenantId;
instrumented.bindingRef.intentId = instrumented.run.intentId;
const tool = tools.find((t) => t.name === "commerce.checkout");
const result = await tool.execute({
toolName: "commerce.checkout",
toolCallId: "demo-1",
requestedSpendCents: 4500,
arguments: {
provider: "zinc",
amountCents: 4500,
zinc: {
retailer: "amazon",
products: [{ product_id: "B00SMOKE", quantity: 1, price_cents: 4500 }],
max_price_cents: 10000,
},
},
});Result: Checkout authorizes under the shopping policy; completed cost_cents drives release. No tenant in tool args.
Do not
- Build a Gateway “buy-proxy” for arbitrary retailer URLs on behalf of tenants.
- Pass tenant / intent in tool arguments — they come from session bind/attach.
- Accept free-form checkout amounts from the LLM when a catalog price exists.
Verify before you continue
Check these off against your terminal or timeline output — progress stays on this device.
If something goes wrong
If something goes wrong
If you see
Assuming multi-provider equals one merchant only
Do this
Register the subset of Shopify/Stripe/Zinc (or custom) adapters your agent needs in the providers map.
If you see
tenantId / intentId in checkout args
Do this
Inject from instrumented run binding after sandbox bind — never from the model.
If you see
Building a Gateway “buy anything” proxy
Do this
Keep merchants as adapters under policy; Kit stays the control layer.
Self-check
Self-check
Answer without scrolling up — then reveal the model answer to compare.
What stays the same when you switch provider from zinc to stripe — and what is allowed to change?
Next steps
Pick a branch — not every path needs every tutorial.
Production recipes (not this lab)
After the sandbox lab is green, use task recipes for provider-specific production smokes — they stay under Recipes, not re-taught here.
Related docs & recipes
Recipes are copy-paste production smokes — not repeated inside this tutorial.