Gates2b

Cripto na cobrança

Como cobrar em cripto pelo POST /charge, escolher as moedas, ler a cotação e saber quando o pagamento foi feito.

Uma cobrança em cripto é uma cobrança comum de Criar cobrança com paymentMethod: "CRYPTO". O valor é definido na moeda da cobrança (BRL, USD ou EUR) e o pagador transfere o equivalente em cripto. O que muda em relação a PIX e boleto está nesta página.

curl -X POST "https://api.gates2b.com/charge" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "grossAmount": "35.00",
    "currency": "BRL",
    "paymentMethod": "CRYPTO",
    "externalReference": "pedido-0004",
    "gatewayOptions": { "cryptoTickers": ["ETH_USDT"] }
  }'

passthroughFees: true não é aceito em cripto e responde 400.

Moedas

gatewayOptions.cryptoTickers lista as moedas aceitas. Cada item é um ticker no formato REDE_ATIVO; moedas nativas usam só o ativo.

AtivoRedeTicker
USDTEthereumETH_USDT
USDTBNB Smart ChainBSC_USDT
USDTPolygonMATIC_USDT
USDCEthereumETH_USDC
USDCPolygonMATIC_USDC
ETHEthereumETH
BNBBNB Smart ChainBNB
MATICPolygonMATIC
  • A oferta real é a das moedas habilitadas na sua conta. cryptoTickers só restringe esse conjunto: pedir um ticker não habilitado não o adiciona.
  • Omitir o campo equivale a aceitar todas as moedas habilitadas. Lista vazia responde 400.
  • De 1 a 20 tickers, sem repetição.

Um ticker ou vários

A quantidade de tickers muda o fluxo, não só a lista de moedas.

Um ticker: moeda travada. A cotação e a carteira são reservadas na criação. A resposta já traz endereço, valor exato e QR Code em checkoutMeta.crypto e checkoutMeta.qr_image, e o pagador não escolhe moeda.

Com um ticker, a reserva de 20 minutos começa na criação

Use um ticker só quando o pagador vai pagar em seguida. Para link enviado por mensagem e aberto mais tarde, use vários tickers ou omita o campo, senão a reserva pode vencer antes de o pagador abrir o link.

Dois ou mais tickers, ou o campo omitido: moeda aberta. Nada é reservado. O pagador escolhe a moeda no checkout e a reserva começa a contar depois da escolha. A resposta vem sem checkoutMeta.crypto e sem qr_image.

Moeda travada: a reserva de 20 minutos começa na criação, e a resposta já traz endereço e valor.

Resposta da criação

A resposta é a tentativa de pagamento. O id da cobrança vem em chargeId.

{
  "id": "0192f4c6-7d1e-7a3b-9c2d-4e5f6a7b8c9f",
  "chargeId": "01JC8Z3R5W7Y9A1C3E5G7J9K2Q",
  "status": "PROCESSING",
  "paymentMethod": "CRYPTO",
  "checkoutMeta": {
    "url": "https://pay.gates2b.com/01JC8Z3R5W7Y9A1C3E5G7J9K2Q",
    "paymentMethod": "CRYPTO",
    "redirectUrl": "https://pay.provider.example/p/6f1c2a90",
    "crypto": {
      "ticker": "ETH_USDT",
      "symbol": "USDT",
      "network": "Ethereum",
      "networkKey": "ethereum",
      "address": "0x9f1C4b2E8a7D3c6F5e0B1a2C3d4E5f6A7b8CE4a2",
      "paymentUri": "ethereum:0x9f1C4b2E8a7D3c6F5e0B1a2C3d4E5f6A7b8CE4a2?amount=6.875105",
      "amount": "6875105",
      "amountFormatted": "6.875105",
      "expiresAt": "2026-10-22T14:20:00.000Z",
      "expirationDurationMin": 20
    },
    "qr_image": "data:image/png;base64,iVBORw0KGgo..."
  },
  "checkoutUrl": "https://pay.gates2b.com/01JC8Z3R5W7Y9A1C3E5G7J9K2Q"
}
CampoO que é
checkoutUrlCheckout onde o pagador vê endereço, valor, QR Code e prazo. Mande o pagador para cá.
checkoutMeta.redirectUrlPágina de pagamento alternativa para esta tentativa. Não é a URL de retorno de gatewayOptions.redirectUrl.
crypto.amountValor na menor unidade do token, inteiro em string.
crypto.amountFormattedValor na unidade do ativo. É o que o pagador transfere.
crypto.paymentUriConteúdo do QR Code, com o valor exato.
crypto.expiresAt, crypto.expirationDurationMinFim e duração da reserva. Podem não vir; sem eles, a tela só perde o contador.

