Agentes con pagos integrados: ACP, AP2, x402 y MPP en producción
Un curso intensivo sobre los cuatro protocolos que permiten a los sistemas del OpenAI Agents SDK gastar dinero: en comercios, contra APIs, con otros agentes y a través de la economía abierta. Para ingenieros que ya han publicado agentes y ahora necesitan que paguen.
19 conceptos. 5 decisiones. 3 diagramas. Cuatro rutas de aprendizaje. La ruta Lector ofrece entre 2 y 3 horas de lectura pura: la pila de cuatro capas, cada protocolo en profundidad, las reglas de composición, sin instalación. Las rutas Principiante, Intermedio y Avanzado añaden práctica progresiva para conectar agentes a protocolos, ejecutar la composición de forma duradera y gestionar identidad, gasto y disputas. Requieren aproximadamente 1 día, 2-3 días y 4-5 días, respectivamente. Estimación honesta: 2-3 horas para leerlo, 4-5 días para que un equipo convierta la pila en un hábito de trabajo. Elige tu ruta antes del laboratorio de decisiones en la Parte 5.
Esta es la única idea sobre la que se construye el curso: los cuatro protocolos no son rivales. Son capas. La mayoría de los artículos preguntan "¿ACP o x402?" Esa pregunta parte de un error sobre qué tipo de cosas son estos protocolos. Un sistema real que se pone en producción en 2026 usa varios de ellos juntos, porque cada uno resuelve una capa distinta del problema del comercio con agentes. Un agente de compras para consumidores usa ACP en la capa de comercio y rieles de tarjeta en la liquidación. Un agente que paga APIs usa x402 en ambas, porque en los micropagos máquina a máquina esas dos capas se fusionan en una. Un agente de adquisiciones empresariales usa mandatos AP2 para demostrar que el humano autorizó el gasto y luego Stripe MPP en la liquidación. Aprenderás a leer el caso de uso y a elegir la composición adecuada.
Este curso menciona algunos cursos relacionados: el curso intensivo Construye agentes de IA (fundamentos del SDK), el curso intensivo Production Worker (ejecución duradera de agentes con Inngest), el curso intensivo Eval-Driven Development y el curso intensivo Arquitecturas agénticas. Puedes leer este sin haber tomado los otros. Los cuatro protocolos, la estructura en capas, el código del SDK y la disciplina de decisión son autosuficientes. Lo único que ayuda: el código de la Parte 3 asume que puedes leer Agent, Runner.run() y @function_tool. Si esos conceptos son nuevos, revisa rápidamente el curso intensivo Construye agentes de IA o la documentación del OpenAI Agents SDK antes de continuar.
A qué corresponde cada protocolo si usas otra plataforma
Si no utilizas OpenAI Agents SDK junto con Stripe, Coinbase y Cloudflare, esta tabla relaciona cada implementación de referencia con alternativas comunes. Las especificaciones de los protocolos son independientes de la plataforma; solo difieren los nombres de los primitivos.
| Protocolo | SDK de referencia principal (2026) | Alternativas comunes | Licencia / gobernanza |
|---|---|---|---|
| ACP (Agentic Commerce Protocol) | SDK de Stripe (stripe) más OpenAI Agents SDK; herramientas de servidor ACP de PayPal; credenciales de Worldpay | ACP de Adyen, API de checkout nativa de Shopify | Apache 2.0, OpenAI y Stripe en github.com/agentic-commerce-protocol/agentic-commerce-protocol |
| AP2 (Agent Payments Protocol) | Google ADK más implementaciones de referencia en Python, TypeScript, Kotlin y Go | LangGraph con firma de mandatos personalizada, AutoGen con a2a-x402 | Apache 2.0, Google y más de 60 socios en github.com/google-agentic-commerce/AP2 |
| x402 | x402-client (Python), @x402/client (JS/TS), Coinbase Developer Platform, withX402Client de Cloudflare, AgentPay MCP | Implementaciones directas de EIP-3009; Lobster.cash; carteras de agentes de Crossmint | Apache 2.0, creado por Coinbase, ahora bajo la x402 Foundation de la Linux Foundation |
| MPP (Machine Payments Protocol) | Stripe PaymentIntents con extensiones MPP; Tempo blockchain SDK | Lightning Network directo; SDKs nativos de Tempo | Apache 2.0, Stripe y Tempo; especificaciones en mpp.dev |
| A2A (Agent2Agent, la capa que AP2 extiende) | Google ADK | Implementaciones personalizadas de A2A | Apache 2.0, Google y Linux Foundation |
| MCP (Model Context Protocol, la capa de descubrimiento) | Servidores y clientes MCP de Anthropic; soporte MCP de openai-agents | MCP de LangChain | MIT, Anthropic |
Cómo usar la tabla: cuando el curso indique "conecta el @function_tool del agente a un endpoint ACP de Stripe" y tú uses Adyen con LangGraph, léelo como "conecta la herramienta equivalente de LangGraph a un endpoint ACP de Adyen." El argumento es el mismo; solo cambian los nombres. No necesitas aprender la plataforma de Stripe para leer este curso. Mapea los primitivos, sigue el marco y aplícalo a tu propia plataforma.
Glosario
📖 Los términos que usa este curso; expande en la primera lectura y consulta más adelante
Los cuatro protocolos principales
- ACP (Agentic Commerce Protocol). El protocolo de compras para consumidores, desarrollado por OpenAI y Stripe. Regula cómo un agente completa el proceso de pago en un comercio real en nombre de una persona. Impulsa ChatGPT Instant Checkout. Opera principalmente en la capa de comercio. Apache 2.0.
- AP2 (Agent Payments Protocol). El protocolo de autorización, desarrollado por Google con más de 60 socios. Produce "mandatos" firmados que demuestran que un humano permitió al agente gastar. No mueve dinero por sí mismo; prueba que el gasto fue autorizado. Apache 2.0.
- x402. El protocolo de liquidación nativo de HTTP, desarrollado por Coinbase y ahora gobernado por la Linux Foundation. Rescata el código de estado HTTP 402 "Payment Required", que estaba en desuso, para que un agente pueda pagar una llamada a una API en uno o dos segundos con una stablecoin. Apache 2.0.
- MPP (Machine Payments Protocol). El protocolo de liquidación de Stripe y Tempo. Su particularidad es la "sesión": el agente preaprueba un límite de gasto y luego transmite muchos pagos pequeños contra él. Compatible con múltiples canales (stablecoin, Lightning, tarjetas). Apache 2.0.
Las capas (la columna vertebral de todo el curso)
- Capa de descubrimiento. La capa donde el agente encuentra lo que puede comprar. La responden servidores MCP, A2A, directorios de agentes o superficies de compras con IA. La pregunta: "¿qué está disponible?"
- Capa de autorización (también identidad y autorización). La capa que prueba dos cosas antes de que se mueva dinero: que el humano autorizó este gasto y que el agente es quien dice ser. La pregunta: "¿tengo permiso para gastar esto?"
- Capa de comercio. La capa que gestiona la compra completa: carrito, pago, cumplimiento, disputa y reembolso. La pregunta: "¿cuál es el ciclo de vida completo de la compra?" Se omite por completo en las llamadas a APIs simples.
- Capa de liquidación. La capa donde el dinero cambia de manos realmente. La pregunta: "¿dónde se mueve el dinero de verdad?"
- Riel de liquidación (o riel). La tubería real por la que viaja el dinero: redes de tarjetas (Visa/Mastercard a través de Stripe), stablecoins en una cadena de bloques, transferencia bancaria (ACH/SEPA) o Lightning. "Elegir un riel" significa "elegir cómo se mueve el dinero."
Primitivos de autorización
- Mandato (AP2). Una prueba digital firmada de que un humano autorizó un tipo específico de gasto. AP2 tiene tres: Intent, Cart y Payment (abajo). Juntos forman una cadena que se puede auditar después.
- Intent Mandate. El primer mandato, firmado por el usuario antes de que el agente comience: las reglas de la tarea. Ejemplo: "compra zapatos por menos de $120." Establece los límites dentro de los cuales debe mantenerse el agente.
- Cart Mandate. El mandato intermedio, firmado por el usuario después de que el agente ha construido un carrito específico: "sí, estos artículos exactos a este precio exacto." Se usa en flujos donde hay un humano presente para aprobar.
- Payment Mandate. El último mandato, firmado (o generado automáticamente contra el Intent Mandate) en el momento del pago: "autoriza este pago exacto en este riel exacto."
- SPT (Shared Payment Token). El primitivo de ACP. Un token de un solo uso del procesador de pagos (Stripe) vinculado a un comercio, un límite de importe y una ventana de tiempo breve. Si un agente autorizado para $50 intenta gastar $1.000, el SPT simplemente falla. El equivalente en rieles de tarjeta de un Payment Mandate de AP2.
- No repudiable. Un registro firmado que el firmante no puede negar posteriormente. La cadena de mandatos AP2 es no repudiable: "nunca autoricé esto" no se sostiene frente a la firma criptográfica del propio usuario.
Primitivos de liquidación y criptomonedas
- Stablecoin. Una criptomoneda vinculada a un valor estable, generalmente un dólar estadounidense. Los agentes la usan para que un "pago de $0,05" siga valiendo cinco centavos entre el envío y la liquidación.
- USDC. La stablecoin específica vinculada al dólar que usa la mayoría de los pagos x402. Un USDC equivale a un dólar estadounidense. Emitida por Circle.
- HTTP 402 Payment Required. Un código de estado HTTP reservado desde 1997 pero no utilizado hasta que x402 lo rescató. El servidor responde con "402" más los requisitos de pago; el cliente reintenta con la prueba de pago firmada adjunta.
- EIP-3009 (transferWithAuthorization). El estándar de Ethereum sobre el que está construido x402. Permite al comprador firmar un pago fuera de la cadena que otra persona envía a la cadena, de modo que el comprador nunca paga comisiones de gas ni interactúa directamente con la cadena de bloques.
- Facilitador (x402). Un tercero opcional que verifica la firma y envía el pago a la cadena en nombre del comercio, para que este no tenga que gestionar su propia infraestructura de cadena de bloques. Coinbase y Cloudflare operan facilitadores.
- CAIP-2. Una forma estándar de nombrar una cadena de bloques para que un protocolo pueda ser independiente de la cadena. x402 escribe las cadenas en formato CAIP-2.
- EIP-155 / chain id. El esquema de numeración dentro de CAIP-2 para cadenas de tipo Ethereum.
eip155:8453hace referencia a la cadena Base; el número es el identificador de cadena. (Veráseip155:8453en el código de x402; simplemente significa "Base.") - Cartera de contrato inteligente. Una cartera de criptomonedas cuyas reglas de gasto (límite por transacción, límite diario, límite por destinatario) son aplicadas por código en la propia cadena de bloques. Dado que la cadena las impone, estos límites se mantienen incluso si el código del agente falla.
- Sesión MPP. El movimiento característico de MPP. En lugar de firmar cada pago individualmente, el agente abre una "sesión" con un límite de gasto y un tiempo máximo, y luego transmite muchos pequeños pagos medidos contra ella hasta que se cierra. Equivale a "una cuenta prepagada para el agente."
- Modelo de sesiones (MPP). El nombre general del patrón anterior: pre-autoriza un límite y una duración, luego mide muchos cargos pequeños contra él. Más económico que firmar cada micropago cuando las llamadas son frecuentes.
Conceptos de comercio y dinero
- Liquidación. El momento en que el dinero realmente se mueve del comprador al vendedor. Todo lo anterior a la liquidación es solo coordinación; el acuerdo solo se completa cuando la liquidación termina.
- Comerciante de registro (MoR). La empresa legalmente responsable de una transacción: gestiona impuestos, disputas y atención al cliente. En ACP el comerciante sigue siendo el MoR. En las llamadas máquina a máquina puras con x402 a menudo no hay MoR.
- Contracargo. Cuando el banco del comprador revierte un pago con tarjeta, normalmente tras una disputa. Los rieles de tarjeta admiten contracargos; el x402 puro no. La necesidad de contracargos a menudo determina qué protocolo se usa.
- Disputa. El cuestionamiento formal de un cargo por parte del comprador ("no autoricé esto" / "el artículo nunca llegó"). Los distintos protocolos resuelven las disputas de forma diferente; esa diferencia a menudo fuerza la elección del protocolo.
- Idempotencia. Una propiedad por la que hacer la misma operación dos veces tiene el mismo efecto que hacerla una vez. Es importante porque Stripe reenvía webhooks con el mismo identificador de evento; sin una clave de idempotencia, tu código podría reembolsar o cobrar dos veces.
La pila del agente y los protocolos adyacentes
- Comercio con agentes. Cualquier transacción en la que un agente de IA autónomo es el comprador, el vendedor o ambos, sin que ningún humano seleccione "comprar" en ese momento. Distinto del comercio "asistido por IA" en el que una persona sigue presionando el botón.
- OpenAI Agents SDK. El kit de herramientas en Python y JavaScript para construir bucles de agentes con
Agent,Runner.run(),@function_tooly guardrails. En este curso es el "cliente universal": cada protocolo de pago se convierte en una o más herramientas que el agente puede llamar. - MCP (Model Context Protocol). El estándar abierto de Anthropic para exponer herramientas y contexto a los agentes. En el comercio con agentes suele ser la capa de descubrimiento: los agentes encuentran servicios comprables a través de servidores MCP. Licencia MIT.
- A2A (Agent2Agent). El protocolo de Google para que los agentes se comuniquen y se descubran entre sí. AP2 está construido sobre A2A: un mandato viaja como un mensaje A2A. Apache 2.0.
- UCP (Universal Commerce Protocol). El protocolo de capa de comercio de Google, homólogo de ACP, construido en torno a las superficies de compras de Google (Gemini, Google AI Mode). Compite con ACP en la capa de comercio.
- TAP (Trusted Agent Protocol). El protocolo de Visa y Cloudflare para probar la identidad de un agente dentro de las cabeceras de solicitudes HTTP. Verifica quién es el agente, no qué tiene permitido gastar, por lo que habitualmente complementa otro protocolo de autenticación en lugar de reemplazarlo.
- ERC-8004. Un estándar en cadena para la identidad y reputación de agentes: un registro público de agentes y su historial de transacciones, para que un agente sin relación previa pueda verificar el historial de otro antes de confiar en él.
tool_input_guardrail. Un guardrail del OpenAI Agents SDK que se ejecuta antes de que una herramienta se ejecute y puede rechazar la llamada. Es la forma nativa del SDK de detener un pago antes de que ocurra. Es la columna vertebral de este curso: aparece en siete herramientas de pago. (Contrasta conoutput_guardrail, que se ejecuta sobre la respuesta final del agente, demasiado tarde para detener un pago.)
Requisitos previos
Obtendrás el máximo provecho de este curso si tienes:
- El curso intensivo Crea agentes de IA, o experiencia equivalente con el SDK. Las integraciones de protocolos se muestran como código del SDK, por lo que necesitas leer
Agent,Runner.run()y@function_toolcon comodidad. Consulta el curso intensivo Crea agentes de IA. - El curso intensivo Elige arquitecturas agénticas, o criterio de diseño equivalente. El marco "qué composición para qué caso de uso" de la Parte 5 se basa en esa disciplina de selección de patrones. Consulta el curso intensivo Elige arquitecturas agénticas.
- HTTP básico. Códigos de estado, el ciclo de solicitud/respuesta, cabeceras. x402 en particular opera a nivel HTTP.
- Vocabulario básico de pagos. Comerciante, liquidación, disputa, contracargo. El curso explica las partes específicas de los agentes, pero asume que sabes qué es un "comerciante de registro".
No necesitas experiencia en blockchain ni en contratos inteligentes (el curso enseña suficiente sobre x402 y EIP-3009 para seguirlo; no se usa Solidity), ni tampoco necesitas experiencia previa con ninguno de los cuatro protocolos. Todos se enseñan desde fuentes primarias.
Las cuatro rutas de aprendizaje
Este curso funciona en cuatro niveles de profundidad. Elige tu ruta antes de la Parte 5.
| Ruta | Tiempo | Qué harás | Ideal para |
|---|---|---|---|
| Lector | 2-3 horas | Leer todos los Conceptos y Decisiones; omitir la ejecución de código. | Ingenieros que deciden si invertir más. PMs y arquitectos que necesitan el marco para evaluar propuestas de proveedores. |
| Principiante | ~1 día | Ruta Lector más ejecutar los ejemplos de cliente x402 más una transacción de prueba de ACP en modo de prueba de Stripe. | Ingenieros nuevos en el comercio con agentes que quieren práctica con el protocolo más simple (x402) y el más listo para producción (ACP). |
| Intermedio | 2-3 días | Ruta Principiante más crear un agente que use ACP para un tipo de transacción y x402 para otro, más conectar verificaciones de AP2 Intent Mandate. | Ingenieros que están entregando un sistema real que debe componer múltiples protocolos. |
| Avanzado | 4-5 días | Ruta Intermedia más ejecutar el sistema compuesto de forma durable (el envelope de Inngest), conectar límites de gasto y puertas de aprobación humana, medir métricas de rastreo, costo y disputa, y gestionar un ciclo completo de reembolso. | Ingenieros responsables de sistemas en producción que mueven dinero real para usuarios reales. |
Una verificación útil: "Para el caso de uso que tengo en mente, ¿cuál es la composición de protocolos más pequeña que entrega valor?" Si no puedes responder eso después de la Parte 4, vuelve a leer la Parte 4. Si puedes, tu ruta es solo una cuestión de hasta dónde quieres llegar desde "composición mínima" hasta "composición lista para producción".
La pila de cuatro capas
Este es el diagrama del que depende todo lo demás.

Cada caso de uso de comercio con agentes toca las cuatro capas, pero distintos casos de uso componen diferentes protocolos en cada una. Un agente de compras de consumidor: MCP para descubrimiento, un token de pago compartido de ACP para autorización, ACP para comercio, redes de tarjetas para liquidación. Un agente que paga APIs: un directorio de agentes para descubrimiento, una firma EIP-3009 para autorización, ninguna capa de comercio, x402 para liquidación. Un agente de adquisiciones empresariales: un directorio A2A, un mandato AP2, ACP o UCP para comercio, Stripe MPP para liquidación. La regla es simple: elige un protocolo por capa y deja que el caso de uso justifique cada elección.
Parte 1: Por qué el comercio con agentes necesita nuevos protocolos
La Parte 1 presenta seis nombres (ACP, AP2, x402, MPP, MCP, A2A) y tres capas rápidamente. Eso es intencional: esta parte es el resumen, no el análisis profundo. Lo mínimo que necesitas retener: ACP es compras de consumidor (Stripe más OpenAI), AP2 son mandatos de autorización (Google más 60 socios), x402 es pago en stablecoin por solicitud sobre HTTP (Coinbase), MPP es pago multirail basado en sesión (Stripe más Tempo). MCP y A2A son cómo los agentes se encuentran y se comunican entre sí, no son protocolos de pago. Retén los nombres de forma provisional. La Parte 2 vuelve a cada uno en profundidad y quedarán fijos en el segundo repaso.
Concepto 1: El supuesto que falló
En una línea: Los sistemas de pago asumían que un humano hacía clic en comprar, y los agentes rompen ese supuesto de tres formas a la vez.
Los sistemas de pago se construyeron sobre un supuesto silencioso: hay un humano en el teclado, haciendo clic en comprar. Cada pantalla, cada verificación de fraude, cada proceso de disputa, cada formulario de registro fue diseñado para personas. Los agentes de IA rompen ese supuesto de tres formas al mismo tiempo.
Ruptura 1: los agentes no tienen direcciones de correo electrónico. Los flujos de pago de consumidor requieren una cuenta. Una cuenta requiere un correo electrónico, un número de teléfono, a menudo un nombre. Un agente autónomo no tiene ninguno de estos. Falsifícalos y habrás creado una entidad que falla el KYC en el momento en que la detección de fraude la examina. El flujo de registro asume un humano solicitando una relación; un agente necesita algo diferente.
Ruptura 2: los agentes actúan miles de veces por segundo. La detección de fraude marca comportamientos inusuales por tasa, ubicación y patrón. Un agente que realiza 1.000 llamadas a la API en un minuto se parece exactamente a un ataque de relleno de credenciales. Lo que es normal para un agente es una alarma para un humano, y los sistemas están calibrados para humanos.
Ruptura 3: los agentes no pueden contestar el teléfono. La resolución de disputas asume que se puede contactar al comprador: "¿autorizaste esto?" Un agente que autorizó un cargo no puede responder, y es posible que el humano detrás de él ni siquiera sepa que ocurrió el cargo. Las disputas necesitan un modelo diferente cuando el comprador es software.
Cada ruptura necesita una solución a nivel de protocolo, no una capa de pintura sobre la interfaz:
| Ruptura | Lo que la solución en sistemas convencionales no puede hacer | Lo que una solución para agentes te ofrece |
|---|---|---|
| Sin correo ni cuenta | Obligar a los agentes a crear cuentas falsas | Identidad criptográfica (TAP, ERC-8004) o tokens de alcance limitado (ACP SPT, AP2 Mandate) |
| Comportamiento de alta frecuencia | Bloquear tráfico que parece un ataque | Pago por solicitud nativo de HTTP (x402) o sesiones preautorizadas (MPP) |
| Sin teléfono para disputas | Disputas por correo que el agente no puede leer | Autorización basada en mandatos (AP2) con una traza de auditoría no repudiable |
El camino de "simplemente envolver pagos antiguos en una interfaz de agente más amigable" ya fracasó. Varias startups lo intentaron en 2024 y 2025: darles a los agentes cuentas similares a las humanas con identidad inventada. La detección de fraude los atrapó, los contracargos se acumularon, las relaciones con los comerciantes se desmoronaron. Las soluciones a nivel de protocolo resultaron ser necesarias, no opcionales. Por eso ACP, AP2, x402 y MPP aparecieron todos dentro de los mismos doce meses.
Conclusión del Concepto 1: Los sistemas de pago asumían que un humano hace clic en comprar. Los agentes rompen eso de tres formas: sin identidad tradicional, patrones de comportamiento alarmantes, sin canal para aclarar una disputa. Cada ruptura necesita una solución a nivel de protocolo. Envolver sistemas convencionales en una interfaz más amigable fracasó. Los cuatro protocolos cubren cada uno una mezcla diferente de estas rupturas.
Concepto 2: Por qué un solo protocolo no puede ganar
En una línea: Las rupturas ocurren en cuatro capas diferentes con cuatro actores establecidos distintos, por lo que los protocolos reparten el trabajo por capa en lugar de que uno absorba todo.
Una pregunta justa: si los cuatro protocolos aparecieron para solucionar las mismas tres rupturas, ¿por qué no ganó uno de ellos? La respuesta es estructural. Las rupturas ocurren en capas distintas, y un solo protocolo que intentara corregirlas todas sería demasiado grande para que alguien lo adoptara.
Piensa en lo que tendría que especificar un protocolo unificado:
- Cómo los agentes encuentran comerciantes y servicios disponibles. Esa es la capa de descubrimiento.
- Cómo los agentes prueban quiénes son y que un humano autorizó el gasto. Esa es la capa de autorización.
- Cómo los agentes ejecutan una compra completa, con disputas y reembolsos incluidos. Esa es la capa de comercio.
- Cómo el dinero se mueve realmente entre las partes. Esa es la capa de liquidación.
Cada capa ya tiene actores establecidos sólidos. El descubrimiento pertenece a los motores de búsqueda y las APIs. La identidad pertenece a OAuth y a las autoridades certificadoras. El comercio pertenece a Stripe, Adyen y Shopify. La liquidación pertenece a Visa, Mastercard y ACH, más las nuevas redes cripto. Un protocolo unificado necesitaría que todos los actores establecidos en cada capa estuvieran de acuerdo. Eso nunca iba a ocurrir.
Lo que ocurrió en cambio es que cada protocolo eligió la capa donde su patrocinador tenía más influencia:
| Protocolo | Dónde tiene influencia su patrocinador | La capa que tomó |
|---|---|---|
| ACP | OpenAI posee el canal de compras (ChatGPT); Stripe posee la integración con comerciantes | Comercio, para flujos de comprador humano vía IA |
| AP2 | Google tiene billeteras de Android y una coalición de 60 socios | Autorización, mandatos como credenciales firmadas |
| x402 | Coinbase tiene infraestructura de stablecoin; Cloudflare tiene el edge HTTP | Liquidación, para micropagos máquina a máquina |
| MPP | Stripe tiene relaciones con comerciantes; Tempo tiene la blockchain | Liquidación, para flujos empresariales y multirail |
Entonces los protocolos no compiten dentro de una capa; compiten por definir una. En liquidación, x402 y MPP compiten genuinamente, y la mayoría de los artículos sobre "x402 vs MPP" pasan por alto que ese es el único lugar donde realmente se solapan. En comercio, ACP y UCP compiten. En autorización, AP2, TAP y ERC-8004 compiten.
Eso nos da la idea principal sobre la que descansa todo este curso. Dentro de una capa, eliges un protocolo. Entre capas, compones varios. Los cuatro protocolos no son alternativas entre las cuales elegir; son capas que apilar. Un agente de compras de consumidor ejecuta ACP en comercio y redes de tarjetas en liquidación. Un agente que paga APIs ejecuta x402 en liquidación y omite el comercio por completo. Un agente empresarial ejecuta mandatos AP2 en autorización y MPP en liquidación. El árbol de decisiones de la Parte 5 recorre esto capa por capa. Recuerda esto: cada sección después de esta lo da por supuesto.
Conclusión del Concepto 2: Un solo protocolo no puede corregir las cuatro rupturas porque estas viven en cuatro capas, cada una con actores establecidos sólidos. Los protocolos se especializan: ACP en comercio, AP2 en autorización, x402 y MPP en liquidación. Dentro de una capa eliges uno; entre capas compones varios.
Concepto 3: El SDK de Agentes de OpenAI como cliente universal
En una línea: No hablas con cuatro protocolos de cuatro formas distintas; cada uno se convierte en una herramienta que el agente llama, y el SDK es el cliente único que los conecta a todos.
Una pregunta práctica: dados cuatro protocolos en cuatro capas, ¿cómo los usa realmente un agente? La respuesta en 2026 es que el framework del agente se convierte en el cliente universal. Cada protocolo expone un SDK o un endpoint HTTP, y el framework lo conecta como una herramienta. Esto aplica para el SDK de Agentes de OpenAI, LangGraph, AutoGen y CrewAI por igual. Usaremos el SDK de Agentes de OpenAI a lo largo del curso.
Para el SDK, cada integración de protocolo sigue la misma estructura: envuelve el protocolo en una o más funciones con @function_tool, pásalas a un Agent y deja que Runner.run maneje el bucle.
Las llamadas
stripe.PaymentTokens.create,X402Client(wallet=...)yfrom ap2 import ...a continuación son ilustrativas: muestran la forma que toma una integración de protocolo. El andamiaje deAgent,Runnery@function_toola su alrededor es real y funciona. Consulta la nota después del bloque para ver qué es un sustituto.
from agents import Agent, Runner, function_tool
import stripe # for ACP/MPP
from x402_client import X402Client # for x402
from ap2 import IntentMandate, CartMandate # for AP2
from decimal import Decimal
from .models import PaymentToolResult, X402PaymentResult # the shared result models
# Each protocol becomes one or more @function_tool decorated functions
@function_tool
async def acp_checkout(merchant_id: str, items: list, max_amount: Decimal) -> PaymentToolResult:
"""Complete an ACP checkout at a merchant with the given items."""
# Mint a one-time payment token scoped to this merchant, then POST the order
spt = stripe.PaymentTokens.create(
amount=int(max_amount * 100), # cents as int
currency="usd",
merchant_id=merchant_id,
max_uses=1,
)
response = await acp_post(merchant_id, items, spt.token)
return PaymentToolResult(
status="success" if response.status == "confirmed" else "failed",
details={"order_id": response.order_id, "merchant_status": response.status},
)
@function_tool
async def x402_fetch(url: str, max_payment_usdc: Decimal) -> X402PaymentResult:
"""Fetch a URL that may require x402 payment up to max_payment_usdc."""
client = X402Client(wallet=agent_wallet, max_per_request=max_payment_usdc)
response = await client.get(url)
return X402PaymentResult(
content=response.content,
amount_paid_usdc=response.amount_paid_usdc,
tx_hash=response.payment_proof,
)
# Compose the tools into an agent
shopping_agent = Agent(
name="ShoppingAgent",
instructions="Help the user find and purchase items. Use acp_checkout for retail goods, x402_fetch for paid APIs.",
tools=[acp_checkout, x402_fetch],
model="gpt-5.5",
)
# Run the agent. The SDK handles tool selection, the loop, and retries.
result = await Runner.run(shopping_agent, "Buy me a red t-shirt under $30")
Qué se ejecuta y qué es un sustituto aquí: el andamiaje de Agent, Runner.run y @function_tool es el SDK real y funciona tal como está escrito. Los clientes de pago son sustitutos. stripe.PaymentTokens.create no es una llamada real de Stripe (la integración ACP en producción se hace a través de los endpoints ACP en vivo de Stripe), y el constructor detallado X402Client(wallet=..., max_per_request=...) también es ilustrativo. El paquete real del lado del comprador es x402-client, y una llamada en vivo necesita una cuenta con fondos y un endpoint 402 real, lo cual este curso no hace. La Parte 3 proporciona a cada protocolo un backend simulado ejecutable para que puedas ver cómo funciona el armazón de extremo a extremo sin mover dinero real.
La estructura es idéntica en los cuatro protocolos. El SDK es el cliente universal; cada protocolo es solo una herramienta sobre la que el agente razona y a la que llama cuando lo necesita. Tres partes de la estructura del SDK importan para los pagos:
- Un valor de retorno tipado para los resultados de pago. Cuando una herramienta de pago devuelve un modelo Pydantic, el razonador del agente obtiene información de tipo clara sobre qué tuvo éxito, qué falló y qué hacer a continuación. La Parte 3 define estos modelos de resultado compartidos una sola vez.
Runner.run(..., context=...)para el contexto de pago. El agente a menudo necesita la identidad del usuario, los límites de gasto y el handle de la billetera. Pasa estos a través del parámetrocontextdel SDK en lugar de integrarlos en las instrucciones.contextes por ejecución y por usuario.tool_input_guardrailpara límites de gasto. Una barrera de entrada de herramienta se ejecuta antes de que cada herramienta se ejecute y puede rechazar la llamada. Es la forma nativa del SDK de bloquear un pago antes de que ocurra, no después. El Concepto 15 recorre la aplicación completa en tres niveles. Eloutput_guardraila nivel de agente no resuelve esto, porque se activa en la respuesta final del agente, después de que cualquier herramienta de pago ya se haya ejecutado.
Conclusión del Concepto 3: El SDK de Agentes de OpenAI es el cliente universal para los cuatro protocolos. Cada uno se convierte en un
@function_toolque el agente llama. Los retornos tipados del SDK,contextytool_input_guardrailse mapean limpiamente a las preocupaciones de pago: resultados estructurados, contexto por usuario, y detener un pago antes de que ocurra. La estructura de integración es la misma para los cuatro; la Parte 3 completa cada uno.

