API compatible Coinbase Commerce

Ouvrir dans ChatGPTOuvrir dans Claude

Les endpoints charge, l’en-tête X-CC-Api-Key, l’objet charge et les webhooks signés avec X-CC-Webhook-Signature suivent la documentation de Coinbase Commerce : les SDK officiels fonctionnent donc après le changement d’une seule ligne. Coinbase Commerce a cessé de servir les marchands hors des États-Unis et de Singapour le 2026-03-31. Vous venez d’ailleurs ? Consultez l’aperçu de la migration.

Dessous, c’est une facture blockwallets ordinaire : les adresses de réception sont les vôtres, la page de paiement est notre caisse hébergée, et un paiement ne compte qu’une fois confirmé on-chain et recoupé avec un second nœud. Ci-dessous : trois étapes, puis ce que chaque API prend en charge et en quoi elle diffère de l’originale — les paramètres que nous n’implémentons pas renvoient une erreur au lieu d’être ignorés en silence.

Trois étapes

  1. Obtenez un compte marchand (demandez-le sur la page d’accueil) et ajoutez vos domaines dans « Domaines du site web », sous « Développeurs › Intégration et clés » du tableau de bord. Les URL de callback (ipn_callback_url) et de redirection (success_url / cancel_url / redirect_url) doivent se trouver sur ces domaines ou sur le domaine de votre URL de callback — une clé divulguée ne peut pas rediriger les webhooks ailleurs.
  2. Générez des identifiants compatibles dans le tableau de bord marchand, sous « Développeurs › Intégration et clés », un jeu pour live et un pour test : NOWPayments reçoit une API key + IPN secret, Coinbase Commerce une API key + webhook shared secret. Ils ne sont affichés qu’une fois ; nous ne conservons que des hashs / du texte chiffré.
  3. Pointez votre code vers l’URL de base ci-dessous et utilisez les nouvelles clés. Lancez d’abord sur les testnets avec les identifiants de test, puis passez en live.
AvantAprèsEn-tête d’authentificationSignature du webhook
https://api.commerce.coinbase.comhttps://blockwallets.io/coinbase/X-CC-Api-KeyX-CC-Webhook-Signature (HMAC-SHA256)

Coinbase Commerce

Tous les SDK officiels acceptent une URL de base — changez une ligne (attention au / final) :

SDK
// Node(coinbase-commerce-node)
const { Client } = require("coinbase-commerce-node");
- Client.init(process.env.COINBASE_COMMERCE_API_KEY);
+ Client.init(process.env.COINBASE_COMMERCE_API_KEY, "https://blockwallets.io/coinbase/");

# Python(coinbase-commerce)
- client = Client(api_key=API_KEY)
+ client = Client(api_key=API_KEY, base_api_uri="https://blockwallets.io/coinbase/")

// PHP(coinbase/coinbase-commerce)
- ApiClient::init($apiKey);
+ ApiClient::init($apiKey, 'https://blockwallets.io/coinbase/');
curl
curl -X POST https://blockwallets.io/coinbase/charges \
  -H "X-CC-Api-Key: $COINBASE_COMMERCE_API_KEY" -H "X-CC-Version: 2018-03-22" \
  -H "content-type: application/json" \
  -d '{"name":"Order #12345","description":"Pro plan","pricing_type":"fixed_price",
       "local_price":{"amount":"100.00","currency":"USD"},
       "redirect_url":"https://shop.example/success","cancel_url":"https://shop.example/cancel",
       "metadata":{"order_id":"12345"}}'
# → 201 {"data": {"id": "…", "code": "7C7V5ECK", "hosted_url": "https://blockwallets.io/pay/inv_…", "timeline": [{"status": "NEW", …}], …}}

Endpoints pris en charge

EndpointRemarques
POST /chargesCrée une charge (charge) ; hosted_url est notre caisse hébergée ; valable 1 heure
GET /charges/:code_or_idRecherche par code de 8 caractères ou par id
GET /chargesListe : limit (≤100) / starting_after / ending_before / order, avec le même objet pagination
POST /charges/:code_or_id/cancelAnnule une charge (charge) sans aucun paiement vu pour l’instant

Non disponibles : /charges/:code/resolve (400 — traitez les charges sous-payées dans le tableau de bord), /checkouts, /events, /invoices (404).

Webhooks

Les webhooks de Coinbase sont au niveau du compte, et les nôtres aussi : ils vont à l’URL de callback définie dans votre tableau de bord (les charges créées avec des identifiants de test vont à l’URL de callback de test). Le corps est celui de Coinbase, {id, scheduled_for, attempt_number, event: {id, type, api_version, created_at, data}}, avec la charge complète dans data ; X-CC-Webhook-Signature = HMAC-SHA256(shared secret, corps brut), de sorte que le Webhook.verifyEventBody des SDK fonctionne tel quel. Lors des nouvelles tentatives, event.id reste identique et attempt_number augmente — dédoublonnez sur event.id.

Node.js
import crypto from "node:crypto";

// Same as the SDK's Webhook.verifySigHeader: HMAC-SHA256(shared secret, raw body)
function verifyWebhook(rawBody, sig, sharedSecret) {
  const hmac = crypto.createHmac("sha256", sharedSecret).update(rawBody, "utf8").digest("hex");
  return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(sig || ""));
}
// verifyWebhook(rawBody, req.headers["x-cc-webhook-signature"], process.env.COINBASE_WEBHOOK_SECRET)
// or with the official SDK:Webhook.verifyEventBody(rawBody, signature, sharedSecret)
ÉvénementQuandDernière entrée de la timeline
charge:confirmedPayé (confirmé on-chain et recoupé ; le trop-perçu compte)COMPLETED
charge:failedExpiré sans paiement / annulé par vous / expiré sous-payéEXPIRED / CANCELED / UNRESOLVED (contexte UNDERPAID)

Lors d’une requête, vous verrez aussi NEW (en attente de paiement) et PENDING (paiement vu on-chain, en cours de confirmation). Livrez sur charge:confirmed : nous n’envoyons ni charge:created, ni charge:pending, ni charge:delayed, ni charge:resolved.

Différences avec Coinbase Commerce

Mode test

Les charges et paiements créés avec des identifiants de test fonctionnent sur le testnet de chaque chaîne et leurs webhooks sont signés avec l’IPN secret / shared secret de test — totalement séparés du live : une clé de test ne voit pas les paiements live.

Tout le reste (caisse, confirmations, réseaux et minimums, remboursements) fonctionne comme dans la documentation principale.