Skip to main content
AgentPay implements two open standards that govern how AI agents transact:
  • AP2 (Agent Payments Protocol) — Google’s standard for cryptographic Cart Mandates that prove a user authorized an agent to make a specific purchase under specific constraints.
  • UCP (Universal Commerce Protocol) — Google’s standard for the conversation between an AI agent and a merchant, built on top of AP2 + MCP + REST/JSON-RPC.
We sign AP2 mandates on every active card, expose a public JWKS for verification, and run a UCP merchant gateway at /ucp/{slug}/checkout that LatAm merchants can plug into without implementing UCP themselves.

Cart Mandate (AP2)

When you create an AgentPay card and it transitions to active (either directly or after user approval), we emit a Cart Mandate as a signed JWT. The mandate captures the user’s authorization for the agent’s purchase under specific constraints. Mandate payload structure:
Algorithm: ES256 (ECDSA P-256), kid ap2-2026-04. Card creation responses include mandate_id and mandate_jwt fields. Pending-approval cards get a mandate when the user approves them.

Verifying a mandate

Anyone can verify mandates we issued without trusting our dashboard. JWKS endpoint:
Returns the public key set in standard JWKS format. Pass it to any JWT library (jsonwebtoken, pyjwt, jose, etc.) to verify signatures locally. Or use our verify endpoint:
Returns { "valid": true, "payload": {...} } if the signature is valid and the mandate hasn’t expired. Returns { "valid": false, "reason": "..." } otherwise. You can also look up by mandate_id: {"mandate_id": "<uuid>"}.

UCP merchant gateway

A registered merchant exposes a UCP endpoint without writing UCP code:
We validate the AP2 Cart Mandate, then route the payment based on the merchant’s configured settlement mode.

Discovery

Returns:

Checkout request

Validation contract

Every checkout request is validated against the mandate before settlement:
  • Signature — verified against our JWKS.
  • Expiry — exp must be in the future.
  • Currency — request.amount.currency must match mandate.cart.max_amount.currency.
  • Amount cap — request.amount.value must be ≤ mandate.cart.max_amount.value.
  • Merchant match (if enforce_merchant_match=true) — mandate.cart.merchant must equal the merchant slug or "any".
If any check fails, the request is rejected with a 400 and the rejection is logged.

Idempotency

Replaying the same mandate JTI returns the same UcpTransaction. Safe for retries.

Settlement modes

Forward — We HMAC-sign the validated request and POST it to the merchant’s forward_url. Merchant settles via their existing rails.
Verify the HMAC by computing hmac.new(forward_secret, body, sha256).hexdigest() and comparing to the X-AgentPay-Signature header (after the sha256= prefix). Card — The agent’s bound AgentPay virtual card is the instrument. The mandate carries the card_id. Merchant charges the card normally; the mandate is the chargeback-evidence anchor. fintoc_clp — We create a Fintoc Checkout Session. The response includes a confirmation_url the agent presents to the user. The user confirms in their bank app, funds move directly to the merchant’s collector account, and we update the UCP transaction status via Fintoc’s callback.

Response

For fintoc_clp mode, status: pending_user_confirmation and confirmation_url is set.

Becoming a merchant

Email [email protected] with:
  1. Your brand name + slug preference (URL-safe, like your-brand)
  2. Settlement preference: forward / card / fintoc_clp
  3. For forward mode: your existing checkout webhook URL
  4. For fintoc_clp mode: your Fintoc collector account ID
We provision the endpoint and HMAC signing secret. See the merchant page for more details.