閱讀建議:本文深入探討 AP2 協議的架構設計與技術實作細節,包含 Python 代碼範例、密碼學機制與系統整合方案。如果您對 AI Agent 支付系統的商業應用更感興趣,建議先閱讀概念性章節(AP2 簡介、為什麼需要 AP2);技術實作章節(Python 範例專案結構、核心實作解析)則更適合有開發背景的讀者。

目錄

  1. AP2 簡介
  2. 為什麼需要 AP2
  3. 核心概念與原理
  4. 角色架構
  5. 交易流程
  6. Python 範例專案結構
  7. 核心實作解析
  8. 實際操作範例

AP2 簡介

Agent Payments Protocol (AP2) 是一個開放的、非專有的協議,專門為 AI Agent 驅動的商務交易設計。它作為 Agent-to-Agent (A2A) 和 Model Context Protocol (MCP) 的擴展,為 AI Agent 之間的支付交易建立了安全、可驗證、可互操作 (Interoperability) 的標準。

核心特性

  • 開放性與互操作性 (Openness and Interoperability):任何符合協議的 Agent 都可以與任何符合協議的商家進行交易
  • 用戶控制與隱私 (User Control and Privacy):用戶始終是最終權威,協議內建隱私保護
  • 可驗證的意圖 (Verifiable Intent):基於確定性、不可否認的用戶意圖證明,而非推測的行為
  • 明確的交易責任 (Clear Accountability):透過密碼學審計追蹤,明確每筆交易的責任歸屬

為什麼需要 AP2

信任危機

當前的支付系統是為人類直接操作而設計的。當自主 AI Agent 發起支付時,會產生以下問題:

  1. 授權與可審計性 (Authorization & Auditability):如何證明用戶確實授權 Agent 進行特定購買?
  2. 意圖的真實性 (Authenticity of Intent):如何確認 Agent 的請求準確反映了用戶的真實意圖,而非 AI “幻覺” (Hallucination)?
  3. 責任歸屬 (Accountability):當交易出現問題時,誰應該負責?用戶、Agent 開發者、商家還是支付網絡?

碎片化風險

沒有統一協議,產業將發展出各種專有的、封閉的解決方案,導致:

  • 用戶體驗混亂:不同 Agent 只能與特定商家或支付方式配合
  • 商家成本高:需要整合多種非標準的 Agent 支付介面
  • 支付生態系統無法統一評估風險:增加欺詐風險和成本

核心概念與原理

指導原則

  1. 開放性與互操作性 (Openness and Interoperability)
  2. 用戶控制與隱私優先 (User Control and Privacy by Design)
  3. 可驗證的意圖 (Verifiable Intent),非推測的行為
  4. 明確的交易責任 (Clear Transaction Accountability)

信任錨點:可驗證數字憑證 (Verifiable Digital Credentials, VDCs)

AP2 的核心創新是使用 可驗證數字憑證 (Verifiable Digital Credentials, VDCs) 來建立信任。VDC 是防篡改、可移植、密碼學簽名的數字對象,作為交易的構建塊。

三種主要 VDC 類型

1. Cart Mandate (用戶在場)

當用戶在場授權購買時使用,由商家生成並由用戶密碼學簽名。

包含內容:

  • 付款人和收款人的可驗證身份
  • 特定支付方式的 token 化表示
  • 最終的交易詳情(商品、地址、金額、幣別)
  • 風險相關信號的容器
2. Intent Mandate (用戶不在場)

用於用戶不在交易現場的場景(例如:“當票價低於 $100 時購買”)。

包含內容:

  • 付款人和收款人的可驗證身份
  • 授權的支付方式列表或類別
  • 購物意圖,包括產品類別等參數
  • Agent 對用戶提示的自然語言理解
  • 有效期限 (TTL)
3. Payment Mandate

與支付網絡和發卡機構共享的獨立 VDC。

目的:

  • 提供 AI Agent 交易的可見性
  • 幫助網絡和發卡機構建立信任並評估風險
  • 包含 AI Agent 存在和交易模式(在場/不在場)的信號

角色架構

AP2 透過明確的角色分離來定義職責:

1. User(用戶)