Os valores em cripto são strings de propósito: um token de 18 casas decimais convertido para número de ponto flutuante perde dígitos. Guarde e compare como string ou com uma biblioteca decimal.

Exibir o valor

Se você mostrar o valor na sua própria tela, arredonde amountFormatted para cima nas casas do ativo. O número na tela é instrução de pagamento: arredondar para baixo pede menos do que a reserva e a transferência fica incompleta.

AtivoCasasExemplo
USDT, USDC, DAI, DOGE26.88
ETH, LTC, BCH60.004312
BTC80.00012345
SHIB01240918
Demais ativos412.3457

Deixe o valor exato acessível para copiar. O QR Code (paymentUri) já carrega o valor exato.

Status e prazo

O status da cobrança segue o mesmo ciclo das outras, com um status a mais, PARTIAL, para pagamento abaixo do cotado.

PENDING

aguardando a transferência

valor cheio recebido
PAID
prazo vence sem transferência
EXPIRED

ainda aceita transferência atrasada

transferência abaixo do valor
PARTIAL

aberta, não expira, não é paga

restante recebido
PAID

dispara charge.paid

Status de uma cobrança em cripto: PARTIAL fica aberta até o restante chegar; só PAID significa pago.

Cripto tem três particularidades:

  • Pagamento a menor. O pagador pode transferir menos que o cotado. A cobrança vai para PARTIAL: continua aberta, não é paga e não expira pelo prazo. Ela vira PAID quando o restante chega. Não libere o pedido em PARTIAL.
  • Prazo ancorado na reserva. Com moeda travada, o expiresAt da cobrança passa a ser o fim da reserva de 20 minutos, não o valor enviado na criação.
  • Pagamento depois do prazo. Uma cobrança EXPIRED que recebe a transferência depois do prazo ainda é creditada: vira PAID com o valor cheio, ou PARTIAL com valor menor.

Saber que foi pago

Assine o evento charge.paid numa inscrição de webhook. Ele é enviado quando a cobrança vira PAID, também em cripto, e traz o externalReference. Veja Webhooks.

Os eventos crypto_payment.* não são enviados para cobranças de /charge. Eles valem só para pagamentos criados em Criar pagamento em cripto.

Dados da liquidação

Depois do pagamento, a cobrança ganha um bloco crypto com os números da transação: moeda e rede pagas, valores bruto e líquido em cripto e tarifas.

"crypto": {
  "currency": "ETH_USDT",
  "blockchain": "ETH",
  "grossAmount": "6.512300",
  "netAmount": "6.317931",
  "fee": "0.194369",
  "feePercent": 2.985,
  "networkFee": "0.900000"
}

O bloco aparece em lastConfirmedAttempt.crypto no detalhe da cobrança (GET /charge/me/{id}), em crypto em cada item da listagem (GET /charge/list) e em crypto nas consultas de tentativa (GET /charge/{chargeId}/attempts e GET /charge/attempts/{attemptId}).

Trate todos os campos do bloco como opcionais. O conteúdo varia conforme a rede e o momento da consulta, e campos como txHash, senderAddress, paidAt e confirmations podem não vir. Use o bloco para conciliação e exibição, não como condição para dar o pedido por pago: essa decisão é do status PAID.

Nesta página