Zum Inhalt springen
Crypto Merchant

Entwickler

Feste Wallets

Geben Sie jedem Ihrer Kunden eigene Einzahlungsadressen, die sich nie ändern, eine pro Netzwerk. Jede Einzahlung wird Ihrem Guthaben bei Crypto Merchant gutgeschrieben, und Ihr Server erfährt, welcher Kunde sie gesendet hat, damit Sie das richtige Konto aufladen können.

So erhalten Sie feste Wallets

Wählen Sie bei der Registrierung Kunden-Wallets, oder bitten Sie den Support, feste Wallets für ein bestehendes Konto freizuschalten. Solange sie nicht freigeschaltet sind, antworten diese Endpunkte mit 403 sticky_wallets_unavailable. Sie verwenden dieselbe Basis-URL, dieselben geheimen Schlüssel und dasselbe Fehlerformat wie der Rest der API.

Bevor Sie beginnen

  1. 1

    Schließen Sie die Einrichtung ab und wählen Sie Ihre Coins. Jeder Kunde erhält eine Adresse in den Netzwerken der Coins, die Sie akzeptieren (Portal, Einstellungen).

  2. 2

    Erstellen Sie einen geheimen Schlüssel. Öffnen Sie im Portal Entwickler und erstellen Sie einen API-Schlüssel. Er wird nur einmal angezeigt: Bewahren Sie ihn auf Ihrem Server auf, zum Beispiel als CM_SECRET_KEY, niemals in einer Webseite oder einer App.

  3. 3

    Fügen Sie einen Webhook-Endpunkt hinzu. Fügen Sie ebenfalls unter Entwickler Ihre URL mit den Ereignissen deposit.pending, deposit.confirmed und deposit.dropped (oder allen Ereignissen) hinzu. Bewahren Sie sein Signaturgeheimnis whsec_… auf, um damit jede Anfrage zu prüfen.

So funktioniert es

  1. 1

    Ein Kunde öffnet die Einzahlungsseite auf Ihrer Website.

  2. 2

    Ihr Server ruft POST /sticky-wallets mit Ihrer eigenen ID für diesen Kunden auf. Der erste Aufruf erstellt die Adressen, jeder spätere Aufruf liefert dieselben.

  3. 3

    Sie zeigen die Adresse mit QR-Code für den Coin an, den der Kunde wählt.

  4. 4

    Wenn die Coins eintreffen, erhalten Sie deposit.pending und dann deposit.confirmed, sobald das Netzwerk sie bestätigt hat.

  5. 5

    Bei deposit.confirmed schreiben Sie den Betrag dem Kunden gut, der in sticky_wallet.reference steht.

Wallet eines Kunden abrufen

POST/sticky-wallets

Erstellt beim ersten Aufruf die Wallet des Kunden und gibt bei jedem späteren Aufruf dieselbe zurück: 201, wenn sie gerade erstellt wurde, danach 200. Sie können den Endpunkt bedenkenlos jedes Mal aufrufen, wenn die Einzahlungsseite geöffnet wird.

Body-Parameter

referenceErforderlichstring
Ihre ID für diesen Kunden: 1 bis 120 Buchstaben, Ziffern oder . _ : @ + -, beginnend mit einem Buchstaben oder einer Ziffer. Eine Wallet pro Referenz, dauerhaft.
labelOptionalstring
Ein Name, den Sie im Portal sehen. Erneutes Senden ersetzt ihn.
metadataOptionalobject
Ein eigenes Objekt, bis zu 4 KB. Erneutes Senden ersetzt es.
curl
curl https://cryptomerchant.online/api/v1/sticky-wallets \
  -H "Authorization: Bearer $CM_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "user-1042",
    "label": "Jane Doe",
    "metadata": { "plan": "pro" }
  }'
Node.js
// On your server, when a customer opens their deposit page
export async function depositAddresses(userId) {
  const res = await fetch("https://cryptomerchant.online/api/v1/sticky-wallets", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.CM_SECRET_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ reference: String(userId) }),
  });
  if (!res.ok) {
    const { error } = await res.json();
    throw new Error(`${error.code}: ${error.message}`);
  }
  const wallet = await res.json();
  return wallet.addresses; // [{ network, address, coins: [...] }, …]
}

Das Objekt der festen Wallet

