CryptoPayIn
Documentação para desenvolvedores

Crie pagamentos que se liquidam on-chain.

Tudo o que você precisa para criar um pagamento, enviar o cliente para o checkout hospedado, acompanhar as confirmações e processar webhooks assinados em produção.

URL base da APIVersão 1
https://cryptopayin.com/v1
ProtocoloREST / JSON
AutenticaçãoSegredo Bearer
ModoSomente produção
Introdução

Uma API, um único fluxo hospedado

A CryptoPayIn precifica um pedido na moeda de apresentação escolhida, trava snapshots verificados de fiat/USD e cripto/USD, aloca um endereço de depósito dedicado e monitora seus próprios nós de blockchain à espera do pagamento. A contabilidade interna, as taxas e os saldos permanecem em USD. Seu backend recebe uma URL de checkout imediatamente e, em seguida, eventos de ciclo de vida assinados.

URL base/v1
Valores em fiatUnidades menores ISO
Valores em criptoStrings decimais
Expiração padrão30 minutos
!

Esta é uma API de produção. Não existe prefixo de sandbox. Toda criação bem-sucedida aloca um endereço on-chain real. Use um valor pequeno em moeda suportada para testes ponta a ponta e mantenha as chaves secretas no seu servidor.

Como a integração se encaixa

1Crie uma chave

Gere um segredo no Painel -> Desenvolvedores.

2Crie um pagamento

Envie via POST a moeda do pedido, o valor e o ativo escolhido.

3Abra o checkout

Envie o cliente para a URL hospedada retornada.

4Processe o evento

Verifique o HMAC e atualize seu pedido de forma idempotente.

Comece agora

Crie seu primeiro pagamento

Gere uma chave de API no painel do lojista, armazene o segredo em uma variável de ambiente e crie um pagamento a partir do seu backend. O exemplo usa ETH para que possa ser testado sem escolher uma rede de token.

curl --request POST https://cryptopayin.com/v1/payments \
  --header "Authorization: Bearer $CPI_SECRET_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: order_1042" \
  --data '{
    "amount": 49.99,
    "currency": "USD",
    "asset": "ETH",
    "order_ref": "order_1042",
    "redirect_url": "https://shop.example/orders/1042/paid"
  }'

Use a resposta

Salve o id do pagamento junto ao seu pedido e redirecione o cliente para checkout_url. Não calcule o valor em cripto nem o endereço de depósito por conta própria.

{
  "id": "P-9F27C1E4KD",
  "object": "payment",
  "status": "created",
  "amount": 49.99,
  "amount_decimal": "49.99",
  "amount_minor": 4999,
  "currency": "USD",
  "currency_minor_units": 2,
  "amount_usd": 49.99,
  "amount_usd_cents": 4999,
  "fx_rate_usd": "1.000000000000",
  "fx_source": "fixed:USD",
  "fx_observed_at": "2026-07-17T13:00:00+00:00",
  "fx_discrepancy_bps": 0,
  "asset": "ETH",
  "network": "mainnet",
  "crypto_amount": "0.01388612",
  "crypto_received": "0",
  "deposit_address": "0x71b8c3d4700000000000000000000000000084e2",
  "exchange_rate": "3600.00000000",
  "exchange_rate_currency": "USD",
  "exchange_rate_source": "median:cb,cg,cl",
  "exchange_rate_source_count": 3,
  "exchange_rate_observed_at": "2026-07-17T13:00:00+00:00",
  "exchange_rate_discrepancy_bps": 12,
  "confirmations": 0,
  "confirmations_required": 12,
  "order_ref": "order_1042",
  "checkout_url": "https://cryptopayin.com/i/P-9F27C1E4KD",
  "expires_at": "2026-07-17T13:30:00+00:00",
  "created_at": "2026-07-17T13:00:00+00:00",
  "completed_at": null
}
Credenciais

Autenticação

Toda requisição à API usa a chave secreta em um cabeçalho HTTP Bearer. As chaves secretas começam com csk_live_. O valor cpk_live_ correspondente é um identificador público do seu painel e não deve ser usado como credencial Bearer.

AUTHAuthorization: Bearer csk_live_...Todos os endpoints
Exibido uma única vez

O segredo bruto é retornado somente no momento da criação da chave. A CryptoPayIn armazena um hash de senha e um índice SHA-256 para consulta, nunca o segredo em texto plano.

Chaves independentes

Crie chaves separadas por aplicação ou ambiente e revogue-as de forma independente. Uma conta pode manter até 50 chaves ativas.

Somente no servidor

Nunca coloque um valor csk_live_ em JavaScript de navegador, em um binário mobile, em um repositório público ou em uma página de checkout.

Escopo de webhook

Um endpoint de webhook pode valer para toda a conta ou ficar vinculado a uma única chave de API, mantendo as integrações isoladas.

i

Um segredo ausente, malformado, revogado ou desconhecido retorna 401 unauthorized. Uma conta de lojista suspensa ou encerrada é rejeitada da mesma forma. Uma chave válida usada fora das permissões concedidas retorna 403 insufficient_scope.

Novas tentativas seguras

Idempotência