Parte 2: Las cuatro capas en profundidad
Ya conociste las cuatro capas en la Parte 1; aquí se examina cada una de cerca. Cada capa responde una pregunta diferente, tiene sus propios protocolos en competencia y obliga a tomar una decisión: para este caso de uso, ¿qué protocolo se adapta mejor a esta capa? Lee la Parte 2 antes de la Parte 3. El enfoque capa por capa que se presenta aquí es lo que hace que los detalles de los protocolos en la Parte 3 sean coherentes, en lugar de parecer una lista de rivales.
Concepto 4: Capa 1, Descubrimiento (cómo los agentes encuentran lo que pueden comprar)
En una línea: El descubrimiento es donde el agente averigua qué está disponible para comprar, y el mecanismo adecuado depende de dónde viven realmente esos servicios.
Antes de que un agente pueda hacer transacciones, tiene que encontrar qué hay disponible. Un agente de compras necesita comerciantes que ofrezcan el producto. Un agente que paga por APIs necesita saber qué endpoints tienen los datos y cuánto cuestan. Un agente de adquisiciones necesita proveedores que cumplan sus reglas de cumplimiento. El descubrimiento responde la pregunta: "¿qué está disponible?"
Cuatro opciones serias compiten en 2026:
| Protocolo | Cómo funciona | Ideal para |
|---|---|---|
| MCP (Anthropic) | Los servidores de herramientas exponen funciones invocables; el agente se conecta, lista las herramientas y las llama | Acceso programático a servicios específicos integrados por el desarrollador; trabajo de agentes de alto volumen; la capa de descubrimiento dominante para herramientas de agentes |
| A2A (Google) | Los agentes publican lo que ofrecen en sobres estándar; otros agentes los descubren | Ecosistemas multiagente donde los agentes necesitan encontrar agentes pares; la capa de descubrimiento que AP2 extiende |
| Directorios de agentes (Agent.market, lobster.cash, Tenzro) | Marketplaces públicos que listan APIs y servicios de pago; los agentes los consultan como un catálogo | Servicios de terceros descubiertos en tiempo de ejecución; las "Páginas Amarillas" del comercio de agentes |
| Superficies de compra con IA (ChatGPT Instant Checkout, Google AI Mode, Walmart en ChatGPT) | Productos de IA para consumidores con descubrimiento de productos y pago ACP integrado | Flujos de consumo donde el usuario habla con la IA y esta presenta productos de forma integrada |
El SDK tiene soporte de primera clase para MCP: conecta un servidor MCP a un agente en pocas líneas y todas sus herramientas quedan disponibles para el razonamiento del agente. Para el descubrimiento fuera de MCP, envuélvelo como un @function_tool ordinario que consulta el directorio y devuelve listados estructurados.
El cableado de
MCPServerStreamableHttpque se muestra a continuación es real e importable. La llamadaagent_market_clientes ilustrativa: representa un cliente de directorio. El andamiaje de@function_toolyAgentes real.
from agents import Agent, function_tool
from agents.mcp import MCPServerStreamableHttp
from decimal import Decimal
# Wire an MCP discovery server: all its tools become available
research_mcp = MCPServerStreamableHttp(
name="research-services",
params={"url": "https://research-services.example.com/mcp"},
)
# Wire a non-MCP directory as a regular tool
@function_tool
async def search_agent_market(query: str, max_price_usdc: Decimal) -> list[dict]:
"""Search Agent.market for x402-paid services matching the query."""
return await agent_market_client.search(query, max_price_usdc=max_price_usdc)
agent = Agent(
name="ResearchAgent",
instructions="Find and use research services. Prefer MCP-discovered tools; fall back to Agent.market for niche needs.",
mcp_servers=[research_mcp],
tools=[search_agent_market],
)
La decisión que tomes aquí no es "MCP vs A2A vs directorios". Es: ¿dónde viven realmente los servicios de mi agente? Si son internos a tu organización, usa MCP. Si abarcan una red de agentes asociados, usa A2A. Si son APIs de terceros que descubres en tiempo de ejecución, usa directorios. Para productos de consumo, usa una superficie de compra con IA (y ACP en la capa de comercio). Estas opciones no son mutuamente excluyentes; un agente real suele utilizar varias.
Conclusión del Concepto 4: El descubrimiento responde "¿qué está disponible?" Cuatro opciones compiten: MCP para servidores de herramientas internos, A2A para ecosistemas multiagente, directorios para servicios de terceros, superficies de IA para productos de consumo. El SDK tiene soporte de primera clase para MCP y conecta el resto como funciones
@function_tool. Elige según dónde vivan los servicios; no son mutuamente excluyentes.
Concepto 5: Capa 2, Identidad y autorización (demostrar que el agente tiene permiso)
En una línea: La autorización es donde el agente demuestra que el humano autorizó este gasto y que el agente es quien dice ser, antes de que se mueva cualquier dinero.
Antes de que el dinero pueda moverse, dos condiciones deben cumplirse: el agente es quien dice ser, y el humano autorizó este gasto. Son problemas distintos con soluciones distintas, y la Capa 2 resuelve ambos antes de que ocurra la liquidación. Omitir la Capa 2 genera uno de dos fallos: fraude (el agente de cualquiera puede gastar el dinero de cualquiera) o parálisis (cada transacción requiere confirmación humana).
Esta es la capa más disputada en 2026. Cuatro opciones, cuatro filosofías:
| Protocolo | Cómo funciona | Más sólido cuando |
|---|---|---|
| Mandatos AP2 (Google) | Credenciales firmadas: Mandato de intención ("comprar zapatos por menos de $120"), Mandato de carrito ("este carrito, este precio"), Mandato de pago ("autorizar este medio") | Flujos con auditoría intensiva que requieren prueba no repudiable de consentimiento; flujos multiagente donde el comerciante nunca ha visto al agente del comprador |
| SPT de ACP (OpenAI más Stripe) | Stripe acuña un Token de Pago Compartido (SPT) con alcance a un comerciante, monto y ventana de tiempo; el agente lo presenta; el comerciante lo verifica y cobra | Compras de consumo donde Stripe es el procesador y los medios de pago tradicionales aplican disciplina de contracargos |
| TAP (Visa más Cloudflare) | La firma de identidad del agente viaja en encabezados HTTP; los comerciantes la verifican contra el directorio de Visa | Verificación de identidad específicamente (no de autorización); generalmente se añade a otro protocolo de autenticación, no se usa de forma aislada |
| ERC-8004 más reputación on-chain | Un registro on-chain de identidades de agentes e historial de transacciones, con una puntuación de reputación basada en operaciones anteriores | Flujos puros multiagente sin confianza previa; operaciones B2B de alto valor donde vale la pena verificar la reputación |
Las dos preguntas que debe responder la Capa 2, y cómo las responde cada protocolo:
- "¿Autorizó el humano esto?" AP2 responde con un mandato que el usuario firmó antes de delegar. ACP responde con un SPT que Stripe acuñó solo tras la autorización del usuario a nivel de cuenta. TAP no responde esto; solo verifica identidad. ERC-8004 responde con transacciones firmadas on-chain.
- "¿Es el agente quien dice ser?" AP2 responde con la clave de firma (solo el agente real puede firmar). ACP responde con el SPT acotado al comerciante (solo el comerciante autorizado puede canjearlo). TAP responde con la consulta al directorio de Visa. ERC-8004 responde con el registro de identidad on-chain.
El SDK te ofrece dos puntos de integración: una guardia de entrada de herramienta que se ejecuta antes de la herramienta de pago, y el contexto de ejecución que lleva el estado por usuario a ambas.
El cableado de la guardia,
@function_toolyAgentque se muestra a continuación es el SDK real y funciona (las rutas de atributodata.context.tool_argumentsydata.context.contextestán confirmadas contra el SDK instalado). La llamadastripe.PaymentTokens.createdentro de la herramienta es ilustrativa; ACP en producción usa los endpoints ACP de Stripe en vivo.
from agents import Agent, function_tool, RunContextWrapper
from agents.tool_guardrails import (
tool_input_guardrail,
ToolInputGuardrailData,
ToolGuardrailFunctionOutput,
)
from decimal import Decimal
import json
import stripe
# Pattern 1: a tool input guardrail. Runs BEFORE the payment tool executes.
# This is the SDK-native way to block a payment before it happens.
@tool_input_guardrail
def block_over_user_cap(data: ToolInputGuardrailData) -> ToolGuardrailFunctionOutput:
"""Reject any payment tool call where the request would exceed the user's per-run cap."""
args = json.loads(data.context.tool_arguments or "{}") # raw JSON args -> dict
requested = Decimal(str(args.get("max_amount_usd", 0)))
ctx = data.context.context # the run context (a dict)
user_cap = Decimal(str(ctx["user_session"].per_run_spend_cap_usd))
run_spent = Decimal(str(ctx.get("run_spend_usd", 0)))
if run_spent + requested > user_cap:
return ToolGuardrailFunctionOutput.reject_content(
f"Refusing payment tool: would spend ${run_spent + requested}, exceeds run cap ${user_cap}"
)
return ToolGuardrailFunctionOutput.allow()
# Pattern 2: the payment tool itself, guarded at the function-tool level
@function_tool(tool_input_guardrails=[block_over_user_cap])
async def purchase_with_acp(
ctx: RunContextWrapper,
merchant_id: str,
items: list,
max_amount_usd: Decimal,
) -> PaymentToolResult:
"""Use ACP to buy items from the merchant up to max_amount_usd.
The guardrail has already verified spend is within bounds before we reach here."""
user_session = ctx.context["user_session"]
spt = stripe.PaymentTokens.create(
amount=int(max_amount_usd * 100), # Stripe expects cents as int
currency="usd",
merchant_id=merchant_id,
user_session_id=user_session.id,
max_uses=1,
)
response = await acp_post(merchant_id, items, spt.token)
return PaymentToolResult(
status="success" if response.status == "confirmed" else "failed",
details={"order_id": response.order_id, "merchant_status": response.status},
)
agent = Agent(
name="ShoppingAgent",
instructions="Help the user shop. Always verify authorization before any purchase.",
tools=[purchase_with_acp],
# No output_guardrails for spend control. Those run on the agent's FINAL output,
# not on individual tool calls. See Concept 15 for the full three-level enforcement.
)
El SDK tiene tres tipos de guardia y se activan en momentos distintos. input_guardrail se ejecuta sobre la entrada inicial del primer agente. output_guardrail se ejecuta sobre la respuesta final del agente al usuario. tool_input_guardrail y tool_output_guardrail se ejecutan en cada llamada a una function-tool, antes y después de que se ejecute. Para la seguridad de pagos necesitas la guardia de entrada de herramienta: se activa antes de que se ejecute la herramienta de pago y puede rechazar la llamada. Una guardia de salida se activa demasiado tarde para detener el pago; es útil para limpiar la respuesta final (por ejemplo, para redactar datos sensibles), no para bloquear una herramienta. El Concepto 15 retoma este punto; es el error más común.
La decisión que tomes aquí depende de tu modelo de confianza. Si el usuario tiene sesión iniciada en tu aplicación y puedes acuñar SPTs a través de Stripe, ACP ofrece la historia más lista para producción. Si necesitas pistas de auditoría no repudiables, como en industrias reguladas o adquisiciones B2B, los mandatos AP2 son los adecuados. Si necesitas identidad criptográfica por sí sola, separada de la autorización, añade TAP. En un entorno puramente multiagente sin confianza compartida, ERC-8004 cubre el vacío. No son intercambiables.
Conclusión del Concepto 5: La autorización responde dos preguntas: "¿autorizó el humano esto?" y "¿es el agente quien dice ser?" Cuatro protocolos compiten: mandatos AP2 (auditoría intensiva), SPT de ACP (nativo de Stripe), TAP (solo identidad), ERC-8004 (confianza multiagente). El SDK se integra mediante el contexto de ejecución para verificaciones por herramienta y
tool_input_guardrail(que se ejecuta antes de cada herramienta y puede rechazarla) para límites de gasto. Elige según tu modelo de confianza.
Concepto 6: Capa 3, Comercio (el ciclo de vida completo de una compra)
En una línea: El comercio abarca todo lo que hay en una compra real que no es autorización ni liquidación: carrito, pedido, cumplimiento, disputa, reembolso; y una simple llamada a la API lo omite por completo.
La autorización y la liquidación juntas cubren "el dinero se mueve con permiso". El comercio cubre todo lo demás en una compra: carritos estructurados, confirmación de pedido, seguimiento del cumplimiento, resolución de disputas, reembolsos, contracargos y devoluciones. Esta es la capa que separa un proceso de pago de una transferencia de dinero. Una llamada API máquina a máquina no necesita una capa de comercio; es solo una llamada a la API. Una compra de consumidor claramente la necesita.
Tres opciones con diferencias significativas:
| Protocolo | Qué hace | Ideal para |
|---|---|---|
| ACP (OpenAI con Stripe) | Un flujo estructurado: formato de carrito, confirmación de pedido, estado de cumplimiento, escalada de disputas, reembolsos. El comerciante sigue siendo el comerciante de registro. | Compras de consumidores: bienes minoristas, suscripciones, cumplimiento físico. Impulsa ChatGPT Instant Checkout. |
| UCP (Google) | Un ciclo de vida similar, construido en torno a las superficies de compras de Google (Gemini, Google AI Mode) y Google Pay | Comerciantes en Google Shopping; agentes en superficies de Google AI |
| API directa (máquina a máquina) | Sin protocolo de comercio, solo una API HTTP. Pago mediante x402 o MPP. Sin carrito, sin disputas, sin reembolsos. | Acceso a API, cómputo, feeds de datos: compras donde lo adquirido es una respuesta de API sin estado |
Así, ACP y UCP compiten; "API directa" es la ausencia de esta capa, no un tercer competidor, y a menudo convive perfectamente sin nada más. Una plataforma de consumo elige ACP o UCP (o ambos, si abarca ChatGPT y Gemini). Un marketplace de API no elige en esta capa en absoluto, porque sus compras no tienen un ciclo de vida que gestionar.
Lo que la mayoría de los ingenieros subestima son los reembolsos y las disputas. Un cliente que pide una camiseta en la talla incorrecta espera poder devolverla. El protocolo de comercio debe especificar cómo inicia la devolución, cómo se entera el agente y cómo fluye el reembolso de regreso a través de la liquidación. ACP resuelve esto correctamente al mantener al comerciante como comerciante de registro: la maquinaria de disputas existente (los flujos de contracargos de Stripe, la política de devoluciones del minorista) simplemente funciona. Los enfoques de API directa lo ignoran. Con frecuencia no existe ninguna ruta de reembolso, lo cual está bien para una llamada a la API de $0.0001 y está mal para $500 de créditos de API.
Los flujos de comercio generalmente requieren varias herramientas trabajando en secuencia:
Las llamadas a
acp_clienta continuación son ilustrativas; representan un backend de comercio ACP. Los modelos Pydantic,@function_tooly el cableado deAgentson reales.
from agents import Agent, function_tool
from pydantic import BaseModel
from decimal import Decimal
class CartItem(BaseModel):
sku: str
quantity: int
unit_price: Decimal
class OrderResult(BaseModel):
order_id: str
status: str # "confirmed", "fulfilled", "shipped", "delivered"
tracking_url: str | None = None
estimated_arrival: str | None = None
@function_tool
async def acp_create_cart(merchant_id: str, items: list[CartItem]) -> PaymentToolResult:
"""Create a cart at an ACP merchant. Does NOT charge yet."""
cart = await acp_client.cart.create(merchant_id=merchant_id, items=items)
return PaymentToolResult(
status="success",
details={"cart_id": cart.id, "merchant_id": merchant_id, "item_count": len(items)},
)
@function_tool
async def acp_checkout(cart_id: str, spt_token: str) -> OrderResult:
"""Complete the checkout for a previously-created cart."""
return await acp_client.checkout.complete(cart_id=cart_id, spt_token=spt_token)
@function_tool
async def acp_check_order_status(order_id: str) -> OrderResult:
"""Get the current status of an order. The agent calls this to follow up."""
return await acp_client.order.status(order_id=order_id)
@function_tool
async def acp_initiate_refund(order_id: str, reason: str) -> RefundResult:
"""Start a refund for an order. Returns refund_id for follow-up."""
response = await acp_client.refund.create(order_id=order_id, reason=reason)
return RefundResult(
refund_id=response.refund_id,
order_id=order_id,
status=response.status,
amount_refunded_usd=response.amount_refunded_usd,
)
shopping_agent = Agent(
name="ShoppingAgent",
instructions="Help the user shop. Create the cart first, confirm items with the user, then check out. Handle refund requests with an ACP refund.",
tools=[acp_create_cart, acp_checkout, acp_check_order_status, acp_initiate_refund],
)
La pregunta clave aquí es si tu caso de uso necesita un ciclo de vida de comercio. Si es así (carrito, reembolso, disputa), elige ACP para alcance en ChatGPT o UCP para alcance en Google, o ambos. Si no es así, omite esta capa y ve directamente de la autorización a la liquidación. Las dos formas de equivocarse: forzar un protocolo de comercio de consumo en una llamada máquina a máquina (demasiado), o saltarse el comercio en una compra real de consumidor y luego reimplementar las disputas mal más adelante (demasiado poco).
Conclusión del Concepto 6: El comercio gestiona el ciclo de vida completo de una compra: carrito, proceso de pago, cumplimiento, disputa, reembolso. ACP y UCP compiten por los flujos de consumidores; el acceso máquina a máquina no tiene capa de comercio en absoluto. La mecánica de reembolsos y disputas es el peso oculto que separa un protocolo de comercio real de uno exclusivamente de pagos. El SDK conecta el comercio como una secuencia de herramientas (carrito, proceso de pago, estado, reembolso). Elige según el caso de uso: ciclo de vida necesario (ACP/UCP) u omitido (API directa).
Concepto 7: Capa 4, Liquidación (el dinero se mueve de verdad)
En una línea: La liquidación es donde los dólares cambian de custodia de manera efectiva, y la elección depende principalmente de la economía de la transacción.
Transferir valor del comprador al vendedor. Todo lo que está por encima de esta capa es coreografía; la liquidación es donde los dólares (o monedas estables, o la unidad que corresponda) cambian de manos de verdad. El agente solo ha completado una transacción una vez que la liquidación concluye.
Cuatro opciones serias, cada una con su propia economía y sus propios límites:
| Protocolo | Cómo funciona | Economía | Ideal para |
|---|---|---|---|
| x402 | Nativo en HTTP; liquida mediante una transferencia de moneda estable en Base/Solana/EVM, firmada con EIP-3009 | Gas de menos de un centavo, finalidad en 1-2 segundos, sin tarifas de protocolo | Micropagos máquina a máquina; alta frecuencia, bajo valor (acceso a API, facturación por llamada) |
| MPP | Sesiones: el agente preautoriza un tope y una duración, luego transmite pagos medidos. Multirraíl (moneda estable en Tempo, Lightning, tarjetas) | Tarifas de Stripe en raíles de tarjeta; casi nulas en moneda estable; compatible con suscripciones | Flujos empresariales y multirraíl; suscripciones recurrentes; casos que requieren fiat y cripto en un mismo entorno |
| Raíles de tarjeta (Stripe/Adyen/Worldpay) | Visa, Mastercard, Amex mediante Stripe; el agente presenta un SPT (ACP) o un Mandato de Pago (AP2); el procesador carga la tarjeta | Alrededor del 2.9% más $0.30 para tarjetas; maquinaria de disputas consolidada | Flujos de consumidores; transacciones con exposición a contracargos; aceptación internacional de tarjetas |
| Transferencia bancaria / Lightning | ACH, SEPA, Bitcoin Lightning | ACH ~$0.25 fijo; Lightning menos de un centavo; SEPA ~€0.20 | Flujos de alto valor donde el 2.9% de tarjeta duele; micropagos transfronterizos mediante Lightning |
La elección de liquidación depende principalmente del dinero. Los pagos de menos de un dólar van a x402, donde el gas de la moneda estable es de menos de un centavo. Las compras de consumidores de hasta aproximadamente $1,000 van a raíles de tarjeta mediante ACP, donde la protección por contracargo vale el 2.9%. Las suscripciones recurrentes van a sesiones MPP. Las transferencias B2B de gran valor van a raíles bancarios o Lightning. Y las capas superiores suelen determinar la elección: ACP en comercio significa principalmente raíles de tarjeta en liquidación; un servidor MCP protegido por x402 en descubrimiento significa principalmente x402 en liquidación.
Ten cuidado con la trampa del número titular. Los artículos que citan el volumen de transacciones de x402 o el recuento de integraciones de MPP pueden inducir a error. La pregunta correcta no es "¿cuál tiene más volumen?", sino "¿cuál se adapta a la economía de esta transacción?". Una llamada a la API de $0.001 liquidada en raíles de tarjeta cuesta más en tarifas que la propia llamada. Una adquisición de $5,000 liquidada en moneda estable mediante x402 descarta la protección por contracargo que ofrecería una tarjeta.
La liquidación generalmente se activa como efecto secundario de una herramienta de capa superior: el agente raramente llama a settle_payment() directamente; la liquidación ocurre dentro de acp_checkout() o x402_fetch(). Sin embargo, los límites de gasto a nivel del SDK siguen siendo importantes:
La llamada a
x402_client.geta continuación es ilustrativa; representa una obtención x402 del lado del comprador. El cableado de@function_tooly la verificación del gasto son Python real.
from agents import function_tool, RunContextWrapper
from decimal import Decimal
from .models import X402PaymentResult, PaymentToolResult
@function_tool
async def x402_fetch(
ctx: RunContextWrapper,
url: str,
max_payment_usdc: Decimal,
) -> X402PaymentResult | PaymentToolResult:
"""Fetch a paid URL via x402. Settlement is automatic if cost <= max_payment_usdc."""
# Check the SDK-level spend tracker before initiating the request
spent_so_far = Decimal(str(ctx.context.get("session_x402_spend_usdc", Decimal(0))))
session_cap = ctx.context["user_session"].x402_session_cap_usdc
if spent_so_far + max_payment_usdc > session_cap:
return PaymentToolResult(
status="rejected",
error=f"Would exceed session spend cap (already spent ${spent_so_far})",
)
# Initiate the x402 flow: the server returns 402, the agent retries with a signed payment
response = await x402_client.get(url, max_payment_usdc=max_payment_usdc)
# Update the spend tracker, kept in ctx.context for cross-tool visibility
ctx.context["session_x402_spend_usdc"] = spent_so_far + response.amount_paid_usdc
return X402PaymentResult(
content=response.content,
amount_paid_usdc=response.amount_paid_usdc,
tx_hash=response.tx_hash,
)
Hay algo que conviene dejar claro: la verificación if spent_so_far + ... es una salvaguarda blanda dentro del cuerpo de la herramienta, útil para un fallo rápido y amigable, pero no es la seguridad real. La seguridad que realmente te protege es la billetera de contrato inteligente del agente. Incluso si eliminaras la verificación en la herramienta, los topes de la billetera del Concepto 15 seguirían rechazando la transferencia en cadena. La verificación de la herramienta es para la experiencia de usuario; los topes de la billetera son la seguridad.
El movimiento aquí es elegir el raíl que se ajusta a la economía de la transacción y luego confirmar que es compatible con tu elección de comercio. Las operaciones máquina a máquina de menos de un dólar van a x402. Las compras de consumidores van a raíles de tarjeta mediante ACP. Las suscripciones empresariales van a MPP. No elijas la liquidación de forma aislada; elígela como la base de una pila compuesta.
Conclusión del Concepto 7: La Capa 4 (Liquidación) es donde el dinero se mueve de verdad. Cuatro opciones compiten. x402 para pagos en moneda estable máquina a máquina. MPP para sesiones multirraíl. Raíles de tarjeta para compras de consumidores que necesitan contracargos. Banco o Lightning para casos de alto valor o comisiones muy bajas. La elección depende principalmente del dinero: menos de un dólar va a x402, el consumidor va a tarjetas, la empresa va a MPP. El SDK ejecuta la liquidación como efecto secundario de herramientas de capas superiores. Limita el gasto a nivel de ejecución y sesión con
RunContextWrapper, y los topes en cadena de la billetera son la capa que nada puede eludir.
Parte 3: Los cuatro protocolos en profundidad, con integración del SDK de OpenAI Agents
Las partes 1 y 2 establecieron el marco: cuatro capas, varios protocolos por capa, el SDK como cliente universal. La parte 3 recorre cada uno de los cuatro protocolos principales de cerca. Para cada uno encontrarás qué es, sus primitivas clave, el código de integración con el SDK y notas breves sobre cómo los equipos los despliegan y ejecutan.
Léelos como cuatro inmersiones profundas en paralelo. Cada protocolo tiene la misma estructura, por lo que puedes compararlos lado a lado.

