Skip to content
Back to blog
developer-guide12 min

Building Agentic Commerce #6: A2A Protocol — When Agents Talk to Agents

How Google's Agent-to-Agent (A2A) protocol enables AI agents to discover merchants, negotiate purchases, and complete transactions — with stateful tasks, SSE streaming, and multi-protocol payment integration.

Executive summary

A deep dive into Google's A2A protocol as implemented in AgenticMCPStores. Covers agent card discovery, JSON-RPC 2.0 messaging with multi-part content, stateful task lifecycle (8 states), SSE streaming and push notifications, x402 on-chain payment integration, concurrent context locking, and how A2A complements MCP and ACP in a multi-protocol stack.

Published

2026-04-06

Updated: 2026-04-06

12 min

Author

MCP Editorial Team

Editorial and research desk

The editorial team at AgenticMCPStores covers agentic commerce, WebMCP adoption, and practical implementation patterns for merchants and platforms.

View profile

Category

developer-guide

A2Aagent-to-agentGoogleprotocolJSON-RPCSSEstreamingagentic commerceMCPx402

MCP lets agents call tools on your store. ACP handles consent flows. x402 settles stablecoin payments. But what happens when an agent on behalf of a buyer needs to have a multi-turn conversation with a merchant agent — negotiating, asking questions, tracking orders? That is where A2A (Agent-to-Agent) comes in. Google's A2A protocol gives agents a standardized way to send messages, create stateful tasks, stream real-time updates, and receive push notifications — all over JSON-RPC 2.0. This post covers the full A2A implementation in AgenticMCPStores: 12 endpoints, 8 task states, dual delivery modes (sync + SSE), and payment integration with x402 and fiat processors.

What A2A Solves That MCP Does Not

MCP is tool-oriented: an agent calls search_products, gets a result, done. Each call is stateless. A2A is conversation-oriented: an agent sends a message, the merchant agent responds, and the exchange can span multiple turns with full context preserved. MCP maps to HTTP request-response. A2A maps to a messaging protocol with tasks that track state over time. In practice, you need both: MCP for structured tool calls (search, cart, checkout) and A2A for open-ended interactions (negotiation, order tracking, complex queries that require back-and-forth).

Agent Card Discovery

Before sending messages, agents discover what a merchant can do via the agent card. GET /.well-known/agent-card.json returns the public card (cached for 1 hour) with: name, description, supported protocols, message capabilities, and available skills. GET /.well-known/a2a/agent-card/extended returns the authenticated card (requires X-Agent-Api-Key header) with additional capabilities based on the agent's tier and scopes. The agent card follows the A2A specification format, making AgenticMCPStores discoverable by any A2A-compatible agent.

Message Format: JSON-RPC 2.0 with Multi-Part Content

A2A messages use JSON-RPC 2.0 with the method a2a.SendMessage. Each message contains parts — an array of typed content blocks: text parts (plain text or markdown), data parts (structured JSON — product data, payment metadata), and file parts (URI references with media type). Messages also carry a role (user or agent), optional contextId for multi-turn conversations, optional taskId to continue an existing task, and metadata for extension data. This multi-part structure lets agents mix natural language with structured data in a single message — something MCP tool calls cannot do.

Task Lifecycle: 8 States

When an authenticated agent sends a message, A2A creates a stateful task. The task moves through 8 states: UNKNOWN (created, not yet processed), WORKING (in progress), INPUT_REQUIRED (awaiting user input — e.g., payment confirmation), AUTH_REQUIRED (awaiting authentication), COMPLETED (finished successfully), FAILED (error), CANCELED (canceled by agent), REJECTED (validation failure). Valid transitions are enforced server-side via a state machine. Terminal states are COMPLETED, FAILED, and CANCELED — once reached, the task cannot change. Cancelable states are WORKING, INPUT_REQUIRED, and AUTH_REQUIRED. Each task type has a TTL: SEARCH and COMPARE tasks expire in 5 minutes, PURCHASE and TRACK tasks in 30 minutes. Expired tasks are cleaned up automatically.

Dual Delivery: Sync and SSE Streaming

A2A supports two delivery modes. Synchronous: POST /a2a/messages sends a message and waits for the complete response. Good for simple queries (search, compare, merchant info). Streaming: POST /a2a/messages/stream sends a message and returns an SSE stream. The server emits multiple events as the task progresses — message events (intermediate results), task-update events (state changes, payment metadata), and error events. The stream closes when the task reaches a terminal state. Task subscription: GET /a2a/tasks/{taskId}/subscribe opens a persistent SSE stream that emits task_update events whenever the task state changes. Maximum 50 concurrent subscribers per task to prevent amplification attacks.

Push Notifications (Webhooks)

For agents that prefer webhooks over SSE polling, A2A supports push notification configs. Register a webhook via POST /a2a/tasks/{taskId}/pushNotificationConfigs with a webhookUrl, auth info (bearer token or custom header), and event types (status_update, artifact_update). The auth info is stored encrypted and never returned in API responses. When a task state changes or an artifact is added, the platform fires an async webhook to the registered URL with the event payload. This enables fire-and-forget patterns where the buyer agent does not need to hold an open connection.