Envie um Idempotency-Key exclusivo em cada criação de pagamento. Se sua conexão cair após o envio, repita o mesmo JSON com a mesma chave: a CryptoPayIn retorna o pagamento original em vez de alocar outro endereço.

CasoResultadoHTTP
Primeiro usoCria e retorna um novo pagamento.201
Mesma chave + mesmo JSONRetorna o pagamento existente com Idempotent-Replayed: true.200
Mesma chave + JSON diferenteRejeita a requisição como idempotency_conflict.409

As chaves são vinculadas à credencial de API e podem conter de 1 a 128 letras, dígitos, pontos, sublinhados, dois-pontos ou hífens. Um UUID duradouro do pedido é uma boa escolha. O mesmo mecanismo também protege os saques, de modo que uma nova tentativa de saque nunca movimenta os fundos duas vezes.

API REST

Referência da API

A API cobre pagamentos, links de pagamento, lojas, produtos, saldos e saques. As respostas usam JSON em UTF-8 sobre HTTPS; toda criação ou atualização exige Content-Type: application/json. As mutações são controladas pelas permissões da chave usada na chamada. Não há, propositalmente, fluxo CORS para navegador: as chamadas pertencem ao seu backend.

GET/v1/assetsDescubra os ativos disponíveis
GET/v1/currenciesDescubra as moedas fiduciárias de apresentação
POST/v1/paymentsCriar um pagamento
GET/v1/paymentsListar e filtrar pagamentos
GET/v1/payments/{id}Consultar um pagamento
i

A Versão 1 pode receber campos e endpoints compatíveis com versões anteriores. Uma mudança de contrato que quebre a compatibilidade usará um novo caminho base, em vez de alterar silenciosamente /v1.

Referência da API

Listar ativos

GET/v1/assetsAutenticação Bearer obrigatória

Use este endpoint como fonte da verdade para as opções de checkout. Ele retorna as entradas ativas do catálogo, as cotações atuais verificadas de forma independente, os valores mínimos equivalentes em USD e se o nó e o feed de preços estão prontos. Uma entrada pode continuar listada com available: false enquanto um nó está sincronizando ou seu preço não pode ser verificado.

curl https://cryptopayin.com/v1/assets \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "data": [{
    "asset": "USDT",
    "network": "TRC20",
    "type": "token",
    "decimals": 6,
    "minimum_amount": 1,
    "currency": "USD",
    "base_confirmations": 19,
    "available": true,
    "rate_usd": "1.00000000",
    "rate_source": "median:cb,cg,cl",
    "rate_source_count": 3,
    "rate_discrepancy_bps": 4,
    "rate_status": "healthy",
    "rate_updated_at": "2026-07-17T13:00:00+00:00"
  }]
}

Catálogo e identificadores de rede

AtivoValor de redeAbreviaçãoConfirmações base
BTCmainnetBTC2
ETHmainnetETH6
USDTTRC20 / ERC20USDT.TRC2019 / 6
USDCERC20USDC.ERC206
DAIERC20DAI6
SHIBERC20SHIB6
PEPEERC20PEPE6
LTCmainnetLTC6
TRXmainnetTRX19
DOGEmainnetDOGE20
XMRmainnetXMR10
SOLmainnetSOL32
!

A disponibilidade é dinâmica. Não fixe a tabela acima como uma lista de permissões em produção. Para símbolos com múltiplas redes, como o USDT, envie network explicitamente ou use a abreviação ASSET.NETWORK.

Referência da API

Listar moedas fiduciárias

GET/v1/currenciesAutenticação Bearer obrigatória

Retorna as moedas de apresentação habilitadas, sua precisão ISO e a saúde atual da conversão para USD. Ofereça apenas as linhas com available: true. O USD é intrínseco; toda outra moeda exige uma cotação em tempo real e uma checagem de referência independente. minimum_amount converte o piso mínimo configurado do ativo habilitado mais barato para essa moeda; o ativo escolhido pode exigir um valor maior, então sempre leia também GET /v1/assets.

curl https://cryptopayin.com/v1/currencies \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "accounting_currency": "USD",
  "data": [{
    "currency": "EUR",
    "name": "Euro",
    "symbol": "€",
    "minor_units": 2,
    "available": true,
    "minimum_amount": "0.86",
    "rate_usd": "1.160000000000",
    "rate_source": "coinbase+ecb",
    "rate_source_count": 2,
    "rate_discrepancy_bps": 18,
    "rate_updated_at": "2026-07-17T13:00:00+00:00",
    "rate_reference_at": "2026-07-16T00:00:00+00:00"
  }]
}
i

A moeda omitida em POST /v1/payments ainda significa USD por compatibilidade com versões anteriores. Moedas sem casas decimais, como o JPY, rejeitam valores fracionários. Trate os mínimos e as cotações do catálogo como dados em tempo real, nunca como constantes fixas.

Referência da API

Criar um pagamento

POST/v1/payments120 requisições / minuto / chave

Cria uma fatura na moeda de apresentação solicitada, trava snapshots recentes e verificados de fiat/USD e cripto/USD, calcula o valor exato em cripto e vincula um endereço de depósito on-chain dedicado.

Corpo da requisição

