Saltar al contenido principal
API DE PAGO

Una API de pago diseñada para el código de agentes de IA.

Una pequeña REST API. Webhooks firmados. SDKs oficiales en cinco idiomas. Construido para que tu agente pueda enviar y liquidar USDC y verificar pagos en unas pocas líneas de código.

Vista de transacciones: pagos entrantes de USDC confirmados en Base

La API de Blockchain0x es deliberadamente pequeña. No queremos que leas la documentación durante una hora para hacer tu primer pago. Queremos que copies un fragmento, pegues tu clave API y lo ejecutes.

LOS PUNTOS DE ENTRADA PRINCIPALES

Una pequeña superficie, construida para código de agente.

Las rutas con forma de pago están a continuación. Webhooks, claves API y permisos de gasto de solo lectura completan la superficie; el SDK envuelve todo esto.

POST/v1/paymentsEnviar un pago de USDC desde una billetera de agente
GET/v1/transactions/{id}Recupera el estado y el hash de una transacción
POST/v1/payment-requests/{id}/settleLiquida una factura con prueba en cadena
GET/v1/agents/{id}Recupera una billetera de agente
POST/v1/agentsCrear una billetera de agente
LOS EVENTOS DE WEBHOOK ENVIADOS

Todos firmados con HMAC-SHA256.

Firma en el X-Blockchain0x-Signature encabezado. Ventana de repetición de 5 minutos. Claves de idempotencia en cada POST.

payment.received

USDC llegó a una de tus billeteras de agente

payment.sent

un pago saliente de su agente se liquidó en la cadena

wallet.deployed

se desplegó la billetera inteligente de un agente

webhook.test

una entrega de prueba que activaste desde el panel

UNAS POCAS LÍNEAS

Enviar USDC desde la billetera de tu agente.

PYTHON
from blockchain0x import Client

client = Client(api_key="sk_test_...")  # sk_test_ testnet, sk_live_ mainnet
tx = client.payments.create(body={
    "agentId": "agt_123",
    "to": "0xRecipient",
    "amountWei": "10000",  # USDC base units (6 decimals): 0.01 USDC
})
print(tx)  # may return 503 until the chain adapter is wired for your network
SDKs OFICIALES

Clientes tipados para TypeScript y Python.

TIPOSCRIPT
npm install @blockchain0x/node

Funciona con Node 18+. Tipos nativos de TypeScript.

PYTHON
pip install blockchain0x

Python 3.9+. Clientes síncronos y asíncronos.

ESQUEMAS COMPLETOS DE PUNTOS DE ACCESO

Los cuerpos de solicitud que envuelve el SDK.

Estas son las entradas verificadas para cada ruta. Las respuestas se muestran breves aquí; las formas tipadas completas viven en el SDK y la referencia de la API. Los montos son unidades base de USDC (6 decimales).

POST/v1/payments

Enviar un pago de USDC (payments.create). amountWei son unidades base de USDC (6 decimales). Puede devolver 503 hasta que el adaptador de cadena esté conectado.

SOLICITUD
{
  "agentId": "agt_123",
  "to": "0xRecipient",
  "amountWei": "10000",
  "metadata": { "reason": "Research report" }
}
RESPUESTA
{
  "txHash": "0xff5...e12"
}
POST/v1/payment-requests/{id}/settle

Liquida una solicitud de pago (factura) creada en el panel, con prueba en cadena (paymentRequests.settle). No hay ruta de creación - solo liquidar.

SOLICITUD
{
  "txHash": "0xff5...e12",
  "payerAddress": "0xBuyer...",
  "amountUsdcVerified": "0.10"
}
RESPUESTA
{
  "txHash": "0xff5...e12"
}
GET/v1/transactions/{id}

Recupera una transacción única por id (transactions.get).

SOLICITUD
(no body)
RESPUESTA
{
  "id": "tx_01J9...",
  "txHash": "0xff5...e12"
}
GET/v1/agents/{id}

Recupera una billetera de agente (agents.get). Su página pública vive en wallet.blockchain0x.com/a/{slug}.

SOLICITUD
(no body)
RESPUESTA
{
  "id": "agt_01J9QKE...",
  "name": "research-bot",
  "public_url": "https://wallet.blockchain0x.com/a/research-bot"
}
GET/v1/agents/{id}/spend-permissions

Leer los permisos de gasto de un agente. SOLO LECTURA a través de la API - la creación y los cambios son solo en el panel.

SOLICITUD
(no body)
RESPUESTA
{
  "allowance_wei": "5000000",
  "per_tx_wei": "1000000",
  "period_seconds": 86400,
  "start_at": "2026-05-15T00:00:00Z",
  "revoked_at": null
}
VERIFICACIÓN DE FIRMA DE WEBHOOK

Siempre verifica la firma antes de confiar en el payload.