idstring
Die ID der Wallet, beginnend mit sw_.
referencestring
Ihre ID für den Kunden.
addressesarray
Ein Eintrag pro Netzwerk: network (tron, evm, sol, btc oder ltc), die address und die coins, die sie akzeptiert. Die evm-Adresse ist auf Ethereum, BNB Smart Chain, Polygon, Base und Arbitrum dieselbe.
pending_networksarray
Netzwerke, deren Adresse noch vorbereitet wird, was selten vorkommt. Rufen Sie den Endpunkt in ein paar Minuten erneut auf, dann erscheinen sie in addresses.
created_atstring
Wann die Wallet erstellt wurde.
sticky_wallet
{
  "id": "sw_8Kd2pQx7Vb1mNc3T",
  "object": "sticky_wallet",
  "reference": "user-1042",
  "label": "Jane Doe",
  "metadata": { "plan": "pro" },
  "addresses": [
    {
      "network": "tron",
      "address": "TXbajeGHq4Vb…",
      "coins": [
        { "id": "TRX.TRON", "symbol": "TRX", "network": "Tron" },
        { "id": "USDT.TRON", "symbol": "USDT", "network": "Tron" }
      ]
    },
    {
      "network": "evm",
      "address": "0xE550EC6d…",
      "coins": [
        { "id": "ETH.ETH", "symbol": "ETH", "network": "Ethereum" },
        { "id": "BNB.BSC", "symbol": "BNB", "network": "BNB Smart Chain" },
        { "id": "USDT.BSC", "symbol": "USDT", "network": "BNB Smart Chain" }
      ]
    }
  ],
  "pending_networks": [],
  "created_at": "2026-10-29T18:20:41.000Z"
}

Sagen Sie Kunden, was sie senden sollen

Zeigen Sie jede Adresse zusammen mit den dafür aufgeführten Coins an. Coins in einem anderen Netzwerk oder nicht aufgeführte Token werden nicht automatisch gutgeschrieben: Wenden Sie sich an den Support, wenn ein Kunde so etwas sendet.

Wallets finden

GET/sticky-wallets

GET/sticky-wallets/{id}

Suchen Sie eine Wallet über Ihre Referenz, rufen Sie eine über ihre ID ab oder blättern Sie durch alle, neueste zuerst: limit von 1 bis 100, starting_after mit der ID der letzten Wallet, die Sie haben, und has_more zeigt an, ob es weitere gibt.

curl
# By your reference
curl "https://cryptomerchant.online/api/v1/sticky-wallets?reference=user-1042" \
  -H "Authorization: Bearer $CM_SECRET_KEY"

# By id
curl https://cryptomerchant.online/api/v1/sticky-wallets/sw_8Kd2pQx7Vb1mNc3T \
  -H "Authorization: Bearer $CM_SECRET_KEY"

# All of them, 50 at a time
curl "https://cryptomerchant.online/api/v1/sticky-wallets?limit=50&starting_after=sw_8Kd2pQx7Vb1mNc3T" \
  -H "Authorization: Bearer $CM_SECRET_KEY"
Antwort
{
  "object": "list",
  "data": [ { "id": "sw_8Kd2pQx7Vb1mNc3T", "object": "sticky_wallet", … } ],
  "has_more": false
}

Einzahlungen auflisten

GET/deposits

Alle Einzahlungen auf die Wallets Ihrer Kunden, neueste zuerst. Filtern Sie nach sticky_wallet (einer Wallet-ID) und status (pending, confirmed oder dropped) und blättern Sie mit limit und starting_after (einer Einzahlungs-ID). So holen Sie nach, was Ihrem Server entgangen ist, wenn Webhooks nicht angekommen sind.

curl
curl "https://cryptomerchant.online/api/v1/deposits?sticky_wallet=sw_8Kd2pQx7Vb1mNc3T&status=confirmed&limit=20" \
  -H "Authorization: Bearer $CM_SECRET_KEY"

Das Einzahlungsobjekt

idstring
Die ID der Einzahlung. Verwenden Sie sie, um jede Einzahlung nur einmal gutzuschreiben.
statusstring
pending: im Netzwerk erkannt, wartet auf Bestätigungen. confirmed: endgültig und Ihrem Guthaben gutgeschrieben. dropped: wurde nie bestätigt.
sticky_walletobject
Die Wallet, an die sie gesendet wurde: id und Ihre reference.
coinobject
Der Coin und sein Netzwerk.
amountstring
Was der Kunde gesendet hat, im Coin.
feestring
Die Gebühr, im Coin.
net_amountstring
Was Ihrem Guthaben gutgeschrieben wurde (Betrag minus Gebühr), sobald die Einzahlung bestätigt ist.
amount_usdstring
Ihr Wert in US-Dollar beim Eingang.
tx_hashstring
Der Transaktions-Hash; explorer_url öffnet ihn in einem Block-Explorer.
deposit
{
  "id": "cmvu1x9a0000l10u8k2f3h7q",
  "object": "deposit",
  "status": "confirmed",
  "sticky_wallet": { "id": "sw_8Kd2pQx7Vb1mNc3T", "reference": "user-1042" },
  "coin": { "id": "USDT.TRON", "symbol": "USDT", "network": "Tron" },
  "address": "TXbajeGHq4Vb…",
  "amount": "250",
  "amount_usd": "250.00",
  "fee": "2.5",
  "net_amount": "247.5",
  "from_address": "TQn9Y2khEsLJ…",
  "tx_hash": "36423ec5…f00d4a",
  "explorer_url": "https://tronscan.org/#/transaction/36423ec5…f00d4a",
  "confirmations": 19,
  "detected_at": "2026-10-29T18:31:02.000Z",
  "confirmed_at": "2026-10-29T18:32:01.000Z"
}