CampoTipoObrigatoriedadeDescrição
amountnumber or decimal stringobrigatórioValor em currency, na precisão ISO dessa moeda. Seu equivalente travado em USD não pode exceder $1,000,000.00; os mínimos do ativo também se aplicam.
currencystringopcionalMoeda habilitada de 3 letras a partir de GET /v1/currencies. Padrão: USD.
assetstringobrigatórioSímbolo como ETH, ou abreviação como USDT.TRC20.
networkstringcondicionalObrigatório quando o símbolo existe em múltiplas redes. Exemplo: ERC20.
order_refstringopcionalIdentificador do seu pedido, com no máximo 128 caracteres. Retornado nas respostas da API e nos eventos.
customer_emailstringopcionalEndereço de e-mail válido, com no máximo 190 caracteres. Armazenado junto ao registro de pagamento do lojista.
redirect_urlstringopcionalURL HTTPS, com no máximo 255 caracteres, oferecida após o checkout bem-sucedido.

Campos da resposta

CampoTipoDescrição
idstringIdentificador estável do pagamento, começando com P-.
statusstringEstado atual do ciclo de vida.
amount / amount_decimal / amount_minornumber / string / integerValor de apresentação solicitado nas formas conveniente, decimal exata e em unidades menores ISO.
currency / currency_minor_unitsstring / integerMoeda de apresentação travada e sua precisão.
amount_usd / amount_usd_centsnumber / integerValor contábil interno imutável em USD.
fx_rate_usd / fx_source / fx_observed_atdecimal string / string / ISO 8601Snapshot travado de USD por unidade de apresentação e seus metadados de auditoria.
asset / networkstringAtivo on-chain resolvido.
crypto_amountdecimal stringValor exato que o cliente deve enviar. Nunca interprete decimais de cripto como floats binários.
crypto_receiveddecimal stringTotal atualmente observado no endereço de depósito.
deposit_addressstringEndereço dedicado alocado para este pagamento.
exchange_ratedecimal stringCotação cripto/USD travada, usada para calcular crypto_amount; este campo mantém seu significado original da v1.
exchange_rate_source / exchange_rate_observed_atstring / ISO 8601Snapshot imutável de auditoria da cotação em cripto.
confirmationsintegerConfirmações atuais na rede.
confirmations_requiredintegerLimite exigido para este pagamento. Faixas de valor em USD mais altas podem exigir confirmações adicionais.
checkout_urlURLFatura hospedada para exibir ao cliente.
expires_atISO 8601Prazo final para uma fatura não paga.
completed_atISO 8601 / nullHorário final da liquidação, quando concluída.

As duas conversões em tempo real são validadas quanto a atualidade, número de fontes e divergência antes da criação. Se a verificação falhar, a criação retorna um erro em vez de usar uma cotação desatualizada. O valor em cripto é arredondado para cima, na precisão útil do ativo, de modo que o arredondamento nunca deixa o lojista no prejuízo.

Referência da API

Listar pagamentos

GET/v1/payments240 requisições / minuto / chave

Retorna primeiro os pagamentos mais recentes da conta de lojista autenticada. Use paginação por cursor para conciliação e filtros exatos para localizar um pedido sem percorrer todo o histórico.

Parâmetros de consulta

ParâmetroPadrãoDescrição
limit20Tamanho da página, de 1 a 100.
starting_afterID de pagamento retornado como next_cursor da página anterior.
statusStatus exato do ciclo de vida, como pending, completed ou expired.
order_refReferência exata do pedido do lojista, com no máximo 128 caracteres.
curl "https://cryptopayin.com/v1/payments?status=completed&limit=20" \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "data": [{
    "id": "P-9F27C1E4KD",
    "object": "payment",
    "status": "completed",
    "amount": 49.99,
    "currency": "USD",
    "asset": "ETH",
    "network": "mainnet",
    "crypto_amount": "0.01388612",
    "crypto_received": "0.01388612",
    "order_ref": "order_1042",
    "confirmations": 12,
    "confirmations_required": 12,
    "completed_at": "2026-07-17T13:12:42+00:00"
  }],
  "has_more": true,
  "next_cursor": "P-9F27C1E4KD"
}
i

Quando has_more for true, envie next_cursor sem alterações como starting_after. Parâmetros de consulta desconhecidos ou repetidos em formato de array são rejeitados, e não ignorados.

Referência da API

Consultar um pagamento

GET/v1/payments/{id}240 requisições / minuto / chave

Retorna o mesmo objeto de pagamento da criação, com status atualizado, valor recebido, hash da transação e confirmações. Uma chave só pode consultar pagamentos pertencentes à sua conta de lojista.

curl https://cryptopayin.com/v1/payments/P-9F27C1E4KD \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
i

Os webhooks devem conduzir as atualizações normais do pedido. Use a consulta para conciliar após um timeout, verificar um evento, renderizar uma página de status no backend ou corrigir entregas perdidas.

Modelo de estados

Ciclo de vida do pagamento

Sempre trate o status da API como autoritativo. Não deduza a conclusão a partir de um redirecionamento do navegador ou porque o cliente disse que pagou.