Cualquiera puede POSTear a tu URL de callback. La firma es lo que prueba que el evento realmente vino de nosotros.

Cada entrega lleva un X-Blockchain0x-Signature encabezado (t=<unix>,v1=<hex>) - un HMAC-SHA256 sobre la cadena `${t}.${rawBody}` con tu secreto de webhook, dentro de una ventana de repetición de 5 minutos. En Node, webhooks.verify de @blockchain0x/node lo hace y devuelve una unión discriminada en la que ramificas. En otros lenguajes, calcula el mismo HMAC y compara en tiempo constante. Lee el cuerpo RAW, no una copia analizada - re-serializar rompe la firma.

TIPOSCRIPT (NODE + EXPRESS)
import express from "express";
import { webhooks } from "@blockchain0x/node";

const app = express();
// Capture the RAW body. The HMAC is over the exact bytes on the wire.
app.use(express.raw({ type: "application/json" }));

app.post("/webhooks/payment", (req, res) => {
  const result = webhooks.verify({
    headers: req.headers,
    rawBody: req.body, // Buffer, raw bytes
    secret: process.env.BLOCKCHAIN0X_WEBHOOK_SECRET!,
  });
  if (!result.ok) return res.status(400).json({ code: result.code });
  // result.eventType is "payment.received" | "payment.sent" | ...
  handleEvent(result);
  res.status(200).send("ok");
});
PYTHON (FLASK)
import hmac, hashlib, os, time
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = os.environ["BLOCKCHAIN0X_WEBHOOK_SECRET"].encode()

@app.post("/webhooks/payment")
def receive():
    raw = request.get_data()  # RAW bytes - do not parse first
    sig = request.headers.get("X-Blockchain0x-Signature", "")
    ts = request.headers.get("X-Blockchain0x-Timestamp", "")
    # Header is "t=<unix>,v1=<hex>"; some proxies send bare hex + the ts header.
    parts = dict(p.split("=", 1) for p in sig.split(",") if "=" in p)
    t, v1 = parts.get("t", ts), parts.get("v1", sig)
    want = hmac.new(SECRET, t.encode() + b"." + raw, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(want, v1) or abs(time.time() - int(t)) > 300:
        abort(401)
    handle_event(request.headers.get("X-Blockchain0x-Event-Type"), request.get_json())
    return "ok", 200

El secreto del webhook se devuelve una vez cuando creas o rotas el webhook (webhooks.rotateSecret), y BLOCKCHAIN0X_WEBHOOK_SECRET es donde tu manejador lo lee. Rotar invalida el antiguo secreto, así que coordina el despliegue: establece el nuevo secreto en el entorno de tu servidor, despliega, luego rota. Los eventos enviados son payment.received, payment.sent, wallet.deployed y webhook.test - ramifica según el tipo de evento, ignora el resto.

IDEMPOATENCIA

Reintenta de manera segura. La API no pagará dos veces.

Reintentos del código del agente. Las redes pierden conexiones. Los LLMs deciden llamar a la herramienta dos veces. Para hacer esto seguro, envía un Idempotency-Key encabezado en el POST. payments.create en el SDK auto-mint un estable para ti, así que una llamada reintentada se colapsa en una única presentación en cadena en lugar de pagar dos veces. Sobrescríbelo con tu propia clave cuando quieras deduplicar la misma operación lógica entre procesos.

BASH
curl -X POST https://api.blockchain0x.com/v1/payments \
  -H "Authorization: Bearer $BLOCKCHAIN0X_API_KEY" \
  -H "Idempotency-Key: 8e2c3a40-pay-vendor-once" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "agt_123", "to": "0xRecipient", "amountWei": "10000" }'
  • Primera llamada: envía el pago, devuelve la transacción.
  • Reintenta con la misma clave: se colapsa a una única presentación en la cadena en lugar de pagar dos veces.
  • El SDK se encarga de ello: payments.create genera automáticamente una Idempotency-Key estable, por lo que una llamada reintentada es segura desde el principio.
  • Anúlalo: pase su propia clave cuando quiera deduplicar la misma operación lógica entre procesos.

El patrón recomendado es generar un UUID por operación lógica en tu código de agente (por ejemplo, un UUID por "pagar al proveedor X por el pedido Y") y reutilizarlo a través de reintentos hasta que la operación tenga éxito. Los SDKs oficiales generan automáticamente uno para payments.create si no lo especificas.

LÍMITES DE TASA

Lee tu límite de la respuesta, no de una tabla.

Los límites escalan con tu plan. En lugar de codificar números que se desvían, cada respuesta te dice dónde estás y los SDK manejan el retroceso por ti.

Encabezados en cada respuesta de éxito

  • X-RateLimit-Limit: la tarifa constante de tu plan
  • X-RateLimit-Remaining: cuántas llamadas quedan en esta ventana
  • X-RateLimit-Reset: segundos unix cuando la ventana se reinicia