將支付任務委託給 Agent 的個人。

2. Shopping Agent / User Agent (SA/UA)

用戶互動的 AI 介面(例如 Gemini、ChatGPT)。

  • 理解用戶需求
  • 建立購物車
  • 獲取用戶授權

3. Credentials Provider (CP)

專門的實體(例如數字錢包)。

  • 安全管理用戶的支付憑證和方式
  • 提供可用的支付方法
  • 促進支付執行

4. Merchant Endpoint (ME)

代表商家運作的介面或 Agent。

  • 展示產品
  • 協商購物車

5. Merchant Payment Processor (MPP)

構建最終交易授權訊息的實體。

  • 處理支付請求
  • 與支付網絡溝通

6. Network and Issuer

支付網絡和發卡金融機構。

  • 批准或拒絕支付
  • 可能發起挑戰(如 3D Secure)

交易流程

Human Present 交易流程

當用戶在場並可以授權最終支付時:

  1. 設置:用戶可能在其 Shopping Agent 和 Credentials Provider 之間建立連接
  2. 發現與協商:Shopping Agent 與商家互動組裝購物車
  3. 商家驗證購物車:商家簽署最終購物車,表明承諾履行
  4. 提供支付方式:Shopping Agent 從 Credentials Provider 請求適用的支付方式
  5. 展示購物車:Agent 在可信介面向用戶展示最終購物車和選定的支付方式
  6. 簽名與支付:用戶批准後生成密碼學簽名的 Cart Mandate
  7. 支付執行:支付詳情傳送給 Credentials Provider 和商家完成交易
  8. 發送給發卡機構:商家或處理商將交易路由到支付網絡和發卡機構
  9. 挑戰(如有必要):任何一方可發起挑戰(如 3D Secure)
  10. 授權:發卡機構批准支付,確認發送給用戶和商家

Human Present 交易序列圖 (30 步驟)

%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'16px'}}}%% sequenceDiagram participant User as 用戶 participant SA as Shopping Agent participant ME as Merchant Agent participant CP as Credentials Provider participant MPP as Merchant Payment
Processor participant Network as Payment Network
& Issuer User->>SA: 1. 購物請求
("買咖啡機") SA->>ME: 2. 查詢產品 ME->>ME: 3. 查找產品並創建 Cart ME->>SA: 4. 返回 CartMandate
(商家簽名) SA->>User: 5. 展示產品選項 User->>SA: 6. 選擇產品 SA->>User: 7. 請求收貨地址 User->>SA: 8. 提供收貨地址 SA->>ME: 9. 更新 Cart (含地址) ME->>SA: 10. 返回更新的 CartMandate SA->>CP: 11. 請求支付方式 CP->>SA: 12. 返回可用支付方式列表 SA->>User: 13. 展示購物車、地址、支付方式 User->>SA: 14. 確認購買 SA->>SA: 15. 創建 PaymentMandate SA->>User: 16. 請求簽名授權 User->>SA: 17. 簽名 (生成 user_authorization) SA->>CP: 18. 發送 Signed PaymentMandate CP->>CP: 19. 更新 token 綁定 mandate ID CP-->>SA: 20. 確認接收 SA->>MPP: 21. 發起支付請求 MPP->>SA: 22. 請求 OTP 挑戰 SA->>User: 23. 請求 OTP User->>SA: 24. 提供 OTP SA->>MPP: 25. 提交 OTP MPP->>Network: 26. 提交交易授權
(含 PaymentMandate) Network->>Network: 27. 驗證並批准 Network->>MPP: 28. 授權成功 MPP->>SA: 29. 支付確認 SA->>User: 30. 顯示收據

Human Not Present 交易流程

用戶希望 Agent 在其不在場時進行支付的場景:

  1. 捕獲意圖:用戶批准 Agent 對其意圖的理解,創建簽名的 Intent Mandate
  2. 使用 Intent Mandate:此憑證(包含自然語言描述)與商家共享
  3. 商家可強制用戶確認:如果商家不確定,可要求用戶返回會話確認細節

Human Not Present 交易序列圖