created->pending->underpaidouconfirming->completed/overpaid
StatusSignificadoAção do lojista
createdFatura e endereço alocados; nenhum aporte detectado ainda.Exiba o checkout hospedado.
pendingAguardando um pagamento on-chain utilizável.Mantenha o pedido em aberto.
underpaidOs fundos chegaram abaixo da tolerância do lojista.Peça ao pagador que envie o valor restante exibido.
confirmingValor suficiente detectado; aguardando confirmações.Ainda não entregue o pedido.
completedValor exigido e confirmações alcançados.Entregue o pedido uma única vez.
overpaidMais do que o esperado foi confirmado.Entregue o pedido e analise o excedente.
expiredNenhum pagamento válido foi detectado antes da expiração.Crie um novo pagamento.
failedFalha na alocação do endereço ou no processamento.Registre o erro e crie um novo pagamento.
!

As transferências on-chain são irreversíveis e a CryptoPayIn não possui mecanismo de reembolso — um pagamento confirmado é definitivo. Qualquer devolução por cortesia é tratada diretamente entre você e seu cliente, fora da plataforma.

Experiência do cliente

Checkout hospedado

Cada pagamento da API inclui um checkout_url responsivo. Ele exibe o lojista, o valor de apresentação solicitado, o equivalente em USD travado quando pertinente, o valor exato em cripto, o endereço de depósito, o código QR, o aviso de rede, a contagem regressiva e o progresso das confirmações em tempo real.

Cotação travada

O cliente vê o mesmo crypto_amount retornado pela API durante a janela da fatura.

Sem conta do cliente

O pagador não cria uma conta na CryptoPayIn nem compartilha credenciais.

Status em tempo real

A página consulta o pagamento com segurança e avança de aguardando para confirmando até pago.

Redirecionamento do lojista

Um redirect_url HTTPS é oferecido após o sucesso; ele não é prova de pagamento.

i

Mantenha a entrega do pedido no seu backend. A navegação no navegador pode ser abandonada, repetida ou forjada; somente um webhook verificado ou um GET autenticado comprova o estado do pagamento.

Credenciais

Permissões & escopos

Cada chave de API carrega um conjunto fixo de permissões, escolhido no momento da criação em Painel → Desenvolvedores. Todo endpoint verifica os escopos da chave antes de executar qualquer ação; uma chamada fora do escopo concedido retorna 403 insufficient_scope com um cabeçalho X-Required-Scope indicando a permissão ausente. Os escopos são definidos uma única vez na criação e não podem ser ampliados depois — emita uma nova chave em vez disso. Chaves criadas antes da existência dos escopos mantêm exatamente sua capacidade original: payments:read e payments:write.

EscopoConcedeEndpoints
payments:readListar e consultar pagamentosGET /v1/payments, GET /v1/payments/{id}
payments:writeCriar pagamentos hospedadosPOST /v1/payments
links:readListar e consultar links de pagamentoGET /v1/links, GET /v1/links/{id}
links:writeCriar, editar, pausar e excluir links de pagamentoPOST/PATCH/DELETE /v1/links
shops:readListar e consultar lojas e seus produtosGET /v1/shops, GET .../products
shops:writeCriar e editar lojas, produtos e variantesPOST/PATCH/DELETE /v1/shops e produtos
balance:readLer saldos em cripto e estimativas em USDGET /v1/balance
payouts:readListar e consultar saquesGET /v1/payouts, GET /v1/payouts/{id}
payouts:writeSolicitar saques on-chainPOST /v1/payouts
!

payouts:write movimenta fundos on-chain e é irreversível. Conceda-o somente a chaves em que você confia plenamente, mantenha essas chaves no servidor e prefira uma chave dedicada por processo automatizado. GET /v1/account informa os escopos da chave usada na chamada e os limites da sua conta.

Compradores automatizados

Checkout para agentes

Todo link de pagamento ativo também é um checkout legível por máquina: um agente de IA ou qualquer script pode descobri-lo, criar uma fatura e ler a entrega sem navegador — e sem nenhuma chave de API, porque esses são endpoints públicos de comprador no domínio do link, não endpoints de lojista. Contrato completo e exemplo prático: cryptopayin.com/agents.

GEThttps://cryptopaylink.co/pay/{link}.jsonpúblico · descoberta

Retorna o estado, a precificação, os ativos aceitos e o contrato exato de entrada para a chamada da fatura (campos obrigatórios, esquema de envio, variantes).

POSThttps://cryptopaylink.co/pay/{link}/invoicepúblico · aceita Idempotency-Key

Cria a fatura pelo mesmo núcleo, snapshot de precificação e limites antiabuso da página hospedada, e retorna o endereço de depósito, o valor exato em cripto, uma URI de carteira e a URL do recibo. Em seguida, o agente paga on-chain a partir de qualquer carteira que controle.

GEThttps://cryptopaylink.co/pay/{link}/receipt?p={payment}público · consulte a cada 5–10 s

Status e confirmações em tempo real; quando o pagamento é concluído, a resposta traz a entrega — seu conteúdo de texto, URL privada ou uma chave de licença reservada para aquele pagamento — além da sua mensagem de sucesso e da URL de redirecionamento.

