Pular para o conteúdo
Crypto Merchant

Desenvolvedores

Carteiras fixas

Dê a cada um dos seus clientes endereços de depósito próprios que nunca mudam, um por rede. Cada depósito é somado ao seu saldo no Crypto Merchant, e o seu servidor fica sabendo qual cliente o enviou, para que você recarregue a conta certa.

Como obter carteiras fixas

Escolha carteiras de clientes ao se cadastrar, ou peça ao suporte para ativar as carteiras fixas em uma conta que você já tem. Até que estejam ativadas, estes endpoints respondem 403 sticky_wallets_unavailable. Eles usam a mesma URL base, as mesmas chaves secretas e o mesmo formato de erro do restante da API.

Antes de começar

  1. 1

    Conclua a configuração e escolha suas moedas. Cada cliente recebe um endereço nas redes das moedas que você aceita (portal, Configurações).

  2. 2

    Crie uma chave secreta. No portal, abra Desenvolvedores e crie uma chave de API. Ela é exibida só uma vez: guarde-a no seu servidor, por exemplo como CM_SECRET_KEY, nunca em uma página web ou em um app.

  3. 3

    Adicione um endpoint de webhook. Também em Desenvolvedores, adicione a sua URL com os eventos deposit.pending, deposit.confirmed e deposit.dropped (ou todos os eventos). Guarde o segredo de assinatura dele, whsec_…, para verificar cada solicitação.

Como funciona

  1. 1

    Um cliente abre a página de depósito do seu site.

  2. 2

    O seu servidor chama POST /sticky-wallets com o seu próprio ID para esse cliente. A primeira chamada cria os endereços; todas as chamadas seguintes retornam os mesmos.

  3. 3

    Você mostra o endereço, com um QR code, da moeda que o cliente escolher.

  4. 4

    Quando as moedas chegam, você recebe deposit.pending e depois deposit.confirmed, assim que a rede as confirma.

  5. 5

    Em deposit.confirmed, você credita o cliente indicado em sticky_wallet.reference.

Obter a carteira de um cliente

POST/sticky-wallets

Cria a carteira do cliente na primeira chamada e retorna a mesma em todas as chamadas seguintes: 201 quando ela acabou de ser criada, 200 depois disso. Você pode chamar sem problema toda vez que a página de depósito for aberta.

Parâmetros do corpo

referenceObrigatóriostring
O seu ID para este cliente: de 1 a 120 letras, números ou . _ : @ + -, começando com uma letra ou um número. Uma carteira por referência, para sempre.
labelOpcionalstring
Um nome que você verá no portal. Enviá-lo de novo o substitui.
metadataOpcionalobject
Um objeto seu, de até 4 KB. Enviá-lo de novo o substitui.
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: [...] }, …]
}

O objeto de carteira fixa

idstring
O ID da carteira, começando com sw_.
referencestring
O seu ID para o cliente.
addressesarray
Uma entrada por rede: network (tron, evm, sol, btc ou ltc), o address e as coins que ele aceita. O endereço evm é o mesmo em Ethereum, BNB Smart Chain, Polygon, Base e Arbitrum.
pending_networksarray
Redes cujo endereço ainda está sendo preparado, o que é raro. Chame de novo em alguns minutos e elas aparecerão em addresses.
created_atstring
Quando a carteira foi criada.
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"
}

Diga aos clientes o que enviar

Mostre cada endereço com as moedas listadas para ele. Moedas em outra rede, ou tokens que não estão na lista, não são creditados automaticamente: fale com o suporte se um cliente enviar algum.

Encontrar carteiras

GET/sticky-wallets

GET/sticky-wallets/{id}

Busque uma carteira pela sua referência, obtenha uma pelo ID ou percorra todas, das mais recentes para as mais antigas: limit de 1 a 100, starting_after com o ID da última carteira que você tem, e has_more informa se há mais.

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"
Resposta
{
  "object": "list",
  "data": [ { "id": "sw_8Kd2pQx7Vb1mNc3T", "object": "sticky_wallet", … } ],
  "has_more": false
}

Listar depósitos

GET/deposits

Todos os depósitos nas carteiras dos seus clientes, dos mais recentes para os mais antigos. Filtre por sticky_wallet (um ID de carteira) e status (pending, confirmed ou dropped) e pagine com limit e starting_after (um ID de depósito). Use para recuperar o que perdeu quando o seu servidor não recebeu webhooks.

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

O objeto de depósito

idstring
O ID do depósito. Use-o para creditar cada depósito uma única vez.
statusstring
pending: detectado na rede, aguardando confirmações. confirmed: definitivo e somado ao seu saldo. dropped: nunca foi confirmado.
sticky_walletobject
A carteira para a qual foi enviado: id e a sua reference.
coinobject
A moeda e a rede dela.
amountstring
O que o cliente enviou, na moeda.
feestring
A taxa, na moeda.
net_amountstring
O que foi somado ao seu saldo (valor menos a taxa), depois de confirmado.
amount_usdstring
O valor em dólares americanos no momento em que chegou.
tx_hashstring
O hash da transação; explorer_url a abre em um explorador de blocos.
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

Os eventos de depósito trazem o objeto de depósito em data. Verifique a assinatura, como mostrado em Webhooks, antes de confiar em um deles.

deposit.pending
Um depósito na carteira fixa de um dos seus clientes foi detectado on-chain e está aguardando confirmações.
deposit.confirmed
Um depósito em carteira fixa foi confirmado e somado ao seu saldo, já descontada a taxa: credite esse cliente agora.
deposit.dropped
Um depósito detectado em carteira fixa nunca foi confirmado (falhou ou foi removido da blockchain).
server.js · creditar o cliente
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]);
  }
}

Erros

400
invalid_request: um campo está ausente ou incorreto; a mensagem informa qual.
401
unauthorized: a chave secreta está ausente ou não é válida.
403
sticky_wallets_unavailable: as carteiras fixas não estão ativadas para esta empresa, ou a configuração dela não foi concluída.
404
not_found: não existe nenhuma carteira fixa com esse ID.

Boas práticas

  • Credite um cliente só em deposit.confirmed, e só uma vez por id de depósito: um webhook pode chegar mais de uma vez.
  • Decida quem paga a taxa: credite net_amount para repassá-la ao cliente, ou amount para assumi-la você mesmo.
  • A sua referência é a chave: chamar POST /sticky-wallets de novo é sempre seguro, então você não precisa guardar os endereços.
  • Mantenha a chave secreta no seu servidor. Se ela vazar, revogue-a em Desenvolvedores e crie uma nova.
  • Se o seu endpoint ficou fora do ar, liste os depósitos confirmed e credite os que você ainda não processou.
  • Vai criar um saldo para seus clientes? Veja como adicionar recargas em cripto às contas de clientes.