---
title: "AP2（Agent Payments Protocol）とは？v0.2のマンデートとx402・ACPとの違い"
url: "https://www.issoh.co.jp/tech/details/9716/"
published: 2025-11-10
updated: 2026-11-08
categories: ["AIエージェント・MCP"]
publisher: "株式会社一創"
---

# AP2（Agent Payments Protocol）とは？v0.2のマンデートとx402・ACPとの違い

AP2（Agent Payments Protocol）は、AIエージェントが人の代わりに買い物や支払いをするとき、「本人がその購入を認めた」ことを暗号署名で証明するプロトコルです。Googleが2025年9月に公開し、2026年4月28日にv0.2を出すと同時にFIDO Allianceへ寄贈しました。v0.2でマンデート（委任状）の構成が変わったため、2025年の発表時に広まった「Intent Mandate・Cart Mandate」という説明は現行仕様と合いません。本記事は[v0.2の仕様書](https://ap2-protocol.org/ap2/specification/)と[公式Python SDK](https://github.com/google-agentic-commerce/AP2/blob/e1ea56db72a6385bce3e5c1112b3a56ce60acb43/code/sdk/python/ap2/sdk/README.md)の実行結果をもとに、仕組み、x402・ACP・UCPとの違い、実装で踏みやすい落とし穴を整理します。

## まとめ：AP2の要点（2026年11月・v0.2時点）

- AP2は決済そのものではなく、エージェントによる購入の**認可を証明する層**です。カタログやチェックアウトAPIは対象外で、UCPなどのコマースプロトコルの中で使う前提です。
- v0.2のマンデートは**Checkout MandateとPayment Mandateの2種類**で、それぞれ条件だけを決めるopenと、取引を確定するclosedの2段階があります。形式はSD-JWTです。
- x402はHTTP 402を使い主にステーブルコインで支払う別仕様で、AP2から見ると支払い手段のひとつです。ACPはチェックアウトAPIの仕様で、担当する層が違います。
- 公式SDKの`MandateClient.verify()`は署名や有効期限を例外で止めますが、金額上限などの制約違反は`PaymentMandateChain.verify()`がリストで返すだけです。
- SDKの現行コードには、円の`payment.budget`を100倍に解釈する、`frequency`を判定しないといった挙動があります。繰り返し購入は自前の検証を足してください。

## AP2の定義と、発表からFIDO Alliance移管までの経緯

[Google Cloudの発表ブログ](https://cloud.google.com/blog/ja/products/ai-machine-learning/announcing-agents-to-payments-ap2-protocol)は、AP2をA2A（Agent2Agent）プロトコルとModel Context Protocol（MCP）の拡張として使えるオープンプロトコルと説明しています。協力組織にはAdyen、American Express、Coinbase、Mastercard、PayPal、JCBなど60を超える名前が並びました。カード、リアルタイム口座振替、ステーブルコインのどれにも依存しない「支払い手段非依存」が設計方針です。

| 日付         | 出来事                            |
| ---------- | ------------------------------ |
| 2025-09-16 | AP2を発表、v0.1.0とa2a-x402 v0.1を公開 |
| 2025-12-09 | x402仕様v2.0（ヘッダー名を刷新）           |
| 2026-01-11 | UCP公開（AP2をUCPの拡張として組み込み）       |
| 2026-04-28 | AP2 v0.2.0公開・FIDO Allianceへ寄贈  |
| 2026-09-10 | AP2への誘導攻撃を示す論文がarXivに投稿        |

### FIDO Allianceへの寄贈とVerifiable Intentの位置づけ

[FIDO Allianceは2026年4月28日](https://fidoalliance.org/fido-alliance-to-develop-standards-for-trusted-ai-agent-interactions/)、Agentic Authentication技術作業部会を新設し、AP2とMastercardの「Verifiable Intent」の寄贈内容をPayments作業部会でレビューすると発表しました。AP2のFAQも、[中核仕様の作業はFIDOで続け、サンプルとSDKは引き続き強化する](https://github.com/google-agentic-commerce/AP2/blob/main/docs/faq.md)と書いています。今後の仕様変更はGoogle単独では決まらないので、追うべき場所はFIDOの標準化とGitHubのリファレンス実装の2つに分かれます。2026年11月8日時点で、FIDOの公開ページは作業中と説明しており、本記事の調査では公開された仕様ドラフトや完成時期は確認できませんでした。リポジトリ（google-agentic-commerce/AP2、Apache-2.0）の最終コミットは2026年4月29日で、2026年11月8日時点でv0.2.0より新しいリリースはありません。

[Verifiable Intent](https://github.com/agent-intent/verifiable-intent)は、利用者の委任を階層型のSD-JWTで証明する仕様で、状態はDraft（v0.1）、管理はMastercardです。[Googleの寄贈発表](https://blog.google/products-and-platforms/platforms/google-pay/agent-payments-protocol-fido-alliance/)は、Mastercardと共同開発したAP2互換の標準と説明しています。READMEは、金額・支払先・販売者を実行時に機械で検証する制約とし、商品名や色などは参考情報と区別しています。AP2のopenマンデートと考え方が近く、FIDOでどう一本化されるかは未確定です。いま本番向けの設計を固めるなら、マンデートの構造を自社コードに直書きせず、変換層を挟んでおくと差し替えが効きます。

### 本番採用の状況：公式発表は「導入予定」が中心

協力企業の数と、実際に動いている本番環境は別の話です。Googleは2026年5月19日の[Universal Cartの発表](https://blog.google/products-and-platforms/products/shopping/google-shopping-cart/)で、今後数か月でGoogle製品にAP2を導入し、Gemini Sparkから始めると述べました。Mastercardは2026年3月5日、[Verifiable IntentをAgent Payのintent APIへ統合する](https://www.mastercard.com/us/en/news-and-trends/stories/2026/verifiable-intent.html)と発表しています。本記事の調査では、AP2 v0.2のマンデートを本番決済で使っていると明記した企業発表や、AP2固有の提供国一覧は確認できませんでした。「60社超が支持」は協力の表明と読み、接続先の決済事業者には対応状況を個別に確認してください。

## v0.2のマンデート構造：Checkout MandateとPayment Mandate

マンデートは、ユーザーがエージェントに与えた権限を検証できる形で記録した署名付きデータです。v0.2の仕様書は次の2種類を定義しています。

### v0.1のIntent・Cart・Payment Mandateからの変更点

v0.1では、Intent・Cart・Paymentの3種類のマンデートで説明されていました。v0.2で変わった点は次のとおりです。

| 項目      | v0.1（2025-09）                 | v0.2（2026-04）                    |
| ------- | ----------------------------- | -------------------------------- |
| マンデート   | Intent・Cart・Payment           | Checkout・Payment（各open/closed）   |
| 署名形式    | Verifiable Credential         | SD-JWT（委任チェーン）                   |
| ロール数    | 6（User、Network and Issuerを含む） | 5（Trusted Surfaceを新設）            |
| 上位プロトコル | A2A・MCPの拡張                    | UCPとの互換を明記                       |
| 受領証     | フロー図中の手順                      | Checkout/Payment Receiptの返却がMUST |

v0.1のIntent Mandateが担っていた「人がいない間の購入条件」は、v0.2ではopenマンデートの制約（constraints）で表します。Cart Mandateの役割はclosedのCheckout Mandateが引き継ぎました。

### openとclosedの2段階とvctによる版管理

openマンデートは「どの店で、いくらまで、いつまでに」という条件だけを決めた状態、closedマンデートは特定の1件の取引を確定させた状態です。種類と段階はSD-JWTの`vct`クレームで区別し、値は`mandate.checkout.open.1`、`mandate.checkout.1`、`mandate.payment.open.1`、`mandate.payment.1`の4つです。末尾の`.1`はスキーマの版で、仕様は版番号まで含めた完全一致の照合を求めています（MUST）。前方一致で受け入れる実装にはしないでください。

Checkout Mandateは、販売者が署名したチェックアウトのJWT（`checkout_jwt`）のハッシュを`checkout_hash`として持ちます。Payment Mandateは同じハッシュを`transaction_id`に持ちます。検証側が両者を照合することで、支払いとカートの対応を確認できます。仕様は、`checkout_jwt`の署名にEd25519のような決定的な方式を使わず、ECDSAのような方式を使うよう定めています。レインボーテーブル攻撃を防ぐためです。

### 金額・支払先・回数・期限を縛る10種類の制約

openマンデートに書ける制約は、仕様の拡張ポイントとして定義されています。

| type                                  | 縛る内容                     |
| ------------------------------------- | ------------------------ |
| checkout.allowed\_merchants           | 購入してよい販売者                |
| checkout.line\_items                  | 許可する商品と数量                |
| payment.amount\_range                 | 1回の金額の下限・上限と通貨           |
| payment.budget                        | 繰り返し購入の累計上限              |
| payment.agent\_recurrence             | 再利用の頻度と最大回数              |
| payment.allowed\_payees               | 支払先                      |
| payment.allowed\_payment\_instruments | 使ってよい支払い手段               |
| payment.allowed\_pisps                | 決済指図サービス業者（PISP）         |
| payment.reference                     | 特定のCheckout Mandateへの紐付け |
| payment.execution\_date               | 実行してよい期間                 |

金額の単位には注意が必要です。仕様書の`payment.amount_range`の例は`"max": 100.50`と小数ですが、SDKの型では通貨の最小単位（米ドルならセント）の整数で、`max=100.50`を渡すとpydanticの`ValidationError`になります。100.50ドルは`10050`、1,000円は`1000`と書きます。

## AP2の5つのロールと検証の分担

v0.2は5つのロールを定義しています。1つの事業者が複数のロールを兼ねてもかまいません。

| ロール                             | 受け取って検証するもの      | エージェント化   |
| ------------------------------- | ---------------- | --------- |
| Shopping Agent（SA）              | （マンデートを組み立てて提示）  | エージェント前提  |
| Credential Provider（CP）         | Payment Mandate  | どちらでも可    |
| Merchant（M）                     | Checkout Mandate | どちらでも可    |
| Merchant Payment Processor（MPP） | 支払い資格情報のスコープ     | どちらでも可    |
| Trusted Surface（TS）             | （同意を得て署名する画面）    | 非エージェント必須 |

設計の前提は「Shopping Agentは少なくともLLMで動いており、そのエージェント自体が攻撃者になりうる」という点です。そのため仕様は、各ロールの検証を決定的なコードで行うよう求めています（MUST）。LLMに「このマンデートは正しいか」と判断させる実装は仕様違反です。カード決済で本人確認を担ってきた[3Dセキュア](/tech/details/15732/)には、利用者不在の継続課金を扱う3RIもあります。AP2は、エージェントへの購入権限の委任を署名で証明する点に特徴があります。

## Human PresentとHuman Not Presentの処理の流れ

AP2のモードは2つです。どちらでも検証側が受け取るのはclosedマンデートで、違うのは誰がそれに署名したかです。

### Human Present（direct）の支払いフェーズ

ユーザーが確定したカートをその場で承認するモードです。

1. SAがCheckout MandateとPayment Mandateの中身を組み立て、Trusted Surfaceに承認を求める
2. Trusted Surfaceが内容を表示し、生体認証などで同意を得て署名する
3. SAがPayment MandateをCPに渡し、CPが検証してスコープを限定した支払いトークンを返す
4. SAがトークンとCheckout Mandateを販売者に送り、販売者が現在のカートと照合する
5. MPPがトークン内のPayment Mandateと`checkout_jwt`のハッシュの結び付きを検証する
6. MPPが署名したPayment Receiptと、販売者が署名したCheckout Receiptが返る

仕様は、このモードは「従来のECの購入手順で置き換えられることも多い」と注記しています。AP2の価値が大きいのは次のHuman Not Presentです。

### Human Not Present（autonomous）と鍵の委任

「チケット発売の瞬間に買う」のように、ユーザーが事前に条件だけを承認しておくモードです。openマンデートにはエージェントの公開鍵を`cnf`クレームとして必ず入れます（MUST）。条件を満たすカートができたら、エージェントは自分の鍵でclosedマンデートに署名し、ユーザー署名のopenマンデートと一緒に提示します。前のopenマンデートの拒否受領証を受け取るまで次を提示してはいけない（MUST NOT）という規定は、同じ委任で複数のカートを承認させないためのものです。販売者やCPが`unresolved_constraint`エラーを返すと、ユーザーを呼び戻してHuman Presentに切り替えられます。

## 受領証と紛争時の証拠：AP2が残すもの

v0.2では、マンデートを受け入れても拒否しても署名付きの受領証を返します（MUST）。販売者はCheckout Receiptを、MPPはPayment Receiptを発行し、受領証の`reference`には閉じたマンデートのハッシュ（`sd_hash`と同じ計算）が入ります。受領証を後から別の取引へ付け替えることはできません。

紛争時の手順は[仕様のDisputeの節](https://ap2-protocol.org/ap2/specification/)にあります。`checkout_jwt`のハッシュを独立に計算し直し、2つの受領証の`reference`を照合し、Payment Mandateを`checkout_hash`で検証して、ようやく「ユーザーと各ロールが何を見たか」の証拠として使えるという順序です。

範囲外の事項も明記されています。紛争解決での具体的な使い方、保存期間、取得方法は仕様の対象外で、マンデートを自動で取り寄せる手段も現行版にはありません。仕様は紛争時の証拠の提供元として、Checkout Mandateと受領証にはSA・販売者、Payment Mandateと受領証にはSA・CP・ネットワーク・MPPを挙げているので、チャージバック対応に使うつもりなら、誰が何年保管するかを契約で先に決める必要があります。

## 公式Python SDKでマンデートを発行・検証する手順

v0.2のリファレンス実装にはPython SDK（`code/sdk/python/ap2/`）が含まれています。以下の結果はmainのコミット`e1ea56d`（2026-04-29）をPython 3.12で実行したものです。

### SDKの導入：PyPIのap2は別物

公式SDKはPyPIに公開されていません。PyPIの同名`ap2`（2026年11月時点で0.1.1）のプロジェクトURLは、Googleではない第三者のGitHubリポジトリです。`pip install ap2`で入るのはこちらなので、公式SDKはcloneして編集可能モードで入れます。

```
git clone https://github.com/google-agentic-commerce/AP2.git
cd AP2
git checkout e1ea56db72a6385bce3e5c1112b3a56ce60acb43
uv venv -p 3.12
uv pip install -e .
```

pyproject.tomlは`version = "0.1"`のままなので、`pip show ap2`の表示は0.1です。版の確認にはコミットを使ってください。

### openからclosedへの委任チェーンの生成と検証

発行者が「上限50.00ドル・支払先はM-1だけ」というopen Payment Mandateを発行し、そこへエージェントが60.00ドルのclosed Payment Mandateを重ねる例です。

```
import json, time
from cryptography.hazmat.primitives.asymmetric import ec
from jwcrypto.jwk import JWK
from ap2.sdk.mandate import MandateClient
from ap2.sdk.payment_mandate_chain import PaymentMandateChain
from ap2.sdk.generated.open_payment_mandate import AllowedPayees, AmountRange, OpenPaymentMandate
from ap2.sdk.generated.payment_mandate import PaymentMandate
from ap2.sdk.generated.types.amount import Amount
from ap2.sdk.generated.types.merchant import Merchant
from ap2.sdk.generated.types.payment_instrument import PaymentInstrument

def new_key(kid):  # ローカル検証用のP-256鍵
    jwk = json.loads(JWK.from_pyca(ec.generate_private_key(ec.SECP256R1())).export())
    jwk["kid"] = kid
    return JWK(**jwk)

issuer_jwk, agent_jwk = new_key("issuer-1"), new_key("agent-1")
agent_pub = json.loads(agent_jwk.export_public())
client, now = MandateClient(), int(time.time())

# 1. 発行者（ユーザー側）がopen Payment Mandateを発行。cnfでエージェント鍵へ委任
open_token = client.create(payloads=[OpenPaymentMandate(
    constraints=[AmountRange(currency="USD", min=0, max=5000),
                 AllowedPayees(allowed=[Merchant(id="M-1", name="Cat Store")])],
    cnf={"jwk": agent_pub}, iat=now, exp=now + 3600)], issuer_key=issuer_jwk)

# 2. エージェントが自分の鍵でclosed Payment Mandateを重ねる（6000セント=60.00ドル）
# transaction_idは仕様上checkout_jwtのハッシュ。ここでは説明用の短い値を入れている
chain = client.present(holder_key=agent_jwk, mandate_token=open_token,
    payloads=[PaymentMandate(transaction_id="tx_abc",
        payee=Merchant(id="M-1", name="Cat Store"),
        payment_amount=Amount(amount=6000, currency="USD"),
        payment_instrument=PaymentInstrument(type="card", id="stub", description="Demo"),
        iat=now, exp=now + 3600)], nonce="tx_abc", aud="merchant")

# 3. 署名チェーン・aud・nonceはMandateClient.verify()、制約はPaymentMandateChain.verify()
payloads = client.verify(token=chain, key_or_provider=lambda t: issuer_jwk,
                         expected_aud="merchant", expected_nonce="tx_abc")
violations = PaymentMandateChain.parse(payloads).verify(expected_transaction_id="tx_abc")
if violations:
    raise PermissionError(violations)  # ここで止めないと上限超過の支払いが通る
```

### 制約違反は例外にならない：7条件の検証結果

同じopenマンデートに条件を変えたclosedマンデートを重ねて比べました。

| 条件            | MandateClient.verify() | violationsの中身                            |
| ------------- | ---------------------- | ---------------------------------------- |
| 25.00ドル・M-1宛  | 通過                     | 空リスト                                     |
| 60.00ドル（上限超過） | 通過                     | Amount 6000 exceeds maximum 5000         |
| 支払先M-2        | 通過                     | Payee X not in allowed list              |
| 通貨JPY         | 通過                     | Currency mismatch: expected USD, got JPY |
| audが不一致       | ValueError             | （例外で停止）                                  |
| 別の発行者鍵で検証     | InvalidJWSSignature    | （例外で停止）                                  |
| exp切れのマンデート   | ValueError             | （例外で停止）                                  |

「`MandateClient.verify()`が例外を出さなければOK」という実装では、上限超過の支払いがそのまま通ります。violationsが空であることを確認する分岐まで必ず書いてください。

### checkout\_hashの照合と期待値の指定

`CheckoutMandateChain.verify()`の`expected_checkout_hash`は省略可能で、SDKはハッシュを自分では計算しません。省略すると、マンデートの`checkout_hash`が受け取った`checkout_jwt`と一致しなくても、空リストが返りました。

| 条件                  | violations              |
| ------------------- | ----------------------- |
| 正常・期待値あり            | 空リスト                    |
| hash不一致・期待値なし       | 空リスト（素通り）               |
| 金額違いのJWTに差し替え・期待値なし | 空リスト（素通り）               |
| hash不一致・期待値あり       | checkout\_hash mismatch |
| 許可外の販売者             | not in allowed list     |

販売者のハッシュ照合は仕様上のMUSTなので、受け取ったJWTから必ず自分で計算して渡します。

```
from ap2.sdk.checkout_mandate_chain import CheckoutMandateChain
from ap2.sdk.utils import compute_sha256_b64url

expected = compute_sha256_b64url(received_checkout_jwt)
violations = CheckoutMandateChain.parse(payloads).verify(
    expected_checkout_hash=expected, checkout_jwt=received_checkout_jwt)
if violations:
    raise PermissionError(violations)
```

### 繰り返し購入のbudgetとagent\_recurrence：円の上限換算と頻度検証

定期購入のようにopenマンデートを再利用する場合、`payment.agent_recurrence`と`payment.budget`を組み合わせます。SDKは`agent_recurrence`があるのに`amount_range`か`budget`が欠けていると違反を返し、利用実績（`MandateContext`）を渡さないと「Missing mandate context」を返します。累計の保存と更新は検証する側の仕事です。

実行すると、現行コードには仕様どおりに動かない箇所が3つありました。

- **予算の単位**：`BudgetEvaluator`は通貨を問わず`int(max * 100)`で換算します。小数桁のない円では、`Budget(max=10000, currency="JPY")`の上限が1,000,000円になり、累計99万円の支払いが違反なしで通りました。
- **小数の切り捨て**：`int(19.99 * 100)`は1998です。予算19.99ドルに対するちょうど19.99ドルの支払いが「超過」と判定されました（4.35ドルも同様）。
- **頻度の判定なし**：仕様は前回の提示から`frequency`で定めた間隔が空いていることを条件にしていますが、SDKは`max_occurrences`しか見ません。MONTHLYの委任で1秒前に使った記録があっても通りました。

もう1点、`AgentRecurrence(frequency=Frequency.MONTHLY)`をそのまま`client.create()`に渡すと、列挙型をJSON化できず`TypeError`で止まります。今回は`model_construct(frequency="MONTHLY", ...)`で回避しました。仕様の`max`の例は`1000.00`で主単位に読めますが、スキーマの説明に単位の明記はありません。実装では次のようにISO 4217の小数桁で換算し、前回の利用時刻との間隔も自前で確認してください。

```
from decimal import Decimal

MINOR_DIGITS = {"USD": 2, "JPY": 0, "KWD": 3}  # ISO 4217の小数桁

def budget_ok(budget_max, currency, past, amount):
    limit = int(Decimal(str(budget_max)).scaleb(MINOR_DIGITS[currency]))
    return past + amount <= limit

budget_ok(10000, "JPY", 9000, 2000)  # False（SDKでは通過）
budget_ok(19.99, "USD", 0, 1999)     # True（SDKでは超過扱い）
```

## AP2とx402の関係：認可を証明する層と、HTTP 402で支払う層

x402は、HTTPのステータスコード402 Payment Requiredを使い、APIやWebリソースの利用料をその場で払う仕様です。Coinbaseが開発し、Linux Foundation傘下のx402 Foundationが2026年7月14日に本格始動して管理を引き継ぎました。正本のリポジトリは[x402-foundation/x402](https://github.com/x402-foundation/x402)です。AP2が「誰が何を認めたか」を証明するのに対し、x402は「どう送金するか」を決めます。競合ではなく、組み合わせて使うものです。

### x402 v2の3つのヘッダーとfacilitator

v2では支払い情報をすべてヘッダーで運びます。サーバーは402と一緒に`PAYMENT-REQUIRED`を返し、クライアントは署名した支払いデータを`PAYMENT-SIGNATURE`に入れて再送し、サーバーは決済結果を`PAYMENT-RESPONSE`で返します。v1は`X-PAYMENT`と`X-PAYMENT-RESPONSE`だったので、v1の形式だけを使うコードは、v2のみを受け付けるサーバーにはそのまま接続できません。ネットワーク指定もCAIP-2形式（Base Sepoliaは`eip155:84532`）に変わりました。検証と決済はfacilitatorの`POST /verify`と`POST /settle`に任せられます。仕様例の支払いデータはUSDCの[EIP-3009（transferWithAuthorization）](/tech/details/9717/)の署名です。PyPIの`x402`は2.27.0（2026-11-04公開）で、更新は頻繁です。

### a2a-x402拡張とAP2サンプルの現状

AP2の発表と同じ日に公開された[A2A x402 extension](https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.2/spec.md)は、2025年11月に仕様v0.2が加わりました。x402をAP2などの上位プロトコルに埋め込むEmbedded Flowを定めていますが、埋め込み先の例は旧来の`CartMandate`で、例の`x402Version`は1のままです。AP2リポジトリのHuman Present用x402サンプルのREADMEにも「AP2互換のx402拡張は近日公開」とあり、IntentMandateを使う説明が残っています。つまり拡張の版番号v0.2はAP2のv0.2とは別物で、Checkout Mandateとx402 v2を組み合わせた規範仕様は、2026年11月8日時点の公式リポジトリに見当たりません。「ap2 x402」で探している人は、AP2 v0.2で認可を設計し、x402は支払い手段として別に実装するのが現実的です。A2A自体の仕組みは[A2Aプロトコルの解説](/tech/details/6732/)にまとめています。

## AP2・ACP・UCP・x402・MPPの違いと組み合わせ方

5つの仕様は、認可の証明、購入手続き、支払い処理のどこを受け持つかで分かれます。

| 仕様   | 主導                        | 担う層               | 現行版              |
| ---- | ------------------------- | ----------------- | ---------------- |
| AP2  | Google→FIDO Alliance      | 購入の認可と証跡          | v0.2.0           |
| ACP  | OpenAI・Stripe             | チェックアウトAPIと決済トークン | 2026-04-17（beta） |
| UCP  | Google・Shopifyほか          | 商品発見から購入後までの手順    | v2026-08-25      |
| x402 | Coinbase→Linux Foundation | HTTP 402による従量決済   | v2               |
| MPP  | Stripe・Tempo              | 機械間の継続的な少額決済      | IETF個人提案         |

### AP2とACPの違い：署名された委任とチェックアウトAPIの役割

[ACP（Agentic Commerce Protocol）](https://github.com/agentic-commerce-protocol/agentic-commerce-protocol)は、ChatGPTのような対話面から販売者のチェックアウトを作成・更新・完了させるAPIの仕様で、決済は共有トークンで受け渡します。ユーザーの同意を委任チェーンとして署名で残すことは目的にしていません。ACPだけで作る場合、「その購入を本人が認めたか」の証明は、プラットフォーム内の記録に頼ることになります。ユーザー不在の購入を複数の事業者で検証したいならAP2、対話画面の購入をチェックアウトAPIにつなぐだけならACP、という分け方になります。

### AP2とUCPの使い分け：公式FAQの導入条件

AP2のFAQは、GoogleのAI面（AI ModeやGemini）でインライン購入を提供したい販売者はUCPを使い、ユーザー不在の自律購入まで扱うならAP2拡張を足すと書いています。UCPの拡張名やACPとの比較は[UCPの解説](/tech/details/10560/)に、機械同士の継続課金は[MPP](/tech/details/11520/)に、AWS上で支払い機能を持つエージェントを組むなら[AgentCore payments](/tech/details/12036/)にまとめています。Google Search・Geminiなどをまたぐカートの提供状況は[Universal Cartの解説](/tech/details/12368/)を見てください。

## AP2の署名が保証する範囲と購入判断への誘導攻撃

AP2が証明するのは、「ユーザーが条件に同意し、エージェントがその条件内のカートに署名した」ことです。選んだ商品が本当にユーザーの望んだものかまでは証明しません。2026年9月10日投稿の論文「[Signing the Transaction but Not the Decision](https://arxiv.org/abs/2609.11757)」（arXiv:2609.11757）は、この隙間を突く攻撃を3つ示しました。商品説明の文言でエージェントを誘導し、(1)他人の支払い資格情報を取得させる、(2)見せた内容と違うカートを作らせる、(3)安い表示商品から高い商品へ乗り換えさせるものです。成功率は(1)90%、(2)56%、(3)73.3%で、試行数もモデルも異なるため攻撃同士の強さは比べられないと論文自身が断っています。(3)のカートは表示内容と矛盾せず、プロトコル上の検証をすべて通過します。

論文は防御策A-VIPも提案しています。資格情報の参照を要求元セッションに、カートの行を表示された商品に結び付ける方式で、(1)(2)は構造上の痕跡で止められる一方、痕跡の残らない(3)は未承認の支出としてユーザーに確認を求める形です。v0.2.0のHuman Present用サンプルエージェントが、マンデートを制約なしで作っている点も指摘しています。v0.2を対象にした[Beyond the Mandate](https://arxiv.org/abs/2608.23858)（arXiv:2608.23858）も48件の脅威を分類し、署名が有効でも認可前の文脈を操作されれば利用者の意図は保証されないと結論しています。

実装側で取れる対策は、openマンデートの制約を広く取らないことです。`checkout.allowed_merchants`と`checkout.line_items`で販売者と商品を絞り、`payment.amount_range`の上限を低くし、`exp`を短くします。高額な購入や初めての販売者との取引は、`unresolved_constraint`でHuman Presentに戻すのが現実的です。署名が正しく詐欺でもない「認可済みの誤購入」の扱いは、前述のとおり仕様の範囲外です。ステーブルコイン決済はチャージバックもないので、確定前に止める設計が前提になります。

## AP2を今採用すべき条件と見送る条件

次のいずれかに当てはまるなら、現時点のAP2採用は見送ってかまいません。

- ユーザーが毎回カートを確認して購入する：仕様自身が従来のEC手順で置き換えられるとしています
- 本番の決済網との接続が目的：スキーマの版は`.1`で、FIDOでの標準化はこれからです。公式SDKもPyPIに出ていません
- ステーブルコイン決済だけが目的：x402を直接使うほうが部品が少なく済みます

逆に、ユーザー不在の自律購入を検証環境で試す段階なら、SDKで制約の書き方とviolationsの扱いを固めておく価値があります。販売者側で今やっておくとAP2に限らず効くのは、チェックアウトをAPIとして呼べるようにすること、カートの署名と合計金額の確定、受け取ったマンデートと受領証の保存です。エージェントと既存の決済基盤の接続を外部に相談するなら、[AIエージェント開発の支援](/service/ai/agent/)も選択肢になります。

## よくある質問

### AP2とは何の略ですか？

Agent Payments Protocolの略です。AIエージェントによる購入と支払いについて、ユーザーの認可を署名付きのマンデートで証明するプロトコルです。Googleが2025年9月に公開し、2026年4月にFIDO Allianceへ寄贈しました。

### AP2のマンデートには何種類ありますか？

v0.2ではCheckout MandateとPayment Mandateの2種類で、それぞれにopen（条件）とclosed（確定）の段階があります。Intent MandateとCart Mandateはv0.1の用語で、現行仕様にはありません。

### AP2とACPの違いは何ですか？

AP2は「ユーザーがその購入を認めた」ことを署名で証明する層で、ACPはOpenAIとStripeによるチェックアウトを作成・完了させるAPIの仕様です。競合というより担当する層が違います。

### AP2とx402は同じものですか？

別の仕様です。x402はHTTP 402を使い、主にステーブルコインで支払う送金の仕様で、AP2は支払い手段に依存しない認可の仕様です。x402をAP2の支払い手段として組み合わせる拡張（a2a-x402）の仕様v0.2は、旧来のCartMandateとx402 v1を前提にしています。

### AP2は日本の決済でも使えますか？

仕様は通貨をISO 4217で扱い、特定の国に限っていません。ただしv0.2は版0.xの段階で、本番の決済網に接続するにはCredential Providerや決済代行の対応が必要です。SDKで円の累計上限を扱うときは、本文のとおり`payment.budget`の換算に注意してください。

## 関連記事

- [UCPとは？Universal Commerce Protocolの仕組みと試し方、ACP・AP2との違い【v2026-08-25対応】](/tech/details/10560/)
- [A2A（Agent2Agent）プロトコルとは？v1.0の仕組み・MCPとの違い・セキュリティ対策と実装手順](/tech/details/6732/)
- [EIP-3009（ERC-3009）とは？transferWithAuthorizationの仕組みと署名実装・チェーン別対応表【2026年11月】](/tech/details/9717/)
- [MPP（Machine Payments Protocol）とは？HTTP 402の仕組みとx402との違い・Stripeでの実装【2026年10月】](/tech/details/11520/)
- [AgentCore paymentsとは？x402・MPP対応の仕組みと料金・実装手順【2026年8月GA】](/tech/details/12036/)

---

出典: [AP2（Agent Payments Protocol）とは？v0.2のマンデートとx402・ACPとの違い](<https://www.issoh.co.jp/tech/details/9716/>)（株式会社一創）