Cada protocolo de los conceptos 8 al 11 se conecta al SDK a través de uno de los patrones de este diagrama. La pila de tres niveles de límites de gasto en la parte inferior anticipa el concepto 15 de la parte 6. Tenla presente mientras lees: la disciplina de seguridad que muestra es lo que convierte este código en algo que realmente puedes desplegar.
🧰 Pydantic como capa de contrato: léelo una vez, aplica a todos los protocolos a continuación
Cada muestra de código en la parte 3 usa modelos Pydantic, no diccionarios Python simples, para los payloads de protocolo, los retornos de herramientas, los cuerpos de solicitud y respuesta de FastAPI, y los payloads de eventos de Inngest. Esta es la parte que no puedes omitir. Es lo que mantiene unido todo el sistema.
En un flujo típico de agente-comercio se cruzan cuatro fronteras:
- El
@function_tooldel SDK devuelve un valor al razonador del agente. - Ese valor cruza la red hacia un endpoint de protocolo (ACP, AP2, x402, MPP).
- El protocolo devuelve una respuesta que vuelve a cruzar.
- A veces llega un webhook más tarde y cruza hacia un manejador de FastAPI.
En cada frontera, un diccionario sin tipo pierde campos silenciosamente, omite coerciones y envía la forma incorrecta. Los modelos Pydantic capturan los cuatro tipos de fallo justo en la frontera, con errores que apuntan al campo exacto.
Este es el patrón que se repite en cada concepto a continuación:
from pydantic import BaseModel, Field
from decimal import Decimal
from typing import Literal
from agents import function_tool, RunContextWrapper
class CartItem(BaseModel):
sku: str
quantity: int = Field(ge=1)
unit_price_usd: Decimal
class CheckoutRequest(BaseModel):
merchant_id: str
items: list[CartItem]
max_total_usd: Decimal = Field(gt=0)
class CheckoutResult(BaseModel):
order_id: str
status: Literal["confirmed", "failed", "pending_user_confirmation"]
total_charged_usd: Decimal
estimated_delivery: str | None = None
@function_tool
async def acp_checkout(ctx: RunContextWrapper, request: CheckoutRequest) -> CheckoutResult:
# Pydantic has already validated the request shape before this line runs.
# Returning a CheckoutResult means the agent's reasoner gets typed feedback.
...
Tres razones concretas por las que importa a esta escala:
- El razonador usa el tipo de retorno como retroalimentación. Cuando
acp_checkoutdevuelve unCheckoutResulttipado, el siguiente paso de razonamiento del agente obtiene nombres de campo y tipos limpios, no un diccionario convertido a cadena de texto. La precisión en la selección de herramientas mejora de forma medible. - FastAPI usa Pydantic de forma nativa. Los webhooks de Stripe, las devoluciones de llamada de mandato AP2 y los eventos de sesión MPP se deserializan en modelos Pydantic en el manejador de FastAPI: los mismos modelos que devuelven las herramientas del agente. Un contrato, dos endpoints.
- Los eventos de Inngest llevan payloads Pydantic. Cuando un manejador de webhook de FastAPI dispara un evento de Inngest, el payload es un modelo Pydantic. El
step.wait_for_eventsuspendido recibe el payload tipado directamente. Sin análisis JSON en el flujo de trabajo.
Decimal para el dinero, siempre. Toda cantidad monetaria en este curso usa Decimal, nunca float. Las operaciones de punto flotante con dinero pierden precisión de formas que se acumulan a lo largo de miles de micropagos. El SDK de Stripe acepta ambos pero reporta en Decimal. Los montos de x402 llegan como enteros en cadena (USDC tiene 6 decimales) que se envuelven en Decimal. El dinero permanece en Decimal en todas partes donde no se está serializando a un formato de red.
Los modelos de resultado compartidos. En lugar de redefinir los tipos de resultado en cada concepto, el curso define un pequeño conjunto de modelos de resultado una sola vez. Cada bloque de código a continuación los importa por nombre. Colócalos en tu models.py:
from pydantic import BaseModel, Field
from decimal import Decimal
from typing import Literal
from datetime import datetime
# --- Tool-result models (returned by @function_tool functions) ---
class PaymentToolResult(BaseModel):
"""Generic envelope for any payment-related tool action."""
status: Literal["success", "failed", "rejected", "pending"]
error: str | None = None
details: dict | None = None # protocol-specific details
class MandateResult(BaseModel):
"""Result of creating an AP2 mandate (Intent / Cart / Payment)."""
mandate_id: str | None = None
status: Literal["signed", "declined", "pending", "failed"]
expires_at: str | None = None # ISO 8601
error: str | None = None
class OrderStatusResult(BaseModel):
"""Result of fetching ACP order status."""
order_id: str
status: Literal["confirmed", "shipped", "delivered", "cancelled", "refunded", "pending"]
tracking_url: str | None = None
estimated_delivery: str | None = None
class RefundResult(BaseModel):
"""Result of initiating an ACP refund."""
refund_id: str
order_id: str
status: Literal["initiated", "processing", "completed", "failed"]
amount_refunded_usd: Decimal | None = None
class DiscoveryResult(BaseModel):
"""Result of an Agent.market or similar agent-directory search."""
service_id: str
name: str
description: str
price_per_call_usdc: Decimal
endpoint_url: str
class X402PaymentResult(BaseModel):
"""Result of an x402-paid fetch."""
content: str
amount_paid_usdc: Decimal
tx_hash: str | None = None
class MPPSessionResult(BaseModel):
"""Result of creating or closing an MPP session."""
session_id: str
status: Literal["active", "closed", "expired", "failed"]
total_charged_usd: Decimal | None = None # only populated on close
expires_at: datetime | None = None
rail_breakdown: dict[str, Decimal] | None = None # only on close
class MPPMeteredCallResult(BaseModel):
"""Result of a metered call within an active MPP session."""
session_id: str
cost_usd: Decimal
response_payload: dict
accumulated_session_spend_usd: Decimal
# --- FastAPI handler models (request/response bodies for webhooks/callbacks) ---
class WebhookAck(BaseModel):
"""Generic webhook handler ack."""
received: bool = True
event_id: str | None = None
# --- Inngest workflow result models (return types of @inngest_client functions) ---
class WorkflowResult(BaseModel):
"""Generic workflow completion envelope."""
status: Literal["completed", "abandoned", "failed", "partial"]
reason: str | None = None
output: dict | None = None
Estos modelos reaparecen a lo largo de la parte 3 y la parte 6. Los bloques de código a continuación los importan por nombre y nunca los redefinen. Verás el patrón de importación repetido en cada concepto; esta barra lateral no se repite.
Concepto 8: ACP (Agentic Commerce Protocol), el protocolo de compras para consumidores
En una línea: ACP es cómo un agente completa una compra real en un comerciante real en nombre de una persona, con el comerciante aún siendo responsable de la venta.
Qué es. ACP es una especificación abierta creada por OpenAI y Stripe, lanzada el 29 de septiembre de 2025 con Etsy y Shopify como socios de lanzamiento. A principios de 2026 impulsa ChatGPT Instant Checkout en comerciantes integrados con Shopify y varias grandes marcas de retail. El número de comerciantes y las listas de marcas varían según la fuente, así que verifica en el directorio de integración de ACP para conocer la adopción actual. El protocolo es Apache 2.0, gobernado a través de un proceso de Propuesta de Mejora de Especificación en github.com/agentic-commerce-protocol/agentic-commerce-protocol. El repositorio marca la especificación como beta, así que espera diferencias entre los ejemplos del curso y la especificación activa.
Dónde se ubica. ACP vive principalmente en la capa 3 (Commerce) y alcanza la capa 2 (Authorization) a través de su mecanismo de token. Abarca la formación de carritos, el pago, la gestión de pedidos, el estado de cumplimiento y los mecanismos de reembolso. El comerciante sigue siendo el comerciante de registro: los contracargos, las devoluciones y el servicio al cliente fluyen a través de los sistemas existentes del comerciante. (El comerciante de registro es el negocio legalmente responsable de una transacción.)
Las dos primitivas que importan.
- Token de pago compartido (SPT, por sus siglas en inglés). Un token de un solo uso del procesador de pagos (Stripe en la implementación de referencia), bloqueado a un comerciante, un límite de monto, una ventana de tiempo corta y generalmente un solo uso. Si un agente autorizado para $50 intenta gastar $1,000, el SPT falla a nivel de protocolo. El SPT es cómo ACP mantiene al agente dentro del ámbito autorizado por el usuario.
- Mandato de carrito (mediante la extensión AP2). ACP puede componerse con AP2 para mayor rigor de auditoría: el usuario firma un mandato de carrito antes de que el agente envíe el SPT. Esto es opcional en ACP pero cada vez más común en flujos regulados. (Un mandato es una prueba firmada de que un humano autorizó un tipo específico de gasto.)
La integración con el SDK de OpenAI Agents. ACP es el protocolo más listo para producción para el SDK, porque OpenAI lo co-construyó. El SDK de Python de Stripe más un cliente ACP liviano proporcionan la integración completa.
Las llamadas a
acp_clientystripe.PaymentTokens.create(...)a continuación son ilustrativas: muestran la forma que toma una integración ACP. La acuñación real del SPT se realiza a través de endpoints ACP activos de Stripe, no mediante un métodostripe.PaymentTokens. El cableado del agente, el guardrail y los modelos de resultado son reales y funcionan hoy. Consulta la nota después del bloque.
from agents import Agent, Runner, function_tool, RunContextWrapper
from agents.tool_guardrails import (
tool_input_guardrail,
ToolInputGuardrailData,
ToolGuardrailFunctionOutput,
)
from pydantic import BaseModel
from decimal import Decimal
from typing import Literal
import json
import stripe
import time
from .models import OrderStatusResult, RefundResult
class CartItem(BaseModel):
sku: str
name: str
quantity: int
unit_price_usd: Decimal
class CheckoutResult(BaseModel):
order_id: str
status: Literal["confirmed", "failed", "pending_user_confirmation"]
total_charged_usd: Decimal
estimated_delivery: str | None = None
# Tool input guardrail: refuse the checkout if the user can't authorize the spend
@tool_input_guardrail
def verify_user_can_spend(data: ToolInputGuardrailData) -> ToolGuardrailFunctionOutput:
args = json.loads(data.context.tool_arguments or "{}")
max_total = Decimal(str(args.get("max_total_usd", 0)))
merchant_id = args.get("merchant_id", "")
user_session = data.context.context["user_session"]
if not user_session.can_spend(max_total, merchant_id):
return ToolGuardrailFunctionOutput.reject_content(
f"User cannot authorize ${max_total} at merchant {merchant_id}"
)
return ToolGuardrailFunctionOutput.allow()
@function_tool
async def acp_browse_merchant(merchant_id: str, query: str) -> list[dict]:
"""Search a merchant's catalog via their ACP catalog endpoint."""
response = await acp_client.catalog.search(
merchant_id=merchant_id,
query=query,
limit=20,
)
return [item.model_dump() for item in response.items]
@function_tool(tool_input_guardrails=[verify_user_can_spend])
async def acp_create_cart_and_checkout(
ctx: RunContextWrapper,
merchant_id: str,
items: list[CartItem],
max_total_usd: Decimal,
) -> CheckoutResult:
"""Create a cart at the merchant and complete checkout in one transaction.
Mints an SPT scoped to max_total_usd; the merchant verifies and charges.
The verify_user_can_spend guardrail above has already validated authorization."""
user_session = ctx.context["user_session"]
# Mint the Shared Payment Token via Stripe (Decimal to cents via quantize)
cents = int((max_total_usd * 100).quantize(Decimal("1")))
spt = stripe.PaymentTokens.create(
amount=cents,
currency="usd",
merchant_id=merchant_id,
user_session_id=user_session.id,
max_uses=1,
expires_at=int(time.time()) + 600, # 10-minute window
)
# Submit the cart and SPT to the merchant's ACP endpoint
result = await acp_client.checkout.complete(
merchant_id=merchant_id,
items=[i.model_dump() for i in items],
spt_token=spt.token,
)
# Update the user's spend tracker (Decimal in, Decimal out)
user_session.record_spend(
amount_usd=Decimal(str(result.total_charged_usd)),
merchant_id=merchant_id,
order_id=result.order_id,
)
return CheckoutResult(**result.model_dump())
@function_tool
async def acp_check_order(order_id: str) -> OrderStatusResult:
"""Get the current status of an ACP order (fulfillment, shipping, delivery)."""
raw = await acp_client.orders.get(order_id=order_id)
return OrderStatusResult(
order_id=raw.order_id,
status=raw.status,
tracking_url=raw.tracking_url,
estimated_delivery=raw.estimated_delivery,
)
@function_tool
async def acp_refund(
order_id: str,
reason: str,
amount_usd: Decimal | None = None,
) -> RefundResult:
"""Start a refund for an ACP order. Returns refund_id for follow-up.
If amount_usd is None, a full refund is requested."""
raw = await acp_client.refunds.create(
order_id=order_id,
reason=reason,
amount_usd=amount_usd,
)
return RefundResult(
refund_id=raw.refund_id,
order_id=order_id,
status=raw.status,
amount_refunded_usd=raw.amount_refunded_usd,
)
shopping_agent = Agent(
name="ShoppingAgent",
instructions="""Help the user shop at ACP-enabled merchants. Workflow:
1. Use acp_browse_merchant to find products matching the user's request
2. Present the matched items to the user (via reasoning, not a tool)
3. When the user confirms, use acp_create_cart_and_checkout to complete the purchase
4. Use acp_check_order to report order status when the user asks
5. Use acp_refund only when the user explicitly requests a return""",
tools=[acp_browse_merchant, acp_create_cart_and_checkout, acp_check_order, acp_refund],
model="gpt-5.5",
)
Lo que es real aquí: el scaffolding de Agent, Runner, @function_tool y tool_input_guardrail, junto con los modelos de resultado tipados. Esa es la parte que reutilizas para cada protocolo. Lo que es un sustituto: el acp_client y la llamada a stripe.PaymentTokens.create, que representan el backend ACP-Stripe. En producción cambias ese backend por los endpoints ACP activos de Stripe y el resto permanece igual. Aquí está la misma estructura con un mock ejecutable para que puedas verlo funcionar:
class MockACPClient:
"""Illustrative backend. Real ACP uses live Stripe ACP endpoints, not stripe.PaymentTokens."""
async def checkout(self, merchant_id: str, amount_usd) -> dict:
return {"order_id": "ord_mock_1", "status": "confirmed", "total_charged_usd": str(amount_usd)}
acp_client = MockACPClient() # stands in for the ACP/Stripe backend
El arnés estándar (declarado una vez aquí, referenciado por los tres conceptos siguientes). ACP se ejecuta en el arnés de nube simple sin partes adicionales. El SDK de Stripe se ejecuta dentro del manejador de FastAPI; las llamadas ACP son HTTPS salientes; los SPT viven en el contexto de alcance de ejecución del agente, pasados a través de RunContextWrapper. La única regla: mantén las claves API de Stripe en un almacén de secretos (un almacén de claves), no en variables de entorno, y rótalas según el calendario de Stripe. No se necesita sandbox (ACP no ejecuta código) ni almacenamiento especial (los pedidos persisten en Stripe y en el sistema del comerciante, con registros shadow opcionales para auditoría). Esta línea base de despliegue es la misma para AP2, x402 y MPP. Los tres conceptos siguientes describen solo lo que cada uno añade. El despliegue en la nube se cubre en el curso rápido de despliegue de agentes (en desarrollo).
Ejecución duradera (Inngest). Las transacciones ACP son cortas, generalmente de 5 a 30 segundos de extremo a extremo. Encajan limpiamente en bloques step.run de Inngest. La primitiva step.wait_for_event muestra su valor cuando el agente debe pausar para que el usuario confirme el carrito entre la creación del carrito y el pago (el patrón de humano en el bucle). El curso rápido de Production Worker cubre esta capa de durabilidad en profundidad; aquí está la estructura:
import inngest
from datetime import timedelta
from .models import WorkflowResult
@inngest_client.create_function(
fn_id="shopping-workflow",
trigger=inngest.TriggerEvent(event="shopping/checkout.requested"),
concurrency=[inngest.Concurrency(limit=5, key="event.data.user_id")],
)
async def shopping_workflow(ctx: inngest.Context) -> dict:
# Run the agent to produce the cart proposal
cart = await ctx.step.run(
"agent-builds-cart", build_cart_fn, ctx.event.data["user_query"],
)
# Wait for the user to confirm the proposed cart (human-in-the-loop)
confirmation = await ctx.step.wait_for_event(
"wait-for-user-confirm",
event="shopping/cart.confirmed",
if_exp=f"async.data.cart_id == '{cart['cart_id']}'",
timeout=timedelta(minutes=15),
)
if confirmation is None: # timeout returns None
return {"status": "abandoned", "reason": "user did not confirm in time"}
# The user confirmed; complete checkout with the now-valid SPT
result = await ctx.step.run("complete-checkout", complete_checkout_fn, cart["cart_id"])
return {"status": "completed", "output": result}
Hay un par de detalles que suelen confundir a la gente: wait_for_event hace coincidir el payload entrante con if_exp (una pequeña expresión), y los campos esperados viven bajo el prefijo async.. Un timeout devuelve None, así que compruébalo antes de continuar.
Dónde los equipos se equivocan. Omiten el paso de confirmación del usuario. ACP admite tanto "el usuario confirma cada carrito" como "el usuario preautorizó este tipo de compra." Los equipos suelen elegir la segunda opción por velocidad, y luego descubren que una pequeña mala configuración del SPT permite al agente comprar artículos ligeramente incorrectos sin forma de recuperarse. Por defecto, confirma el carrito durante el primer mes en producción. Relájalo solo una vez que hayas medido con qué frecuencia el agente acierta en el carrito.
Conclusión del concepto 8: ACP es el protocolo de comercio listo para producción para compras de consumidores con el SDK de OpenAI Agents. El SPT limita el gasto del agente; el comerciante sigue siendo el comerciante de registro. Se integra como cuatro funciones
@function_tool(explorar, pagar, estado, reembolso) sobre el SDK de Stripe y un cliente ACP liviano. Elstep.wait_for_eventde Inngest construye la puerta de confirmación del usuario, y el arnés de nube simple es suficiente. Por defecto, confirma los carritos hasta que hayas medido la precisión del agente en la selección de artículos.
Concepto 9: AP2 (Agent Payments Protocol), la capa de autorización
En una línea: AP2 produce pruebas firmadas de que un humano autorizó el gasto; no mueve el dinero en sí, sino que demuestra que el dinero tenía permiso de moverse.
Qué es. AP2 es una especificación abierta de Google con más de 60 socios, lanzada en septiembre de 2025 (última versión v0.2.0, abril de 2026). Licencia Apache 2.0, mantenida en github.com/google-agentic-commerce/AP2, con implementaciones de referencia en Python, TypeScript, Kotlin y Go. AP2 es la capa de autorización, no un protocolo de comercio ni de liquidación. Produce mandatos firmados que prueban que un agente está autorizado a gastar, y luego delega la liquidación efectiva al canal que corresponda (tarjetas, banco o x402 mediante la extensión a2a-x402).
Dónde se ubica. AP2 vive en la Capa 2 (Identidad y Autorización). Se construye sobre dos protocolos subyacentes: A2A (Agent2Agent, para mensajería entre agentes) y MCP (para exposición de herramientas). Un mandato AP2 viaja como credencial firmada sobre A2A o adjunto a una llamada a herramienta MCP.
Los tres primitivos que importan, los tres tipos de mandato.
| Mandato | Cuándo se crea | Qué demuestra |
|---|---|---|
| Intent Mandate | Al inicio de la tarea, firmado por el usuario en su interfaz | El usuario permitió que el agente actuara dentro de reglas establecidas (límites de precio, ventanas de tiempo, comerciantes permitidos) |
| Cart Mandate | Después de que el agente construyó un carrito específico, firmado por el usuario antes del pago (flujos con presencia humana) | El usuario aprobó este carrito exacto a este precio exacto |
| Payment Mandate | En el momento del pago, firmado por el usuario o generado automáticamente contra el Intent Mandate | El usuario autorizó este pago exacto en este canal exacto |
El rastro de auditoría. Los tres mandatos forman una cadena que el firmante no puede negar después: Intent ("comprar zapatos por menos de $120") lleva a Cart ("estos zapatos a $110") lleva a Payment ("cobrar esta billetera de stablecoin"). Cada mandato apunta al anterior. Si algún paso se cuestiona más adelante en una disputa o reclamo de fraude, toda la cadena es auditable. Esa propiedad es de no repudio: "nunca autoricé esto" no se sostiene frente a la firma del propio usuario. Por eso AP2 encaja en industrias reguladas como la salud y los servicios financieros, donde la pregunta "¿el usuario realmente autorizó esto?" tiene peso legal.
Qué cambia para el SDK. AP2 no tiene un lugar de primera clase en el OpenAI Agents SDK; sus compilaciones de referencia usan el Agent Development Kit de Google. Se integra como funciones @function_tool que crean, firman, validan y despachan mandatos. El andamiaje es el mismo del Concepto 8. Lo que AP2 agrega: una superficie de firma donde el usuario firma efectivamente cada mandato.
Las importaciones
from ap2 import ..., elMandateSignery las llamadasap2_x402que aparecen a continuación son ilustrativos. El paquete Python real de AP2 esap2, con modelos de mandato bajoap2.types.mandate, y sus campos reales difieren delprincipal_did/agent_did/rulessimplificado que se muestra aquí. No existe una claseMandateSigner; la firma real usa credenciales verificables sobre A2A. El concepto de cadena de mandatos es real; este código exacto es un sustituto pedagógico. El andamiaje del SDK y los resultados tipados sí son reales.
from agents import Agent, function_tool, RunContextWrapper
from agents.tool_guardrails import (
tool_input_guardrail,
ToolInputGuardrailData,
ToolGuardrailFunctionOutput,
)
from ap2 import IntentMandate, CartMandate, PaymentMandate, MandateSigner
from pydantic import BaseModel
from decimal import Decimal
from datetime import datetime
from .models import MandateResult, PaymentToolResult
class IntentRules(BaseModel):
max_total_usd: Decimal
allowed_merchants: list[str] | None = None
allowed_categories: list[str] | None = None
expires_at: str # ISO 8601 datetime
# Guardrail: refuse any cart that has no preceding Intent Mandate
@tool_input_guardrail
def require_intent_mandate(data: ToolInputGuardrailData) -> ToolGuardrailFunctionOutput:
intent = data.context.context.get("intent_mandate")
if not intent:
return ToolGuardrailFunctionOutput.reject_content(
"No Intent Mandate found. Create one via ap2_create_intent_mandate first."
)
return ToolGuardrailFunctionOutput.allow()
@function_tool
async def ap2_create_intent_mandate(
ctx: RunContextWrapper,
task_description: str,
rules: IntentRules,
) -> MandateResult:
"""Create an Intent Mandate at the start of a purchasing task.
Needs the user's signature, so call this BEFORE the agent shops."""
user_session = ctx.context["user_session"]
mandate = IntentMandate(
principal_did=user_session.did, # decentralized identifier
agent_did=ctx.context["agent_did"],
task=task_description,
rules=rules.model_dump(),
issued_at=datetime.utcnow().isoformat(),
)
# Send to the user's signing UI; block until the user signs or rejects
signed = await user_session.signer.request_signature(
mandate,
ui_prompt="Approve this shopping task?",
timeout_seconds=300,
)
if not signed:
return MandateResult(status="declined", error="User declined to sign Intent Mandate")
# Store the mandate for later reference by Cart/Payment mandates
ctx.context["intent_mandate"] = signed
return MandateResult(mandate_id=signed.id, status="signed", expires_at=rules.expires_at)
@function_tool(tool_input_guardrails=[require_intent_mandate])
async def ap2_create_cart_mandate(
ctx: RunContextWrapper,
cart_items: list[dict],
total_usd: Decimal,
merchant_id: str,
) -> MandateResult:
"""Create a Cart Mandate that references the current Intent Mandate.
Needs the user's signature in human-present flows.
The require_intent_mandate guardrail above has verified an Intent Mandate exists."""
intent = ctx.context["intent_mandate"] # guaranteed present by the guardrail
# Check that the cart fits inside the Intent Mandate's rules
if total_usd > Decimal(str(intent.rules["max_total_usd"])):
return MandateResult(
status="failed",
error=f"Cart total ${total_usd} exceeds Intent Mandate cap ${intent.rules['max_total_usd']}",
)
cart_mandate = CartMandate(
parent_intent_id=intent.id,
cart_items=cart_items,
total_usd=str(total_usd), # serialize Decimal as a string on the wire
merchant_id=merchant_id,
issued_at=datetime.utcnow().isoformat(),
)
user_session = ctx.context["user_session"]
signed = await user_session.signer.request_signature(
cart_mandate,
ui_prompt=f"Approve this cart for ${total_usd}?",
timeout_seconds=300,
)
if not signed:
return MandateResult(status="declined", error="User declined to sign Cart Mandate")
ctx.context["cart_mandate"] = signed
return MandateResult(mandate_id=signed.id, status="signed")
@function_tool
async def ap2_settle_via_x402(
ctx: RunContextWrapper,
merchant_x402_url: str,
) -> PaymentToolResult:
"""Use the AP2 a2a-x402 extension to settle the current Cart Mandate via an x402 stablecoin payment."""
cart = ctx.context.get("cart_mandate")
if not cart:
return PaymentToolResult(status="failed", error="No Cart Mandate to settle")
# The a2a-x402 extension generates a Payment Mandate authorizing the x402 transfer
payment_mandate = await ap2_x402.create_payment_mandate(
cart_mandate=cart,
rail="x402",
chain="eip155:8453", # Base
asset="USDC",
)
# Dispatch the x402 payment with the Payment Mandate attached as proof
result = await x402_client.pay(
url=merchant_x402_url,
amount_usdc=Decimal(str(cart.total_usd)),
payment_mandate=payment_mandate,
)
return PaymentToolResult(status="success", details=result.model_dump())
procurement_agent = Agent(
name="ProcurementAgent",
instructions="""Enterprise procurement workflow:
1. ALWAYS create an Intent Mandate first via ap2_create_intent_mandate
2. Search merchants for matching items
3. Build a cart and create a Cart Mandate via ap2_create_cart_mandate
4. Settle via x402 (stablecoin) using ap2_settle_via_x402, or via card rails
5. Record every mandate ID in the procurement system for audit""",
tools=[ap2_create_intent_mandate, ap2_create_cart_mandate, ap2_settle_via_x402],
model="gpt-5.5",
)
Lo que es real: el mismo andamiaje del SDK y los resultados tipados del Concepto 8. Lo que es un sustituto: las clases de mandato ap2, el MandateSigner y la extensión ap2_x402. La cadena de mandatos en sí es una idea real que puedes construir; la API exacta aquí está simplificada para la enseñanza. A continuación se muestra un mock ejecutable para que el patrón funcione:
class MockSignedMandate:
def __init__(self, mid, rules=None): self.id, self.rules = mid, (rules or {})
class MockSigner:
"""Illustrative. Real AP2 signing uses verifiable credentials over A2A; no MandateSigner class exists."""
async def request_signature(self, mandate, ui_prompt="", timeout_seconds=300):
return MockSignedMandate(getattr(mandate, "id", "mandate_mock_1"))
ap2_x402 = type("Mock", (), {"create_payment_mandate": staticmethod(lambda **k: MockSignedMandate("pm_mock_1"))})()
Qué agrega al andamiaje. Dos cosas más allá de la base del Concepto 8: una superficie de firma para que el usuario firme los mandatos (una aplicación web, una aplicación móvil o una herramienta de firma por notificaciones), y almacenamiento duradero para los mandatos firmados que dure tanto como tus ventanas de disputas (la retención de 7 años es estándar para mandatos financieros). La superficie de firma es la diferencia real con ACP: ACP puede reutilizar sesiones de inicio de sesión existentes, pero AP2 necesita un flujo de firma dedicado.
Ejecución duradera (Inngest). La firma de mandatos es el caso de uso clásico de step.wait_for_event. La función del agente dispara un evento "signing requested", la función se suspende, el usuario firma en la interfaz lo que dispara "signing signed", y la función se reanuda. No se consume cómputo mientras espera, lo que importa porque una firma empresarial puede tardar horas. El crash course de Production Worker profundiza en este patrón de reanudación.
Dónde se equivocan los equipos. Tratan la creación del mandato como una preocupación del momento del pago y firman el mandato después de que el agente ya hizo mucho trabajo. Crea el Intent Mandate primero, antes de que el agente compre nada. Eso detecta un desajuste de alcance de forma temprana (el usuario quería zapatos pero el Intent Mandate solo permite artículos de oficina), en lugar de que el agente haya gastado cómputo construyendo un carrito que nunca podrá financiar.
Conclusión del Concepto 9: AP2 es la capa de autorización para el comercio agencial en entornos con auditoría estricta. Tres tipos de mandato (Intent, Cart, Payment) forman una cadena que el usuario no puede negar después, probando el consentimiento en cada paso. Las implementaciones de referencia se distribuyen en Python, TypeScript, Kotlin y Go mediante el Agent Development Kit de Google; la integración con el OpenAI Agents SDK se hace como funciones
@function_toolque crean, firman y validan mandatos.step.wait_for_eventde Inngest es la solución natural para la espera de firma. Crea los Intent Mandates primero, antes de comenzar a comprar, nunca como un añadido al momento del pago.
Concepto 10: x402, el protocolo de liquidación nativo de HTTP
En una línea: x402 permite que un agente pague por una llamada a una API en uno o dos segundos con una stablecoin, reviviendo el antiguo código de estado HTTP 402 "Payment Required".
Qué es. x402 convierte el código de estado HTTP 402 en una capa de pagos funcional para APIs y comercio entre máquinas. Fue creado por Coinbase (mayo de 2025), con la V2 lanzada en diciembre de 2025, y ahora está bajo la tutela de la x402 Foundation de la Linux Foundation (abril de 2026), con Cloudflare, Stripe, AWS, Google y otros como miembros. Licencia Apache 2.0. A comienzos de 2026, x402 reporta más de 100 millones de pagos acumulados en Base y Solana, con un ecosistema de facilitadores en crecimiento; las cifras cambian rápido, así que verifica los datos actuales en x402.org y en las páginas de lanzamiento de x402 de Coinbase.
Dónde se ubica. x402 opera principalmente en la Capa 4 (Liquidación) para flujos entre máquinas, pero alcanza la Capa 1 (a través de Agent.market y directorios similares) y la Capa 3 (funciona como capa de comercio completa para acceso a APIs simples donde no existe un ciclo de compra real). Para flujos puramente entre máquinas, x402 suele ser el único protocolo necesario.
Los cuatro primitivos que importan.
- El código de estado HTTP 402. Cuando un cliente sin pago solicita un recurso de pago, el servidor devuelve
402 Payment Requiredmás un encabezado con los requisitos de pago: el esquema (exactpara un monto fijo), la red (en formato CAIP-2 comoeip155:8453, que simplemente significa "Base"), el activo (USDC), la dirección del destinatario, el monto máximo y una fecha de expiración. (CAIP-2 es una forma estándar de nombrar una blockchain para que el protocolo permanezca agnóstico respecto a la cadena.) - El encabezado de autorización de pago. El cliente reintenta con un encabezado que contiene una autorización de pago firmada. La firma se realiza fuera de la cadena, por lo que el comprador no paga gas.
- EIP-3009 (transferWithAuthorization). El estándar de Ethereum sobre el que se construye x402. Permite que el comprador firme un pago fuera de la cadena y que otra parte lo envíe en la cadena, de modo que el comprador nunca interactúa directamente con la blockchain ni paga gas.
- Facilitador. Un tercero opcional que verifica la firma y envía el pago en la cadena en nombre del comerciante, de modo que este no necesita infraestructura blockchain. Tanto Coinbase como Cloudflare operan facilitadores.
x402 pasó por la V1 y la V2, y los nombres de encabezados difieren entre versiones de la especificación, facilitadores y SDKs. La documentación actual de Cloudflare usa PAYMENT-REQUIRED en la respuesta 402, PAYMENT-SIGNATURE en el reintento del cliente y PAYMENT-RESPONSE en la respuesta de éxito. Algunos ejemplos anteriores usan X-PAYMENT y X-PAYMENT-PROOF. El flujo es idéntico; solo difieren los nombres en el wire. Verifica los nombres exactos en x402.gitbook.io y en la documentación de tu facilitador antes de escribir código. La traza a continuación usa los roles (solicitud, 402 con requisitos, reintento firmado, éxito con prueba) sin adoptar una convención de nombres específica.
El flujo en una sola traza.
1. Agent: GET https://api.example.com/data
2. Server: 402 Payment Required
<payment-required header>: { network: "eip155:8453", asset: USDC,
recipient: 0xMerchant..., max_amount: 100000,
expiry: 1716304800 }
3. Agent (signs an EIP-3009 authorization off-chain):
GET https://api.example.com/data
<payment-signature header>: <base64-encoded signed authorization>
4. Server: 200 OK
<payment-response header>: <transaction hash>
{ data: ... }
La transacción completa toma uno o dos segundos. Sin creación de cuenta, sin clave de API, sin sesión, sin intervención humana.
Qué cambia en el SDK. x402 tiene la historia más simple de los cuatro. Cloudflare incluye un helper que envuelve un cliente MCP con capacidad de pago x402; para uso sin MCP, una biblioteca Python del lado del comprador más el patrón canónico a continuación es suficiente. El harness es el mismo baseline del Concepto 8.
El constructor
from x402_client import ...mostrado aquí, la importaciónfrom cloudflare_agents import withX402Clienty el camporesponse.amount_paid_usdcson ilustrativos. El paquete real del lado del comprador esx402-client(from x402_client import X402Client, constructor realX402Client(account=...),.get(url)devuelve unhttpx.Response). El constructor de wallet más detallado que se muestra aquí es un sustituto pedagógico, y una llamada real requiere una cuenta con fondos y un endpoint 402 real, lo cual este curso no realiza. ElwithX402Clientde Cloudflare es un helper de JavaScript; no existe un paquete Pythoncloudflare_agents. El servidor MCP (MCPServerStreamableHttp) es Python real; envolverlo con pagos es ilustrativo aquí. No se mueven fondos reales.
from agents import Agent, function_tool, RunContextWrapper
from agents.mcp import MCPServerStreamableHttp
from agents.tool_guardrails import (
tool_input_guardrail,
ToolInputGuardrailData,
ToolGuardrailFunctionOutput,
)
from x402_client import X402Client, X402Wallet
from cloudflare_agents import withX402Client
from decimal import Decimal
import json
from .models import DiscoveryResult, X402PaymentResult, PaymentToolResult
# Pattern 1: wrap an MCP server's tools with x402 payment ability
research_mcp = MCPServerStreamableHttp(
name="research-services",
params={"url": "https://research-services.example.com/mcp"},
)
research_mcp_with_payments = withX402Client(
research_mcp,
wallet=agent_wallet, # smart-contract wallet the agent controls
max_per_call_usdc=Decimal("0.10"),
max_per_session_usdc=Decimal("10.00"),
)
# Pattern 2: direct x402 calls as @function_tool
x402_client = X402Client(wallet=agent_wallet)
# Guardrail: refuse any x402 call that would exceed the session cap
@tool_input_guardrail
def enforce_x402_session_cap(data: ToolInputGuardrailData) -> ToolGuardrailFunctionOutput:
args = json.loads(data.context.tool_arguments or "{}")
max_payment = Decimal(str(args.get("max_payment_usdc", 0)))
ctx = data.context.context
spent = Decimal(str(ctx.get("session_x402_spend_usdc", 0)))
cap = Decimal(str(ctx["user_session"].x402_session_cap_usdc))
if spent + max_payment > cap:
return ToolGuardrailFunctionOutput.reject_content(
f"x402 session cap would be exceeded: ${spent} spent + ${max_payment} requested > ${cap}"
)
return ToolGuardrailFunctionOutput.allow()
@function_tool(tool_input_guardrails=[enforce_x402_session_cap])
async def x402_fetch(
ctx: RunContextWrapper,
url: str,
max_payment_usdc: Decimal = Decimal("0.10"),
) -> X402PaymentResult | PaymentToolResult:
"""Fetch a URL that may require an x402 payment up to max_payment_usdc.
Signs the EIP-3009 authorization and retries with the payment-signature header.
The enforce_x402_session_cap guardrail above has already checked the session bound."""
try:
response = await x402_client.get(url, max_payment_usdc=max_payment_usdc)
# Update the spend tracker for later guardrail checks
current = Decimal(str(ctx.context.get("session_x402_spend_usdc", 0)))
ctx.context["session_x402_spend_usdc"] = current + Decimal(str(response.amount_paid_usdc))
return X402PaymentResult(
content=response.content,
amount_paid_usdc=Decimal(str(response.amount_paid_usdc)),
tx_hash=response.tx_hash,
)
except X402PaymentRequired as e:
return PaymentToolResult(
status="rejected",
error=f"Resource requires ${e.required_usdc}, exceeds max ${max_payment_usdc}",
)
@function_tool
async def x402_search_agent_market(
query: str,
max_price_per_call_usdc: Decimal = Decimal("0.05"),
) -> list[DiscoveryResult]:
"""Search Agent.market for x402-paywalled services matching the query."""
results = await agent_market_client.search(
query=query,
max_price_per_call_usdc=max_price_per_call_usdc,
)
return [
DiscoveryResult(
service_id=r.service_id,
name=r.name,
description=r.description,
price_per_call_usdc=Decimal(str(r.price_per_call_usdc)),
endpoint_url=r.endpoint_url,
)
for r in results
]
research_agent = Agent(
name="ResearchAgent",
instructions="""Research user queries by paying for data sources via x402.
Workflow:
1. Use x402_search_agent_market to find relevant paid services
2. Use x402_fetch to pull data from selected services (max $0.10 per call)
3. Synthesize the findings into a final report
Stay under $10 per research session.""",
tools=[x402_fetch, x402_search_agent_market],
mcp_servers=[research_mcp_with_payments],
)
Lo que es real: el scaffolding del SDK, los resultados tipados y MCPServerStreamableHttp (el servidor MCP es Python genuino). Lo que es un sustituto: el cliente x402 del lado del comprador tal como está escrito aquí, el wrapper withX402Client (solo JavaScript en la realidad) y agent_market_client. A continuación se presentan mocks ejecutables para que el patrón del harness funcione sin fondos reales:
from decimal import Decimal
class MockX402Response:
def __init__(self, content, amount, tx):
self.content, self.amount_paid_usdc, self.tx_hash = content, amount, tx
class MockX402Client:
"""Illustrative. Real buyer-side package: x402-client (X402Client(account=...), .get() -> httpx.Response)."""
async def get(self, url: str, max_payment_usdc: Decimal = Decimal("0.10")):
return MockX402Response(content="<paid data>", amount=Decimal("0.02"), tx="0xmocktx")
x402_client = MockX402Client()
agent_wallet = object() # stands in for the wallet handle
def withX402Client(mcp_server, **kwargs):
"""Illustrative: JavaScript-only in reality. Returns the server unchanged for the Python demo."""
return mcp_server
Qué agrega al harness. Casi nada. x402 no necesita infraestructura adicional más allá del baseline del Concepto 8. La wallet de contrato inteligente del agente reside en una dirección de la cadena en la que opera (Base en la mayoría de los casos), la clave de firma de la wallet se almacena en el key vault, y la biblioteca del lado del comprador se encarga de la firma y el reintento HTTP. (Una wallet de contrato inteligente es una wallet de criptomonedas cuyos límites de gasto están impuestos por código en la propia blockchain, por lo que se mantienen incluso si el código del agente falla.)
Ejecución durable (Inngest). Las llamadas x402 son cortas (uno o dos segundos) e idempotentes: la misma solicitud y firma siempre producen el mismo resultado. Se integran limpiamente en bloques step.run, y la memoización resulta especialmente útil aquí. Si la ejecución falla tras pagar 5 de 10 llamadas a la API, las 5 llamadas pagadas quedan memoizadas y el reintento solo paga las 5 restantes. Sin esto, el reintento pagaría las 10 de nuevo.
El error típico es tratar x402 como si le entregaras al agente una tarjeta de crédito. La protección real es el límite de gasto en la cadena de la wallet, no el max_payment_usdc por solicitud. Si omites el límite en la cadena y usas una hot wallet sin límite, un bucle de agente bloqueado puede vaciarla. Configura límites de gasto en la cadena por identidad del agente, por sesión y por comerciante: tres capas independientes, de modo que un error en una no vacíe la wallet.
Conclusión del Concepto 10: x402 es el protocolo de liquidación nativo de HTTP listo para producción para micropagos entre máquinas. El código de estado 402, un encabezado de autorización de pago firmado y el flujo de firma EIP-3009 liquidan en uno o dos segundos sin creación de cuenta. El helper de Cloudflare envuelve servidores MCP con capacidad de pago; las llamadas directas funcionan a través de la biblioteca Python del lado del comprador. La memoización de
step.runde Inngest evita pagos duplicados en reintentos. El límite de gasto en la cadena de la wallet es la protección que te resguarda, no el límite por solicitud. Verifica los nombres de encabezados según la versión de la especificación y el facilitador con el que integres.
Concepto 11: MPP (Machine Payments Protocol), el protocolo de liquidación basado en sesiones
En una línea: MPP permite que el agente abra una cuenta prepaga con un límite de gasto y luego transmita muchos pagos pequeños a través de varios canales hasta cerrar la cuenta.
Qué es. MPP está desarrollado por Stripe y Tempo, con anuncios de lanzamiento público en marzo de 2026. Tempo es una blockchain de capa 1 incubada por Stripe y Paradigm para pagos de máquina de alta frecuencia. MPP se lanzó con socios de Stripe, Visa, Lightspark (Lightning Network) y otros actores del ecosistema; la lista de socios crece, así que verifica en mpp.dev y en la documentación de MPP de Cloudflare para conocer los participantes actuales. Apache 2.0. MPP es la respuesta de Stripe en la capa de liquidación a x402: caso de uso superpuesto, filosofía diferente.
Dónde se ubica. MPP vive en la Capa 4 (Liquidación) y compite directamente con x402 para pagos máquina a máquina. La diferencia clave: MPP es multicanal y admite autenticación tanto por cargo como por sesión, mientras que x402 es solo de stablecoin y por solicitud.
La forma HTTP. Donde x402 usa el código 402 y cabeceras personalizadas, MPP superpone el pago sobre la autenticación HTTP estándar. El servidor devuelve WWW-Authenticate: Payment con los requisitos, el cliente reintenta con Authorization: Payment <signed-payload>, y el servidor responde con Payment-Receipt que lleva la prueba de liquidación. Esto hace que MPP se sienta como un flujo de autenticación HTTP familiar en lugar de un protocolo personalizado.
Los dos tipos de intención.
| Intención | Ciclo de vida | Ideal para |
|---|---|---|
charge | Una transferencia única, autorizada y liquidada en un solo ciclo | Compras individuales, acceso único a la API, reemplazo de llamadas x402 individuales cuando se necesitan múltiples canales |
session | El agente pre-autoriza un límite y una duración, luego transmite micropagos medidos hasta que los cierra | Micropagos de alta frecuencia donde firmar cada solicitud es costoso; suscripciones recurrentes; el modelo de "Stripe Subscription para agentes" |
La comparación con x402.
| Dimensión | x402 | MPP |
|---|---|---|
| Frecuencia de autorización | Por solicitud (una firma EIP-3009 cada vez) | Por charge o por session (una autorización, muchas llamadas medidas) |
| Forma HTTP | 402 personalizado más cabeceras de pago | WWW-Authenticate / Authorization / Payment-Receipt estándar |
| Canales | Solo stablecoin (USDC en Base/Solana/EVM) | Multi-canal (stablecoin de Tempo, Lightning, tarjetas, ACH) |
| Comisiones | Sin comisión de protocolo más gas de centavos | Comisiones de procesamiento de Stripe en canales de tarjeta; casi cero en stablecoin de Tempo |
| Soporte recurrente | Limitado (requiere firma por período) | Nativo mediante la intención session |
| Mejor uso | Llamadas a la API únicas, infraestructura pública | Suscripciones recurrentes, comerciantes empresariales integrados con Stripe, flujos con respaldo fiat |
Qué cambia en el SDK. MPP se integra a través del SDK de Python de Stripe más la superficie MPP de Stripe. La integración se apoya en la gestión de sesiones. El arnés es la misma base del Concepto 8.
La importación
from stripe.mpp import MPPSessiony las llamadas astripe.MPPSessiona continuación son ilustrativas.stripe.MPPSessionystripe.mppno están en el SDK de Python de Stripe; MPP es el estándar de Stripe y Tempo (mainnet 18 de marzo de 2026), integrado a través de la superficie MPP de Stripe. El concepto de sesión (pre-autorizar un límite, transmitir llamadas medidas) es real; la API exacta aquí es un sustituto pedagógico. El andamiaje del SDK y los resultados tipados son reales.
from agents import Agent, function_tool, RunContextWrapper
from agents.tool_guardrails import (
tool_input_guardrail,
ToolInputGuardrailData,
ToolGuardrailFunctionOutput,
)
from decimal import Decimal
import json
import stripe
from stripe.mpp import MPPSession
from .models import MPPSessionResult, MPPMeteredCallResult, PaymentToolResult
@tool_input_guardrail
def verify_mpp_session_authorized(data: ToolInputGuardrailData) -> ToolGuardrailFunctionOutput:
"""Refuse session creation if the user has not pre-authorized this service."""
args = json.loads(data.context.tool_arguments or "{}")
service_id = args.get("service_id", "")
max_total = Decimal(str(args.get("max_total_usd", 0)))
user_session = data.context.context["user_session"]
if not user_session.can_authorize_mpp_session(max_total, service_id):
return ToolGuardrailFunctionOutput.reject_content(
f"User has not authorized MPP sessions of ${max_total} for service {service_id}"
)
return ToolGuardrailFunctionOutput.allow()
@function_tool(tool_input_guardrails=[verify_mpp_session_authorized])
async def mpp_create_session(
ctx: RunContextWrapper,
service_id: str,
max_total_usd: Decimal,
duration_seconds: int = 3600,
) -> MPPSessionResult:
"""Create an MPP session for one service with a spending cap and duration.
Returns session_id for the metered calls that follow.
The verify_mpp_session_authorized guardrail above has already validated consent."""
user_session = ctx.context["user_session"]
cents = int((max_total_usd * 100).quantize(Decimal("1")))
session = stripe.MPPSession.create(
service_id=service_id,
max_total_usd=cents,
duration_seconds=duration_seconds,
user_session_id=user_session.id,
# The MPP server picks the rail (stablecoin/Lightning/card) by service preference
)
ctx.context.setdefault("mpp_sessions", {})[service_id] = session.id
return MPPSessionResult(
session_id=session.id,
status="active",
expires_at=session.expires_at,
)
@function_tool
async def mpp_metered_call(
ctx: RunContextWrapper,
service_url: str,
payload: dict,
cost_estimate_usd: Decimal,
) -> MPPMeteredCallResult | PaymentToolResult:
"""Make a metered call inside an active MPP session.
The session's running spend updates automatically; the cap is enforced server-side."""
service_id = extract_service_id(service_url)
sessions = ctx.context.get("mpp_sessions", {})
session_id = sessions.get(service_id)
if not session_id:
return PaymentToolResult(
status="failed",
error=f"No active MPP session for service {service_id}. Create one first.",
)
response = await mpp_client.metered_call(
url=service_url,
payload=payload,
session_id=session_id,
cost_estimate_usd=cost_estimate_usd,
)
return MPPMeteredCallResult(
session_id=session_id,
cost_usd=Decimal(str(response.cost_usd)),
response_payload=response.payload,
accumulated_session_spend_usd=Decimal(str(response.accumulated_session_spend_usd)),
)
@function_tool
async def mpp_close_session(ctx: RunContextWrapper, session_id: str) -> MPPSessionResult:
"""Close an MPP session and finalize payment. Returns the total charged and the breakdown by rail."""
closed = await stripe.MPPSession.close(session_id)
return MPPSessionResult(
session_id=session_id,
status="closed",
total_charged_usd=Decimal(str(closed.total_charged_usd)),
rail_breakdown={
rail: Decimal(str(amount))
for rail, amount in closed.rail_breakdown.items()
},
)
api_consumer_agent = Agent(
name="APIConsumerAgent",
instructions="""Consume third-party APIs efficiently using MPP sessions.
Workflow:
1. Identify the service to consume
2. Create an MPP session with mpp_create_session ($X cap, Y seconds duration)
3. Make metered calls via mpp_metered_call
4. Close the session with mpp_close_session when done
Sessions are cheaper than per-request payment for high-frequency calls.""",
tools=[mpp_create_session, mpp_metered_call, mpp_close_session],
model="gpt-5.5",
)
Lo que es real: el andamiaje del SDK y los resultados tipados. Lo que es un sustituto: stripe.MPPSession y mpp_client. El ciclo de vida de la sesión es un patrón real; la API exacta de Stripe aquí está simplificada para la enseñanza. A continuación se presenta un mock ejecutable:
from decimal import Decimal
class MockMPPSession:
@staticmethod
def create(**kw):
return type("S", (), {"id": "mpp_sess_1", "expires_at": None})()
@staticmethod
async def close(session_id):
return type("S", (), {"total_charged_usd": Decimal("4.20"),
"rail_breakdown": {"stablecoin": Decimal("4.20")}})()
mpp_client = type("Mock", (), {"metered_call": staticmethod(
lambda **k: type("R", (), {"cost_usd": Decimal("0.05"), "payload": {},
"accumulated_session_spend_usd": Decimal("0.05")})())})()
Qué agrega al arnés. Un paso de configuración: tu cuenta de Stripe necesita tener MPP habilitado. La integración con la blockchain de Tempo la gestiona el servidor MPP de Stripe, por lo que el agente nunca toca Tempo directamente. Más allá del SDK de Stripe y la gestión de claves (igual que ACP), no hay nada extra.
Ejecutarlo de forma duradera (Inngest). Las sesiones de MPP se mapean limpiamente sobre el patrón de funciones de larga duración de Inngest. El ciclo de vida de la sesión (crear, usar, cerrar) se convierte en una secuencia de bloques step.run, con step.sleep disponible para la expiración basada en tiempo. El modelo de sesión y la ejecución duradera se combinan bien: ambos están diseñados para trabajo con estado y múltiples pasos.
Dónde se equivocan los equipos. Crean sesiones demasiado grandes o demasiado largas. El límite de la sesión es tu límite de pérdida si algo sale mal. Una sesión de $1,000 establecida "por conveniencia" te expone a $1,000 de pérdidas si el bucle del agente falla. Ajusta el tamaño de las sesiones al trabajo esperado real: para una tarea de 30 llamadas, una sesión de $5 con una duración de 5 minutos es más segura que una sesión de $50 de una hora.
Conclusión del Concepto 11: MPP es la respuesta de Stripe en la capa de liquidación a x402, ajustada para medición basada en sesiones y despacho multicanal. Dos intenciones,
chargepara pagos únicos ysessionpara transmisión preautorizada, cubren tanto compras individuales como medición recurrente. La primitiva de sesión es más económica que x402 para llamadas de alta frecuencia, y el despacho multicanal gestiona stablecoin, Lightning y tarjetas en un solo envoltorio. La forma HTTP usaWWW-Authenticate: PaymentyAuthorization: Paymentestándar en lugar de las cabeceras personalizadas de x402, lo que la hace sentirse como autenticación familiar. La integración se realiza a través del SDK de Stripe y la superficie MPP de Stripe, y la ejecución duradera de Inngest se combina bien con el ciclo de vida de la sesión. Ajusta los límites de sesión al trabajo esperado, no a la "conveniencia".
Parte 4: Reglas de composición, cuándo usar qué protocolos en conjunto
La Parte 3 recorrió los cuatro protocolos uno a la vez. Ahora los reunimos. Ya conociste la idea en la Parte 1: un sistema real usa varios protocolos a la vez, uno por capa. La Parte 4 te da las reglas sobre qué combinaciones funcionan, cuáles fallan y cómo mantener el stack tan pequeño como el trabajo lo permite.
Concepto 12: El stack mínimo viable de agente y pagos
En una línea: El stack correcto es el conjunto más pequeño de protocolos que genera valor para un caso de uso, no los cuatro protocolos en cada capa.
Antes de componer cualquier cosa, hazte una pregunta: ¿cuál es el stack más pequeño que genera valor aquí? La respuesta casi nunca es "los cuatro protocolos en cada capa." La mayoría de los sistemas en producción comienza con una capa completamente conectada y agrega el resto solo cuando el caso de uso lo exige.
Aquí está el stack más pequeño para cada caso de uso común. También anticipa las cinco decisiones de la Parte 5.
| Caso de uso | Capa 1 (Descubrimiento) | Capa 2 (Autenticación) | Capa 3 (Comercio) | Capa 4 (Liquidación) | Por qué este es el MVP |
|---|---|---|---|---|---|
| Compras de consumidor (el agente compra bienes minoristas para una persona) | Superficie de compras con IA, o un servidor MCP con catálogo de comerciante | ACP SPT (o un mandato AP2 en sectores regulados) | ACP | Rieles de tarjeta vía Stripe | La mayoría de los compradores quieren cobertura de contracargo. ACP más Stripe es el camino que funciona hoy. |
| Agente pagador de API (el agente llama APIs de terceros que cobran) | Servidor MCP con soporte x402, o un directorio Agent.market | Firma EIP-3009 (el predeterminado de x402) | Ninguno: llamada directa a la API | x402 en Base o Solana | Para máquina a máquina, las Capas 2 y 4 se fusionan. No hay ciclo de vida de compra. |
| Aprovisionamiento empresarial (el agente compra a proveedores aprobados con reglas) | Descubrimiento A2A dentro de la red de socios | AP2 Intent Mandate (obligatorio para auditoría) | ACP o UCP para proveedores con catálogo; API directa para compras de servicio | Sesiones MPP para recurrentes; ACP SPT vía rieles de tarjeta para pagos únicos | La trazabilidad de auditoría es la parte que no puedes omitir. Los mandatos AP2 son obligatorios. |
| Marketplace multi-agente (el agente contrata a otros agentes) | A2A o un directorio de agentes | Mandato AP2 más una verificación de reputación ERC-8004 | Ninguno: directo agente a agente | x402 (el más común), o MPP si Stripe ya está conectado | La confianza fluye en ambas direcciones. Cada parte necesita identidad verificable y prueba de pago. |
La regla de composición. Elige el protocolo en cada capa que el caso de uso exige. No agregues protocolos en capas que el caso de uso nunca toca. Un agente puramente pagador de API no necesita ACP. Un agente de compras de consumidor no debería usar x402 en una camiseta de $50, porque la cobertura de contracargo en tarjetas vale la comisión del 2.9%.
La trampa. Algunos equipos intentan conectar ACP, AP2, x402 y MPP todos a la vez "para mayor flexibilidad." Obtienes cuatro veces la superficie de integración y ninguna respuesta clara a "¿qué protocolo se activa cuándo?" Elige un stack. Publícalo. Añade un segundo stack solo cuando un segundo caso de uso lo exija.
Conclusión del Concepto 12: El stack mínimo viable es el conjunto de protocolos más pequeño que genera valor para un caso de uso. Cuatro stacks comunes cubren la mayoría. Las compras de consumidor son ACP más rieles de tarjeta. Los pagos de API son x402 solo. El aprovisionamiento empresarial es AP2 más ACP o UCP más MPP o tarjetas. Un marketplace multi-agente es AP2 más ERC-8004 más x402. No construyas un stack universal; elige una composición por caso de uso y publícala.
Concepto 13: Cuándo los protocolos se componen entre capas y compiten dentro de una
En una línea: Los protocolos en capas distintas están diseñados para apilarse juntos; los protocolos en la misma capa están diseñados para reemplazarse mutuamente, así que la única pregunta es si dos protocolos se ubican en la misma capa.
Dos protocolos se relacionan de una de dos maneras. O bien se componen, porque están en capas distintas y fueron diseñados para apilarse, o bien compiten, porque están en la misma capa y fueron diseñados para sustituirse. La mayor parte de la confusión arquitectónica proviene de leer el segundo caso como el primero.
Entre capas, diseñados para componerse:
| Composición | Mapeo de capas | Dónde se implementa |
|---|---|---|
| AP2 + ACP | AP2 en Capa 2 (autenticación de grado auditoria), ACP en Capa 3 (comercio) | Sectores regulados donde el flujo normal de ACP necesita auditoría extra |
| AP2 + x402 | AP2 en Capa 2 (autenticación de mandato), x402 en Capa 4 (liquidación en stablecoin) | Flujos nativos de cripto que aún necesitan auditoría, vía la extensión a2a-x402 |
| ACP + x402 | ACP en Capa 3 (comercio), x402 en Capa 4 para subflujos máquina a máquina dentro de una compra de consumidor | Plataformas híbridas donde una compra de consumidor incluye gasto de API |
MCP + x402 (vía withX402Client) | MCP en Capa 1 (descubrimiento), x402 en Capa 4 (liquidación) | El patrón estándar de Cloudflare para herramientas MCP de pago |
Dentro de una capa, diseñados para competir:
| Competencia | Capa | Cuándo gana cada uno |
|---|---|---|
| AP2 vs. ACP SPT vs. TAP | Capa 2 | AP2 para flujos de grado auditoría; ACP SPT para flujos de consumidor conectados a Stripe; TAP para verificaciones solo de identidad |
| ACP vs. UCP | Capa 3 | ACP para alcance en ChatGPT; UCP para alcance en Gemini; ambos para vendedores multi-superficie |
| x402 vs. MPP | Capa 4 | x402 para micropagos únicos y flujos puros de stablecoin; MPP para sesiones, suscripciones y flujos multi-riel |
La prueba. Cuando estés indeciso entre dos protocolos, pregúntate una cosa: ¿están en la misma capa? Si sí, eliges uno, o pagas por admitir ambos para distintos subflujos. Si no, probablemente se componen, y el diseño correcto a menudo usa los dos.
Una composición trabajada: el stack AP2 + x402. Este es el patrón nativo de cripto, común hoy en flujos B2B y agente a agente:
Layer 1 (Discovery): A2A directory inside the partner network
Layer 2 (Auth): AP2 Intent + Cart + Payment Mandates
Layer 3 (Commerce): Often none (direct service request), or ACP for a catalog
Layer 4 (Settlement): x402 via the a2a-x402 extension
El ensamblado del SDK simplemente compone las herramientas por protocolo de la Parte 3. Estas herramientas (a2a_discover_partners, ap2_create_intent_mandate y el resto) están definidas en los Conceptos 8 al 11; aquí solo las conectas a un agente.
agent = Agent(
name="EnterpriseB2BAgent",
instructions="...",
tools=[
# Layer 1: Discovery
a2a_discover_partners,
# Layer 2: Authorization
ap2_create_intent_mandate,
ap2_create_cart_mandate,
# Layer 4: Settlement (a2a-x402 composes Layers 2 and 4)
ap2_settle_via_x402,
],
model="gpt-5.5",
# No commerce tools: direct B2B procurement.
)
Conclusión del Concepto 13: Los protocolos en capas distintas se componen: AP2 más x402, ACP más x402, MCP más x402. Los protocolos en la misma capa compiten: AP2 frente a ACP SPT, ACP frente a UCP, x402 frente a MPP. La prueba es "¿están estos en la misma capa?" Si sí, elige uno. Si no, probablemente se componen. El stack AP2 más x402 es la composición B2B nativa de cripto estándar.
Concepto 14: Costo y latencia, qué fuerza la elección
En una línea: El tamaño de la transacción y la espera que puedes aceptar deciden el protocolo de liquidación, porque las comisiones de tarjeta destruyen los pagos pequeños y los procesos de pago lentos rompen los bucles ajustados.
Toda composición tiene un precio y una velocidad. Un flujo de compras de consumidor con ACP más rieles de tarjeta cuesta aproximadamente 2.9% + $0.30 por transacción y tarda de 5 a 30 segundos de extremo a extremo. Un agente pagador de API con x402 cuesta menos de un centavo y tarda de 1 a 2 segundos. La composición correcta está determinada en parte por el costo y la espera que tu caso de uso puede absorber.
Costo por transacción según la composición.
| Composición | Costo típico por transacción | Latencia típica |
|---|---|---|
| ACP + rieles de tarjeta (compras de consumidor) | 2.9% + $0.30 (tarifa de Stripe) | 5 a 30 segundos |
| ACP + sesiones MPP (suscripciones) | 2.9% en tarjetas, o aproximadamente 0.5% en stablecoin Tempo, por sesión | 1 a 3 segundos por llamada medida |
| AP2 + x402 (stablecoin B2B) | Gas por debajo de un centavo, sin comisiones de protocolo | 2 a 5 segundos (la firma del mandato agrega 1 a 3) |
| Solo x402 (agente pagador de API) | Gas por debajo de un centavo, sin comisiones de protocolo | 1 a 2 segundos |
| Solo sesiones MPP (API recurrente) | Casi cero en stablecoin Tempo; tarifa de Stripe en tarjetas | 50 a 500 ms por llamada medida dentro de una sesión activa |
Qué fuerza el dinero. Las comisiones superiores a aproximadamente el 5% de la transacción son un problema. Una llamada de API de $0.05 que paga 2.9% + $0.30 en comisiones de tarjeta cuesta más en comisiones que el valor de la llamada, lo cual es una señal clara de usar x402 o stablecoin MPP en su lugar. Una camiseta de $50 que paga el mismo 2.9% + $0.30 está bien. El umbral en dólares donde los rieles de tarjeta dejan de tener sentido es alrededor de $5 a $10. Por debajo de eso, los rieles de pago entre máquinas ganan; por encima, la cobertura de contracargo en tarjetas suele valer la comisión.
Qué fuerza la latencia. Una espera superior a 5 segundos por paso visible al usuario es un problema. La firma de mandatos AP2 puede agregar 1 a 3 segundos, mucho más si espera una firma humana; el proceso de pago de ACP agrega de 5 a 30. Para flujos agente a agente sin intervención humana, el presupuesto es aún más ajustado, a menudo por debajo del segundo, lo que convierte a x402 en Base y MPP en Tempo en las opciones predeterminadas.
El árbol de decisión, condensado.
What is the transaction value?
├── Sub-dollar (per-call API, per-token billing)
│ → x402 only, or MPP sessions
├── $1 to $10 (small, low-stakes buys)
│ → x402 or MPP, with AP2 audit if you need it
├── $10 to $1,000 (consumer purchases)
│ → ACP + card rails (chargeback cover is worth the fee)
└── $1,000+ (B2B, enterprise procurement)
→ AP2 + ACP/UCP + MPP sessions, or bank rails
What is the latency budget?
├── Sub-second (multi-agent loops)
│ → MPP sessions on Tempo, or x402 on Base
├── 1 to 5 seconds (interactive)
│ → x402 or MPP; AP2 only if mandates are pre-signed
└── 5+ seconds (an acceptable user wait)
→ Full ACP checkout works
Conclusión del Concepto 14: Las elecciones de composición tienen costo y latencia reales. Los rieles de tarjeta cuestan 2.9% + $0.30 pero te dan cobertura de contracargo; los rieles de stablecoin cuestan menos de un centavo pero necesitan integración cripto nativa. Los rieles de tarjeta dejan de tener sentido alrededor de $5 a $10 por transacción. El proceso de pago de ACP se vuelve demasiado lento alrededor de 5 segundos para flujos visibles al usuario. Deja que el costo y la latencia fuercen la composición, no el gusto.
Parte 5: El laboratorio de decisiones, cinco ejemplos resueltos
Las partes 2 a 4 te dieron el marco de trabajo: cuatro capas, algunos protocolos por capa y composición entre capas. La parte 5 recorre cinco decisiones reales. Cada una muestra el razonamiento completo: qué capas toca el caso de uso, qué protocolo en cada capa, por qué y cómo es el código del agente.

