Three Agents and a Hoodie: A2A Across the Purchase Lifecycle A developer's hands-on test of the Agent2Agent (A2A) protocol across a three-agent commerce flow — checkout, shipping, and claims — shows the protocol's task model is its key value, while payment authorization, enforceable agent identity, and skill selection remain gaps. The A2A protocol joined the Agentic AI Foundation on 17 August, alongside MCP, following the September 2025 launch of the Agentic Commerce Protocol by OpenAI and Stripe and the January 2026 Universal Commerce Protocol from Google and Shopify. Three Agents and a Hoodie: A2A Across the Purchase Lifecycle A2A joined the Agentic AI Foundation alongside MCP. I built a three-agent commerce mesh — checkout, shipping, claims — to see what it actually buys you. Agentic commerce is still early. OpenAI and Stripe put the first real stake in the ground in September 2025 with the Agentic Commerce Protocol — an open standard for an agent running checkout against a merchant it does not own. 1 Google and Shopify followed at NRF in January 2026 with the Universal Commerce Protocol, co-developed with Etsy, Wayfair, Target and Walmart and endorsed by a couple of dozen payment networks. Plenty of people will tell you the agentic channel is here to stay and will move serious money over the next few years. 2 user-content-fn-ucp Look closer, though, and nearly all of that movement is American. Adoption in Europe is thinner, and I’d expect that to change over the year rather than the quarter. There’s also an ordering problem nobody gets to skip: the human-to-agent journey has to work before agent-to-agent commerce means very much. A shopper has to be willing to hand an agent a card before two agents have anything to settle between them. But this is AI, and it moves fast. On 17 August the Agent2Agent protocol joined the Agentic AI Foundation, the Linux Foundation body that already houses MCP. 3 user-content-fn-aaif-announce 4 Two protocols that spent 2025 being described as rivals now sit under the same roof, which is roughly the outcome anyone who had actually read both specs expected. Which brings me to the part the explainers skip. Almost every agent demo you have seen is one agent with several tools. That shape is easy to build and it teaches you nothing about the actual problem, which is what happens when the parties on either end of a call do not belong to the same organisation and cannot see each other’s data. A merchant’s checkout system, a carrier’s tracking system, and a claims desk are three different parties even inside one company. Between companies it isn’t close. So this post walks through what an agent-to-agent commerce flow could look like on A2A: three agents that genuinely cannot see each other’s data, handling one purchase from basket to claim, and what the protocol had to do to get them there. The short version A2A’s tasks — not its messages — are the thing worth having. Commerce is full of work that pauses for a human, or runs for three days, and a tool call cannot model either. What A2A deliberately does not give you is payment authorisation, agent identity you can enforce, or any way to say which skill you want. Those gaps are real and you will fill them yourself. Part 1: Agentic commerce, a primer Strip the marketing off and agentic commerce is one change: the buyer stops being a human with a browser . What replaces the browsing is a mapping problem — turning a user’s intent into an order intent, and an order intent into a payment intent. Take “I want to buy red sneakers.” In the human-to-agent shape we have today, the agent maps that to an order intent and comes back with a ranked list to choose from. That is ChatGPT and Gemini right now. The shopper picks the pair they like and, in principle, finishes checkout in the chat. In practice they mostly don’t. What we have seen so far is that people are happy to do discovery in a chat and then leave — they would rather be handed off to the merchant’s own site to pay. The payment-intent step gets sidestepped, and not for want of plumbing: ACP ships a delegated payment spec, and Google’s AP2 exists for precisely this, modelling a purchase as three signed mandates — intent, cart, payment — which is the same chain written in cryptography. 5 The capability is further along than the behaviour. Replace that human with an agent and three things move at once. Intent gets specified earlier and more completely. A shopper browses; an agent arrives with constraints. “Under 1,200 SEK, delivered before Friday, returnable.” That’s closer to a procurement request than a shopping session, and it rewards merchants who can answer questions rather than merchants who can rank products. Trust has to become explicit. When a human clicks pay, consent is the click. When an agent transacts, “the buyer agreed to this” becomes something you have to represent, sign, and later prove. This is the whole reason protocols like AP2 and ACP exist, and it’s a different problem from “let agents talk to each other.” The post-purchase tail becomes the hard part. This is the bit that gets skipped. Buying is one request. Everything after — where is it, it arrived broken, I want my money back — is a long-running conversation across multiple systems, and it’s where most of the operational cost of retail actually lives. A demo that stops at “order placed” has demoed the easy 10%. And that tail is where agent-to-agent stops being a nice idea and becomes the only shape that works. “Where is my parcel, and can I have my money back?” cannot be answered by one agent with tools, because no single party holds the answer: the merchant knows what was paid, the carrier knows what happened to the box, and the claims desk knows the policy. Three systems, three owners, often three companies. Note also what is missing here compared to checkout. When a chat can’t close a purchase, there is an escape hatch — hand the shopper to the merchant’s website. There is no equivalent for the tail. The entire value of an agent handling a damaged delivery is that the buyer does not have to go and chase three companies themselves. Take away the coordination and there is nothing left worth automating. Not to minimise the ordering problem: human-to-agent has to work before agent-to-agent becomes a big thing. But many of the building blocks are already here. I mapped the protocol landscape a while back — MCP for tools, A2A for agent coordination, AP2/ACP/x402 for the money, identity layers on top. 6 The short version of that piece: no single protocol covers agentic commerce, and pretending otherwise gets you an architecture with a hole in it. This post is about one layer of that stack — probably the more futuristic one — and about being honest where its edges are. Part 2: What A2A actually unlocks for commerce A2A is an open protocol for agents built by different people, in different frameworks, to discover each other and get work done together. 7 It went 1.0 in March 2026, and 1.0 is what added cryptographically signed agent cards — JWS over a canonicalised card — so a client can verify the card really came from the domain it claims. 8 user-content-fn-a2a-v1 The common framing is “MCP connects agents to tools, A2A connects agents to agents.” True, and not the useful part. The useful part is the shape of the interaction. The card is a business document An agent card is JSON at a well-known URL describing who the agent is, what it can do, how to reach it, and how to authenticate. 7 Structurally it resembles an OpenAPI document. Functionally it’s closer to a capabilities statement — the thing a partner reads before deciding whether to integrate. That distinction matters more than it sounds. A skill description isn’t documentation for a developer who will read it once. It’s the text another agent uses at runtime to decide whether you are the right counterparty. I found myself writing them the way you’d write a service description for a procurement portal, and that was the right instinct. Signing the card, and the question it forces v1.0 added JWS-signed cards, so I signed mine. Each agent serves a card with a signature over a JCS-canonicalised body, and the client verifies it before it sends anything. That ordering is the entire point: a card is a claim about who an agent is, and checking it after you have already placed an order is theatre. Implementing it forced a question I had not thought hard enough about, and it’s the most useful thing I learned building this. A JWS header can carry a jku — a URL saying where to find the key. It is very tempting to just fetch it. Don’t. A card that names its own key location proves nothing, because anyone who can serve you a card can serve you a matching key; you would be asking the forger to vouch for the forgery. My verifier ignores jku entirely and resolves keys from the origin the card was fetched from — the one thing in the exchange I had already decided to trust: js const verifier = verifyAgentCardSignature async kid = { // Deliberately NOT the signature's own jku. The only thing worth // trusting is the origin you already chose to talk to. const response = await fetch new URL "/a2a/jwks", origin ; const { keys } = await response.json ; const match = keys.find k = k.kid === kid ; if match throw new Error No key ${kid} published by ${origin} ; return match; } ; Which surfaces the honest limit of card signing: it proves a card came from a domain. It does not tell you that domain deserves your money. That’s a different problem, and nobody has solved it — see the closing section. I also had to decide what to do with an unsigned card. Refusing outright is the satisfying answer and the wrong one right now: it would leave the mesh unable to talk to any agent that hasn’t adopted v1.0 signing. So an invalid signature is refused, an absent one is recorded and allowed, and a real deployment makes that call per counterparty rather than globally. Tasks are the actual feature Here’s the thing I’d put in front of anyone evaluating A2A for commerce. A tool call has two states: you called it, and it returned. Commerce is full of work that fits neither: - An order total needs a human to approve it. The work isn’t done, isn’t failed, and isn’t running. It’s waiting on you . - A parcel takes three days to arrive. The work is running, for three days, across an unbounded number of client disconnections. A2A models both natively. input-required is a first-class task state — the agent stops and says what it needs. Long-running tasks stay in working and emit status updates as things happen, and a client can register a webhook instead of holding a stream open for the duration. 7 user-content-fn-a2a-spec Those two states are, I think, the entire commerce case for A2A. Everything else you could bodge with an HTTP API and a job queue. These are what you’d end up reinventing badly. What it deliberately doesn’t do A2A does not authorise payments. It gives you a place to pause for authorisation — that’s what input-required is — but the mandate itself, the cryptographic evidence that a human agreed to spend this money, belongs to AP2 or ACP. 6 Anyone selling you A2A as an agentic-payments story is selling you a socket and calling it electricity. It also doesn’t tell you how to select a skill. Cards describe skills; requests carry a natural-language message. There is no method field. For an agent talking to a human’s agent that’s the right call — it keeps agents opaque, which is the design principle. For a merchant’s checkout agent calling a merchant’s shipping agent forty times a second, routing through an LLM to work out that you meant quote shipping is absurd. Every mesh I’ve seen fills this in privately. Mine does too — a metadata key for machine callers, keyword classification for prose. I’d rather it were standardised. And that gap is bigger than it first looks, because selecting the skill is only half the job . I had routing working and thought I was done. Then I sent the checkout agent a sentence a real buyer’s agent would send: I would like to buy two Umai Kanji hoodies, ship them to London please. It routed to place order correctly, and then offered me one Nebula Purple hoodie, delivered to Stockholm, in Swedish kronor , ready to confirm. Wrong product, wrong quantity, wrong country, wrong currency — presented as a total to approve. Nothing had failed. The router worked; there was simply no parameter extraction behind it, so every unparsed field fell through to a default that happened to be sitting in the code. That is the worst failure mode a commerce agent has. A crash is loud. A confidently wrong purchase confirmation is not, and the buyer’s agent has no way to tell the difference — the reply is well-formed, correctly typed, and about the wrong hoodie. The fix isn’t clever, it’s just a decision: read what the sentence says, and ask about what it doesn’t. js const missing = ... items.length === 0 ? "product" : , ... country ? "destination" : , ; // Defaulting here would mean handing back a confirmable total // for a product nobody named. if missing.length 0 throw new NeedsMoreInfo askFor missing , pending ; NeedsMoreInfo becomes an input-required carrying what was understood so far, so the follow-up resumes the original request rather than starting over — a bare “Tokyo” still lands on the place order that asked the question, instead of falling through to the default skill with no keywords to match on. Which is the second thing input-required turned out to be for. I reached for it as the payment-confirmation gate. It’s also how an agent says I don’t know enough yet without failing, and that turns a one-shot request into a conversation — the same state, doing two quite different jobs. Part 3: The build — three agents and a hoodie I have a demo store called Hoodtopia: Next.js, MedusaJS for real commerce primitives, Kustom for checkout, built originally for a LangChain Stockholm meetup. 9 It already had a working shipping integration, real per-market carriers, and real order flow. Perfect substrate — the agents wrap something that was already load-bearing rather than a mock. I added three agents. The mesh | Agent | Owns | Cannot see | Skills | |---|---|---|---| | Checkout | Orders, pricing, what was paid | Anything about carriers | quote cart , place order , order status , issue replacement | | Shipping | Rates, labels, carrier scans | Anything about money | quote shipping , book shipment , track shipment , shipment evidence | | Claims | Claims and their outcomes | Both of the above | open claim , claim status | That third row is the whole design. The claims agent has to decide whether to refund someone, and it can’t read the order table or the carrier feed. It has to ask . The constraint is artificial and that's the point All three run in one process. I could have let them share a database and saved myself a week. Enforcing the boundary is what forces the demo to exercise the protocol instead of quietly cheating — and it’s what makes the code honest about what a real multi-party deployment would need. The shape graph TD S "Shopper agent