Reading Guide: This article provides an in-depth exploration of AP2 protocol architecture and technical implementation details, including Python code examples, cryptographic mechanisms, and system integration solutions. If you’re primarily interested in the business applications of AI Agent payment systems, we recommend starting with the conceptual chapters (Introduction to AP2, Why AP2 Matters). The technical implementation chapters (Python Sample Project Structure, Core Implementation Analysis) are better suited for readers with development background.
Table of Contents
- Introduction to AP2
- Why AP2 Matters
- Core Concepts and Principles
- Role Architecture
- Transaction Flows
- Python Sample Project Structure
- Core Implementation Analysis
- Practical Examples
Introduction to AP2
Agent Payments Protocol (AP2) is an open, non-proprietary protocol designed specifically for AI Agent-driven commerce transactions. Built as an extension of Agent-to-Agent (A2A) and Model Context Protocol (MCP), it establishes secure, verifiable, and interoperable standards for payment transactions between AI Agents.
Core Features
- Openness and Interoperability: Any compliant Agent can transact with any compliant merchant
- User Control and Privacy: Users remain the ultimate authority, with privacy protection built into the protocol
- Verifiable Intent: Based on deterministic, non-repudiable proof of user intent rather than speculative behavior
- Clear Accountability: Cryptographic audit trails establish clear responsibility for each transaction
Why AP2 Matters
The Trust Crisis
Current payment systems were designed for direct human operation. When autonomous AI Agents initiate payments, several critical challenges emerge:
- Authorization & Auditability: How do you prove the user genuinely authorized the Agent to make a specific purchase?
- Authenticity of Intent: How do you confirm the Agent’s request accurately reflects the user’s true intent rather than AI “hallucination”?
- Accountability: When transactions go wrong, who’s responsible? The user, Agent developer, merchant, or payment network?
Fragmentation Risk
Without a unified protocol, the industry will develop various proprietary, closed solutions, leading to:
- Fragmented user experience: Different Agents only work with specific merchants or payment methods
- High merchant costs: Need to integrate multiple non-standard Agent payment interfaces
- Inability for payment ecosystems to assess risk uniformly: Increasing fraud risk and costs
Core Concepts and Principles
Guiding Principles
- Openness and Interoperability
- User Control and Privacy by Design
- Verifiable Intent, not speculative behavior
- Clear Transaction Accountability
Trust Anchor: Verifiable Digital Credentials (VDCs)
AP2’s core innovation is the use of Verifiable Digital Credentials (VDCs) to establish trust. VDCs are tamper-proof, portable, cryptographically signed digital objects that serve as transaction building blocks.
Three Primary VDC Types
1. Cart Mandate (Human Present)
Used when the user is present to authorize a purchase, generated by the merchant and cryptographically signed by the user.
Contains:
- Verifiable identities of payer and payee
- Tokenized representation of specific payment method
- Final transaction details (items, address, amount, currency)
- Container for risk-related signals
2. Intent Mandate (Human Not Present)
For scenarios where the user is not present during the transaction (e.g., “Purchase when ticket price drops below $100”).
Contains:
- Verifiable identities of payer and payee
- List or categories of authorized payment methods
- Shopping intent including parameters like product categories
- Agent’s natural language understanding of user prompt
- Time-to-live (TTL)
3. Payment Mandate
Independent VDC shared with payment networks and issuers.
Purpose:
- Provide visibility into AI Agent transactions
- Help networks and issuers build trust and assess risk
- Include signals about AI Agent presence and transaction patterns (present/not present)
Role Architecture
AP2 defines responsibilities through clear role separation:
1. User
The individual delegating payment tasks to an Agent.
2. Shopping Agent / User Agent (SA/UA)
The AI interface the user interacts with (e.g., Gemini, ChatGPT).
- Understands user needs
- Builds shopping cart
- Obtains user authorization
3. Credentials Provider (CP)
Specialized entity (e.g., digital wallet).
- Securely manages user’s payment credentials and methods
- Provides available payment methods
- Facilitates payment execution
4. Merchant Endpoint (ME)
Interface or Agent operating on behalf of the merchant.
- Showcases products
- Negotiates shopping cart
5. Merchant Payment Processor (MPP)
Entity that builds the final transaction authorization message.
- Processes payment requests
- Communicates with payment network
6. Network and Issuer
Payment network and issuing financial institution.
- Approve or decline payment
- May initiate challenges (e.g., 3D Secure)
Transaction Flows
Human Present Transaction Flow
When the user is present and can authorize final payment:
- Setup: User may establish connection between Shopping Agent and Credentials Provider
- Discovery & Negotiation: Shopping Agent interacts with merchant to assemble cart
- Merchant Cart Verification: Merchant signs final cart, indicating commitment to fulfill
- Payment Method Provision: Shopping Agent requests applicable payment methods from Credentials Provider
- Cart Presentation: Agent presents final cart and selected payment method to user in trusted interface
- Signature & Payment: Upon user approval, generates cryptographically signed Cart Mandate
- Payment Execution: Payment details transmitted to Credentials Provider and merchant to complete transaction
- Send to Issuer: Merchant or processor routes transaction to payment network and issuer
- Challenge (if necessary): Any party may initiate challenge (e.g., 3D Secure)
- Authorization: Issuer approves payment, confirmation sent to user and merchant
Human Present Transaction Sequence Diagram (30 Steps)
Processor participant Network as Payment Network
& Issuer User->>SA: 1. Shopping request
("Buy a coffee maker") SA->>ME: 2. Query products ME->>ME: 3. Find product and create Cart ME->>SA: 4. Return CartMandate
(merchant signed) SA->>User: 5. Display product options User->>SA: 6. Select product SA->>User: 7. Request shipping address User->>SA: 8. Provide shipping address SA->>ME: 9. Update Cart (with address) ME->>SA: 10. Return updated CartMandate SA->>CP: 11. Request payment methods CP->>SA: 12. Return available payment methods SA->>User: 13. Display cart, address, payment method User->>SA: 14. Confirm purchase SA->>SA: 15. Create PaymentMandate SA->>User: 16. Request signature authorization User->>SA: 17. Sign (generate user_authorization) SA->>CP: 18. Send Signed PaymentMandate CP->>CP: 19. Update token binding mandate ID CP-->>SA: 20. Confirm receipt SA->>MPP: 21. Initiate payment request MPP->>SA: 22. Request OTP challenge SA->>User: 23. Request OTP User->>SA: 24. Provide OTP SA->>MPP: 25. Submit OTP MPP->>Network: 26. Submit transaction authorization
(with PaymentMandate) Network->>Network: 27. Verify and approve Network->>MPP: 28. Authorization successful MPP->>SA: 29. Payment confirmation SA->>User: 30. Display receipt
Human Not Present Transaction Flow
Scenarios where the user wants the Agent to make payments when they’re not present:
- Capture Intent: User approves Agent’s understanding of their intent, creating a signed Intent Mandate
- Use Intent Mandate: This credential (containing natural language description) is shared with merchant
- Merchant Can Enforce User Confirmation: If merchant is uncertain, they can require user to return to session to confirm details
Human Not Present Transaction Sequence Diagram
Processor participant Network as Payment Network
& Issuer User->>SA: 1. Shopping intent
("Buy shoes when price below $100") SA->>SA: 2. Understand and parse intent SA->>User: 3. Confirm intent understanding User->>SA: 4. Sign IntentMandate
(authorize future execution) Note over SA,ME: [Time passes, condition triggers] SA->>ME: 5. Send IntentMandate
query matching products ME->>ME: 6. Verify IntentMandate
find matching products alt Merchant certain can fulfill ME->>SA: 7a. Return CartMandate SA->>CP: 8a. Request payment method CP->>SA: 9a. Return payment method SA->>SA: 10a. Create PaymentMandate SA->>CP: 11a. Send PaymentMandate SA->>MPP: 12a. Initiate payment MPP->>Network: 13a. Submit authorization Network->>MPP: 14a. Authorization successful MPP->>SA: 15a. Confirmation SA->>User: 16a. Notify transaction complete else Merchant needs confirmation ME->>SA: 7b. Request user confirmation SA->>User: 8b. Request confirmation details User->>SA: 9b. Provide confirmation/update Note over SA,ME: Convert to Human Present flow end
Python Sample Project Structure
Directory Structure
samples/python/
├── pyproject.toml # Python project configuration
├── README.md # Python sample documentation
├── scenarios/ # Various scenario demonstrations
│ └── a2a/
│ └── human-present/
│ ├── cards/ # Card payment scenarios
│ └── x402/ # X402 protocol scenarios
└── src/
├── common/ # Shared utilities and infrastructure
│ ├── a2a_extension_utils.py
│ ├── a2a_message_builder.py
│ ├── payment_remote_a2a_client.py
│ ├── base_server_executor.py
│ ├── server.py
│ └── ...
└── roles/ # Various role Agent implementations
├── shopping_agent/
├── merchant_agent/
├── merchant_payment_processor_agent/
└── credentials_provider_agent/
Primary Modules
1. Common Module
a2a_message_builder.py
- Builder class for constructing A2A Message objects
- Supports adding TextPart and DataPart
- Auto-generates message_id and sets roles
payment_remote_a2a_client.py
- A2A client wrapper
- Handles connections to remote Agents
- Sends messages and manages Task lifecycle
base_server_executor.py
- Base class for Agent executors
- Handles request interpretation, tool selection, and invocation
2. Roles Module
Each role has its own directory containing:
__main__.pyor launch scriptagent_executor.pyoragent.py: Core logictools.py: Available tool functions
Core Implementation Analysis
Shopping Agent Implementation
Location: src/roles/shopping_agent/agent.py
Shopping Agent uses Google ADK (Agent Development Kit) and Gemini 2.5 Flash model.
root_agent = RetryingLlmAgent(
max_retries=5,
model="gemini-2.5-flash",
name="root_agent",
instruction="""
You are a shopping agent responsible for helping users find and purchase products...
""",
tools=[
tools.create_payment_mandate,
tools.initiate_payment,
tools.sign_mandates_on_user_device,
# ...
],
sub_agents=[
shopper,
shipping_address_collector,
payment_method_collector,
],
)
Primary Responsibilities
- Find Products: Interact with Merchant Agent to find products meeting user needs
- Collect Information:
- Delegate to
shoppersub-agent to collect products - Delegate to
shipping_address_collectorto collect shipping address - Delegate to
payment_method_collectorto collect payment method
- Delegate to
- Complete Purchase: Create and sign Payment Mandate, initiate payment
A2A Message Builder
Location: src/common/a2a_message_builder.py
This is a Builder pattern implementation for constructing A2A protocol-compliant messages.
message = (
A2aMessageBuilder()
.set_context_id(context_id)
.add_text("Update the cart with shipping address")
.add_data("cart_id", chosen_cart_id)
.add_data("shipping_address", shipping_address)
.build()
)
Primary Methods:
add_text(text): Add text partadd_data(key, data): Add data partset_context_id(context_id): Set context IDset_task_id(task_id): Set task IDbuild(): Return constructed Message object
Payment Mandate Creation
Location: src/roles/shopping_agent/tools.py
def create_payment_mandate(
payment_method_alias: str,
user_email: str,
tool_context: ToolContext,
) -> str:
cart_mandate = tool_context.state["cart_mandate"]
payment_request = cart_mandate.contents.payment_request
payment_response = PaymentResponse(
request_id=payment_request.details.id,
method_name="CARD",
details={"token": tool_context.state["payment_credential_token"]},
shipping_address=shipping_address,
payer_email=user_email,
)
payment_mandate = PaymentMandate(
payment_mandate_contents=PaymentMandateContents(
payment_mandate_id=uuid.uuid4().hex,
timestamp=datetime.now(timezone.utc).isoformat(),
payment_details_id=payment_request.details.id,
payment_details_total=payment_request.details.total,
payment_response=payment_response,
merchant_agent=cart_mandate.contents.merchant_name,
),
)
return payment_mandate
User Device Signing
Location: src/roles/shopping_agent/tools.py:198
Simulates signing transaction details on the user’s secure device.
def sign_mandates_on_user_device(tool_context: ToolContext) -> str:
"""Simulates signing transaction details on user's secure device.
In actual implementation, this would send final transaction details
(including hashes of cart and payment mandates) to the user device's
secure hardware component (like Secure Enclave) for cryptographic
signing using the user's private key.
"""
payment_mandate = tool_context.state["payment_mandate"]
cart_mandate = tool_context.state["cart_mandate"]
cart_mandate_hash = _generate_cart_mandate_hash(cart_mandate)
payment_mandate_hash = _generate_payment_mandate_hash(
payment_mandate.payment_mandate_contents
)
# Generate JWT containing user's digital signature to authorize transaction
# Use hashes to bind signature to specific cart and payment details
# Include nonce to prevent replay attacks
payment_mandate.user_authorization = (
cart_mandate_hash + "_" + payment_mandate_hash
)
return payment_mandate.user_authorization
Credentials Provider Agent
Location: src/roles/credentials_provider_agent/agent_executor.py
Credentials Provider plays multiple roles:
- Manage user’s payment credentials and shipping addresses
- Find available payment methods for specific purchases
- Provide payment credential tokens for specific payment methods
- Supply payment credentials to processor to complete payment
class CredentialsProviderExecutor(BaseServerExecutor):
_system_prompt = """
You are a credentials provider agent acting as a secure digital wallet.
Your job is to manage user payment methods and shipping addresses.
Based on user requests, identify their intent and select the right tools to use.
Your output should only be tool calls, don't engage in conversation.
"""
def __init__(self, supported_extensions=None):
agent_tools = [
tools.handle_create_payment_credential_token,
tools.handle_get_payment_method_raw_credentials,
tools.handle_get_shipping_address,
tools.handle_search_payment_methods,
tools.handle_signed_payment_mandate,
]
super().__init__(supported_extensions, agent_tools, self._system_prompt)
Remote A2A Client
Location: src/common/payment_remote_a2a_client.py
Encapsulates A2A client functionality, simplifying communication with remote Agents.
class PaymentRemoteA2aClient:
async def send_a2a_message(
self, message: a2a_types.Message
) -> a2a_types.Task:
"""Retrieve A2A client, send message, and return event."""
my_a2a_client: Client = await self._get_a2a_client()
task_manager = ClientTaskManager()
async for event in my_a2a_client.send_message(message):
if isinstance(event, tuple):
event = event[0]
await task_manager.process(event)
task = task_manager.get_task()
if task is None:
raise RuntimeError(f"No response from {self._name}")
return task
Practical Examples
Human Present Card Purchase Scenario
Location: samples/python/scenarios/a2a/human-present/cards/
This example demonstrates a Human Present transaction using cards as the payment method.
Scenario Features
DPAN Card Purchase
- Merchant Agent advertises card purchase support through its agent card
- User’s preferred payment method in wallet is tokenized (DPAN) card
OTP Challenge
- Merchant Payment Processor Agent requests OTP challenge to complete payment
Execution Steps
# Execute from project root
bash samples/python/scenarios/a2a/human-present/cards/run.sh
Or launch services separately in different terminals:
# Terminal 1: Start Merchant Agent
uv run --package ap2-samples python -m roles.merchant_agent
# Terminal 2: Start Credentials Provider
uv run --package ap2-samples python -m roles.credentials_provider_agent
# Terminal 3: Start Merchant Payment Processor Agent
uv run --package ap2-samples python -m roles.merchant_payment_processor_agent
# Terminal 4: Start Shopping Agent
uv run --package ap2-samples adk web samples/python/src/roles
Then open browser to http://0.0.0.0:8000/dev-ui
Interaction Flow
- Initial Request: “I want to buy a coffee maker”
- Product Search: Shopping Agent delegates to Merchant Agent to find products
- Create Cart: Merchant Agent creates one or more
CartMandateand shares with Shopping Agent - Product Selection: Shopping Agent presents product options to user
- Link Credentials Provider: Shopping Agent prompts to link Credential Provider
- Select Payment Method: Get available payment methods list from Credentials Provider Agent
- Create PaymentMandate: Shopping Agent packages cart and transaction information
- OTP Challenge: Merchant Payment Processor requests OTP (use
123for testing) - Complete Purchase: After providing OTP, payment is processed and confirmation message with digital receipt is received
Interaction Flow Sequence Diagram
(Browser) participant SA as Shopping Agent
(port 8000) participant Shopper as Shopper
Sub-Agent participant MA as Merchant Agent
(port 8001) participant CP as Credentials Provider
(port 8002) participant MPP as Merchant Payment
Processor (port 8003) User->>SA: "I want to buy a coffee maker" SA->>Shopper: Delegate shopping task Shopper->>MA: Query coffee maker products MA->>MA: Search products and create CartMandate MA-->>Shopper: CartMandate (merchant signed) Shopper-->>SA: Return product options SA->>User: Display product list User->>SA: Select product SA->>User: Request shipping address User->>SA: Provide address SA->>MA: Update cart (with address) MA-->>SA: Updated CartMandate SA->>User: Prompt to link Credentials Provider User->>SA: Confirm link SA->>CP: Request available payment methods CP-->>SA: Payment methods list (DPAN card) SA->>User: Display payment methods User->>SA: Select payment method SA->>SA: Create PaymentMandate SA->>User: Display final cart details
(items, address, payment method) User->>SA: Confirm purchase SA->>SA: Sign Mandates
(simulate device signing) SA->>CP: Send Signed PaymentMandate CP->>CP: Update token binding mandate ID CP-->>SA: Confirm receipt SA->>MPP: Initiate payment request MPP->>MPP: Verify PaymentMandate MPP-->>SA: Request OTP challenge SA->>User: Display OTP request User->>SA: Enter OTP: "123" SA->>MPP: Submit OTP MPP->>MPP: Verify OTP and process payment MPP-->>SA: Payment successful SA->>User: Display digital receipt
Verbose Mode
If you want to understand Agent internal operations or inspect mandate objects, enable verbose mode:
"I want to buy a pair of shoes. Please explain in detail what you're doing throughout the process and display all data payloads."
When enabled, the Agent provides:
- Description of current and next steps
- JSON representation of all data payloads (such as IntentMandates, CartMandates, PaymentMandates)
Viewing Agent Communication
The system automatically creates detailed log files (default .logs/watch.log) containing:
| Category | Details |
|---|---|
| Raw HTTP Data | HTTP methods, URLs, JSON request and response bodies |
| A2A Message Data | A2A Message request instructions and data in DataParts |
| AP2 Protocol Data | Mandate objects in message DataParts |
Key Data Structures
CartMandate
{
"contents": {
"id": "cart_id_xxx",
"merchant_name": "Example Merchant",
"payment_request": {
"details": {
"id": "payment_details_id",
"total": {
"currency": "USD",
"value": "99.99"
}
}
},
"items": [...],
"shipping_options": [...]
},
"merchant_authorization": "merchant_signature_xxx"
}
PaymentMandate
{
"payment_mandate_contents": {
"payment_mandate_id": "mandate_id_xxx",
"timestamp": "2025-01-09T10:30:00Z",
"payment_details_id": "payment_details_id",
"payment_details_total": {
"currency": "USD",
"value": "99.99"
},
"payment_response": {
"request_id": "payment_details_id",
"method_name": "CARD",
"details": {
"token": "dpan_token_xxx"
},
"shipping_address": {...},
"payer_email": "user@example.com"
},
"merchant_agent": "Example Merchant"
},
"user_authorization": "user_signature_jwt_xxx"
}
Security Considerations
Cryptographic Signatures
Cart Mandate Signature
- Merchant signs cart using its private key
- Ensures cart contents haven’t been tampered with
- Merchant commits to fulfilling the offer
Payment Mandate Signature
- User signs using their device private key
- Bound to specific cart and payment details
- Uses hashes to prevent tampering, uses nonce to prevent replay attacks
Data Privacy
Role Separation
- Shopping Agent cannot see complete payment credentials
- Credentials Provider only provides tokenized credentials
- Merchant never receives raw payment card numbers
Encrypted Transmission
- All Agent-to-Agent communication uses HTTPS
- Sensitive data uses end-to-end encryption
Risk Assessment
Each transaction includes risk_data:
- Transaction context information
- Agent behavior patterns
- User device fingerprint
- Assists payment networks in assessing fraud risk
Summary
AP2 addresses the trust challenge in AI Agent commerce transactions through:
- Standardized Protocol: Defines open, interoperable standards
- Role Separation: Clarifies each participant’s responsibilities and permissions
- Verifiable Credentials: Uses VDCs to establish non-repudiable transaction evidence
- Cryptographic Assurance: Ensures data integrity through signatures and hashes
- Privacy Protection: Designed to ensure security of user data and payment information
The Python sample project provides a complete reference implementation, demonstrating how to build AP2-compliant Agent systems using Google ADK and A2A protocol. By studying this example, developers can understand how to implement secure AI Agent payment capabilities in their own applications.
Reference Resources
- Project Website: AP2 GitHub Repository
- Documentation: Complete specifications and guides in the
/docs/directory - A2A Protocol: https://a2a-protocol.org/
- Google ADK: https://google.github.io/adk-docs/
- Introduction Video: AP2 Intro Video