As lojas falam o mesmo protocolo

As vitrines expõem o mesmo fluxo em seu próprio domínio: o catálogo com estoque em tempo real e, em seguida, uma única chamada que valida o carrinho, reserva o estoque e retorna a fatura.

GEThttps://shopycrypto.com/s/{shop}.jsonpúblico · catálogo
POSThttps://shopycrypto.com/s/{shop}/orderpúblico · carrinho → fatura, aceita Idempotency-Key
GEThttps://shopycrypto.com/s/{shop}/o/{order}/receipt?p={payment}público · consulte a cada 5–10 s

Controles do vendedor

O checkout para agentes vem habilitado por padrão e custa a mesma taxa fixa de 1%. Desative-o para toda a conta em Painel → Configurações → Geral → IA & checkout para agentes: os endpoints de máquina em links e lojas passam então a responder 403 agents_disabled enquanto suas páginas de checkout humano continuam funcionando. Pagamentos criados por agentes não carregam nenhuma sinalização especial — são pagamentos comuns no seu painel, webhooks e exportações.

Recursos do lojista

Lojas

Uma vitrine hospedada que agrupa produtos em uma única página com a marca do lojista. Uma conta mantém até 10 lojas. Os produtos são gerenciados pelos endpoints de produto aninhados abaixo.

GET/v1/shopsshops:read
POST/v1/shopsshops:write
GET/v1/shops/{id}shops:read
PATCH/v1/shops/{id}shops:write
DELETE/v1/shops/{id}shops:write

Corpo da requisição

CampoTipoObrigatoriedadeDescrição
namestringobrigatório2–80 caracteres.
taglinestringopcionalAté 160 caracteres.
themestringopcionallight (padrão) ou dark.
accentstringopcionalCor de destaque em hexadecimal, da paleta da loja retornada como accent_palette em GET /v1/shops.
accepted_assetsarray of stringsopcionalAtivos padrão para os produtos da loja, ex.: ["BTC","LTC","XMR"]. Aplicado a todos os produtos quando alterado.
statusstringopcionalSomente PATCH: active ou paused.
i

Uma loja desativada pela CryptoPayIn por motivos de política não pode ser reativada nem excluída pela API, e retorna admin_disabled (403). Excluir uma loja remove seus produtos; os pagamentos anteriores permanecem intactos.

Recursos do lojista

Produtos & variantes

Os produtos existem dentro de uma loja. Cada loja mantém até 50 produtos. Um produto pode ser digital (com entrega instantânea) ou físico (com países de envio), e pode expor até 30 combinações de variantes, construídas a partir de 1–3 grupos de opções.

GET/v1/shops/{shop}/productsshops:read
POST/v1/shops/{shop}/productsshops:write
GET/v1/shops/{shop}/products/{id}shops:read
PATCH/v1/shops/{shop}/products/{id}shops:write
DELETE/v1/shops/{shop}/products/{id}shops:write

Corpo da requisição

CampoTipoObrigatoriedadeDescrição
titlestringobrigatório3–120 caracteres.
description / blurbstringopcionalDescrição completa e uma linha de ≤200 caracteres para o cartão da loja.
emojistringopcionalUm único emoji exibido no cartão do produto.
featuredbooleanopcionalNo máximo um produto em destaque por loja.
product_typestringopcionaldigital (padrão) ou physical.
shipping_countriesarray of stringscondicionalSomente físico: códigos ISO como ["FR","BE"], ou ["*"] para envio mundial.
amount_type / currency / amount / min / maxmixedcondicionalPrecificação base, com regras idênticas às dos links de pagamento. Produtos físicos devem ser fixed.
max_usesintegeropcionalLimite total de vendas (0 = ilimitado).
delivery_type + delivery_text/url/keysmixedopcionalEntrega digital para o produto base, nos mesmos formatos dos links de pagamento.
variant_optionsarrayopcional1–3 grupos {name, values[]}, cada um com 2–10 valores. As combinações não podem exceder 30.
variantsarraycondicionalUm objeto por combinação (veja abaixo). Obrigatório e exaustivo quando variant_options está presente.
statusstringopcionalSomente PATCH: active ou paused.

Objeto de variante

CampoTipoDescrição
optionsarray of stringsUm valor por grupo de opções, na ordem dos grupos, ex.: ["Pro","Lifetime"].
pricenumber or stringPreço da variante na moeda do produto.
stockinteger or nullUnidades restantes, ou null para ilimitado.
delivery_type + delivery_text/url/keysmixedSubstituição opcional de entrega digital por variante (inherit por padrão). As chaves devem ser únicas em todo o produto.
curl -X POST https://cryptopayin.com/v1/shops/SH-JYRK8TFJ/products \
  -H "Authorization: Bearer $CPI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Software license",
    "amount": 30,
    "currency": "USD",
    "variant_options": [
      {"name": "Edition", "values": ["Standard", "Pro"]},
      {"name": "Term", "values": ["1 year", "Lifetime"]}
    ],
    "variants": [
      {"options": ["Standard","1 year"], "price": 30, "delivery_type": "keys", "delivery_keys": ["S1Y-1"]},
      {"options": ["Standard","Lifetime"], "price": 79, "stock": 10, "delivery_type": "keys", "delivery_keys": ["SLT-1"]},
      {"options": ["Pro","1 year"], "price": 59, "delivery_type": "keys", "delivery_keys": ["P1Y-1"]},
      {"options": ["Pro","Lifetime"], "price": 149, "stock": 5, "delivery_type": "keys", "delivery_keys": ["PLT-1"]}
    ]
  }'
