This technical guide provides a try of a "practical blueprint" for implementing the Agent Payments Protocol (AP2) in our applications. We will explore the JSON structure of a Payment Mandate, how an AI agent attaches it to requests, and how a merchant service verifies it cryptographically.
1. The Payment Mandate JSON Structure
Before an AI agent can execute any financial transaction, the user must issue a cryptographically signed Payment Mandate. This structure defines the strict boundaries of what the agent is allowed to spend.
{
"mandate_id": "man_9f88c7a1e2b43",
"holder_did": "did:key:z6MksH3...UserKey",
"agent_did": "did:key:z6MktA9...AgentKey",
"constraints": {
"spending_cap_usd": 50.00,
"current_spent_usd": 12.50,
"currency": "USD",
"valid_from": "2026-10-20T00:00:00Z",
"valid_until": "2026-11-03T23:59:59Z",
"merchant_whitelist": [
"api.cloudcompute.io",
"datafeed.analytics.com"
],
"scope_intent": "Provision temporary GPU compute instances and fetch real-time market data."
},
"signature": {
"algorithm": "Ed25519",
"value": "3K7v8x9...cryptographic_signature_from_holder...=="
}
}
2. Agent Execution Payload
When the autonomous agent encounters a paid resource or an API request requiring authorization, it bundles the target operation with the active Payment Mandate and signs the request payload using its own assigned private key.
{
"request_id": "req_55410a2b",
"timestamp": "2026-10-20T16:30:00Z",
"action": "POST /v1/compute/provision",
"payload": {
"instance_type": "gpu-small",
"duration_hours": 2
},
"payment_authorization": {
"mandate": {
"mandate_id": "man_9f88c7a1e2b43",
"holder_did": "did:key:z6MksH3...UserKey",
"agent_did": "did:key:z6MktA9...AgentKey",
"constraints": {
"spending_cap_usd": 50.00,
"current_spent_usd": 12.50,
"currency": "USD",
"valid_until": "2026-11-03T23:59:59Z",
"merchant_whitelist": ["api.cloudcompute.io"]
},
"signature": "3K7v8x9...holder_sig...=="
},
"agent_signature": "9mQ1z2x...agent_sig...=="
}
}
3. Merchant-Side Verification Logic (Pseudocode)
When the merchant's API gateway receives the request, it executes a validation pipeline before provisioning the resource or settling the payment:
def verify_ap2_request(incoming_request, merchant_domain):
mandate = incoming_request.payment_authorization.mandate
# 1. Verify Holder's cryptographic signature on the mandate
if not crypto.verify_signature(mandate.holder_did, mandate, mandate.signature):
raise InvalidMandateException("Holder signature verification failed.")
# 2. Check expiration time (TTL)
if datetime.utcnow() > datetime.fromisoformat(mandate.constraints.valid_until):
raise MandateExpiredException("The payment mandate has expired.")
# 3. Validate Merchant Whitelist
if merchant_domain not in mandate.constraints.merchant_whitelist:
raise UnauthorizedMerchantException("Merchant is not whitelisted in this mandate.")
# 4. Check Spending Caps
requested_amount = incoming_request.get_cost()
remaining_balance = mandate.constraints.spending_cap_usd - mandate.constraints.current_spent_usd
if requested_amount > remaining_balance:
raise SpendingCapExceededException("Transaction exceeds remaining mandate limit.")
# 5. Verify Agent's signature
if not crypto.verify_signature(mandate.agent_did, incoming_request, incoming_request.payment_authorization.agent_signature):
raise InvalidAgentSignatureException("Agent signature verification failed.")
return True # Proceed to payment gateway settlement
4. Summary and Best Practices
- Always Rotate Agent Keys: Treat agent cryptographic keys with limited lifespans to minimize blast radius if an agent container is compromised.
-
Enforce Strict Whitelists: Prevent agents from dynamically expanding their
merchant_whitelistwithout direct human authorization. -
Log Every Transaction: Maintain an immutable ledger mapping
mandate_idto actual settlement records for accounting and audit compliance.

Top comments (0)