%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'16px'}}}%% sequenceDiagram participant User as 用戶 participant SA as Shopping Agent participant ME as Merchant Agent participant CP as Credentials Provider participant MPP as Merchant Payment
Processor participant Network as Payment Network
& Issuer User->>SA: 1. 購物意圖
("價格低於$100時買鞋") SA->>SA: 2. 理解並解析意圖 SA->>User: 3. 確認意圖理解 User->>SA: 4. 簽名 IntentMandate
(授權未來執行) Note over SA,ME: [時間經過,條件觸發] SA->>ME: 5. 發送 IntentMandate
查詢符合條件的產品 ME->>ME: 6. 驗證 IntentMandate
查找符合條件的產品 alt 商家確定可履行 ME->>SA: 7a. 返回 CartMandate SA->>CP: 8a. 請求支付方式 CP->>SA: 9a. 返回支付方式 SA->>SA: 10a. 創建 PaymentMandate SA->>CP: 11a. 發送 PaymentMandate SA->>MPP: 12a. 發起支付 MPP->>Network: 13a. 提交授權 Network->>MPP: 14a. 授權成功 MPP->>SA: 15a. 確認 SA->>User: 16a. 通知交易完成 else 商家需要確認 ME->>SA: 7b. 請求用戶確認 SA->>User: 8b. 請求確認細節 User->>SA: 9b. 提供確認/更新 Note over SA,ME: 轉為 Human Present 流程 end

Python 範例專案結構

目錄結構

samples/python/
├── pyproject.toml          # Python 專案配置
├── README.md              # Python 範例說明
├── scenarios/             # 各種場景演示
│   └── a2a/
│       └── human-present/
│           ├── cards/     # 卡片支付場景
│           └── x402/      # X402 協議場景
└── src/
    ├── common/            # 共用工具和基礎設施
    │   ├── a2a_extension_utils.py
    │   ├── a2a_message_builder.py
    │   ├── payment_remote_a2a_client.py
    │   ├── base_server_executor.py
    │   ├── server.py
    │   └── ...
    └── roles/             # 各種角色 Agent 實作
        ├── shopping_agent/
        ├── merchant_agent/
        ├── merchant_payment_processor_agent/
        └── credentials_provider_agent/

主要模組

1. Common 模組

a2a_message_builder.py

  • 用於建立 A2A Message 對象的 Builder 類別
  • 支援添加文字部分 (TextPart) 和數據部分 (DataPart)
  • 自動生成 message_id 和設置角色

payment_remote_a2a_client.py

  • A2A 客戶端的封裝
  • 處理與遠端 Agent 的連接
  • 發送訊息並管理 Task 生命週期

base_server_executor.py

  • Agent 執行器的基礎類別
  • 處理請求解釋、工具選擇和調用

2. Roles 模組

每個角色都有自己的目錄,包含:

  • __main__.py 或啟動腳本
  • agent_executor.pyagent.py:核心邏輯
  • tools.py:可用的工具函數

核心實作解析

Shopping Agent 實作

位置: src/roles/shopping_agent/agent.py

Shopping Agent 使用 Google ADK (Agent Development Kit) 和 Gemini 2.5 Flash 模型。

root_agent = RetryingLlmAgent(
    max_retries=5,
    model="gemini-2.5-flash",
    name="root_agent",
    instruction="""
        你是一個購物代理,負責幫助用戶尋找和購買商品...
    """,
    tools=[
        tools.create_payment_mandate,
        tools.initiate_payment,
        tools.sign_mandates_on_user_device,
        # ...
    ],
    sub_agents=[
        shopper,
        shipping_address_collector,
        payment_method_collector,
    ],
)

主要職責

  1. 尋找產品:與 Merchant Agent 互動找到滿足用戶需求的產品
  2. 收集資訊
    • 委派給 shopper sub-agent 收集產品
    • 委派給 shipping_address_collector 收集送貨地址
    • 委派給 payment_method_collector 收集支付方式
  3. 完成購買:創建和簽署 Payment Mandate,發起支付

A2A Message Builder

位置: src/common/a2a_message_builder.py

這是一個 Builder 模式的實作,用於構建符合 A2A 協議的訊息。

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()
)