Payment Integration: x402 and Fiat

A2A elevates payments from tool-level (MCP complete_checkout) to message-level. When the message router classifies a PURCHASE intent, the payment handler kicks in. For x402 (on-chain USDC): the handler detects purchase intent, creates an x402 payment requirement (supports Base, Polygon, Ethereum, Solana, Arbitrum), returns the task in INPUT_REQUIRED state with payment metadata, the client submits the x402 payment payload, the server verifies the EIP-712 signature and settles on-chain. For KYApay (fiat): similar flow with fiat payment processor integration, enabled via KYAPAY_A2A_ENABLED env var. Payment metadata is tracked via task metadata keys: x402.payment.status, x402.payment.required, x402.payment.receipt. Extension headers (X-A2A-Extensions) signal which payment protocols are available.

Concurrent Safety: Context Locking

Multi-turn conversations need concurrency protection. A2A uses PostgreSQL advisory locks on context IDs (pg_try_advisory_xact_lock with hashtext). If two agents try to write to the same context simultaneously, the second gets a 409 CONTEXT_CONFLICT error. This prevents race conditions in checkout flows where timing matters. Cart association: when a task creates a cart, TaskManagerService.linkCart(taskId, cartId) binds them. If the task is canceled, the linked cart is automatically expired.

Intent Classification and Message Routing

The MessageRouterService classifies incoming messages into intents: SEARCH, COMPARE, PURCHASE, TRACK, MERCHANT_INFO, or AP2_CHECKOUT. Classification uses an ACTION_INTENT_MAP that maps keywords and data parts to intents. Each intent routes to a specialized handler that returns artifacts (search results, comparison tables, purchase receipts, tracking info, merchant profiles). Artifacts are structured result objects attached to the task, each with a UUID, typed parts, and metadata. This intent-based routing means agents can use natural language and A2A will figure out what they want.

A2A vs MCP vs ACP: When to Use What

MCP: use for structured tool calls — search_products, create_cart, complete_checkout. Stateless, one request one response. Best for agents that know exactly what they want. ACP: use for consent-based checkout flows. Agent presents intent, merchant confirms, payment executes with explicit consent at each step. A2A: use for open-ended conversations — product questions, negotiation, order tracking, complex queries. Stateful, multi-turn, streaming. Best for agents that need to reason through a purchase. In AgenticMCPStores, all three work together: an agent might discover a store via MCP (search_products), ask questions via A2A (multi-turn conversation about sizing), then complete checkout via ACP (consent flow with payment). The platform auto-detects which protocol each request uses.

Production Configuration

A2A is available on Growth tier and above. Key configuration: 12 endpoints registered in server.ts, rate limiting per agent key (tier-based), X-Initiated-By header on all responses (EU AI Act compliance), structured logging with pino (requestId, agentKeyId, duration_ms, outcome, intent, taskState). Error codes follow the A2A specification: INVALID_REQUEST (400), INVALID_PARAMS (400), METHOD_NOT_FOUND (405), CONTEXT_CONFLICT (409), UNSUPPORTED_OPERATION (403), TASK_NOT_FOUND (404), TASK_NOT_CANCELABLE (400). The implementation has 128 tests covering discovery, messaging, task lifecycle, streaming, push notifications, and payment integration.

Frequently asked questions

Is A2A a replacement for MCP?

No. A2A complements MCP. MCP is for structured tool calls (search, cart, checkout) — one request, one response. A2A is for multi-turn conversations where agents need to negotiate, ask questions, or track state over time. Most agents will use MCP for browsing and checkout, and A2A for complex interactions that require back-and-forth.

Do I need to implement A2A on my store?

No. AgenticMCPStores handles the A2A protocol for you. When you connect your Shopify, WooCommerce, or Odoo store, the platform automatically exposes A2A endpoints. Your store just needs to have products and policies synced — the platform handles message routing, task management, and payment integration.

Can unauthenticated agents use A2A?

Yes, for read-only operations. Unauthenticated agents can send messages to search products, compare items, and get merchant info. They receive inline results without persistent task tracking. For checkout flows, task management, and push notifications, agents need an API key (X-Agent-Api-Key header).

How does A2A handle payments?

A2A elevates payments to the message level. When a purchase intent is detected, the task enters INPUT_REQUIRED state with payment metadata. For x402, the agent submits an EIP-712 signed USDC payment. For fiat (KYApay), the agent follows the fiat checkout flow. Payment status is tracked in task metadata and streamed via SSE or pushed via webhooks.

What is the maximum number of concurrent A2A connections?

There is no hard connection limit, but rate limiting applies per agent key based on tier (Starter: 100 req/min, Growth: 500, Pro: 2,000, Enterprise: unlimited). SSE subscriptions are capped at 50 concurrent subscribers per task to prevent amplification attacks. Context locking ensures only one agent can write to a context at a time.

Sources and references

Related articles

A2A Protocol for Agentic Commerce: Agent-to-Agent Messaging, Tasks & SSE Streaming | AgenticMCPStores