Lee una fila completa para ver el stack completo de un caso de uso. Lee una columna hacia abajo para ver qué cambia en una capa a medida que cambia el caso de uso. Las cinco decisiones a continuación recorren las filas en detalle. Las primeras cuatro cubren la matriz; la quinta reconstruye una de ellas en un conjunto de herramientas completamente diferente para demostrar que el marco no está atado a ningún proveedor específico.
Decisión 1: Agente de compras para consumidor (el patrón ChatGPT Instant Checkout)
El caso de uso. Estás construyendo un agente que ayuda a las personas a comprar en comercios habilitados con ACP como Walmart, Etsy y vendedores de Shopify. El usuario describe lo que quiere; el agente busca en catálogos, muestra opciones y finaliza la compra al confirmar. Un comprador a un comercio, de $5 a $500 por pedido, con devoluciones y contracargos requeridos.
Recorriendo las cuatro capas.
- Capa 1 (Descubrimiento). El agente tiene que encontrar productos en muchos comercios. Podrías integrar el catálogo MCP de cada comercio, o usar la superficie de compras de ChatGPT que ya agrega comercios ACP. Elección: la superficie de compras con IA, porque el trabajo de descubrimiento ya está hecho y conectar un millón de catálogos tú mismo no es viable.
- Capa 2 (Autorización). El usuario está autenticado en la superficie y confirma cada compra, por lo que la autorización es sencilla. Elección: ACP SPT, generado por Stripe por compra, limitado a un comercio, un monto y una ventana de 10 minutos.
- Capa 3 (Comercio). El ciclo de vida completo importa: carrito, pago, cumplimiento, disputas y devoluciones. Elección: ACP, el protocolo diseñado exactamente para esto.
- Capa 4 (Liquidación). Los valores de $5 a $500 están justo en el punto ideal de los rieles de tarjeta, y la cobertura de contracargos vale la tarifa. Elección: rieles de tarjeta vía Stripe, el riel que ACP asume por defecto.
La implementación. Este es el código del Concepto 8; las herramientas provienen del Concepto 8.
shopping_agent = Agent(
name="ShoppingAgent",
instructions="""Help the user shop. Workflow:
1. Use acp_browse_merchant to find products matching the request
2. Show matched items; wait for the user to confirm
3. On confirm, use acp_create_cart_and_checkout to buy
4. Use acp_check_order for status
5. Use acp_refund only when the user asks""",
tools=[acp_browse_merchant, acp_create_cart_and_checkout, acp_check_order, acp_refund],
model="gpt-5.5",
)
El fallo más probable en producción. Discrepancias en el carrito: el agente construye un carrito que no coincide con la solicitud ("pedí rojo, llegó rosa"). Solución: requiere que el usuario confirme el carrito antes de que se genere el SPT, registra la precisión del carrito y ajusta las instrucciones cuando la precisión baja del 95%.
Ejecutarlo de forma duradera (Inngest). Usa el patrón step.wait_for_event del Concepto 8 para el punto de confirmación del carrito, más un límite de concurrencia por usuario.
Elige este primero. Este es el caso de uso activo hoy: ChatGPT Instant Checkout, el ecosistema ACP, cada comercio de Shopify con ACP habilitado. Si solo puedes poner en producción una composición, pon esta.
Decisión 2: Agente de investigación que paga por API (el patrón solo x402)
El caso de uso. Estás construyendo un agente de investigación que paga a APIs de terceros por datos: feeds financieros, noticias, búsqueda especializada. Descubre APIs de pago en tiempo de ejecución a través de un directorio como Agent.market, evalúa el costo frente al valor y paga por llamada. Micropagos de alta frecuencia de $0.001 a $0.50, sin intervención humana una vez iniciada la tarea, sin ciclo de vida de comercio.
Recorriendo las cuatro capas.
- Capa 1 (Descubrimiento). Agent.market y directorios similares protegidos por x402 permiten que el agente encuentre servicios en tiempo de ejecución; los servidores MCP con soporte x402 manejan los preintegrados. Elección: Agent.market más MCP-vía-Cloudflare, descubrimiento en tiempo de ejecución con un conjunto de respaldo preconfigurado.
- Capas 2 y 4 (Autorización y Liquidación, combinadas). Sin intervención humana después de iniciar la tarea. Los límites en cadena de la billetera acotan el gasto por transacción; los límites a nivel de usuario se aplican mediante un
tool_input_guardraildel SDK en cada herramienta de pago. La firma EIP-3009 es tanto la autorización como la liquidación. Elección: x402 en Base (USDC), sin protocolo de mandato separado. - Capa 3 (Comercio). La "compra" es simplemente una llamada a la API. Elección: ninguna, acceso directo a la API vía x402.
La implementación. Este es el código del Concepto 10; las herramientas provienen del Concepto 10.
research_agent = Agent(
name="ResearchAgent",
instructions="""Research the user's query by paying for data via x402.
1. Use x402_search_agent_market to find relevant paid services
2. Use x402_fetch to pull data (max $0.10 per call)
3. Write up the findings
Stay under $10 per session.""",
tools=[x402_fetch, x402_search_agent_market],
mcp_servers=[research_mcp_with_payments],
model="gpt-5.5",
# Spend caps live on x402_fetch via tool_input_guardrails
# (Concept 10's enforce_x402_session_cap), not on the agent.
)
El fallo más probable en producción. Gasto descontrolado por un bucle atascado: el agente vuelve a obtener los mismos datos y consume el presupuesto. Solución: los límites en cadena de la billetera (la protección que realmente te protege), los controles de gasto de sesión del SDK y una caché de deduplicación para que las mismas solicitudes no vuelvan a pagar.
Ejecutarlo de forma duradera (Inngest). La memoización de step.run es útil aquí. Si hay un fallo a mitad de la sesión, el reintento se reanuda con los datos ya pagados intactos. Un límite de concurrencia por usuario evita que una ráfaga acapare todo.
Máquina a máquina puro. Las capas 2 y 4 se combinan en una sola firma, y la capa 3 queda vacía. Este stack es estructuralmente más simple que la Decisión 1: menos protocolos, menos puntos de integración, menor costo por llamada. El intercambio es que no hay cobertura de contracargos ni semántica de comercio, lo cual está bien porque el caso de uso no necesita ninguna de las dos.
Decisión 3: Agente de adquisiciones empresariales (el patrón AP2 más stack compuesto)
El caso de uso. Estás construyendo un agente de adquisiciones para una empresa regulada en servicios financieros. Los compradores delegan tareas: "compra 50 teclados ergonómicos de nuestros proveedores aprobados, por menos de $5,000, antes del viernes." El registro de auditoría es legalmente obligatorio, los límites de gasto operan en varios niveles y los proveedores están preaprobados, por lo que no hay descubrimiento en tiempo de ejecución.
Recorriendo las cuatro capas.
- Capa 1 (Descubrimiento). La lista de proveedores se conoce de antemano. Elección: un servidor MCP interno con catálogos de proveedores, porque el alcance del descubrimiento está acotado.
- Capa 2 (Autorización). Un registro de auditoría no repudiable es la parte que no puedes saltarte; un registro no repudiable es aquel que el firmante no puede negar posteriormente. Los mandatos AP2 proporcionan exactamente eso. Elección: AP2, con un Mandato de Intención en la creación de la tarea, un Mandato de Carrito antes del pago y un Mandato de Pago en la liquidación, cada uno firmado por el responsable de adquisiciones.
- Capa 3 (Comercio). Los proveedores grandes exponen ACP o UCP; los más pequeños exponen APIs B2B directas. Elección: ACP para proveedores habilitados con ACP, API directa para el resto; el agente maneja ambos.
- Capa 4 (Liquidación). Los proveedores recurrentes prefieren sesiones MPP; las compras únicas prefieren rieles de tarjeta para cobertura de contracargos en valores más altos. Elección: sesiones MPP para recurrentes, ACP SPT más rieles de tarjeta para compras únicas, seleccionado según el historial del proveedor.
La implementación. Este compone las herramientas de los Conceptos 8, 9 y 11.
procurement_agent = Agent(
name="ProcurementAgent",
instructions="""Run procurement under audit-grade compliance:
1. ALWAYS create an Intent Mandate first via ap2_create_intent_mandate
2. Search approved suppliers via the internal MCP server
3. Build the cart and create a Cart Mandate via ap2_create_cart_mandate
4. Recurring suppliers: use an MPP session.
One-off buys: use ACP plus card rails via ap2_settle_via_acp
5. Record every mandate ID in the procurement audit log""",
mcp_servers=[approved_suppliers_mcp],
tools=[
ap2_create_intent_mandate,
ap2_create_cart_mandate,
ap2_settle_via_acp,
mpp_create_session,
mpp_metered_call,
mpp_close_session,
],
model="gpt-5.5",
# Caps and mandate rules run via tool_input_guardrails on the paying tools
# (Concepts 9, 11, 15). require_intent_mandate on ap2_create_cart_mandate blocks
# any cart with no prior Intent Mandate; enforce_per_run_spend_cap blocks any
# payment over the user's run cap.
)
El fallo más probable en producción. Discrepancias en el alcance del Mandato de Intención: el responsable firma un mandato, el agente hace el trabajo y luego el carrito no encaja en el mandato. Solución: valida el alcance del mandato antes de que el agente comience a buscar (la instrucción "crear Mandatos de Intención primero" del Concepto 9) y rechaza las tareas cuyo alcance supere lo que el usuario puede autorizar.
Ejecutarlo de forma duradera (Inngest). La firma de mandatos AP2 es el ajuste natural para step.wait_for_event. Las tareas de múltiples etapas usan step.run por etapa, con un límite de concurrencia por usuario.
Industria regulada. Las reglas de auditoría obligan a usar AP2 en la capa 2; muchos proveedores obligan a usar ACP y APIs directas juntas en la capa 3; los proveedores recurrentes frente a los de una sola vez obligan a usar MPP y tarjetas juntas en la capa 4. Esta composición es más pesada que las Decisiones 1 y 2, y el requisito de auditoría es lo que justifica ese peso.
Decisión 4: Marketplace multi-agente (el patrón AP2 más x402 más ERC-8004)
El caso de uso. Estás construyendo una plataforma donde los agentes contratan a otros agentes. El agente A necesita investigación; el agente B vende investigación como un servicio x402. Ninguno confía en el otro todavía, las transacciones deben ser verificables y el pago es puramente nativo en cripto, sin tarjetas. Agente a agente, de $0.10 a $100 por transacción; ambos lados necesitan identidad verificable.
Recorriendo las cuatro capas.
- Capa 1 (Descubrimiento). El agente B publica su capacidad mediante A2A; el agente A la encuentra. Elección: A2A, el protocolo diseñado para esto.
- Capa 2 (Autorización). No hay un humano al momento de la transacción, pero la confianza debe ser verificable en ambos sentidos. AP2 exige demostrar el consentimiento del usuario; ERC-8004 le da al agente B una reputación en cadena que el agente A puede consultar primero. Elección: AP2 más ERC-8004, compuestos para verificación bilateral completa.
- Capa 3 (Comercio). Sin carritos, sin reembolsos, solo "realiza esta tarea y entrega el informe". Elección: ninguna, solicitud y respuesta directas por A2A.
- Capa 4 (Liquidación). Nativo en cripto, en fracciones de segundo, sin necesidad de cobertura ante contracargos. Elección: x402 a través de la extensión
a2a-x402para AP2.
La implementación. Esta composición combina las herramientas de los Conceptos 9 y 10 con el descubrimiento A2A.
researcher_hiring_agent = Agent(
name="ResearcherHiringAgent",
instructions="""Hire research-specialist agents to work for you:
1. Use a2a_discover_researchers to find available agents
2. Check ERC-8004 reputation (>50 successful jobs, no flagged disputes)
3. Create an Intent Mandate scoped by amount and recipient
4. Submit the task via A2A with the mandate attached
5. Receive the result; settle via ap2_settle_via_x402""",
tools=[
a2a_discover_researchers,
erc8004_check_reputation,
ap2_create_intent_mandate,
a2a_submit_task_with_mandate,
ap2_settle_via_x402,
],
model="gpt-5.5",
)
El fallo más probable en producción. Confiar en una reputación que ha sido manipulada: los puntajes de ERC-8004 son auditables, pero un operador puede inflarlos con trabajos exitosos de bajo valor. Solución: combinar la reputación con otras señales (identidad del operador, umbrales de volumen de transacciones, historial de disputas) y agregar revisión humana por encima de un monto definido para contrapartes nuevas.
Ejecutarlo de forma durable (Inngest). Distribuye el trabajo en abanico al contratar varios especialistas a la vez; usa step.wait_for_event para cada resultado y step.run por etapa. Esta decisión toca todos los primitivos de Inngest.
Economía multi-agente pura. No hay humano en el ciclo al momento de la transacción; ambos agentes actúan dentro de los alcances preautorizados. Esta es la forma en que se está construyendo la economía de agentes, y tiene la mayor cantidad de modos de fallo, porque la confianza bilateral sin una relación previa es difícil y la pila de protocolos solo la resuelve en parte.
Decisión 5: Una pila sin Stripe ni OpenAI (demostrando que el marco es portable)
Cada ejemplo de código hasta ahora usó stripe.PaymentTokens.create(...) y el OpenAI Agents SDK. Estas son las integraciones más maduras para ACP, y el SDK es el entorno de ejecución de este curso, pero la arquitectura de cuatro capas es agnóstica respecto a la pila por diseño, y un curso que solo muestra una pila no ha demostrado eso. Por eso, esta decisión reconstruye la Decisión 2, el agente de investigación que paga por API, sobre una cadena de herramientas completamente diferente: el Agent Development Kit (ADK) de Google para el entorno de ejecución, una billetera de contrato inteligente de Coinbase para identidad en cadena, mandatos AP2 para autorización y x402 directo para liquidación. Sin Stripe, sin OpenAI.
El caso de uso sigue siendo el de la Decisión 2. Un agente de investigación que paga de $0.001 a $0.10 por llamada, con un límite de $10 por sesión. Por debajo del dólar, sin intervención humana tras la autorización, liquidación de máquina a máquina. La arquitectura también sigue siendo la de la Decisión 2: x402 colapsa las capas 2 y 4, sin capa de comercio, MCP para descubrimiento. Solo cambia la biblioteca.
El bloque a continuación es ilustrativo. La estructura de Google ADK (
Agent, el decorador de herramienta) es real ygoogle-adkes un paquete real. Las piezas de pago son sustitutos: el paquete real de AP2 esap2con campos de mandato muy diferentes y sin claseMandateSigner; la billetera de Coinbase se configura a través decoinbase_agentkity suSmartWalletProvider; y una llamada x402 real necesita una cuenta con fondos y un endpoint real que devuelva 402. Aquí no se mueve dinero real. Lo que importa es la forma, no un comprador ejecutable.
from google.adk import Agent
from google.adk.tools import function_tool # ADK's tool decorator
from coinbase_agentkit import AgentKit, SmartWalletProvider
from decimal import Decimal
from datetime import datetime, timedelta
# Shared result models come from the Pydantic sidebar in Part 3.
from .models import X402PaymentResult, PaymentToolResult, DiscoveryResult
# --- Illustrative stand-ins for the payment rails (real APIs differ) ---
class MockMandate:
def __init__(self, mid, rules=None): self.id, self.rules = mid, (rules or {})
class MockSigner:
async def sign(self, mandate): return mandate # real AP2 signs over A2A
agent_market_client = type("Mock", (), {"search": staticmethod(lambda **k: [])})()
x402_client = type("Mock", (), {})() # real client: x402-client
# -----------------------------------------------------------------------
# Layer 2 (Authorization): a Coinbase smart-contract wallet gives the agent its
# on-chain identity and its spend caps. This is the analog of a Stripe customer
# plus per-customer caps, but enforced by the chain.
wallet_provider = SmartWalletProvider(
config={
"chain": "base-mainnet",
"spend_limits": {
"per_transaction_usdc": Decimal("0.50"),
"per_session_usdc": Decimal("10.00"),
"per_day_usdc": Decimal("100.00"),
},
},
)
agent_kit = AgentKit(wallet_provider=wallet_provider)
# Layer 2 (Authorization): an AP2 Intent Mandate, signed by the user at session start.
# The analog of a signed, revocable Stripe authorization, but declarative.
async def create_research_intent_mandate(user_did, user_signer, session_cap_usdc):
mandate = MockMandate(
"intent_mock_1",
rules={
"max_total_usd": str(session_cap_usdc),
"allowed_categories": ["data-api", "research-service"],
"expires_at": (datetime.utcnow() + timedelta(hours=1)).isoformat(),
},
)
return await user_signer.sign(mandate)
# Layer 1 (Discovery) + Layer 4 (Settlement) as one tool.
# ADK's @function_tool is the analog of the SDK's @function_tool.
@function_tool
async def x402_paid_fetch(url: str, max_payment_usdc: Decimal) -> X402PaymentResult | PaymentToolResult:
"""Fetch a URL that may need x402 payment up to max_payment_usdc.
The wallet handles the signature; the on-chain cap is the safety that protects you."""
# ADK has no tool_input_guardrail, so the check runs in-tool,
# backed by the wallet's on-chain cap (the layer nothing can bypass).
resp = await x402_client.get(url, max_payment_usdc=max_payment_usdc)
return X402PaymentResult(
content=resp.content,
amount_paid_usdc=Decimal(str(resp.amount_paid_usdc)),
tx_hash=resp.tx_hash,
)
@function_tool
async def search_agent_directory(query: str, max_price_per_call_usdc: Decimal) -> list[DiscoveryResult]:
"""Search Agent.market for x402-paywalled services."""
results = await agent_market_client.search(query=query, max_price_per_call_usdc=max_price_per_call_usdc)
return [
DiscoveryResult(
service_id=r.service_id,
name=r.name,
description=r.description,
price_per_call_usdc=Decimal(str(r.price_per_call_usdc)),
endpoint_url=r.endpoint_url,
)
for r in results
]
# The agent itself: a Google ADK Agent, the direct analog of the SDK's Agent.
research_agent = Agent(
name="research-agent",
description="Research the user's query by paying for data via x402.",
instructions="""Research the query.
1. Use search_agent_directory to find relevant paid services
2. Use x402_paid_fetch to pull data ($0.50 max per call)
3. Write up the findings
Stay under $10 per session.""",
model="deepseek-v4-flash", # illustrative; any ADK-compatible model id works
tools=[search_agent_directory, x402_paid_fetch],
)
# Driver: the user signs the Intent Mandate once at session start;
# the agent then runs on its own inside the mandate's scope until the session ends.
async def run_research_session(user_did, user_signer, query):
intent = await create_research_intent_mandate(
user_did=user_did,
user_signer=user_signer,
session_cap_usdc=Decimal("10.00"),
)
return await research_agent.run_async(
query,
context={"intent_mandate": intent, "wallet": agent_kit},
)
La traducción línea por línea. El código de la Decisión 2 con OpenAI más Stripe a la izquierda; el código de la Decisión 5 con Google ADK más Coinbase a la derecha. Esta tabla es la recompensa: cada fila es el mismo concepto bajo un nombre diferente.
| Decisión 2 (OpenAI + Stripe) | Decisión 5 (Google ADK + Coinbase) | El mismo concepto, distinta biblioteca |
|---|---|---|
from agents import Agent, function_tool | from google.adk import Agent + from google.adk.tools import function_tool | Entorno de ejecución del agente |
@function_tool (OpenAI Agents SDK) | @function_tool (Google ADK) | Decorador de herramienta |
RunContextWrapper | argumento context={...} en run_async | Estado por ejecución |
stripe.Customer.modify(...) para límites | SmartWalletProvider(spend_limits={...}) | Límites de gasto, nativos en cadena |
Decorador tool_input_guardrail | verificación en la herramienta + límites de la billetera | Validación previa a la ejecución |
Runner.run(agent, ...) | agent.run_async(...) | Ejecución del agente |
Lo que se mantiene idéntico. La arquitectura: la capa 1 es MCP o un directorio; la capa 2 es un mandato más límites de la billetera; la capa 3 es ninguna (la comunicación de máquina a máquina colapsa el comercio); la capa 4 es x402. Los primitivos: Intent Mandate, firmas EIP-3009, respuestas 402, encabezados de firma de pago, límites de gasto en cadena. El marco es lo que sobrevive al cambio de biblioteca.
Dos diferencias operativas reales.
- Google ADK no tiene una guardarrail de entrada de herramienta de primera clase (a mediados de 2026). El
tool_input_guardraildel SDK es genuinamente útil para verificaciones previas a la ejecución; el decorador de herramienta de ADK aún no tiene un equivalente directo. La solución alternativa es la validación dentro de la herramienta, respaldada por los límites en cadena de la billetera. Los límites siguen protegiéndote; la verificación interna simplemente falla más rápido. Si eliges ADK, cambias la comodidad del guardarrail por una propuesta diferente en multi-agente. - La firma de mandatos AP2 es más nativa aquí. Google construyó AP2, por lo que el ecosistema ADK integra los flujos de interfaz de firma de mandatos de forma más limpia. Si tu caso de uso depende fuertemente de la autorización rigurosa por mandato (Decisiones 3 y 4), ADK más AP2 es una opción real, no solo una alternativa.
Conclusión de la Decisión 5: La arquitectura de cuatro capas no es, en el fondo, una historia de Stripe y OpenAI. Descubrimiento, Autorización, Comercio, Liquidación: elige un protocolo por capa, justifícalo según el caso de uso; eso sobrevive a cualquier cambio de biblioteca. La Decisión 5 usó Google ADK y una billetera de Coinbase para construir exactamente la misma composición que la Decisión 2; solo cambiaron las importaciones. Si un marco no puede expresarse en una pila diferente, es un tutorial de biblioteca disfrazado de marco. Este no lo es.
Parte 6: Consideraciones de producción: qué te destruye cuando el sistema sale a producción
Las partes 1 a 5 construyeron el framework y recorrieron decisiones reales. La parte 6 cubre los factores que determinan si tu stack sobrevive a usuarios reales. Estos son los fallos que no aparecen en una demo y sí aparecen a las 2 a.m.
Si lees para entender, no para desplegar, puedes hojear la parte 6. Si estás construyendo algo de esto en serio, aquí es donde las cosas se ponen serias. Los cuatro conceptos de aquí son la diferencia entre un sistema que funciona y uno que vacía una billetera.
Concepto 15: Aplicación de límites de gasto en tres niveles arquitectónicos
En una línea: Evita que un agente gaste de más aplicando el límite en tres lugares independientes, de modo que un error en uno sea detectado por los otros dos.
La forma más común en que un sistema de comercio con agentes falla gravemente es simple: el agente gasta más de lo que se le permitía. Un bucle de agente atascado puede vaciar una billetera en segundos. Cada protocolo tiene su propio límite (el monto SPT de ACP, el límite de sesión de MPP, el máximo por solicitud de x402), pero ninguno de ellos es suficiente por sí solo. Los sistemas de producción aplican límites de gasto en tres niveles separados.
Nivel 1: límites de la billetera y del método de pago. Este es el límite que realmente te protege. La billetera de contrato inteligente del agente (para x402) o su cuenta de cliente de Stripe (para ACP y MPP) lleva límites de gasto configurados a nivel de infraestructura. La cadena o Stripe los aplica sin importar lo que haga el código del agente. Este es el único nivel que se sostiene cuando el bucle del agente falla por completo.
Para x402 con una billetera de contrato inteligente:
La llamada
SmartContractWallet.deploy(...)de abajo es ilustrativa. Muestra dónde viven los límites del Nivel 1, no es un paquete pip real. En la práctica, configuras estos límites en una billetera de contrato inteligente real (por ejemplo, a través delSmartWalletProviderde Coinbase AgentKit). La disciplina de los tres niveles es la lección real.
from decimal import Decimal
# Set ONCE when the wallet is deployed. The agent cannot change this.
wallet_spend_limits = {
"max_per_transaction_usdc": Decimal("10.00"), # cap per single transfer
"max_per_day_usdc": Decimal("100.00"), # rolling 24-hour cap
"max_per_merchant_usdc": Decimal("50.00"), # cap to any single recipient
}
agent_wallet = SmartContractWallet.deploy(
owner=user_did,
spend_limits=wallet_spend_limits,
chain="eip155:8453", # Base
)
Para ACP o MPP con Stripe, el límite vive en el cliente de Stripe:
stripe.Customer.modify(...)es una llamada real a la API de Stripe. Se ejecuta contra tu cuenta de Stripe.
# Set once via the Stripe Dashboard or API. The caps live in Stripe's infrastructure.
stripe.Customer.modify(
user_session.stripe_customer_id,
metadata={
"max_per_session_usd": "500",
"max_per_day_usd": "2000",
},
)
# When an SPT or MPP session is minted above these, Stripe rejects it at the API level.
Nivel 2: salvaguardas de herramientas del SDK. El tool_input_guardrail del SDK de Agentes de OpenAI se ejecuta antes de que cada herramienta de pago se ejecute y puede rechazar la llamada. Ya lo viste en el Concepto 5: es la forma nativa del SDK de detener un pago antes de que ocurra, y la familia que actúa a tiempo. Aquí se le da el tratamiento completo, porque este es el bloque de salvaguarda canónico para todo el curso. El código de abajo es real y funciona.
import json
from decimal import Decimal
from agents import Agent, function_tool, RunContextWrapper
from agents.tool_guardrails import (
tool_input_guardrail,
tool_output_guardrail,
ToolInputGuardrailData,
ToolOutputGuardrailData,
ToolGuardrailFunctionOutput,
)
# Tool INPUT guardrail: pre-payment check. Runs BEFORE the tool executes.
@tool_input_guardrail
def enforce_per_run_spend_cap(data: ToolInputGuardrailData) -> ToolGuardrailFunctionOutput:
"""Reject any payment tool call where the run's total spend would exceed the user's cap.
Runs before the tool executes, the only guardrail family that can stop a payment in time."""
args = json.loads(data.context.tool_arguments or "{}") # raw JSON args string -> dict
requested = Decimal(str(args.get("max_total_usd") or args.get("max_payment_usdc") or 0))
ctx = data.context.context # the run context (a dict)
cap = Decimal(str(ctx["user_session"].per_run_spend_cap_usd))
spent = Decimal(str(ctx.get("run_spend_usd", 0)))
if spent + requested > cap:
return ToolGuardrailFunctionOutput.reject_content(
f"Refused: would spend ${spent + requested}, run cap is ${cap}"
)
return ToolGuardrailFunctionOutput.allow()
# Tool OUTPUT guardrail: post-payment check. Runs AFTER the tool executes.
# Useful for verifying receipts (paid more than expected, wrong amount, etc.).
@tool_output_guardrail
def verify_receipt_integrity(data: ToolOutputGuardrailData) -> ToolGuardrailFunctionOutput:
output = data.output or {}
if isinstance(output, dict) and "amount_paid_usdc" in output:
# Cross-check the receipt against what we asked for.
pass
return ToolGuardrailFunctionOutput.allow()
# Attach BOTH guardrails to every payment-authorizing tool.
@function_tool(
tool_input_guardrails=[enforce_per_run_spend_cap],
tool_output_guardrails=[verify_receipt_integrity],
)
async def x402_fetch(
ctx: RunContextWrapper,
url: str,
max_payment_usdc: Decimal,
) -> "X402PaymentResult":
...
# An agent-level output_guardrail is fine for final-reply safety
# (like redacting PII in the agent's answer), but it does NOT prevent payments.
agent = Agent(
name="ShoppingAgent",
tools=[x402_fetch],
# output_guardrails=[response_safety_guardrail], # different job, not payment safety
)
El SDK tiene tres familias de salvaguardas. Las salvaguardas de entrada se ejecutan en el primer mensaje del usuario al agente. Las salvaguardas de salida se ejecutan en la respuesta final del agente. Las salvaguardas de herramientas (tool_input_guardrail y tool_output_guardrail) se ejecutan en cada llamada a una herramienta personalizada. Para la seguridad de pagos, necesitas tool_input_guardrail específicamente: es la única familia que se activa antes de que se ejecute una herramienta de pago y puede bloquearlo. Usar output_guardrail para controlar el gasto es el error más común en el código de comercio con agentes. Para cuando se activa, el dinero ya se fue.
Nivel 3: límites de la aplicación y de la lógica de negocio. Tu propio código aplica las reglas específicas del usuario: límites diarios por usuario, límites por categoría, comerciantes permitidos. Aquí es donde viven las reglas de negocio. "Este usuario puede gastar $500 al día en cualquier comerciante, pero solo $50 al día en comerciantes no verificados." Esa regla pertenece aquí, no en un protocolo. Este código es Python simple y real.
from decimal import Decimal
class UserSession:
def can_spend(self, amount_usd: Decimal, merchant_id: str) -> bool:
# Per-day cap
if self.today_spend_usd + amount_usd > self.daily_cap_usd:
return False
# Per-merchant cap
merchant_cap = self._merchant_cap_for(merchant_id)
if self.merchant_spend_usd[merchant_id] + amount_usd > merchant_cap:
return False
# Per-category cap (for example, "office supplies" vs "personal")
category = self._category_for(merchant_id)
if self.category_spend_usd[category] + amount_usd > self.category_caps[category]:
return False
return True
Cada nivel vive en una infraestructura diferente. El Nivel 1 está en la cadena o en Stripe. El Nivel 2 está en el SDK del agente. El Nivel 3 está en el código de tu aplicación. Un error en uno es detectado por los otros dos. Si omites el Nivel 1, un solo error en el bucle del agente puede vaciar toda la billetera. Si omites el Nivel 2, pierdes la capacidad de interrumpir una ejecución en curso. Si omites el Nivel 3, no puedes aplicar políticas por usuario o por categoría.
La trampa es confiar solo en los límites de protocolo. El límite SPT de ACP, el límite de sesión de MPP y el máximo por solicitud de x402 son límites a nivel de protocolo. Detienen abusos específicos del protocolo, pero no se acumulan entre protocolos. Un equipo que usa solo SPTs de ACP con un límite de $50 cada uno no tiene protección contra un agente que acuñe 100 de ellos seguidos, por un total de $5,000. Los tres niveles anteriores existen precisamente porque los límites de protocolo no se agregan.
Conclusión del Concepto 15: Aplica límites de gasto en tres niveles independientes: infraestructura de billetera o método de pago, salvaguardas de herramientas del SDK (
tool_input_guardrailespecíficamente, ya que se ejecuta antes de cada herramienta y puede bloquearla), y lógica de negocio de la aplicación. Cada nivel usa una infraestructura diferente, de modo que un error en uno es detectado por los demás. El error más común es usaroutput_guardraila nivel de agente para controlar el gasto: se ejecuta en la respuesta final, demasiado tarde, el pago ya ocurrió. Los límites a nivel de protocolo (SPT, sesión de MPP, solicitud de x402) son necesarios pero no suficientes; no se agregan entre protocolos ni entre ejecuciones. Los sistemas de producción aplican en los tres niveles.
Concepto 16: Higiene de identidad del agente: claves, billeteras y registros de auditoría
En una línea: La clave de firma del agente es lo único que separa el gasto autorizado del fraude, por lo que debes proteger la clave, separarla por agente, rotarla y registrar cada gasto en almacenamiento duradero.
El comercio con agentes introduce un fallo único en los sistemas autónomos: la identidad criptográfica del agente es todo lo que está entre el gasto real y el fraude. Si la clave de firma se filtra, la billetera (o el cliente de Stripe, o el firmante del mandato AP2) puede ser vaciada o suplantada hasta que rotes la clave. La higiene de identidad es el conjunto de hábitos que previene esto. Son cuatro.
1. Separación de billeteras por agente. Cada agente, o cada clase de agente, obtiene su propia billetera o identificador de pago. Nunca compartas claves de firma entre agentes con tareas diferentes. Si tu agente de compras y tu agente de adquisiciones comparten una billetera, el compromiso de cualquiera de los dos vacía ambas. Las billeteras separadas cuestan casi nada (un costo único de despliegue) y la ganancia en seguridad es real.
SmartContractWallet.deploy(...)es ilustrativo, como en el Concepto 15. El patrón es lo que importa: una billetera por clase de agente, nunca compartida.
# Wrong: one wallet shared across agents
shared_wallet = SmartContractWallet.deploy(...)
shopping_agent.wallet = shared_wallet
procurement_agent.wallet = shared_wallet
research_agent.wallet = shared_wallet # one compromise drains all three
# Right: a separate wallet per agent class
shopping_agent.wallet = SmartContractWallet.deploy(
spend_limits={"max_per_day_usdc": 100},
)
procurement_agent.wallet = SmartContractWallet.deploy(
spend_limits={"max_per_day_usdc": 1000, "allowed_recipients": [...]},
)
research_agent.wallet = SmartContractWallet.deploy(
spend_limits={"max_per_day_usdc": 50, "max_per_call_usdc": 0.50},
)
2. Rotación de claves, según un calendario y bajo demanda. Rota las claves de firma cada 90 días como línea base (siguiendo el consejo de Stripe para las claves de API). Rótalas de inmediato cuando un operador del agente abandone el equipo, cuando un despliegue toque la superficie de firma o cuando algo parezca incorrecto. El hábito de rotar importa más que el número exacto de días.
El patrón de abajo es real. El nombre del cliente
azure_key_vaultes ilustrativo; usa el SDK del almacén de tu proveedor. El punto es que la clave vive en un almacén y lees la versión actual en el momento de usarla.
# Read the current key version from the vault. The version changes when the key rotates.
def get_signing_key(agent_class: str) -> SigningKey:
return azure_key_vault.get_latest_version(
secret_name=f"agent-wallet-signing-key-{agent_class}",
)
# Old transactions, signed with the previous version, stay valid until they expire.
# New transactions use the current version.
3. Registros de auditoría que sobreviven a un fallo. Cada decisión de autorización se registra en almacenamiento duradero que vive separado del entorno de ejecución del agente: cada SPT acuñado, cada mandato firmado, cada firma x402, cada sesión MPP abierta. Si el agente falla, el registro de auditoría debe seguir estando ahí. Neon Postgres junto con la memoización de pasos de Inngest te da esto; también puedes escribir directamente en almacenamiento de objetos (S3 o equivalente) para máxima durabilidad.
El patrón de registro de auditoría es la enseñanza. El nombre del cliente
neon_clientes ilustrativo; usa tu propio cliente de base de datos. La regla es registrar la decisión antes de que ocurra el pago.
# Every payment-authorizing action logs to durable storage BEFORE the action completes.
@function_tool
async def acp_create_cart_and_checkout(
ctx: RunContextWrapper,
merchant_id: str,
items: list["CartItem"],
max_total_usd: Decimal,
) -> "CheckoutResult":
audit_id = str(uuid4())
# Log the authorization decision FIRST, before any payment happens.
await neon_client.audit_log.insert({
"audit_id": audit_id,
"agent_class": ctx.context["agent_class"],
"user_did": ctx.context["user_session"].did,
"action": "acp_create_cart_and_checkout",
"merchant_id": merchant_id,
"max_total_usd": max_total_usd,
"timestamp": datetime.utcnow().isoformat(),
"status": "initiated",
})
try:
result = await _actually_complete_checkout(merchant_id, items, max_total_usd)
await neon_client.audit_log.update(audit_id, {
"status": "completed",
"actual_total_usd": result.total_charged_usd,
"order_id": result.order_id,
})
return result
except Exception as e:
await neon_client.audit_log.update(audit_id, {"status": "failed", "error": str(e)})
raise
4. Trazas distribuidas a lo largo de toda la transacción. El registro de auditoría te dice qué tuvo éxito. Las trazas te dicen qué ocurrió, incluidas las llamadas que fallaron, reintentaron o se detuvieron. En el comercio con agentes, la traza completa es a menudo la única forma de depurar una transacción fallida, porque una sola solicitud de usuario puede ramificarse en una ejecución del SDK, de 5 a 10 llamadas a herramientas, de 2 a 3 solicitudes HTTP de protocolo, un webhook de Stripe que llega después y una función de Inngest que se reanuda horas más tarde. Sin un ID de traza que una todo eso, un análisis post mortem es imposible. El código de OpenTelemetry de abajo es la API real y estable de OTel.
from opentelemetry import trace
from opentelemetry.trace import Status, StatusCode
tracer = trace.get_tracer("agent-commerce")
@function_tool
async def acp_create_cart_and_checkout(
ctx: RunContextWrapper,
merchant_id: str,
items: list["CartItem"],
max_total_usd: Decimal,
) -> "CheckoutResult":
# The span name is the protocol action; attributes capture what you filter by
# in your observability tool (Datadog, Honeycomb, Grafana, and so on).
with tracer.start_as_current_span(
"acp.checkout",
attributes={
"agent.class": ctx.context["agent_class"],
"user.did": ctx.context["user_session"].did,
"acp.merchant_id": merchant_id,
"acp.max_total_usd": float(max_total_usd),
"acp.item_count": len(items),
},
) as span:
try:
result = await _actually_complete_checkout(merchant_id, items, max_total_usd)
span.set_attribute("acp.order_id", result.order_id)
span.set_attribute("acp.actual_total_usd", float(result.total_charged_usd))
span.set_status(Status(StatusCode.OK))
return result
except Exception as e:
span.set_status(Status(StatusCode.ERROR, str(e)))
span.record_exception(e)
raise
El contexto de la traza fluye automáticamente a través de httpx, openai-agents e Inngest con la instrumentación correcta. Cuando un webhook de Stripe llega 20 minutos después por una disputa sobre este pedido, el manejador del webhook se une a la misma traza a través del trace_id almacenado en los metadatos del pedido. Un ID de traza cubre toda la vida de la transacción, desde la primera solicitud hasta la resolución de la disputa.
Los registros de auditoría y las trazas responden preguntas diferentes, y necesitas ambas. Los registros de auditoría responden preguntas de negocio ("¿cuánto gastó este usuario el martes?"). Las trazas responden preguntas de depuración ("¿por qué falló el pago del pedido abc123?"). El registro de auditoría solo registra el camino exitoso; nunca captura la llamada que reintentó cinco veces antes de funcionar, ni la llamada de protocolo que se detuvo 30 segundos antes de agotar el tiempo. Esas formas de fallo solo aparecen en las trazas. Omitir las trazas porque tienes registros de auditoría es un error sobre para qué sirve cada herramienta.
El error de identidad más común es tratar la dirección de la billetera como la identidad del agente. La dirección es pública: cualquiera puede enviarle fondos y cualquiera puede verificar que una transacción provino de ella. La clave de firma privada es la identidad, y la proteges como tal. Los equipos que guardan las claves de firma en variables de entorno (o peor, en el código fuente) han entregado la identidad del agente a cualquiera que tenga acceso a esos secretos. Las claves van en un almacén, nunca en variables de entorno.
Conclusión del Concepto 16: La identidad del agente es criptográfica; la clave de firma es lo único que separa el gasto autorizado del fraude. Cuatro hábitos la protegen: separación de billeteras por agente, para que un compromiso no vacíe todos los agentes; rotación de claves según un calendario y bajo demanda (línea base de 90 días, inmediata ante un evento desencadenante); registros de auditoría en almacenamiento duradero separado del entorno de ejecución (Neon Postgres o almacenamiento de objetos); trazas distribuidas con un ID de traza que abarca toda la transacción (OpenTelemetry a través del SDK, httpx, Inngest y FastAPI). Las claves de firma van en un almacén de claves, nunca en variables de entorno ni en el código fuente. Los registros de auditoría responden preguntas de negocio; las trazas responden preguntas de depuración; necesitas ambas.
Concepto 17: Mecánicas de disputas y reembolsos en los cuatro protocolos
En una línea: Cada protocolo gestiona las disputas y los reembolsos de manera diferente, y el modelo de disputas que necesita tu caso de uso es con frecuencia el factor más determinante al decidir qué protocolos componer.
Los cuatro protocolos abordan las disputas y los reembolsos de manera distinta, y esa diferencia suele decidir la elección del protocolo para un caso de uso. Un caso de uso que necesita protección contra contracargos no puede funcionar sobre x402 puro. Un caso de uso en el que el vendedor no tiene soporte de atención al cliente no puede usar ACP. A continuación se explica cómo gestiona cada protocolo una disputa, de modo que puedas asociar el protocolo al modelo de disputas que realmente necesitas.
ACP: disputas a través de la red de tarjetas. Dado que el comerciante sigue siendo el comerciante de registro en ACP, todas las rutas estándar de disputas de la red de tarjetas funcionan. El banco del comprador inicia el contracargo; Stripe (o el procesador que corresponda) gestiona la defensa del comerciante; el comerciante sigue su política de reembolsos existente. Esta es la mayor ventaja práctica de ACP. Todas las expectativas de cualquier comprador minorista respecto a las devoluciones simplemente funcionan.
Para un reembolso de ACP, el agente inicia:
acp_client.refunds.create(...)es ilustrativo, como las demás llamadas al cliente ACP en este curso. El modelo de resultado y el cableado de la herramienta son reales.
@function_tool
async def acp_refund(
order_id: str,
reason: str,
amount_usd: Decimal | None = None,
) -> "RefundResult":
"""Start a refund through ACP. The merchant's standard refund policy applies."""
raw = await acp_client.refunds.create(
order_id=order_id,
reason=reason,
amount_usd=amount_usd, # None means full refund
)
return RefundResult(
refund_id=raw.refund_id,
order_id=order_id,
status=raw.status,
amount_refunded_usd=raw.amount_refunded_usd,
)
AP2: disputas resueltas mediante el rastro de auditoría. La contribución de AP2 a una disputa es la cadena de mandatos (Intent, luego Cart, luego Payment). Cuando surge una disputa, esa cadena es evidencia de lo que el usuario autorizó efectivamente, y tiene validez legal. No reemplaza la ruta de disputas del riel subyacente: si el mandato AP2 autorizó un pago con tarjeta a través de Stripe, el proceso de disputas de Stripe sigue aplicándose. AP2 añade la prueba de lo que el usuario acordó.
El flujo de disputa:
1. User claims: "I never authorized this purchase."
2. Merchant retrieves the signed AP2 Cart Mandate from the transaction record.
3. Merchant presents the Cart Mandate (with the user's signature) to the
payment processor as part of the dispute defense.
4. The card network or processor checks the signature against the user's
registered public key. If it is valid, the dispute is resolved for the merchant.
x402: sin mecanismo formal de disputas. Los pagos x402 puros no son reembolsables por diseño. El pago se liquida en cadena en uno o dos segundos; no existe contracargo. Esta es la mayor limitación práctica de x402. Es adecuado para una llamada a API de $0.001 (una disputa costaría más que el pago) y es inadecuado para cualquier situación en la que el comprador pudiera razonablemente querer un reembolso.
Tres formas de suavizar la propiedad de no reembolso de x402:
- Custodia (escrow). Para pagos x402 de mayor valor, utiliza una custodia de contrato inteligente que retenga los fondos hasta que el comprador señale la aceptación. ERC-8004 incluye primitivas de custodia para transacciones de múltiples agentes.
- Componer con AP2 y un riel diferente. Si necesitas la velocidad de x402 pero también soporte para disputas, la composición AP2 más x402 te ofrece la cadena de mandatos como evidencia, mientras que x402 mantiene la liquidación rápida. La liquidación en sí sigue siendo irreversible; el mandato solo prueba lo que se acordó.
- Garantías del vendedor. Para APIs de pago, los términos del vendedor suelen incluir reglas de reembolso aplicadas fuera de la cadena (el vendedor envía voluntariamente USDC de vuelta si el servicio falló). Esto funciona con vendedores de confianza y falla con vendedores anónimos.
MPP: disputas a través de Stripe. Las sesiones MPP liquidadas en rieles de tarjeta heredan la maquinaria estándar de disputas de Stripe, igual que ACP. Las sesiones MPP liquidadas con stablecoin en Tempo, o mediante Lightning, pasan por la resolución de disputas del lado del vendedor de Stripe. Stripe hace al comerciante responsable del resultado independientemente del riel.
El modelo de disputas que necesitas a menudo impulsa la composición más que el costo o la latencia. Una plataforma de compras para consumidores necesita contracargos, por lo que ACP encaja. Un mercado API puramente de máquina a máquina no necesita disputas en absoluto, por lo que x402 encaja. Una plataforma de adquisiciones empresariales necesita evidencia de grado de auditoría, por lo que AP2 con cualquier riel de liquidación encaja.
Conclusión del concepto 17: Las mecánicas de disputas y reembolsos difieren significativamente entre protocolos. ACP hereda los contracargos de la red de tarjetas, por lo que la política de devoluciones existente del comerciante funciona. AP2 proporciona la cadena de mandatos como evidencia legal, pero no reemplaza la ruta de disputas del riel subyacente. x402 no es reembolsable por diseño: adecuado para micropagos, inadecuado cuando los reembolsos importan. MPP hereda la maquinaria de disputas de Stripe en todos los rieles. El modelo de disputas que necesita tu caso de uso es con frecuencia el factor más determinante para la composición de protocolos.
Concepto 18: El enrutamiento de webhooks con FastAPI e Inngest: cerrando el ciclo de solicitud y respuesta
En una línea: Algunos eventos de pago llegan según su propio calendario (disputas, firmas de mandatos, solicitudes de pago del lado del vendedor), por lo que necesitas un controlador FastAPI delgado para capturarlos y un evento Inngest para llevar el trabajo a un flujo de trabajo duradero.
Las partes 1 a 5 y los conceptos 15 a 17 trataron al agente como comprador: envía una solicitud, el protocolo responde, el SDK razona sobre el resultado. Pero el comercio de agentes funciona en ambas direcciones. Stripe envía webhooks charge.dispute.created. La firma de mandatos AP2 ocurre fuera de tu servidor, en el dispositivo del usuario, y se publica de vuelta más tarde. Los vendedores x402 necesitan un middleware del lado del servidor que devuelva 402 Payment Required y verifique los encabezados X-PAYMENT. Ninguno de estos encaja dentro de una sola llamada Runner.run(). Necesitan controladores FastAPI como límite HTTP y eventos Inngest como puente de vuelta a flujos de trabajo duraderos.
Este concepto recorre los tres patrones que necesitarás en producción. Sin ellos, el sistema tiene fisuras por donde caen los eventos asíncronos.
Patrón 1: un webhook de Stripe que fluye hacia una función Inngest suspendida. Cuando un usuario presenta un contracargo en un pedido ACP, Stripe envía charge.dispute.created a tu endpoint. Puede llegar cinco minutos después del pedido o 60 días más tarde. El flujo de trabajo que realizó el pedido hace tiempo que finalizó, pero el agente aún necesita reaccionar: notificar al comerciante, registrar en la auditoría, quizás construir una defensa. El controlador FastAPI convierte el webhook en un evento Inngest, y una función Inngest lo recoge y ejecuta un agente para gestionar la disputa.
stripe.Webhook.construct_event(...)ystripe.error.SignatureVerificationErrorson APIs reales de Stripe. El cableado de Inngest es real. Nota la API de envío: los eventos se despachan comosend(events=[inngest.Event(...)]), no como un dict simple.
from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel
from decimal import Decimal
import stripe, inngest
app = FastAPI()
inngest_client = inngest.Inngest(app_id="agent-commerce", is_production=False)
class StripeDisputeEventPayload(BaseModel):
order_id: str
dispute_id: str
amount_usd: Decimal
reason: str
raw_event_id: str
@app.post("/webhooks/stripe")
async def stripe_webhook(request: Request):
# 1. Verify the Stripe signature. This security gate is required.
signature = request.headers.get("Stripe-Signature")
payload = await request.body()
try:
event = stripe.Webhook.construct_event(
payload=payload, sig_header=signature, secret=settings.stripe_webhook_secret,
)
except stripe.error.SignatureVerificationError:
raise HTTPException(status_code=400, detail="Invalid signature")
# 2. Route by event type. This handler does NO business logic.
# It only fires Inngest events so the durable workflow does the work.
if event.type == "charge.dispute.created":
await inngest_client.send(events=[
inngest.Event(
name="stripe/dispute.created",
data=StripeDisputeEventPayload(
order_id=event.data.object.metadata.get("order_id"),
dispute_id=event.data.object.id,
amount_usd=Decimal(event.data.object.amount) / 100,
reason=event.data.object.reason,
raw_event_id=event.id,
).model_dump(),
id=event.id, # idempotency seed
),
])
# 3. ACK Stripe right away. The real work runs in Inngest, durably.
return {"received": True, "event_id": event.id}
# The Inngest function that handles the dispute: fully durable and retryable.
@inngest_client.create_function(
fn_id="handle-stripe-dispute",
trigger=inngest.TriggerEvent(event="stripe/dispute.created"),
# Idempotency by raw_event_id makes sure Stripe retries do not process twice.
idempotency="event.data.raw_event_id",
)
async def handle_stripe_dispute(ctx: inngest.Context) -> dict:
payload = StripeDisputeEventPayload(**ctx.event.data)
# Log to audit immediately.
await ctx.step.run("audit-dispute-received", log_dispute_to_neon, payload)
# Run an agent to assemble the dispute defense.
defense_agent = Agent(
name="DisputeDefenseAgent",
instructions="Assemble dispute defense materials: order receipt, AP2 mandate if any, "
"delivery confirmation, customer communication history.",
tools=[fetch_order_details, fetch_mandate_chain, fetch_delivery_proof, submit_dispute_response],
)
defense = await ctx.step.run(
"build-and-submit-defense",
Runner.run, defense_agent, f"Build defense for dispute {payload.dispute_id}",
)
return {"status": "completed", "output": {"defense_submitted": defense.final_output.model_dump()}}
El controlador FastAPI se mantiene delgado (verificar y luego disparar un evento). La función Inngest es duradera (idempotencia, reintentos, memoización de pasos). El razonamiento del agente ocurre dentro de la función Inngest, nunca dentro del controlador del webhook. Esta separación importa porque Stripe espera una respuesta 2xx en aproximadamente cinco segundos, y una ejecución de agente puede tardar 30 segundos o más.
Patrón 2: un callback de firma de mandato AP2 que reanuda un step.wait_for_event suspendido. El concepto 9 mostró la herramienta de firma AP2 solicitando una firma y esperando. En producción, esa firma ocurre fuera de tu servidor: el usuario abre su aplicación en el teléfono, ve el mandato, presiona Aprobar, y el mandato firmado se publica de vuelta. El flujo de trabajo Inngest del agente estaba suspendido en step.wait_for_event; el callback FastAPI dispara el evento que lo despierta.
El callback de firma es tu propia ruta FastAPI. La correlación Inngest usa
if_exp=(una expresión CEL), y el payload esperado está bajo el prefijoasync..wait_for_eventdevuelveNoneal agotar el tiempo de espera.ap2_verify_signaturey el cliente de persistencia son ilustrativos; la forma del flujo de trabajo es real.
from datetime import timedelta
from pydantic import BaseModel
class MandateSignedPayload(BaseModel):
mandate_id: str
user_did: str
signature: str # the user's signature over the mandate hash
signed_at: str
@app.post("/callbacks/ap2/mandate-signed")
async def mandate_signed_callback(payload: MandateSignedPayload, request: Request):
# 1. Verify the signature against this user's registered public key.
is_valid = await ap2_verify_signature(
mandate_id=payload.mandate_id,
user_did=payload.user_did,
signature=payload.signature,
)
if not is_valid:
raise HTTPException(status_code=400, detail="Invalid mandate signature")
# 2. Persist the signed mandate. Mandates have a 7-year retention requirement.
await neon_client.mandates.insert({
"mandate_id": payload.mandate_id,
"user_did": payload.user_did,
"signature": payload.signature,
"signed_at": payload.signed_at,
"status": "signed",
})
# 3. Fire the Inngest event that resumes the agent's workflow.
await inngest_client.send(events=[
inngest.Event(name="ap2/mandate.signed", data=payload.model_dump(), id=payload.mandate_id),
])
return {"received": True, "event_id": payload.mandate_id}
# The Inngest function that was waiting. if_exp correlates the wait to this mandate.
@inngest_client.create_function(
fn_id="agent-procurement-workflow",
trigger=inngest.TriggerEvent(event="procurement/task.created"),
)
async def procurement_workflow(ctx: inngest.Context) -> dict:
# ... agent creates the Intent Mandate, fires "ap2/mandate.signing.requested" ...
# Suspend until the user signs. Zero compute is used during the wait.
signed = await ctx.step.wait_for_event(
"wait-for-intent-mandate-signature",
event="ap2/mandate.signed",
if_exp=f"async.data.mandate_id == '{ctx.event.data['mandate_id']}'",
timeout=timedelta(hours=24), # users can take real time
)
if signed is None: # timeout returns None
return {"status": "abandoned", "reason": "user did not sign within 24h"}
# Resume with the signed mandate. The agent continues from exactly where it left off.
cont = await ctx.step.run("continue-procurement", continue_with_signed_mandate, signed)
return {"status": "completed", "output": {"procurement_continuation": cont}}
step.wait_for_event de Inngest con if_exp está diseñado exactamente para esto. El controlador FastAPI es un puente unidireccional de HTTP al bus de eventos de Inngest. El flujo de trabajo que se suspendió hace horas se reanuda con el payload firmado, y el agente retoma desde donde se detuvo.
Patrón 3: middleware del lado del vendedor x402 (cuando expones una API de pago, no solo la consumes). En un mercado multiagente (Decisión 4), tu agente es a veces el comprador y a veces el vendedor, donde otros agentes pagan al tuyo por investigación, análisis o código. El lado del vendedor necesita un middleware FastAPI que devuelva 402 Payment Required, verifique los encabezados X-PAYMENT y sirva el recurso solo una vez que un facilitador haya verificado el pago.
El
X402Middlewaredel lado del vendedor que aparece a continuación es ilustrativo; no existe un paquete PyPIx402_server. El x402 del lado del servidor real se implementa a través de los helpers de servidor y facilitador del paquetex402más una integración con el framework. La idea de comprador y vendedor simétricos es real, y la ruta FastAPI es real.
from fastapi import FastAPI, Request, Response
from decimal import Decimal
# Illustrative seller-side imports (see note above).
from x402_server import X402Middleware, PaymentRequirement
# Configure the middleware once at app startup.
app = FastAPI()
app.add_middleware(
X402Middleware,
payment_requirements_by_route={
"/api/research": PaymentRequirement(
scheme="exact",
network="eip155:8453", # Base
asset=USDC_BASE_CONTRACT,
recipient=settings.merchant_wallet_address,
max_amount_usdc=Decimal("0.50"),
expiry_seconds=300,
),
"/api/code-review": PaymentRequirement(
scheme="exact",
network="eip155:8453",
asset=USDC_BASE_CONTRACT,
recipient=settings.merchant_wallet_address,
max_amount_usdc=Decimal("2.00"),
expiry_seconds=300,
),
},
facilitator_url="https://facilitator.cloudflare.com/x402",
)
# Your business logic. The middleware enforces payment before this runs.
@app.post("/api/research")
async def research_endpoint(request: Request):
# By the time we reach here, the X-PAYMENT header has been verified and settled.
# request.state.x402_proof carries the on-chain transaction hash for audit.
query = (await request.json())["query"]
research_agent = Agent(
name="ResearchAgent",
instructions="Conduct deep research on the query and return a structured report.",
tools=[search_web, fetch_papers, summarize],
)
result = await Runner.run(research_agent, query)
return Response(
content=result.final_output,
headers={"X-PAYMENT-PROOF": request.state.x402_proof.tx_hash},
)
x402 es simétrico. El código del lado del comprador del concepto 10 y el middleware del lado del vendedor aquí son las dos mitades del mismo protocolo. Un mercado multiagente ejecuta ambos: sus agentes compran de servicios externos y venden a agentes externos.
Tres fallas se repiten en producción:
- Controladores de webhook ejecutando lógica de negocio en línea. Un controlador FastAPI que ejecuta el agente dentro de la respuesta del webhook superará el tiempo límite de cinco segundos de Stripe. Stripe reintenta, el agente se ejecuta dos veces, y cobras al usuario dos veces. El controlador se mantiene delgado; la función Inngest es duradera.
- Olvidar la idempotencia del webhook. Stripe reintenta entregas fallidas con el mismo
event.id. Sin una clave deidempotencyen la función Inngest, cada reintento crea un duplicado. Usa"event.data.raw_event_id"como clave de idempotencia. - Sin verificación de firma en los callbacks. Los callbacks de mandato firmado AP2 deben verificar la firma del usuario contra la clave pública registrada. De lo contrario, cualquier llamante puede falsificar eventos de mandato firmado. Una verificación fallida devuelve un 400, no una advertencia en el registro.
Conclusión del concepto 18: El comercio de agentes es bidireccional. Las respuestas de los protocolos llegan de forma síncrona y el SDK las gestiona, pero las disputas, las firmas de mandatos, los reembolsos y las solicitudes de pago del lado del vendedor llegan de forma asíncrona a través de webhooks y callbacks. Tres patrones cubren la necesidad operativa. Un controlador de webhook de Stripe dispara un evento Inngest hacia un flujo de trabajo de agente duradero para disputas y reembolsos. Un callback de mandato firmado AP2 dispara un evento Inngest que reanuda un
step.wait_for_eventsuspendido para la firma fuera de banda. Un middleware FastAPI del lado del vendedor x402 expone APIs de pago con pago verificado. Los controladores FastAPI se mantienen delgados (verificar y disparar); las funciones Inngest son duraderas (idempotentes y con reintentos). El enfoque del lado del comprador de las partes 1 a 5 está incompleto sin estos tres; los sistemas en producción ejecutan los tres.
Parte 7: Cierre: lo que este curso realmente enseñaba
Concepto 19: La disciplina de la composición por capas
En una línea: Todo en este curso se reduce a una tarea: leer el caso de uso, dividirlo en cuatro capas y elegir el protocolo correcto en cada capa.
Este curso tiene 19 Conceptos y 5 Decisiones. Todos son andamiaje para una afirmación: el comercio de agentes en 2026 no es un protocolo único, sino una arquitectura por capas, y tu trabajo es elegir el protocolo correcto en cada capa para el caso de uso que tienes delante. Todo lo demás se desprende de eso.
La misma forma aparece a tres escalas.
A escala de protocolo, los cuatro protocolos principales resuelven problemas distintos en capas diferentes: ACP en la Capa 3, AP2 en la Capa 2, x402 y MPP en la Capa 4. Tratarlos como rivales en la misma capa es el error arquitectónico más común. Compiten solo donde sus capas se superponen (x402 contra MPP en la liquidación; AP2 contra el SPT de ACP en la autorización para algunos flujos). En todos los demás casos, se componen.
A escala de sistema, un sistema en producción tiene un protocolo de cada capa, conectados entre sí a través del OpenAI Agents SDK como cliente universal. Los elementos @function_tool, RunContextWrapper y tool_input_guardrail del SDK se corresponden claramente con las responsabilidades de cada capa. El SDK no es un protocolo. Es el orquestador que permite componer los protocolos de forma limpia.
A escala de disciplina, tu trabajo es leer un caso de uso, dividirlo en las cuatro capas, elegir el protocolo correcto en cada una y justificar cada elección según las restricciones reales del caso de uso: valor de la transacción, presupuesto de latencia, modelo de disputas, requisitos de auditoría. El trabajo no es "elegir un protocolo favorito". Es "para este caso de uso, ¿qué exige cada capa?"
Las cinco Decisiones de la Parte 5 guiaron casos de uso reales a través de esta disciplina. La Decisión 1 (compras de consumidores) llegó a ACP más los canales de tarjeta de Stripe, porque el caso de uso requería protección contra contracargos. La Decisión 2 (un agente que paga por APIs) llegó solo a x402, porque las Capas 2 y 4 se colapsan en flujos máquina a máquina. La Decisión 3 (adquisiciones empresariales) alcanzó la composición más compleja (AP2 más ACP más MPP), porque las necesidades de auditoría y recurrencia lo exigían. La Decisión 4 (un mercado multiagente) llegó a AP2 más ERC-8004 más x402, porque la necesidad de confianza bilateral no podía satisfacerse de ninguna otra manera. La Decisión 5 reconstruyó la Decisión 2 sobre una pila completamente diferente (Google ADK más una billetera Coinbase más AP2 más x402) y llegó a la misma forma de cuatro capas, lo que demostró que la arquitectura no es un envoltorio alrededor de Stripe y OpenAI.
La composición a la que se llega la determina el caso de uso, no el gusto personal. Un equipo que elige x402 porque "las stablecoins son el futuro" pero está construyendo una experiencia de compras para consumidores tiene la composición incorrecta. Un equipo que elige ACP porque "Stripe es de nivel empresarial" pero está pagando por acceso a APIs a $0.001 por llamada tiene la composición incorrecta. Deja que el caso de uso guíe la elección.
Conclusión del Concepto 19, y de este curso: Los cuatro protocolos (ACP, AP2, x402, MPP) son capas, no alternativas. Tu trabajo es leer el caso de uso, dividirlo en las cuatro capas (descubrimiento, autorización, comercio, liquidación), elegir el protocolo correcto en cada capa y justificar la elección según las restricciones reales del caso de uso. El OpenAI Agents SDK es el cliente universal que compone los protocolos elegidos. La disciplina sobrevive a cualquier protocolo que gane en los próximos 24 meses. Las capas son estables, aunque los protocolos en cada capa evolucionen.
Guía de referencia rápida: el marco en una página
Imprímela. Pégala en la pared. Úsala cuando revises cualquier diseño de comercio de agentes.
Las cuatro capas (memoriza esta pila)
Layer 1: DISCOVERY -> "What's available to buy?"
Layer 2: AUTHORIZATION -> "Am I allowed to spend this?"
Layer 3: COMMERCE -> "What's the full purchase lifecycle?"
Layer 4: SETTLEMENT -> "Where does the money actually move?"
Los protocolos en cada capa (mejores opciones en 2026)
| Capa | Mejores opciones | Elige por |
|---|---|---|
| Descubrimiento | MCP, A2A, directorios de agentes, superficies de compras con IA | Dónde viven los servicios que necesita el agente |
| Autorización | Mandatos AP2, SPT de ACP, TAP, ERC-8004 | Modelo de confianza: riguroso para auditoría, nativo de Stripe, solo identidad o multiagente |
| Comercio | ACP, UCP, API directa (ninguno) | ¿El caso de uso necesita un ciclo de vida de comercio? |
| Liquidación | x402, MPP, canales de tarjeta, banca/Lightning | Economía: el valor de la transacción determina el canal |
Las cuatro composiciones canónicas
| Caso de uso | Pila |
|---|---|
| Compras de consumidores | Superficie de IA + SPT de ACP + ACP + tarjetas Stripe |
| Agente que paga por APIs | MCP/directorio + EIP-3009 + (ninguno) + x402 |
| Adquisiciones empresariales | A2A/MCP + AP2 + ACP/UCP + MPP/tarjetas |
| Mercado multiagente | A2A + AP2 + ERC-8004 + (ninguno) + x402 |
Aplicación de límites de gasto en tres niveles (obligatorio)
Level 1: Wallet / payment-method limits (smart-contract caps OR Stripe customer caps)
Level 2: SDK tool guardrails (tool_input_guardrail on each payment tool)
Level 3: Application business logic (per-user, per-category, per-merchant policies)
Omite cualquiera de estos y estarás a un solo error de un drenaje total. El error más común es usar output_guardrail a nivel de agente para el Nivel 2. Se ejecuta en la respuesta final del agente, demasiado tarde para detener un pago. Usa tool_input_guardrail en su lugar.
El umbral económico (memorízalo)
Transaction value
├── < $5 → x402 or MPP stablecoin (card fees exceed the transaction)
├── $5 - $1,000 → ACP + card rails (chargeback protection worth the 2.9%)
└── > $1,000 → AP2 + composed stack (audit + dispute defense + multi-rail)
El modelo de disputas (a menudo la restricción más determinante)
Use case needs chargeback protection?
├── Yes → ACP + card rails (or MPP card mode)
└── No → x402 acceptable (faster, cheaper, no refunds)
Use case needs audit evidence?
├── Yes → AP2 at Layer 2 (mandates as legally-admissible evidence)
└── No → SPT or EIP-3009 sufficient
Lista de verificación de producción antes del lanzamiento
- Límites de gasto de billetera/método de pago configurados en el Nivel 1
-
tool_input_guardraildel SDK adjunto a cada herramienta que autoriza pagos (Nivel 2) - La aplicación aplica límites por usuario, por categoría y por comerciante (Nivel 3)
- Claves de firma en un almacén de claves (Azure Key Vault o equivalente), nunca en variables de entorno
- Separación de billeteras por agente (sin claves compartidas entre clases de agentes)
- Calendario de rotación de claves definido (línea base de 90 días)
- Registros de auditoría en almacenamiento duradero independiente del tiempo de ejecución del agente
- Trazas de OpenTelemetry que abarcan el SDK, httpx, Inngest y FastAPI; un ID de traza por transacción
- Modelos Pydantic en cada límite (retornos de herramientas, cargas útiles de protocolo, cuerpos de FastAPI, eventos de Inngest)
-
Decimalpara dinero en todas partes (nuncafloat) - El manejador de webhooks de Stripe verifica la firma y dispara un evento de Inngest (manejador delgado, función duradera)
- El callback firmado de mandato AP2 verifica la firma y reanuda
step.wait_for_event - Si se exponen APIs de pago: middleware de vendedor x402 configurado por ruta
- Clave de
idempotencyde Inngest establecida en cada función disparada por webhook - Mecanismo de disputas y reembolsos comprendido y documentado por protocolo
- Puerta de confirmación con supervisión humana durante los primeros 30 días en producción
- Métrica de precisión del carrito medida antes de relajar la confirmación
Referencia rápida: el árbol de decisión, comprimido
Cuando tengas un nuevo caso de uso, recorre este árbol.
1. What's the agent buying?
├── Retail goods for a user → Decision 1 pattern (ACP + cards)
├── API access for itself → Decision 2 pattern (x402-only)
├── Supplier goods/services for an org → Decision 3 pattern (AP2 + composed)
└── Work from another agent → Decision 4 pattern (AP2 + ERC-8004 + x402)
2. What's the transaction value?
├── < $5 → settlement = x402 or MPP stablecoin
├── $5-$1,000 → settlement = card rails via ACP/MPP
└── > $1,000 → settlement = MPP sessions OR bank rails
3. What's the dispute model?
├── Need chargeback protection → must include card rails somewhere
├── Need audit evidence → must include AP2 at Layer 2
└── Neither → x402 / direct rail sufficient
4. What's the latency budget?
├── < 1 sec → only stablecoin rails work
├── 1-5 sec → x402, MPP, or pre-signed AP2 mandates
└── > 5 sec → full ACP checkout works
5. Compose: pick one protocol from each layer, justified against the constraints above.
Repaso de 10 minutos: los 19 conceptos en una oración cada uno
Lee esto cuando hayas olvidado lo que dijo cada concepto. Cada entrada es la conclusión final que cierra el concepto; reunidas aquí para una consulta rápida.
1. El supuesto que se rompió
Los sistemas de pago se construyeron sobre el supuesto de que un humano hace clic en el botón de compra. Los agentes lo rompen de tres maneras: sin identidad tradicional, comportamiento que parece anómalo y sin canal para resolver una disputa. Cada ruptura necesita una solución a nivel de protocolo. Envolver los canales de pago antiguos en una interfaz de agente más agradable no funcionó.
2. Por qué un protocolo no puede resolver todas las rupturas
Un protocolo no puede resolver las cuatro rupturas, porque ocurren en capas distintas, cada una con sus propios actores establecidos. Los cuatro protocolos se especializan: ACP en el comercio, AP2 en la autorización, x402 y MPP en la liquidación. Dentro de una capa, elige uno; entre capas, compones varios.
3. El OpenAI Agents SDK como cliente universal
El SDK es el cliente universal para los cuatro protocolos. Cada protocolo se convierte en una o más funciones
@function_toolque el agente llama. Los elementosoutput_type,contextytool_input_guardraildel SDK se corresponden claramente con las responsabilidades del protocolo: resultados de pago estructurados, contexto de pago por usuario y verificaciones de límite de gasto previas a la ejecución.
4. Capa 1, descubrimiento (cómo los agentes encuentran lo que pueden comprar)
La Capa 1 responde "¿qué está disponible?" Cuatro opciones compiten: MCP para servidores de herramientas internos, A2A para ecosistemas multiagente, directorios de agentes para servicios de terceros y superficies de compras con IA para productos de consumo. Elige la que coincida con dónde viven los servicios que necesita el agente; no son mutuamente excluyentes.
5. Capa 2, identidad y autorización (demostrar que el agente tiene permiso)
La Capa 2 responde dos preguntas: ¿autorizó el humano esto, y es el agente quien dice ser? Cuatro protocolos compiten: mandatos AP2 (rigurosos para auditoría), SPT de ACP (nativo de Stripe), TAP (solo identidad), ERC-8004 (confianza multiagente). Se integran a través de
RunContextWrapperpara autenticación por herramienta ytool_input_guardrailpara aplicación del gasto. Elige según el modelo de confianza; no son intercambiables.
6. Capa 3, comercio (el ciclo de vida completo de la compra)
La Capa 3 maneja el carrito, el pago, el cumplimiento, la disputa y el reembolso. ACP y UCP compiten para flujos de consumidores; el acceso a APIs máquina a máquina no tiene capa de comercio. La mecánica de reembolsos y disputas es la complejidad oculta que separa un protocolo de comercio real de uno que solo hace pagos. Elige según el caso de uso: ciclo de vida necesario (ACP/UCP) o ciclo de vida omitido (API directa).
7. Capa 4, liquidación (el dinero realmente se mueve)
La Capa 4 es donde se mueve el dinero. Cuatro opciones compiten: x402 para stablecoin máquina a máquina, MPP para sesiones multicanal, canales de tarjeta para compras de consumidores con contracargos, banca o Lightning para casos de alto valor o comisiones muy bajas. La elección es principalmente económica: por debajo de un dólar a x402, consumidores a tarjetas, empresas a MPP. La liquidación suele estar determinada por tu elección de comercio; elige el fondo de la pila, no canales aislados.
8. ACP, el protocolo de compras de consumidores
ACP es el protocolo de comercio listo para producción en compras de consumidores. El SPT limita el gasto del agente; el comerciante sigue siendo el comerciante de registro. Se integra a través del SDK de Stripe más un cliente ACP delgado, conectado como cuatro funciones
@function_tool(navegar, pagar, estado, reembolso). Usa confirmación del usuario en los carritos hasta que se mida la precisión del carrito del agente.
9. AP2, la capa de autorización
AP2 es la capa de autorización para el comercio de agentes riguroso en auditoría. Tres tipos de mandato (Intent, Cart, Payment) forman una cadena no repudiable que demuestra el consentimiento del usuario.
step.wait_for_eventes la solución natural para los flujos de firma de mandatos. Crea los Intent Mandates primero, antes de comenzar las compras, no como un añadido al momento del pago.
10. x402, el protocolo de liquidación nativo de HTTP
x402 es el protocolo de liquidación nativo de HTTP para micropagos máquina a máquina. El código de estado 402 más un encabezado de pago firmado más una firma EIP-3009 liquida en uno o dos segundos sin creación de cuenta. Los límites de gasto del contrato inteligente de la billetera son la protección que realmente te resguarda, no el límite por solicitud. Verifica el nombre de los encabezados con la versión de la especificación y el facilitador con el que te integras; difiere entre V1 y V2.
11. MPP, el protocolo de liquidación basado en sesiones
MPP es la respuesta de Stripe en liquidación a x402, construido para medición basada en sesiones y despacho multicanal. Dos intenciones,
charge(único) ysession(preautorizado en streaming), cubren compras únicas y medición recurrente. La forma HTTP usa los encabezados estándarWWW-Authenticate: Payment,Authorization: PaymentyPayment-Receipt, por lo que se siente como autenticación HTTP familiar. Ajusta los límites de sesión al trabajo esperado, no a la conveniencia.
12. La pila mínima viable de pago de agentes
La pila mínima viable es la composición más pequeña que aporta valor para el caso de uso. Cuatro comunes: compras de consumidores (ACP más tarjetas), pago por API (solo x402), adquisiciones empresariales (AP2 más ACP/UCP más MPP/tarjetas), mercado multiagente (AP2 más ERC-8004 más x402). No construyas pilas universales; elige una composición por caso de uso y lánzala.
13. Cuándo los protocolos se componen entre capas frente a competir dentro de una capa
Los protocolos entre capas se componen (AP2 más x402, ACP más x402, MCP más x402); los protocolos dentro de una capa compiten (AP2 vs. SPT de ACP, ACP vs. UCP, x402 vs. MPP). La prueba es: "¿están estos en la misma capa?" Si la respuesta es sí, elige uno; si no, probablemente se componen.
14. Implicaciones de costo y latencia de las elecciones de composición
Los canales de tarjeta cuestan el 2,9% más $0,30 por transacción, pero ofrecen protección contra contracargos; los canales de stablecoin cuestan fracciones de centavo, pero requieren infraestructura nativa de criptomonedas. El punto en dólares donde los canales de tarjeta dejan de tener sentido ronda los $5 a $10. El punto de latencia donde el pago de ACP se vuelve demasiado lento ronda los cinco segundos para flujos orientados al usuario. Usa el costo y la latencia para decidir la composición, no la preferencia abstracta.
15. Aplicación de límites de gasto en tres niveles arquitectónicos
Aplica límites de gasto en tres niveles independientes: infraestructura de billetera o método de pago, protecciones de herramientas del SDK (
tool_input_guardrailespecíficamente, ya que se ejecuta antes de cada herramienta y puede bloquearla) y lógica de negocio de la aplicación. Cada nivel usa una infraestructura diferente, por lo que un error en uno lo detectan los otros. Usaroutput_guardrailpara el control de gasto es el error más común; se ejecuta en la respuesta final, demasiado tarde para detener un pago.
16. Higiene de identidad de agentes: claves, billeteras y registros de auditoría
La identidad del agente es criptográfica; la clave de firma es lo único que separa el gasto autorizado del fraude. Cuatro hábitos: separación de billeteras por agente, rotación de claves según un calendario y bajo demanda, registros de auditoría en almacenamiento duradero independiente del tiempo de ejecución y trazas distribuidas con un ID de traza que abarca toda la transacción. Las claves de firma van en un almacén de claves, nunca en variables de entorno ni en el código fuente.
17. Mecánica de disputas y reembolsos en los cuatro protocolos
ACP hereda los contracargos de la red de tarjetas. AP2 proporciona la cadena de mandatos como evidencia legal, pero no reemplaza la vía de disputas del canal subyacente. x402 no admite reembolsos por diseño: correcto para micropagos, incorrecto donde los reembolsos importan. MPP hereda la maquinaria de disputas de Stripe en todos los canales. El modelo de disputas que necesita tu caso de uso es a menudo lo que más fuerza la composición de protocolos.
18. Conexión de webhooks de FastAPI e Inngest: cerrando el ciclo de solicitud y respuesta
El comercio de agentes es bidireccional: disputas, firmas de mandatos, reembolsos y solicitudes de pago del vendedor llegan de forma asíncrona a través de webhooks. Tres patrones cubren la necesidad: un webhook de Stripe dispara un evento de Inngest en un flujo de trabajo duradero; un callback firmado de mandato AP2 dispara un evento que reanuda
step.wait_for_event; un middleware de FastAPI del vendedor de x402 expone APIs de pago. Los manejadores de FastAPI permanecen delgados; las funciones de Inngest son duraderas. Los sistemas en producción ejecutan los tres.
19. La disciplina de la composición por capas
Los cuatro protocolos (ACP, AP2, x402, MPP) son capas, no alternativas. Tu trabajo es leer el caso de uso, dividirlo en las cuatro capas, elegir el protocolo correcto en cada una y justificar la elección según las restricciones reales del caso de uso. El OpenAI Agents SDK es el cliente universal. La disciplina sobrevive a cualquier protocolo que gane en los próximos 24 meses; las capas son estables, aunque los protocolos en cada capa evolucionen.
Plantilla de revisión de diseño: preguntas para evaluar cualquier arquitectura de agente-comercio
Cuando revisas el diseño de un colega (o tu propio borrador, con un día de distancia), recorre estas preguntas en orden. Cada una corresponde a una sección de este curso; si la respuesta no satisface la pregunta, vuelve a esa sección.
Preguntas de arquitectura
- ¿Qué caso de uso atiende este diseño? Si son "varios", ¿cuál es el principal? Un diseño que intenta atender los cuatro casos de uso canónicos es el antipatrón del Concepto 12; márcalo.
- Recorre las cuatro capas de forma explícita. ¿Descubrimiento? ¿Autorización? ¿Comercio? ¿Liquidación? ¿Qué protocolo hay en cada capa? Declara en voz alta la composición de los cuatro protocolos.
- Justifica la elección de cada capa frente al caso de uso. ¿Por qué este protocolo en esta capa? ¿Qué cambiaría con uno diferente? Aquí aplica la prueba entre-capas-vs-dentro-de-capa del Concepto 13.
- ¿Hay superposición de protocolos en alguna capa? ¿Dos protocolos compitiendo en la Capa 4? ¿Dos en la Capa 2? Si es así, esa es una complejidad que necesita un caso de uso que la justifique.
Preguntas económicas
- ¿Cuál es la distribución del valor de las transacciones? ¿Menos de un dólar? ¿De 10 a 100 dólares? ¿Más de 1 000 dólares? El umbral económico del Concepto 14 debe guiar la elección de liquidación.
- ¿Cuál es el presupuesto de latencia? ¿Menos de un segundo? ¿De 5 a 30 segundos? El presupuesto de latencia debe restringir la liquidación y las opciones de mandate.
- ¿Cuál es el costo por transacción al volumen esperado? Suma las tarifas del protocolo, más las tarifas del procesador, más el costo de infraestructura por transacción. Úsalo para verificar que la composición sea económicamente viable.
Preguntas operativas
- ¿Hay aplicación de límites de gasto en los tres niveles? Cartera/método de pago, SDK, lógica de negocio de la aplicación. Concepto 15: omitir cualquiera te deja expuesto.
- ¿Higiene de identidad? Separación de cartera por agente, rotación de claves, registros de auditoría en almacenamiento duradero, trazas distribuidas con un único ID de traza por transacción. Los cuatro hábitos del Concepto 16.
- ¿Mecánica de disputas y reembolsos? ¿La composición maneja las disputas que tu caso de uso realmente recibirá? Concepto 17: esta suele ser la restricción más fuerte.
- ¿Envolvente operativo? ¿Dónde gestiona Inngest (o su equivalente de ejecución duradera) los flujos de larga duración, los reintentos y la idempotencia? Cubierto en el curso express de Production Worker.
- ¿Puertas de confirmación humana? ¿En qué punto del flujo confirma el usuario u operador? De forma predeterminada, usa una puerta de confirmación durante los primeros 30 días en producción.
Preguntas sobre webhooks y callbacks asincrónicos (Concepto 18)
- ¿El manejador de webhooks de Stripe existe y es liviano? Verifica la firma, dispara un evento de Inngest y responde con ACK en menos de cinco segundos. La lógica de negocio vive en la función de Inngest, no en el manejador.
- ¿El callback de firma de mandate de AP2 existe y verifica las firmas del usuario? Sin él, el
step.wait_for_eventdel agente nunca reanuda. Sin verificación de firma, cualquiera puede falsificar eventos de mandate firmado. - Si se exponen APIs de pago: ¿el middleware de vendedor x402 está configurado por ruta? Los mercados multiagente ejecutan código tanto del lado del comprador como del vendedor; el lado del vendedor necesita el middleware.
- ¿Claves de idempotencia de Inngest en cada función disparada por webhook? Stripe reintenta con el mismo
event.id; sin idempotencia cobras o reembolsas dos veces. - ¿Capa de contrato: modelos Pydantic en cada límite? Retornos de herramientas, cargas de protocolo, cuerpos de solicitud y respuesta de FastAPI, cargas de eventos de Inngest, todos tipados.
Decimalpara dinero, nuncafloat.
Preguntas sobre modos de fallo
- ¿Cuál es el modo de fallo más probable en producción? Cada decisión canónica tenía uno: discrepancia en el carrito (Decisión 1), gasto descontrolado (Decisión 2), discrepancia de alcance del Intent Mandate (Decisión 3), reputación manipulada (Decisión 4). ¿Cuál es el tuyo?
- ¿Cuál es la mitigación? Cada modo de fallo en la Parte 5 tenía una mitigación explícita. ¿El diseño la incluye, o confía en que "el protocolo lo resolverá"?
Preguntas de preparación para producción (para despliegue en producción)
- ¿En qué pista de aprendizaje opera el equipo? Lector, principiante, intermedio, avanzado. Sé honesto. El despliegue en producción requiere profundidad de nivel avanzado, no la familiaridad del nivel lector.
- ¿Cuál es el plan de reversión si el agente se comporta mal? ¿Interruptor de la cartera? ¿Revocación de SPT? ¿Desactivar el agente a nivel del SDK? Define esto antes del lanzamiento, no después del incidente.
Referencias
Fuentes primarias de los cuatro protocolos. Prefiere estas sobre los comentarios secundarios; las especificaciones evolucionan más rápido que los escritos sobre ellas.
ACP (Agentic Commerce Protocol)
- Repositorio de especificación:
github.com/agentic-commerce-protocol/agentic-commerce-protocol(Apache 2.0) - Sitio para desarrolladores:
agenticcommerce.dev - Comantenedores: OpenAI y Stripe
- Documentación de integración con Stripe:
stripe.com/docs/agentic-commerce - Última versión de especificación citada:
2026-04-17
AP2 (Agent Payments Protocol)
- Repositorio de especificación:
github.com/google-agentic-commerce/AP2(Apache 2.0) - Sitio de documentación:
ap2-protocol.org - Miembros de la coalición: Google más 60 socios (Salesforce, ServiceNow, Adobe, Shopee, Etsy, Adyen, American Express, JCB, UnionPay International, PayPal, Mastercard, Coinbase, entre otros)
- Repositorio de la extensión a2a-x402:
github.com/google-a2a/a2a-x402 - Última versión citada: v0.2.0 (abril de 2026)
x402
- Repositorio de especificación:
github.com/coinbase/x402(Apache 2.0) - Sitio de documentación:
x402.gitbook.io(tambiénx402.org) - Creado por Coinbase y ahora administrado por la x402 Foundation de la Linux Foundation (abril de 2026), con Cloudflare, Stripe, AWS, Google y otros.
- Integración del SDK de OpenAI Agents con Cloudflare:
developers.cloudflare.com/agents/x402 - Directorio de adopción:
agent.market - Miembros de la x402 Foundation: Adyen, AWS, American Express, Base, Circle, Cloudflare, Coinbase, Google, Mastercard, Microsoft, Polygon Labs, Shopify, Solana Foundation, Stripe, Visa
MPP (Machine Payments Protocol)
- Sitio de especificación:
mpp.dev - Codesarrolladores: Stripe y Tempo (la cadena de bloques L1 de Stripe, incubada con Paradigm)
- Anuncio de Stripe:
stripe.com/blog/machine-payments-protocol - Fecha de lanzamiento: 18 de marzo de 2026 (mainnet)
- Socios en el lanzamiento: Stripe, Visa, Lightspark, Anthropic, OpenAI, Shopify y más de 100 servicios
Protocolos adyacentes
- A2A (Agent2Agent, Google):
github.com/google-a2a/A2A, el protocolo que AP2 extiende - MCP (Model Context Protocol, Anthropic):
modelcontextprotocol.io, la capa de herramientas y contexto a través de la cual los agentes descubren servicios - UCP (Universal Commerce Protocol, Google): anunciado como par de ACP para las superficies de compras de Google
- TAP (Trusted Agent Protocol, Visa y Cloudflare): protocolo de verificación de identidad lanzado el 14 de octubre de 2025
- ERC-8004: estándar de confianza en cadena para transacciones multiagente
OpenAI Agents SDK
- SDK de Python:
pip install openai-agents(última versión: 19 de mayo de 2026) - Documentación:
openai.github.io/openai-agents-python - SDK de JavaScript/TypeScript:
github.com/openai/openai-agents-js
Cursos express de Agent Factory relacionados
- El curso express de Build AI Agents: fundamentos del OpenAI Agents SDK (
Agent,Runner.run(),@function_tool) - El curso express de Production Worker: Inngest como envolvente operativo para flujos de agentes duraderos
- El curso express de Eval-Driven Development: pruebas y evaluación de agentes
- El curso express de Choosing Agentic Architectures: qué patrón agéntico se adapta a cada caso de uso
- El curso express de despliegue de agentes (despliegue en la nube): el arnés cloud (Azure Container Apps más Neon más Cloudflare). En curso; el enlace se publicará cuando esté disponible.
Herramientas operativas y de capa de contrato (utilizadas extensamente en los Conceptos 16 y 18)
- Inngest:
inngest.com, la plataforma de ejecución duradera que ejecuta los flujos de agentes en este curso - FastAPI:
fastapi.tiangolo.com, la capa HTTP asíncrona donde viven los endpoints de webhook y el middleware de vendedor x402 - Pydantic:
pydantic.dev, el contrato de tipos en cada límite (retornos de herramientas, cargas de protocolo, cuerpos de FastAPI, eventos de Inngest) - OpenTelemetry:
opentelemetry.io, trazado distribuido con instrumentación automática parahttpx,openai-agents, FastAPI e Inngest; un ID de traza abarca toda la transacción - httpx:
python-httpx.org, el cliente HTTP asíncrono que subyace ax402-client, el cliente de ACP y la extensión a2a-x402 de AP2 - Azure Key Vault: donde viven las claves de firma en producción, rotadas según la disciplina del Concepto 16
- Documentación de webhooks de Stripe:
stripe.com/docs/webhooks, verificación de firma, tipos de eventos y semántica de reintentos
Ahora tienes el marco completo: las cuatro capas, los cuatro protocolos, las reglas para componerlos, cinco decisiones trabajadas, las consideraciones de producción que determinan si el sistema sobrevive, y una referencia de una página para conservar. Los protocolos seguirán evolucionando. La disciplina de las cuatro capas, no. Construye desde las capas y seguirás teniendo razón cuando los nombres de los protocolos cambien.