Passer au contenu principal
API DE PAIEMENT

Une API de paiement conçue pour le code d'agent IA.

Une petite API REST. Webhooks signés. SDK officiels dans cinq langues. Conçu pour que votre agent puisse envoyer et régler des USDC et vérifier les paiements en quelques lignes de code.

Vue des transactions : paiements USDC entrants confirmés sur Base

L'API Blockchain0x est délibérément petite. Nous ne voulons pas que vous lisiez la documentation pendant une heure pour effectuer votre premier paiement. Nous voulons que vous copiez un extrait, colliez votre clé API et l'exécutiez.

LES POINTS D'ACCÈS PRINCIPAUX

Une petite surface, conçue pour le code d'agent.

Les routes de paiement sont ci-dessous. Les webhooks, les clés API et les permissions de dépense en lecture seule complètent la surface ; le SDK les enveloppe tous.

POST/v1/paymentsEnvoyez un paiement USDC depuis un portefeuille d'agent
GET/v1/transactions/{id}Récupérez le statut et le hash d'une transaction
POST/v1/payment-requests/{id}/settleRégler une facture avec une preuve sur la chaîne
GET/v1/agents/{id}Récupérez un portefeuille d'agent
POST/v1/agentsCréer un portefeuille d'agent
LES ÉVÉNEMENTS WEBHOOK EXPÉDIÉS

Tous signés avec HMAC-SHA256.

Signature dans le X-Blockchain0x-Signature en-tête. Fenêtre de relecture de 5 minutes. Clés d'idempotence sur chaque POST.

payment.received

USDC est arrivé dans l'un de vos portefeuilles d'agent

payment.sent

un paiement sortant de votre agent a été réglé sur la chaîne

wallet.deployed

un portefeuille intelligent d'agent a été déployé

webhook.test

une livraison de test que vous avez déclenchée depuis le tableau de bord

QUELQUES LIGNES

Envoyez USDC depuis le portefeuille de votre agent.

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
SDK OFFICIELS

Clients typés pour TypeScript et Python.

TYPESCRIPT
npm install @blockchain0x/node

Fonctionne avec Node 18+. Types TypeScript natifs.

PYTHON
pip install blockchain0x

Python 3.9+. Clients synchrones et asynchrones.

SCHÉMAS DE POINTS DE TERMINAISON COMPLETS

Les corps de requête que le SDK enveloppe.

Voici les entrées vérifiées pour chaque route. Les réponses sont montrées ici en abrégé ; les formes typées complètes se trouvent dans le SDK et la référence API. Les montants sont des unités de base USDC (6 décimales).

POST/v1/payments

Envoyez un paiement USDC (payments.create). amountWei est en unités de base USDC (6 décimales). Peut renvoyer 503 jusqu'à ce que l'adaptateur de chaîne soit câblé.

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

Régler une demande de paiement (facture) créée dans le tableau de bord, avec une preuve sur la chaîne (paymentRequests.settle). Il n'y a pas de route de création - uniquement le règlement.

DEMANDE
{
  "txHash": "0xff5...e12",
  "payerAddress": "0xBuyer...",
  "amountUsdcVerified": "0.10"
}
RÉPONSE
{
  "txHash": "0xff5...e12"
}
GET/v1/transactions/{id}

Récupérez une seule transaction par id (transactions.get).

DEMANDE
(no body)
RÉPONSE
{
  "id": "tx_01J9...",
  "txHash": "0xff5...e12"
}
GET/v1/agents/{id}

Récupérez un portefeuille d'agent (agents.get). Sa page publique se trouve à wallet.blockchain0x.com/a/{slug}.

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

Lire les autorisations de dépenses d'un agent. EN LECTURE SEULE via l'API - la création et les modifications sont uniquement dans le tableau de bord.

DEMANDE
(no body)
RÉPONSE
{
  "allowance_wei": "5000000",
  "per_tx_wei": "1000000",
  "period_seconds": 86400,
  "start_at": "2026-05-15T00:00:00Z",
  "revoked_at": null
}
VÉRIFICATION DE LA SIGNATURE DES WEBHOOKS