i

PATCH preserva os pedidos existentes e as chaves já entregues. Para ajustar preços ou estoque, reenvie o array variants correspondente; as combinações omitidas são pausadas se tiverem pedidos, ou removidas caso contrário. Um produto pode manter no máximo 10,000 chaves de licença ativas entre sua base e suas variantes, e cada chave deve ser única dentro do produto.

Recursos do lojista

Saldo

GET/v1/balancebalance:read

Retorna seus saldos liquidados em cripto por ativo, com uma estimativa em USD de melhor esforço e a taxa de rede cobrada em um saque. A contabilidade interna é sempre em USD; os saldos acumulam a partir dos pagamentos concluídos, líquidos da taxa do lojista.

{
  "object": "list",
  "accounting_currency": "USD",
  "minimum_payout_usd": 25,
  "data": [{
    "asset": "USDT",
    "network": "TRC20",
    "amount": "99.099",
    "usd_estimate": 99.02,
    "payout_network_fee": "2.445463"
  }]
}
i

usd_estimate é null quando uma cotação verificada em tempo real está momentaneamente indisponível; o saldo subjacente continua exato. Use esses valores para decidir saques, não para a contabilidade final.

Recursos do lojista

Saques

Transfere cripto liquidada para uma carteira externa. Os saques são irreversíveis, portanto este endpoint aplica todas as proteções que o painel aplica: um destino válido para o ativo, uma cotação verificada em tempo real, o mínimo da conta, saldo suficiente incluindo a taxa de rede, e confirmação de dois fatores quando a conta tem 2FA habilitado.

GET/v1/payoutspayouts:read
POST/v1/payoutspayouts:write · 30 / min / chave
GET/v1/payouts/{id}payouts:read

Corpo da requisição

CampoTipoObrigatoriedadeDescrição
assetstringobrigatórioSímbolo ou abreviação, ex.: LTC ou USDT.TRC20.
networkstringcondicionalObrigatório quando o símbolo existe em múltiplas redes.
amountnumber or stringobrigatórioValor a enviar, excluindo a taxa de rede, na precisão do ativo. Seu valor em USD deve atingir o mínimo da conta.
addressstringobrigatórioEndereço de destino, validado para a rede do ativo.
notestringopcionalSua própria referência, com até 255 caracteres.
totp_codestringcondicionalCódigo atual de 6 dígitos ou código de recuperação. Obrigatório quando o 2FA está habilitado na conta.
curl -X POST https://cryptopayin.com/v1/payouts \
  -H "Authorization: Bearer $CPI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: withdraw-2026-07-19-01" \
  -d '{
    "asset": "USDT.TRC20",
    "amount": "50",
    "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "note": "weekly settlement"
  }'
{
  "id": "W-EM64ZCJB",
  "object": "payout",
  "status": "requested",
  "asset": "USDT",
  "network": "TRC20",
  "amount": "50",
  "fee": "2.445463",
  "total_debited": "52.445463",
  "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
  "txid": null,
  "confirmations": 0,
  "created_at": "2026-07-19T19:10:00+00:00"
}

Ciclo de vida do status

StatusSignificado
requestedReservado do seu saldo; aguardando análise do operador ou aprovação automática.
approved / processingAprovado e na fila para transmissão pelo executor.
sentTransmitido on-chain; txid é preenchido.
confirmedAtingiu as confirmações exigidas. Definitivo.
failedNão pôde ser enviado; failure_message explica o motivo e o saldo é devolvido.
cancelledCancelado antes da transmissão; o saldo reservado é devolvido.

Envie um Idempotency-Key para que uma nova tentativa de rede nunca crie um segundo saque: a mesma chave com o mesmo corpo retorna o saque original (Idempotent-Replayed: true); a mesma chave com um corpo diferente retorna 409 idempotency_conflict. O código de 2FA é deliberadamente excluído da impressão digital de idempotência, para que um código rotativo não gere um falso conflito. A reserva debita seu saldo imediatamente; um saque com falha ou cancelado o devolve.

Recursos do lojista

Conta

GET/v1/accountqualquer chave válida

Retorna o perfil da sua conta, os escopos da chave usada na chamada, a taxa da plataforma e todos os limites em tempo real — útil para uma integração autoconfigurável ou uma checagem prévia.

{
  "object": "account",
  "id": "MC67T3PHQZ",
  "fee_bps": 100,
  "fee_percent": 1,
  "default_currency": "USD",
  "two_factor_enabled": false,
  "api_key": {"label": "production", "scopes": ["payments:read","payments:write"]},
  "limits": {
    "shops": {"used": 1, "max": 10},
    "payment_links": {"used": 0, "max": 50},
    "products_per_shop_max": 50,
    "variant_combinations_per_product_max": 30,
    "license_keys_per_product_max": 10000,
    "active_api_keys_max": 50,
    "checkout_fields_per_link_max": 5
  },
  "minimum_payout_usd": 25
}
Eventos servidor a servidor

