Agentic commerce workflows
Let an agent buy from merchants on your behalf: AP2 checkout and payment mandates, the ACP buyer side, layered spending ceilings, settlement over x402 or MPP, and an audit trail.
An agent that shops for you needs three things: a clear statement of what you allow it to buy, a way to take part in a merchant's checkout, and limits the network enforces no matter what the agent does. On Tenzro Network 1 these are AP2 mandates, the ACP buyer side and your agent's delegation scope. This tutorial walks one purchase from mandate to settlement and audit.
The flow
- You, the principal, sign a CheckoutMandate: what the agent may buy, from whom, up to how much, in which asset, on which chains, until when.
- The agent opens a checkout with an ACP merchant as the buyer and builds the cart.
- The agent signs a PaymentMandate for that exact cart, bound to your CheckoutMandate.
- The network validates the pair against every ceiling.
- The agent pays through the rail the merchant accepts, x402 or MPP, in TNZO or stablecoins.
- The validated pair is stored under your DID for audit.
Every payment passes these ceilings, outermost first:
| Ceiling | Set by | What it bounds |
|---|---|---|
| CheckoutMandate | You, per purchase intent | Total, asset, merchants, categories, chains, number of uses, expiry |
| Delegation scope | You, per agent, in the console | Per-transaction and daily caps, allowed operations, protocols and chains |
| Escrow (optional) | You, when the mandate pre-locks funds | The amount actually available to release |
| Agent bond (optional) | The agent's operator | What is slashed if the agent breaks a mandate |
Prerequisites
- A passkey wallet and a delegated agent with limits. Follow Build an AI payment agent first.
npm install tenzro-sdk.- Background: Agent commerce.
1. Read the protocol profile
The node reports the AP2 version it speaks, the mandate kinds, the presence modes (human present or not present), the key-binding forms and the ceilings it applies.
import { TenzroClient } from "tenzro-sdk";
const client = new TenzroClient({ endpoint: "https://rpc.tenzro.xyz" });
const info = await client.ap2().protocolInfo();
console.log(info.mandate_kinds, info.presence_modes, info.ceilings);2. Sign the CheckoutMandate as the principal
The CheckoutMandate is your pre-authorisation. Amounts are in the smallest unit of the asset; for USDC, 6 decimals, so 25000000 is 25 USDC. Leave max_uses out for a single charge.
const checkout = {
mandate_id: "chk-2026-10-02-001",
principal_did: "did:tenzro:human:<your-id>",
agent_did: "did:tenzro:machine:<your-id>:<agent-id>",
description: "Buy up to 25 USDC of labelled image data for the detector fine-tune",
max_amount: 25000000,
asset: "USDC",
allowed_merchants: ["did:tenzro:machine:<merchant-id>"],
allowed_categories: ["datasets"],
accepted_chains: ["tenzro"],
issued_at: "2026-10-02T09:00:00Z",
expires_at: "2026-10-03T09:00:00Z",
presence: "human_not_present",
};
// Signed by the principal's account; confirm with your passkey when prompted.
const checkoutVdc = await client.ap2().signMandate("checkout", checkout, checkout.principal_did);The node builds the canonical AP2 preimage, signs it with the principal's account and returns a verifiable credential that verifies itself before it is returned. The caller never handles key material.
3. Build the cart as an ACP buyer
The merchant sells through the Agentic Commerce Protocol (ACP). The agent acts on the buyer side: it opens a checkout session with the merchant, adds items, and receives a priced cart with line items and a total. Tenzro maps the ACP cart onto a PaymentMandate one to one:
| ACP checkout | PaymentMandate field |
|---|---|
| Line items (id, title, quantity, unit price, total) | items (sku, description, quantity, unit_price, total, category) |
| Order total and currency | total_amount, asset |
| Merchant identity | merchant_did |
| Checkout expiry | expires_at |
Before committing, the agent checks the cart locally against the CheckoutMandate: same asset, a merchant on the list, a total under max_amount. The network checks again in step 5, so a buggy or manipulated agent cannot get past it.
4. Sign the PaymentMandate as the agent
The agent commits to the exact cart. checkout_mandate_id ties it to your mandate, and chain must be one of your accepted_chains.
const payment = {
mandate_id: "pay-2026-10-02-001",
checkout_mandate_id: checkout.mandate_id,
agent_did: checkout.agent_did,
merchant_did: "did:tenzro:machine:<merchant-id>",
items: [
{ sku: "img-set-street-v2", description: "Street scenes, 5k labelled images", quantity: 1, unit_price: 18000000, total: 18000000, category: "datasets" },
],
total_amount: 18000000,
asset: "USDC",
chain: "tenzro",
committed_at: "2026-10-02T09:14:00Z",
expires_at: "2026-10-02T09:44:00Z",
};
// Run inside the agent runtime, authenticated as the agent.
const agentClient = new TenzroClient({ endpoint: "https://rpc.tenzro.xyz" });
const paymentVdc = await agentClient.ap2().signMandate("payment", payment, payment.agent_did);5. Validate the pair
Validation checks that both credentials verify, that the payment references the checkout, that items, totals, asset, merchant and chain fit the checkout, and, with enforceDelegation set, that the total also fits the agent's delegation scope.
const result = await client.ap2().validateMandatePair(checkoutVdc, paymentVdc, true);
if (!result.valid) throw new Error(result.error);
console.log(result);
// {
// valid: true,
// checkout_mandate_id: "chk-2026-10-02-001",
// payment_mandate_id: "pay-2026-10-02-001",
// principal_did: "did:tenzro:human:...",
// agent_did: "did:tenzro:machine:...",
// delegation_enforced: true
// }A single mandate can be checked on its own with verifyMandate(vdc), which returns the mandate id, kind and signer.
6. Pay the merchant
Complete the ACP checkout with the payment rail the merchant accepts:
- x402: the merchant's payment endpoint answers
402 Payment Required; the agent's SDK answers the challenge in USDC or TNZO and retries. See Payments with x402. - MPP: for merchants that meter a session, the agent opens an MPP session and settles when it closes. See Payments with MPP.
- Escrow: if your CheckoutMandate carried an
escrow_id, the funds were locked when you signed and the payment releases them to the merchant.
The same ceilings run again at settlement. A payment that would push the agent over its daily cap is refused even if the mandate pair was valid.
7. Audit what the agent bought
Validated pairs are stored under the principal's DID with the mandate ids, the DIDs involved, amounts, asset, chain, expiry, whether delegation was enforced, and the signed credentials themselves.
const { mandates } = await client.ap2().listMandates("did:tenzro:human:<your-id>");
for (const m of mandates) {
console.log(m.mandate_id, m.merchant_did, m.total_amount, "of", m.max_amount, m.asset);
}If an agent ever pays outside a mandate, report it with tenzro_ap2ReportMandateViolation. When the agent carries an agent bond, a proven violation slashes it.
Next steps
- The agent wallet and limits used here: Build an AI payment agent.
- Paying in stablecoins end to end: Pay for inference in stablecoins.
- How mandates, x402, MPP and ACP fit together: Agent commerce.