# Coinbase-Commerce-kompatible API

> Wechseln Sie von Coinbase Commerce zu blockwallets, indem Sie Base-URL des SDK und Schlüssel ändern: unterstützte Charge-Endpoints, Webhooks und Signaturen sowie Unterschiede.
>
> HTML: https://blockwallets.io/docs/coinbase-commerce?lang=de · English: https://blockwallets.io/docs/coinbase-commerce.md?lang=en

## Coinbase-Commerce-kompatible API

Charge-Endpoints, der Header `X-CC-Api-Key`, das Charge-Objekt und mit `X-CC-Webhook-Signature` signierte Webhooks folgen der Dokumentation von Coinbase Commerce, sodass die offiziellen SDKs nach der Änderung einer einzigen Zeile funktionieren. Coinbase Commerce hat am 2026-03-31 aufgehört, Händler außerhalb der USA und Singapurs zu bedienen. Sie kommen von woanders? Siehe die [Migrationsübersicht](https://blockwallets.io/docs/migrate?lang=de).

Darunter liegt eine ganz normale blockwallets-Rechnung: Die Empfangsadressen gehören Ihnen, die Zahlungsseite ist unser gehosteter Checkout, und eine Zahlung zählt erst, wenn sie on-chain bestätigt und gegen einen zweiten Node geprüft wurde. Unten: drei Schritte, dann was jede API unterstützt und **wie sie sich vom Original unterscheidet** – Parameter, die wir nicht umsetzen, liefern einen Fehler, statt stillschweigend ignoriert zu werden.

### Drei Schritte

- Besorgen Sie sich ein Händlerkonto ([auf der Startseite beantragen](https://blockwallets.io/?lang=de#join)) und tragen Sie im Dashboard unter „Entwickler › Integration & Keys“ bei „Website-Domains“ Ihre Domains ein. Callback-URLs (`ipn_callback_url`) und Weiterleitungs-URLs (`success_url` / `cancel_url` / `redirect_url`) müssen auf diesen Domains oder der Domain Ihrer Callback-URL liegen – ein geleakter Schlüssel kann Webhooks so nicht woandershin lenken.

- Erzeugen Sie kompatible Zugangsdaten im Händler-Dashboard unter „Entwickler › Integration & Keys“, je einen Satz für Live und für Test: NOWPayments erhält einen **API key + IPN secret**, Coinbase Commerce einen **API key + Webhook shared secret**. Sie werden nur einmal angezeigt; wir speichern nur Hashes / Chiffretext.

- Richten Sie Ihren Code auf die untenstehende Base-URL und nutzen Sie die neuen Schlüssel. Testen Sie zuerst mit den Test-Zugangsdaten auf Testnets und wechseln Sie dann auf Live.

| Vorher | Nachher | Auth-Header | Webhook-Signatur |
| --- | --- | --- | --- |
| `https://api.commerce.coinbase.com` | `https://blockwallets.io/coinbase/` | `X-CC-Api-Key` | `X-CC-Webhook-Signature` (HMAC-SHA256) |

### Coinbase Commerce

Alle offiziellen SDKs nehmen eine Base-URL – ändern Sie eine Zeile (achten Sie auf den abschließenden `/`):

```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", …}], …}}
```

#### Unterstützte Endpoints

| Endpoint | Hinweise |
| --- | --- |
| `POST /charges` | Charge erstellen; `hosted_url` ist unser gehosteter Checkout; 1 Stunde gültig |
| `GET /charges/:code_or_id` | Abfrage per 8-stelligem Code oder id |
| `GET /charges` | Liste: `limit` (≤100) / `starting_after` / `ending_before` / `order`, mit demselben `pagination`-Objekt |
| `POST /charges/:code_or_id/cancel` | Charge stornieren, für die noch keine Zahlung gesehen wurde |

Nicht verfügbar: `/charges/:code/resolve` (400 – behandeln Sie unterzahlte Charges im Dashboard), `/checkouts`, `/events`, `/invoices` (404).

#### Webhooks

Coinbase-Webhooks gelten kontoweit, unsere ebenfalls: Sie gehen an die im Dashboard gesetzte **Callback-URL** (mit Test-Zugangsdaten erstellte Charges gehen an die Test-Callback-URL). Der Body ist der von Coinbase `{id, scheduled_for, attempt_number, event: {id, type, api_version, created_at, data}}` mit der vollständigen Charge in `data`; `X-CC-Webhook-Signature` = HMAC-SHA256(shared secret, Rohtext), sodass `Webhook.verifyEventBody` der SDKs unverändert funktioniert. Bei Wiederholungen bleibt `event.id` gleich und `attempt_number` steigt – deduplizieren Sie über `event.id`.

```nodejs
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)
```

| Event | Wann | Letzter Timeline-Eintrag |
| --- | --- | --- |
| `charge:confirmed` | Bezahlt (on-chain bestätigt und gegengeprüft; Überzahlung zählt) | `COMPLETED` |
| `charge:failed` | Unbezahlt abgelaufen / von Ihnen storniert / unterzahlt abgelaufen | `EXPIRED` / `CANCELED` / `UNRESOLVED` (Kontext `UNDERPAID`) |

Bei Abfragen sehen Sie außerdem `NEW` (wartet auf Zahlung) und `PENDING` (Zahlung on-chain gesehen, wird bestätigt). **Liefern Sie bei `charge:confirmed` aus**: `charge:created`, `charge:pending`, `charge:delayed` und `charge:resolved` senden wir nicht.

#### Unterschiede zu Coinbase Commerce

- `pricing_type` muss `fixed_price` sein; `local_price.currency` muss USD sein (USDC / USDT zu 1:1). `no_price` und andere Fiat-Währungen liefern 400.

- Die Adresse erscheint, sobald der Kunde im Checkout Coin und Netzwerk wählt: `addresses` enthält nur dieses Netzwerk, `pricing` nur `local` sowie nach der Wahl `settlement`; keine `exchange_rates`, kein `checkout` und keine Branding-Felder.

- `metadata` wird unverändert gespeichert und zurückgegeben (bis 4 KB).

- Erstattungen erscheinen nicht in der Timeline; sehen Sie sie im Dashboard.

### Testmodus

Mit Test-Zugangsdaten erstellte Charges und Zahlungen laufen im Testnet der jeweiligen Chain, und ihre Webhooks werden mit dem Test-IPN-secret / shared secret signiert – völlig getrennt von Live: Ein Test-Schlüssel sieht keine Live-Zahlungen.

Alles Übrige (Checkout, Bestätigungen, Netzwerke und Mindestbeträge, Erstattungen) funktioniert wie in der [Hauptdokumentation](https://blockwallets.io/docs/cryptomus?lang=de).