Webhooks

Adicione até 10 endpoints HTTPS públicos em Painel -> Desenvolvedores. Cada endpoint recebe seu próprio segredo de assinatura whsec_..., exibido uma única vez. Ele pode ouvir toda a conta ou ficar vinculado a uma chave de API ativa específica; endpoints vinculados a uma chave recebem somente os pagamentos criados com ela.

Verifique antes de fazer o parsing

A CryptoPayIn assina o corpo bruto exato da requisição usando o segredo do endpoint. A Versão 1 assina timestamp + "." + raw_body. Rejeite timestamps desatualizados antes de aceitar o evento.

import crypto from "node:crypto";

const timestamp = req.headers["x-cpi-timestamp"];
const signature = req.headers["x-cpi-signature"];
const rawBody = req.rawBody; // Buffer captured before JSON parsing

if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
  throw new Error("stale webhook");
}
const expected = "sha256=" + crypto
  .createHmac("sha256", process.env.CPI_WEBHOOK_SECRET)
  .update(Buffer.concat([Buffer.from(`${timestamp}.`), rawBody]))
  .digest("hex");
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!valid) throw new Error("invalid webhook signature");

Cabeçalhos de entrega

CabeçalhoExemploFinalidade
Content-Typeapplication/jsonCorpo JSON em UTF-8.
X-CPI-Timestamp1784293200Segundos Unix incluídos na mensagem assinada.
X-CPI-Signaturesha256=...HMAC-SHA256 em hexadecimal.
X-CPI-Signature-Versionv1Versão do esquema de assinatura.
X-CPI-Event-Idevt_a12b...ID lógico estável do evento; idêntico em todas as tentativas.
X-CPI-Delivery-Id1842ID estável do registro de entrega do endpoint.

Payload do pagamento

{
  "event_id": "evt_a12b34c56d78e90f12345678",
  "event": "payment.completed",
  "id": "P-9F27C1E4KD",
  "status": "completed",
  "order_ref": "order_1042",
  "amount": 49.99,
  "amount_decimal": "49.99",
  "amount_minor": 4999,
  "currency_minor_units": 2,
  "currency": "USD",
  "amount_usd": 49.99,
  "amount_usd_cents": 4999,
  "fx_rate_usd": "1.000000000000",
  "fx_source": "fixed:USD",
  "fx_observed_at": "2026-07-17T13:00:00Z",
  "fx_discrepancy_bps": 0,
  "exchange_rate": "3600.00000000",
  "exchange_rate_currency": "USD",
  "exchange_rate_source": "median:cb,cg,cl",
  "exchange_rate_source_count": 3,
  "exchange_rate_observed_at": "2026-07-17T13:00:00Z",
  "exchange_rate_discrepancy_bps": 12,
  "asset": "ETH",
  "network": "mainnet",
  "crypto_amount": "0.01388612",
  "crypto_received": "0.01388612",
  "txid": "0x9d81...75af",
  "confirmations": 12,
  "confirmations_required": 12,
  "deposit_address": "0x71b8c3d4700000000000000000000000000084e2",
  "sent_at": "2026-07-17T13:12:42Z"
}

Novas tentativas e segurança do endpoint

Retorne qualquer 2xx

Uma entrega é bem-sucedida com HTTP 200-299. Execute tarefas custosas de forma assíncrona e responda rapidamente.

Seis tentativas no total

O corpo exato e o ID do evento são mantidos; as falhas são reenviadas após aproximadamente 1 minuto, 5 minutos, 30 minutos, 2 horas e 6 horas.

Sem redirecionamentos

Respostas 3xx não são seguidas. Registre diretamente a URL HTTPS final.

Somente destinos públicos

IPs privados, loopback, link-local e reservados são bloqueados; toda resposta DNS é validada e a conexão é fixada (pinned).

!

As entregas são "pelo menos uma vez". Torne seu manipulador idempotente, registrando event_id com uma restrição de unicidade antes da entrega. Consulte o objeto da API ao conciliar um evento inesperado.

Webhooks

Referência de eventos

payment.completedValor esperado confirmado.
payment.overpaidMais do que o esperado foi confirmado.
payment.underpaidAporte abaixo da tolerância detectado.
payment.expiredJanela de fatura não paga encerrada.
payment.failedFalha na configuração ou no processamento do pagamento.
payout.sentSaque transmitido on-chain.
payout.confirmedSaque atingiu as confirmações.
payout.failedO saque não pôde ser concluído.
webhook.testTeste manual de conectividade.

Formato do evento de saque

{
  "event_id": "evt_b98c76d54e32a10f87654321",
  "event": "payout.sent",
  "id": "W-8J2K7M4RQP",
  "status": "sent",
  "asset": "ETH",
  "network": "mainnet",
  "amount": "0.25",
  "fee": "0.00081768",
  "address": "0x84f2...9bc1",
  "txid": "0xa1c4...07ee",
  "confirmations": 0,
  "note": "weekly treasury",
  "sent_at": "2026-07-17T14:08:31Z"
}
Confiabilidade