Webhooks

Einzahlungsereignisse enthalten das Einzahlungsobjekt in data. Prüfen Sie die Signatur wie unter Webhooks beschrieben, bevor Sie einem Ereignis vertrauen.

deposit.pending
Eine Einzahlung auf die feste Wallet eines Ihrer Kunden wurde on-chain erkannt und wartet auf Bestätigungen.
deposit.confirmed
Eine Einzahlung auf eine feste Wallet wurde bestätigt und Ihrem Guthaben abzüglich der Gebühr gutgeschrieben: Schreiben Sie sie jetzt diesem Kunden gut.
deposit.dropped
Eine erkannte Einzahlung auf eine feste Wallet wurde nie bestätigt (fehlgeschlagen oder aus der Chain entfernt).
server.js · dem Kunden gutschreiben
import express from "express";
import { verifyWebhook } from "./verify-webhook.js"; // from the Webhooks page
import { db } from "./db.js"; // your database; table webhook_events as on the Webhooks page

const app = express();

app.post(
  "/webhooks/crypto-merchant",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    let event;
    try {
      event = verifyWebhook(req.body, req.get("CM-Signature"), process.env.CM_WEBHOOK_SECRET);
    } catch {
      return res.sendStatus(400);
    }
    try {
      // Save first: a repeat delivery has the same event.id and is ignored
      await db.query(
        "INSERT INTO webhook_events (id, type, payload) VALUES ($1, $2, $3) ON CONFLICT (id) DO NOTHING",
        [event.id, event.type, event],
      );
    } catch {
      return res.sendStatus(500); // not saved: we send it again later
    }
    res.sendStatus(200); // stored, so confirm it
    processEvents().catch(console.error); // or run it from a background job
  },
);

async function processEvents() {
  const { rows } = await db.query(
    "SELECT payload FROM webhook_events WHERE processed_at IS NULL ORDER BY received_at",
  );
  for (const { payload: event } of rows) {
    const deposit = event.data;
    if (event.type === "deposit.pending") {
      // Optional: show "deposit on its way" to deposit.sticky_wallet.reference
    }
    if (event.type === "deposit.confirmed") {
      // Credit once: creditCustomer must skip a deposit.id it has already credited
      await creditCustomer({
        customerId: deposit.sticky_wallet.reference,
        depositId: deposit.id,
        coin: deposit.coin.id, // e.g. "USDT.TRON"
        amount: deposit.net_amount, // or deposit.amount to cover the fee yourself
        txHash: deposit.tx_hash,
      });
    }
    await db.query("UPDATE webhook_events SET processed_at = now() WHERE id = $1", [event.id]);
  }
}

Fehler

400
invalid_request: Ein Feld fehlt oder ist falsch; die Meldung nennt das Feld.
401
unauthorized: Der geheime Schlüssel fehlt oder ist ungültig.
403
sticky_wallets_unavailable: Feste Wallets sind für dieses Unternehmen nicht freigeschaltet, oder seine Einrichtung ist noch nicht abgeschlossen.
404
not_found: Es gibt keine feste Wallet mit dieser ID.

Bewährte Praktiken

  • Schreiben Sie einem Kunden nur bei deposit.confirmed etwas gut, und nur einmal pro Einzahlungs-id: Ein Webhook kann mehr als einmal ankommen.
  • Entscheiden Sie, wer die Gebühr trägt: Schreiben Sie net_amount gut, um sie weiterzugeben, oder amount, um sie selbst zu übernehmen.
  • Ihre Referenz ist der Schlüssel: Ein erneuter Aufruf von POST /sticky-wallets ist immer sicher, Sie müssen die Adressen also nicht speichern.
  • Bewahren Sie den geheimen Schlüssel auf Ihrem Server auf. Falls er offengelegt wurde, widerrufen Sie ihn unter Entwickler und erstellen Sie einen neuen.
  • Wenn Ihr Endpunkt nicht erreichbar war, listen Sie die confirmed-Einzahlungen auf und schreiben Sie die gut, die Sie noch nicht verarbeitet haben.
  • Sie bauen ein Kundenguthaben auf? Lesen Sie, wie Sie Krypto-Aufladungen für Kundenkonten einrichten.