主要方法:

  • add_text(text): 添加文字部分
  • add_data(key, data): 添加數據部分
  • set_context_id(context_id): 設置上下文 ID
  • set_task_id(task_id): 設置任務 ID
  • build(): 返回構建的 Message 對象

Payment Mandate 創建

位置: 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

用戶設備上的簽名

位置: src/roles/shopping_agent/tools.py:198

模擬在用戶安全設備上簽署交易詳情。

def sign_mandates_on_user_device(tool_context: ToolContext) -> str:
    """模擬在用戶安全設備上簽署交易詳情。

    在實際實作中,這會將最終交易詳情(包括 cart 和 payment mandates 的雜湊)
    發送到用戶設備的安全硬體元件(如 Secure Enclave)
    使用用戶的私鑰進行密碼學簽名。
    """
    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
    )

    # 生成 JWT,包含用戶的數字簽名以授權交易
    # 使用雜湊將簽名綁定到特定的購物車和支付詳情
    # 包含 nonce 以防止重放攻擊
    payment_mandate.user_authorization = (
        cart_mandate_hash + "_" + payment_mandate_hash
    )

    return payment_mandate.user_authorization

Credentials Provider Agent

位置: src/roles/credentials_provider_agent/agent_executor.py

Credentials Provider 扮演多個角色:

  1. 管理用戶的支付憑證和送貨地址
  2. 尋找特定購買的可用支付方式
  3. 為特定支付方式提供支付憑證 token
  4. 向處理商提供支付憑證以完成支付
class CredentialsProviderExecutor(BaseServerExecutor):
    _system_prompt = """
        你是一個憑證提供者代理,作為安全數字錢包。
        你的工作是管理用戶的支付方式和送貨地址。

        根據用戶的請求,識別其意圖並選擇正確的工具使用。
        你的輸出應該只是工具調用,不要進行對話。
    """

    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

位置: src/common/payment_remote_a2a_client.py

封裝 A2A 客戶端的功能,簡化與遠端 Agent 的通信。

class PaymentRemoteA2aClient:
    async def send_a2a_message(
        self, message: a2a_types.Message
    ) -> a2a_types.Task:
        """檢索 A2A 客戶端,發送訊息,並返回事件。"""
        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

實際操作範例

Human Present Card Purchase 場景

位置: samples/python/scenarios/a2a/human-present/cards/

這個範例演示了使用卡片作為支付方式的 Human Present 交易。

場景特性

  1. DPAN 卡片購買

    • Merchant Agent 透過其 agent card 廣告支援卡片購買
    • 用戶錢包中的首選支付方式是 tokenized (DPAN) 卡片
  2. OTP 挑戰

    • Merchant Payment Processor Agent 會請求 OTP 挑戰以完成支付

執行步驟

# 從專案根目錄執行
bash samples/python/scenarios/a2a/human-present/cards/run.sh

或分別在不同終端啟動各個服務:

# 終端 1: 啟動 Merchant Agent
uv run --package ap2-samples python -m roles.merchant_agent

# 終端 2: 啟動 Credentials Provider
uv run --package ap2-samples python -m roles.credentials_provider_agent

# 終端 3: 啟動 Merchant Payment Processor Agent
uv run --package ap2-samples python -m roles.merchant_payment_processor_agent

# 終端 4: 啟動 Shopping Agent
uv run --package ap2-samples adk web samples/python/src/roles

然後在瀏覽器開啟 http://0.0.0.0:8000/dev-ui

互動流程

  1. 初始請求:「我想買一台咖啡機」
  2. 產品搜尋:Shopping Agent 委派給 Merchant Agent 尋找產品
  3. 創建購物車:Merchant Agent 創建一個或多個 CartMandate 並與 Shopping Agent 共享
  4. 產品選擇:Shopping Agent 向用戶展示產品選項
  5. 連結憑證提供者:Shopping Agent 提示連結 Credential Provider
  6. 選擇支付方式:從 Credentials Provider Agent 獲取可用支付方式列表
  7. 創建 PaymentMandate:Shopping Agent 打包購物車和交易資訊
  8. OTP 挑戰:Merchant Payment Processor 請求 OTP(使用 123 作為測試)
  9. 完成購買:提供 OTP 後,支付被處理並收到確認訊息和數字收據