Erros e limites de taxa

Os erros sempre usam um único envelope JSON. Trate a lógica com base em error.type; a mensagem legível para humanos pode ser aprimorada sem mudança de versão. Informe error.request_id ou o cabeçalho de resposta X-Request-Id correspondente ao contatar o suporte.

{
  "error": {
    "type": "ambiguous_asset",
    "message": "specify network (e.g. USDT.ERC20 or USDT.TRC20)",
    "request_id": "b942e21f8dca4b06b8672eb9"
  }
}
HTTPTipos típicosSignificado
400invalid_request, unknown_parameterJSON, consulta ou cabeçalho de idempotência malformados.
401unauthorizedCredencial/conta ausente, inválida ou inativa.
403insufficient_scope, admin_disabledChave válida sem a permissão exigida (veja X-Required-Scope), ou um recurso bloqueado por um administrador.
404not_foundEndpoint desconhecido, ou um recurso fora desta conta de lojista.
405method_not_allowedUse o método indicado no cabeçalho Allow.
409idempotency_conflictChave reutilizada com JSON diferente.
413request_too_largeO corpo JSON excede 64 KiB.
415unsupported_media_typeO corpo do POST não está declarado como application/json.
422invalid, limit, invalid_amount, below_minimum, bad_address, 2fa_required, unsupported_assetRequisição bem formada falhou em uma validação determinística ou atingiu um limite de recurso.
429rate_limitedAguarde Retry-After.
500server_errorFalha inesperada; tente novamente com segurança usando a mesma chave de idempotência.
503maintenance, temporarily_unavailable, asset_unavailable, no_rate, price_stale, fiat_rate_unavailable, fiat_rate_stale, derive_failedFalha transitória de plataforma, nó, preço ou alocação de endereço. Nenhuma conversão desatualizada é usada em substituição.

Limites atuais

EscopoLimiteJanela
Teto de segurança do Nginx por IP10 requisições/segundo, burst 30Contínuo
Teto para IP não autenticado300 requisições60 segundos
POST /v1/payments, links, shops, products120 requisições por chave de API60 segundos
POST /v1/payouts30 requisições por chave de API60 segundos
Endpoints GET240 requisições por chave de API60 segundos

Limites da conta

RecursoLimite
Lojas por conta10
Links de pagamento por conta50
Produtos por loja50
Combinações de variantes por produto30
Chaves de licença por produto / link10,000
Perguntas de checkout por link5
Chaves de API ativas por conta50

Consulte seu uso em tempo real em relação a esses limites em GET /v1/account.

Respostas bem-sucedidas limitadas por aplicação expõem X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset. Repita 429, 500 e 503 com espera exponencial e jitter. Para POST, sempre reutilize o Idempotency-Key original e o mesmo JSON.

Segurança em produção

Segurança da integração

Mantenha os segredos de API em um gerenciador de segredos

Carregue-os em tempo de execução; nunca registre o valor completo em log nem o envie para o controle de versão.

Chame a API a partir do seu backend

Um navegador ou cliente mobile não pode armazenar um segredo de lojista com segurança.

Verifique o corpo bruto do webhook

Verifique a atualidade do timestamp e use comparação de assinatura em tempo constante antes de fazer o parsing do JSON.

Torne a entrega idempotente

Registre eventos/pedidos processados de forma transacional, para que novas tentativas nunca entreguem em duplicidade.

Confie no estado final da API, não em redirecionamentos

Consulte o pagamento quando um evento for inesperado ou seu estado local divergir.

Faça a rotação com sobreposição

Crie uma chave substituta, implante-a, verifique o tráfego e só então exclua a chave antiga.

!

O acesso à conta é controlado por uma chave de lojista de 16 dígitos não recuperável, opcionalmente protegida por TOTP. Armazene tanto o acesso do lojista quanto os segredos de API com o mesmo cuidado dado a credenciais de carteira.

Lançamento

Checklist de lançamento

1
Crie uma chave de API dedicada para produção

Não reutilize a cópia pessoal de um desenvolvedor entre serviços.

2
Consulte os dois catálogos em tempo real

Use GET /v1/assets e GET /v1/currencies; renderize somente as entradas presentes e available: true.

3
Adicione e teste seu endpoint de webhook

Salve o segredo de assinatura uma única vez; verifique o timestamp e a assinatura e, em seguida, deduplique o ID estável do evento.

4
Use uma chave de idempotência para cada pedido

Teste uma nova tentativa duplicada e confirme que existe apenas um ID de pagamento.

5
Teste indisponibilidades de cotação, subpagamento e expiração

O estado do seu pedido deve permanecer seguro diante de cotações fiat desatualizadas, ativos indisponíveis, confirmações atrasadas e todo caminho fora do fluxo ideal.

6
Concilie diariamente

Compare seus pedidos com os estados de pagamento da API, os logs de webhook e o razão do lojista.

Pronto para integrar?

Crie uma conta em segundos, gere uma chave e mantenha esta referência ao lado do seu código.

Criar conta