Ap2 payment mandate
Skill fxp/agentic-commerce-skills/skills/03-checkout/ap2-payment-mandate
Produce and verify AP2 (Agent Payments Protocol) mandates — Intent, Cart, and Payment mandates wrapped as Ed25519-signed Verifiable Digital Credentials — and attach the resulting payment to a UCP checkout session via payment.instruments / payment_handlers. Use when a commerce agent must give a merchant cryptographic proof of user consent for an agent-initiated charge, especially at the complete step of a UCP checkout.From its SKILL.md
npx -y skills add fxp/agentic-commerce-skills --skill ap2-payment-mandateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.6 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it
AP2 Payment Mandate
中文摘要:生成并校验 AP2 三类 mandate(Intent/Cart/Payment,包成 Ed25519 签名的可验证数字 凭证 VDC),并把支付通过
payment.instruments/payment_handlers挂到 UCP checkout session。 需要给商家"用户已授权 agent 发起这笔扣款"的密码学证明(尤其在 complete 步骤)时用。
When to use / 何时使用
- A UCP checkout session is
ready_for_completeand you're about toPOST …/complete. - The merchant / PSP needs provable consent for an agent-initiated charge.
- You must bind authorization to an exact amount so it can't be replayed at a new price.
Two layers / 两层
- AP2 mandates — the cryptographic consent layer (separate protocol UCP composes with).
- UCP payment object — how the chosen instrument rides on the checkout session.
AP2 mandates (VDC, Ed25519 over canonical JSON; verify via signer_did)
| Mandate | Real key fields | Created |
|---|---|---|
| IntentMandate | agent_did, max_amount, purpose, expires_at, allowed_merchants, allowed_categories (+ "prompt playback" NLP summary, TTL) | Before a cart exists; enables human-not-present delegated buys within limits |
| CartMandate | parent_id, merchant_did, line_items, total_amount, payment_method | When the cart/total is final; user-present authorization (device-signed) |
| PaymentMandate | hashed Cart/Intent ref, method, amount, presence signal (human-present / not-present), agent_id | At complete, just before charging; shared with network/issuer to build trust |
All three are wrapped in a Verifiable Digital Credential (VDC): an Ed25519 signature
over a canonical JSON serialization; verify by resolving signer_did → public key.
UCP payment object (on the checkout session)
"payment": {
"instruments": [
{
"id": "pi_1",
"handler_id": "google_pay", // matches a key in ucp.payment_handlers (from profile)
"type": "card",
"selected": true,
"display": { "brand": "visa", "last4": "4242" },
"credential": { "type": "network_token", "token": "***" },
"billing_address": { "address_country": "DE", "postal_code": "10115" }
}
]
}
The merchant declares accepted handlers in ucp.payment_handlers (UCP profile); the AP2
PaymentMandate travels alongside to prove consent. UCP calls this Payment Token Exchange.
Workflow / 工作流
- (Optional) IntentMandate for delegated flows: capture
max_amount,allowed_merchants,allowed_categories,expires_atup front so the agent may buy within bounds. - CartMandate when the session total is authoritative: bind
line_items+total_amountmerchant_did,parent_id→ user signs (device/passkey). Don't fabricate consent.
- PaymentMandate: bind hashed Cart/Intent +
method+amount(== sessiontotal) + presence signal +agent_id; sign as a VDC. - Attach the chosen instrument to the session
payment.instruments(handler_idmust match a declaredpayment_handler). POST /checkout-sessions/{id}/completewithpayment+signals+Idempotency-Key. The merchant/PSP verifies the VDC signature and thatamount== session total.- Verifier side: resolve
signer_did, verify Ed25519 over canonical bytes, check amount match, merchant match, non-expiry, single-use.
Edge cases & failure modes / 边界与失败
- Amount mismatch (total changed after consent) → mandate invalid; re-confirm + re-issue. Never reuse a mandate at a new price. 改价必须重签。
- Expired (
expires_at/ TTL) → regenerate. - Delegated buy exceeds
max_amount/ outsideallowed_merchants→ stop; require fresh consent. - Replay → single-use +
expires_at+ Ed25519 signature + UCPIdempotency-Keydefeat it. - No device consent available → fall back to interactive payment; never proceed without real consent.
handler_idnot inpayment_handlers→ merchant can't process it; pick a declared handler.
Worked example / 示例
Session
cs_01H…isready_for_complete,total28322 EUR, Google Pay.
- CartMandate binds
line_items+total_amount:28322+merchant_did, user signs on device. - PaymentMandate: hashed CartMandate +
method:card+amount:28322+ presence:human-presentagent_id, wrapped as Ed25519 VDC.
- Attach
payment.instruments[0]handler_id:"google_pay",credential.token:***. POST …/complete→ PSP verifies VDC +amount==28322 → charge authorized →orderreturned.
References / 参考
- AP2 spec & core concepts: https://ap2-protocol.org/specification/ · https://ap2-protocol.org/topics/core-concepts/
- AP2 × A2A extension: https://ap2-protocol.org/a2a-extension/
- UCP provable payments: https://developers.googleblog.com/under-the-hood-universal-commerce-protocol-ucp/
- Used by:
ucp-checkout-session
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.