Vérifiez toujours la signature avant de faire confiance au payload.

Tout le monde peut POST à votre URL de rappel. La signature prouve que l'événement vient réellement de nous.

Chaque livraison porte un X-Blockchain0x-Signature en-tête (t=<unix>,v1=<hex>) - un HMAC-SHA256 sur la chaîne `${t}.${rawBody}` avec votre secret de webhook, dans une fenêtre de relecture de 5 minutes. Dans Node, webhooks.verify de @blockchain0x/node le fait et renvoie une union discriminée sur laquelle vous branchez. Dans d'autres langages, calculez le même HMAC et comparez en temps constant. Lisez le corps RAW, pas une copie analysée - la re-sérialisation casse la signature.

TYPESCRIPT (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

Le secret du webhook est retourné une fois lorsque vous créez ou faites tourner le webhook (webhooks.rotateSecret), et BLOCKCHAIN0X_WEBHOOK_SECRET est l'endroit où votre gestionnaire le lit. La rotation invalide l'ancien secret, donc coordonnez le déploiement : définissez le nouveau secret dans l'environnement de votre serveur, déployez, puis faites tourner. Les événements expédiés sont payment.received, payment.sent, wallet.deployed et webhook.test - branchez-vous sur le type d'événement, ignorez le reste.

IDEMPOTENCE

Réessayez en toute sécurité. L'API ne paiera pas deux fois.

Les codes d'agent réessaient. Les réseaux perdent des connexions. Les LLM décident d'appeler l'outil deux fois. Pour sécuriser cela, envoyez un Idempotency-Key en-tête sur le POST. payments.create dans le SDK crée automatiquement un stable pour vous, donc un appel réessayé se réduit à une seule soumission sur la chaîne au lieu de payer deux fois. Remplacez-le par votre propre clé lorsque vous souhaitez dédupliquer la même opération logique à travers les processus.

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" }'
  • Premier appel : soumet le paiement, renvoie la transaction.
  • Réessayez avec la même clé : se réduit à une seule soumission on-chain au lieu de payer deux fois.
  • Le SDK s'en occupe : payments.create génère automatiquement une clé d'idempotence stable, donc un appel réessayé est sûr dès le départ.
  • Remplacez-le : passez votre propre clé lorsque vous souhaitez dédupliquer la même opération logique entre les processus.

Le modèle recommandé est de générer un UUID par opération logique dans votre code d'agent (par exemple, un UUID par "payer le fournisseur X pour la commande Y") et de le réutiliser à travers les réessais jusqu'à ce que l'opération réussisse. Les SDK officiels en génèrent automatiquement un pour payments.create si vous ne le spécifiez pas.

LIMITES DE TAUX

Lisez votre limite à partir de la réponse, pas d'un tableau.

Les limites s'adaptent à votre plan. Plutôt que de coder en dur des chiffres qui dérivent, chaque réponse vous indique où vous en êtes et les SDK gèrent le retour pour vous.

En-têtes sur chaque réponse de succès

  • X-RateLimit-Limit: le tarif stable de votre plan
  • X-RateLimit-Remaining: combien d'appels restants dans cette fenêtre
  • X-RateLimit-Reset: secondes unix lorsque la fenêtre se réinitialise

Lorsque vous atteignez le plafond (HTTP 429)

  • La réponse inclut Retry-After en secondes
  • Les SDK officiels réessaient sur 429 et 5xx avec un retour exponentiel, honorant Retry-After
  • La plupart des codes ne gèrent jamais 429 manuellement car le SDK le fait déjà
COMPATIBILITÉ X402

Parle x402 couramment. Fonctionne sans aussi.

x402 est le protocole ouvert pour les paiements natifs HTTP. Le principe : toute API qui renvoie 402 Payment Required peut annoncer des exigences de paiement dans la réponse, et tout client qui comprend la spécification peut payer et réessayer - pas d'inscription, pas de clé API, pas de négociation hors bande. Blockchain0x expédie de véritables packages x402 : un client côté paiement et des adaptateurs de serveur côté réception. Le seul schéma aujourd'hui est exact-usdc, sur Base.

LE 402 QU'UN SERVEUR RETOURNE QUAND UN APPELANT N'A PAS PAYÉ
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" }
  ]
}