互動流程序列圖

%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'16px'}}}%% sequenceDiagram actor User as 用戶
(瀏覽器) 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: "我想買一台咖啡機" SA->>Shopper: 委派購物任務 Shopper->>MA: 查詢咖啡機產品 MA->>MA: 搜尋產品並創建 CartMandate MA-->>Shopper: CartMandate (商家簽名) Shopper-->>SA: 返回產品選項 SA->>User: 展示產品列表 User->>SA: 選擇產品 SA->>User: 請求收貨地址 User->>SA: 提供地址 SA->>MA: 更新購物車 (含地址) MA-->>SA: 更新後的 CartMandate SA->>User: 提示連結 Credentials Provider User->>SA: 確認連結 SA->>CP: 請求可用支付方式 CP-->>SA: 支付方式列表 (DPAN 卡片) SA->>User: 展示支付方式 User->>SA: 選擇支付方式 SA->>SA: 創建 PaymentMandate SA->>User: 展示最終購物車詳情
(商品、地址、支付方式) User->>SA: 確認購買 SA->>SA: 簽署 Mandates
(模擬設備簽名) SA->>CP: 發送 Signed PaymentMandate CP->>CP: 更新 token 綁定 mandate ID CP-->>SA: 確認接收 SA->>MPP: 發起支付請求 MPP->>MPP: 驗證 PaymentMandate MPP-->>SA: 請求 OTP 挑戰 SA->>User: 顯示 OTP 請求 User->>SA: 輸入 OTP: "123" SA->>MPP: 提交 OTP MPP->>MPP: 驗證 OTP 並處理支付 MPP-->>SA: 支付成功 SA->>User: 顯示數字收據

Verbose 模式

如果想了解 Agent 內部運作或檢查 mandate 對象,可以啟用 verbose 模式:

"我想買一雙鞋。請在過程中詳細解釋你在做什麼,並顯示所有資料 payload。"

啟用後,Agent 會提供:

  • 當前和下一步驟的描述
  • 所有資料 payload 的 JSON 表示(如 IntentMandates、CartMandates、PaymentMandates)

查看 Agent 通信

系統會自動創建詳細的日誌文件(預設為 .logs/watch.log),包含:

類別詳情
原始 HTTP 資料HTTP 方法、URL、JSON 請求和回應 body
A2A 訊息資料A2A Message 的請求指令和 DataParts 中的資料
AP2 協議資料訊息 DataParts 中的 Mandate 對象

關鍵數據結構

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"
}

安全性考量

密碼學簽名

  1. Cart Mandate 簽名

    • 商家使用其私鑰簽署購物車
    • 確保購物車內容未被篡改
    • 商家承諾履行該報價
  2. Payment Mandate 簽名

    • 用戶使用其設備私鑰簽署
    • 綁定到特定的購物車和支付詳情
    • 使用雜湊防止篡改,使用 nonce 防止重放攻擊

資料隱私

  1. 角色分離

    • Shopping Agent 看不到完整的支付憑證
    • Credentials Provider 只提供 tokenized 憑證
    • Merchant 不會接收到原始的支付卡號
  2. 加密傳輸

    • 所有 Agent 間通信使用 HTTPS
    • 敏感資料使用端到端加密

風險評估

每筆交易都包含風險資料 (risk_data):

  • 交易上下文資訊
  • Agent 行為模式
  • 用戶設備指紋
  • 協助支付網絡評估欺詐風險

總結

AP2 透過以下方式解決 AI Agent 商務交易的信任問題:

  1. 標準化協議:定義了開放的、可互操作的標準
  2. 角色分離:明確每個參與者的職責和權限
  3. 可驗證憑證:使用 VDC 建立不可否認的交易證據
  4. 密碼學保障:透過簽名和雜湊確保資料完整性
  5. 隱私保護:設計上確保用戶資料和支付資訊的安全

Python 範例專案提供了完整的參考實作,展示了如何使用 Google ADK 和 A2A 協議建構符合 AP2 標準的 Agent 系統。透過學習這個範例,開發者可以理解如何在自己的應用中實作安全的 AI Agent 支付功能。


參考資源