Cuando alcanzas el límite (HTTP 429)

  • La respuesta incluye Retry-After en segundos
  • Los SDKs oficiales reintentan en 429 y 5xx con retroceso exponencial, respetando Retry-After
  • La mayoría del código nunca maneja 429 manualmente porque el SDK ya lo hace
COMPATIBILIDAD X402

Habla x402 con fluidez. También funciona sin él.

x402 es el protocolo abierto para pagos nativos de HTTP. La premisa: cualquier API que devuelva 402 Payment Required puede anunciar requisitos de pago en la respuesta, y cualquier cliente que entienda la especificación puede pagar y reintentar - sin registro, sin clave API, sin negociación fuera de banda. Blockchain0x envía paquetes x402 reales: un cliente del lado de pago y adaptadores de servidor del lado de recepción. El único esquema hoy es exact-usdc, en Base.

EL 402 QUE UN SERVIDOR DEVUELVE CUANDO UN LLAMADOR NO HA PAGADO
HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "version": 1,
  "resource": "https://api.example.com/paid-endpoint",
  "accepts": [
    { "scheme": "exact-usdc", "network": "eip155:8453" }
  ]
}

Lo que hace el llamador del agente

  1. Lee el cuerpo 402: versión 1, el recurso y un accepts[] no vacío de requisitos de pago (scheme exact-usdc, network eip155:8453 para Base).
  2. Construye un pago y reenvía la solicitud con el header X-Payment: exact-usdc:<base64(json)>.
  3. En la parte de pago, createX402Client({ sdk }) de @blockchain0x/x402 hace esto por ti - responde automáticamente a los 402.
  4. Tu servidor verifica el encabezado X-Payment y completa la solicitud original.

Ambos lados, paquetes reales

En el lado del pago, createX402Client({ sdk }) de @blockchain0x/x402 envuelve fetch y responde automáticamente a los 402. En el lado de recepción, createX402Plugin (Fastify) y createX402Middleware (Express) controla tus propios endpoints. O salta x402 y usa la REST API directamente - los dos se componen, así que puedes añadir x402 cuando estés listo.

PREGUNTAS FRECUENTES

Cinco preguntas de API que los desarrolladores hacen primero.

¿Puedo usar la API sin el SDK?

Sí. Los SDK son envoltorios delgados alrededor de JSON estándar sobre HTTPS con autenticación de token portador. Cualquier cosa que pueda hablar HTTP y HMAC-SHA256 puede usar la API directamente. Los SDK existen para tipado ergonómico, reintentos y generación de claves de idempotencia; son convenientes, no obligatorios. Enviamos clientes para Node, Python, Ruby, Go y JVM; en cualquier otro lenguaje, llama a la API RAW.

¿Qué pasa si mi endpoint de webhook está caído cuando se activa un evento?

Las entregas reintentan con retroceso y cada intento se registra en el panel con su código de respuesta HTTP. Si se pierde un evento, puede reconciliar desde la API - obtenga la transacción por id con GET /v1/transactions/{id} - en lugar de confiar solo en el webhook. Verifique cada entrega con webhooks.verify (o el HMAC documentado) antes de confiar en ella, y responda 2xx rápidamente para que un controlador lento no parezca una falla.

¿Cómo evito pagos duplicados si mi agente reintenta en errores de red?

Envía un encabezado Idempotency-Key en el POST. payments.create en el SDK genera automáticamente uno estable para ti, por lo que una llamada reintentada se colapsa en una única presentación en cadena en lugar de pagar dos veces. Sobrescríbelo con tu propia clave cuando quieras deduplicar la misma operación lógica entre procesos. La clave es la red de seguridad para exactamente el caso en que tu agente o la red reintentan en medio del vuelo.

¿Hay un límite de tasa?

Sí, y se escala con tu plan. En lugar de codificar números que se desvían, léelos de la respuesta: cada llamada devuelve X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset, y un 429 incluye Retry-After en segundos. Los SDK oficiales ya reintentan en 429 y 5xx con retroceso exponencial y respetan Retry-After, por lo que la mayoría del código nunca tiene que manejar esto manualmente.

¿Es esto compatible con x402?

Sí. Los paquetes x402 son reales: createX402Client({ sdk }) de @blockchain0x/x402 responde a los desafíos 402 del lado del pago, y createX402Plugin (Fastify) / createX402Middleware (Express) controlan tus propios puntos finales del lado de recepción. El único esquema hoy es exact-usdc, y el formato de wire es un X-Payment: exact-usdc:<base64(json)> encabezado de solicitud contra un 402 cuyo cuerpo anuncia la versión 1 y una lista de accepts[]. También puedes ignorar x402 y usar directamente la API REST.

Envía tu primer pago.

Gratis para comenzar. Unas pocas líneas desde la clave API hasta tu primera transferencia de USDC en Base.