Ce que fait l'appelant de l'agent

  1. Lit le corps 402: version 1, la ressource, et un accepts[] non vide d'exigences de paiement (scheme exact-usdc, network eip155:8453 pour Base).
  2. Crée un paiement et renvoie la requête avec un en-tête X-Payment: exact-usdc:<base64(json)>.
  3. Côté paiement, createX402Client({ sdk }) de @blockchain0x/x402 le fait pour vous - il répond automatiquement aux 402.
  4. Votre serveur vérifie l'en-tête X-Payment et exécute la requête d'origine.

Les deux côtés, vrais packages

Du côté du paiement, createX402Client({ sdk }) de @blockchain0x/x402 enveloppe fetch et répond automatiquement aux 402. Du côté de la réception, createX402Plugin (Fastify) et createX402Middleware (Express) créez vos propres points de terminaison. Ou sautez x402 et utilisez directement l'API REST - les deux se composent, donc vous pouvez ajouter x402 lorsque vous êtes prêt.

QUESTIONS FRÉQUEMMENT POSÉES

Cinq questions API que les développeurs posent en premier.

Puis-je utiliser l'API sans le SDK ?

Oui. Les SDK sont de fins wrappers autour de JSON standard sur HTTPS avec authentification par token porteur. Tout ce qui peut parler HTTP et HMAC-SHA256 peut utiliser l'API directement. Les SDK existent pour une saisie ergonomique, des réessais et la génération de clés d'idempotence ; ils sont pratiques, mais pas obligatoires. Nous expédions des clients pour Node, Python, Ruby, Go et JVM ; dans tout autre langage, appelez l'API brute.

Que se passe-t-il si mon point de terminaison webhook est hors service lorsque qu'un événement se déclenche ?

Les livraisons sont réessayées avec un backoff et chaque tentative est enregistrée dans le tableau de bord avec son code de réponse HTTP. Si vous manquez un événement, vous pouvez le réconcilier depuis l'API - récupérez la transaction par id avec GET /v1/transactions/{id} - plutôt que de vous fier uniquement au webhook. Vérifiez chaque livraison avec webhooks.verify (ou le HMAC documenté) avant de lui faire confiance, et répondez rapidement avec 2xx afin qu'un gestionnaire lent ne ressemble pas à un échec.

Comment puis-je éviter les paiements en double si mon agent réessaie en cas d'erreurs réseau ?

Envoyez un en-tête Idempotency-Key sur le POST. payments.create dans le SDK génère automatiquement un stable pour vous, donc un appel réessayé se réduit à une seule soumission sur la chaîne plutôt que de payer deux fois. Remplacez-le par votre propre clé lorsque vous souhaitez dédupliquer la même opération logique à travers les processus. La clé est le filet de sécurité pour exactement le cas où votre agent ou le réseau réessaie en vol.

Y a-t-il une limite de taux ?

Oui, et cela évolue avec votre plan. Plutôt que de coder en dur des chiffres qui dérivent, lisez-les dans la réponse : chaque appel renvoie X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset, et un 429 inclut Retry-After en secondes. Les SDK officiels réessaient déjà sur 429 et 5xx avec un retour en arrière exponentiel et respectent Retry-After, donc la plupart du code n'a jamais à gérer cela manuellement.

Est-ce compatible avec x402 ?

Oui. Les packages x402 sont réels : createX402Client({ sdk }) de @blockchain0x/x402 répond aux défis 402 du côté paiement, et createX402Plugin (Fastify) / createX402Middleware (Express) contrôlent vos propres points de terminaison du côté réception. Le seul schéma aujourd'hui est exact-usdc, et le format de transmission est un X-Payment : exact-usdc:<base64(json)> en-tête de requête contre un 402 dont le corps annonce la version 1 et une liste accepts[]. Vous pouvez également ignorer x402 et utiliser directement l'API REST.

Expédiez votre premier paiement.

Gratuit pour commencer. Quelques lignes depuis la clé API jusqu'à votre premier transfert USDC sur Base.