Desenvolvedores/Integração

Recarga de celular

A recarga de celular coloca crédito direto em um número de telefone pré-pago. O seu cliente recebe crédito ou dados na linha dele. Não há nenhum código para entregar. Você paga com a sua carteira CardV, como nos outros pedidos.

Veja também: Autenticação · Convenções · Webhooks

#Como funciona

Text
GET  /recharge/countries            países em que você pode fazer recarga
GET  /recharge/operators?country=US  operadoras, tipos de recarga e valores
POST /recharge/quote                o seu preço e um quote_token válido por 300 s
POST /recharge/orders               faz o pedido, pago com a sua carteira
GET  /recharge/orders/{order_id}    consulta o status ou espera um webhook
  • Todos os caminhos começam com /api/v1. Envie os mesmos cabeçalhos de qualquer chamada.
  • As duas chamadas POST precisam ser assinadas. Assine do mesmo jeito que POST/orders, mas com o caminho de cada uma, por exemplo /api/v1/recharge/quote.
  • Os pedidos de recarga são separados dos pedidos de cartões-presente. Use os endpoints /recharge para consultá-los.
  • Só há recarga direta. Produtos com PIN (um código que o cliente digita) não são oferecidos.

#Países

GET/api/v1/recharge/countries lista os países em que você pode fazer recarga agora.

JSON
{
  "count": 2,
  "results": [
    {"code": "MX", "name": "Mexico", "currency_codes": ["MXN"], "operator_count": 4, "offer_count": 37},
    {"code": "US", "name": "United States", "currency_codes": ["USD"], "operator_count": 6, "offer_count": 52}
  ]
}
  • code é o código de país ISO 3166-1 alfa-2. Envie-o como country nas próximas chamadas.
  • currency_codes são as moedas locais em que as operadoras desse país vendem.
  • A lista muda quando operadoras são adicionadas ou ficam indisponíveis. Carregue-a de novo a cada poucas horas.

#Operadoras

GET/api/v1/recharge/operators?country=US lista as operadoras de um país. Adicione search=att para filtrar pelo nome da operadora.

JSON
{
  "count": 1,
  "results": [
    {
      "operator_key": "us-att",
      "name": "AT&T",
      "country": "US",
      "country_name": "United States",
      "logo_url": "https://b2b.cardv.net/api/v1/catalog-assets/3f5c...a1.png",
      "subtypes": ["airtime", "data"],
      "amount_model": "range",
      "currency_codes": ["USD"],
      "amounts": [
        {"min": "5.0000", "max": "100.0000", "currency": "USD", "subtype": "airtime", "label": "5.0000-100.0000 USD"},
        {"min": "15.0000", "max": "15.0000", "currency": "USD", "subtype": "data", "label": "15.0000 USD"}
      ],
      "offer_count": 3
    }
  ]
}
CampoSignificado
operator_keyO ID que você envia na consulta de preço e no pedido, por exemplo us-att. Guarde como texto.
subtypesO que você pode comprar: airtime (crédito para ligações), data ou bundle (ligações e dados).
amount_modelfixed se todos os valores forem fixos, range se algum valor for um intervalo.
amounts[]Cada opção. Se min for igual a max, é um valor fixo. Senão, vale qualquer valor entre os dois.
amounts[].currencyA moeda local dessa opção. Envie como local_currency.
logo_urlImagem hospedada pela CardV, ou "".
  • Os valores são valores locais: o que a linha recebe, na moeda local.
  • Um country desconhecido ou mal formatado retorna HTTP 400.

#Consulta de preço

POST/api/v1/recharge/quote mostra o seu preço para uma recarga. Esta chamada precisa ser assinada.

JSON
{
  "country": "US",
  "operator_key": "us-att",
  "amount": "10.00",
  "local_currency": "USD",
  "subtype": "airtime"
}
CampoObrigatórioSignificado
countrySimCódigo do país, da lista de países.
operator_keySimDa lista de operadoras.
amountSimValor local, como texto. Fixo: um dos valores da lista. Intervalo: entre min e max.
local_currencyRecomendadoCódigo ISO 4217 de amount, tirado de amounts[].currency. Envie quando a operadora tiver mais de uma moeda.
subtypeNãoairtime (padrão), data ou bundle.

A resposta:

JSON
{
  "country": "US",
  "country_name": "United States",
  "operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
  "subtype": "airtime",
  "local_amount": "10.0000",
  "local_currency": "USD",
  "merchant_price": "9.6200",
  "merchant_currency": "USD",
  "expires_at": "2026-09-30T08:20:30.123456+00:00",
  "quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}
  • merchant_price é o que a sua carteira paga, em merchant_currency.
  • O quote_token trava este preço por 300 segundos, até expires_at. Envie-o sem alterações junto com o pedido.
  • O token está ligado à sua conta e a este país, operadora, tipo e valor.
  • Antes de fazer o pedido, confira se local_currency é a moeda que você esperava.
  • A consulta de preço não reserva dinheiro. Você pode pedir uma nova consulta a qualquer momento.

#Fazer um pedido de recarga

POST/api/v1/recharge/orders recarrega o telefone e paga com a sua carteira. Esta chamada precisa ser assinada.

JSON
{
  "external_order_id": "SHOP-RC-20260930-0001",
  "country": "US",
  "operator_key": "us-att",
  "amount": "10.00",
  "local_currency": "USD",
  "subtype": "airtime",
  "account": "12125550100",
  "quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}
CampoObrigatórioSignificado
external_order_idSimO seu número de pedido. Não pode se repetir em nenhum dos seus pedidos, incluindo os de cartões-presente.
country, operator_key, amount, local_currency, subtypeSimOs mesmos valores enviados na consulta de preço.
accountSimO número de telefone que vai receber a recarga: só dígitos, com o código do país, sem + nem espaços.
quote_tokenSimO da consulta de preço, antes de expirar.

Exemplos de número de telefone: 12125550100 (Estados Unidos), 525512345678 (México). Confira se o número é da operadora escolhida. Uma recarga enviada para o número errado não pode ser desfeita.

A CardV confere a consulta de preço, cobra o merchant_price da sua carteira na hora e inicia a recarga em segundo plano. Um pedido novo retorna HTTP 201:

JSON
{
  "idempotent_replay": false,
  "order": {
    "order_id": "O-00005678",
    "external_order_id": "SHOP-RC-20260930-0001",
    "status": "accepted",
    "status_title": "Recharge accepted",
    "poll_after_seconds": 12,
    "account": "12***00",
    "local_amount": "10.0000",
    "local_currency": "USD",
    "merchant_price": "9.6200",
    "merchant_currency": "USD",
    "...": "more fields"
  }
}
  • Guarde o order.order_id.
  • O número de telefone volta mascarado, nunca completo.

#Reenviar com segurança

O external_order_id evita que você faça a mesma recarga duas vezes.

Você enviaVocê recebe
Um número de pedido novoHTTP 201. Um pedido novo. A carteira é cobrada.
O mesmo número e a mesma recargaHTTP 200 e "idempotent_replay": true. O pedido que já existe. Nenhuma cobrança.
O mesmo número, mas uma recarga diferenteHTTP 400 em external_order_id. Nada acontece.

"A mesma recarga" quer dizer o mesmo país, operadora, tipo, valor e número de telefone. A repetição é reconhecida antes da verificação da consulta de preço, então um quote_token expirado ainda retorna o primeiro pedido.

  • Depois de um timeout, um 5xx ou uma conexão perdida, envie o mesmo corpo com o mesmo número de pedido. Assine de novo com timestamp e nonce novos.
  • Nunca use um número de pedido novo só porque uma resposta se perdeu. Isso pode recarregar o telefone duas vezes.

#Consultar pedidos de recarga

GET/api/v1/recharge/orders/{order_id} retorna um pedido. Você pode usar o ID de pedido da CardV (O-00005678).

JSON
{
  "order_id": "O-00005678",
  "external_order_id": "SHOP-RC-20260930-0001",
  "status": "processing",
  "order_status": "processing",
  "status_title": "Recharge processing",
  "status_message": "The recharge request is being processed. Delivery is not confirmed yet.",
  "next_step": "Keep this order open and wait for confirmation before placing another recharge.",
  "poll_after_seconds": 12,
  "country": "US",
  "operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
  "subtype": "airtime",
  "account": "12***00",
  "local_amount": "10.0000",
  "local_currency": "USD",
  "merchant_price": "9.6200",
  "merchant_currency": "USD",
  "attempts": [{"attempt_no": 1, "status": "processing", "error_message": "", "submitted_at": "2026-09-30T08:16:02.511201Z", "completed_at": null}],
  "created_at": "2026-09-30T08:16:01.004211Z",
  "updated_at": "2026-09-30T08:16:02.611978Z",
  "...": "more fields"
}
  • Um ID de pedido desconhecido, ou um pedido de outra conta, retorna HTTP 404.
  • status_title, status_message e next_step são textos em inglês que você pode mostrar à sua equipe.
  • poll_after_seconds é quanto tempo esperar antes da próxima consulta. 0 quer dizer que o pedido terminou.

#Listar pedidos de recarga

GET/api/v1/recharge/orders lista os seus pedidos de recarga, do mais recente para o mais antigo.

HTTP
GET /api/v1/recharge/orders?status=processing&limit=50&offset=0
JSON
{"count": 3, "limit": 50, "results": ["..."]}
  • Filtros: status e search (ID de pedido da CardV, o seu número de pedido ou o nome da operadora).
  • O padrão de limit é 20 e o máximo é 100. Valores maiores viram 100.
  • Um limit ou offset negativo ou que não seja número retorna HTTP 400.

#Status

Text
accepted ──► processing ──► succeeded
                  │
                  ├──► manual_review ──► succeeded ou refunded
                  │
                  └──► failed ──► refunded   (dinheiro devolvido à sua carteira)
StatusTerminou?O que fazer
acceptedNãoAguarde. A carteira já foi cobrada e a recarga ainda não começou.
processingNãoAguarde. Pode levar alguns minutos. Não faça o pedido de novo.
manual_reviewNãoA CardV está conferindo o resultado com a operadora. Aguarde.
succeededSimO telefone foi recarregado. Avise o seu cliente.
failedAinda nãoA recarga não foi concluída. Aguarde o refunded.
refundedSimO dinheiro voltou para a sua carteira. Você pode fazer um pedido novo.
  • Consulte depois de poll_after_seconds e vá aumentando o intervalo: 30 s, 60 s e depois a cada 5 minutos. Respeite o limite de requisições.
  • Trate um status desconhecido como "ainda não terminou".
  • Enquanto um pedido não terminar, não envie outra recarga para o mesmo número com um número de pedido novo. Se o primeiro também der certo, o telefone é recarregado duas vezes.

#Webhooks e reembolsos

Os pedidos de recarga enviam os mesmos webhooks que os outros pedidos: order.succeeded, order.failed e order.refunded. O webhook traz o ID de pedido da CardV e o seu número de pedido, com uma lista items vazia. Depois de um webhook, consulte o pedido com GET/api/v1/recharge/orders/{order_id}.

Os reembolsos são automáticos. Quando a operadora confirma uma falha, a CardV devolve o merchant_price completo para a sua carteira e o pedido passa para refunded. Você vê o reembolso na página de transações do Portal. Uma recarga que deu certo não pode ser reembolsada nem cancelada.

#Erros

Os erros seguem as Convenções. Uma consulta de preço ou pedido recusado retorna HTTP 400 e nada é cobrado.

ChaveOndeO que fazer
detailConsulta de preço, pedidoPaís, operadora, tipo ou valor indisponível. Confira a lista de operadoras.
amountConsulta de preço, pedidoNão é número, é zero ou está fora do intervalo.
local_currencyConsulta de preço, pedidoNão é um código ISO 4217 de 3 letras.
accountPedidoNúmero de telefone ausente.
quote_tokenPedidoAusente, expirado, alterado ou sem correspondência. Veja o code e consulte o preço de novo.
balancePedidoAdicione saldo no Portal.
riskPedidoVocê atingiu um limite de pedidos. Fale com a CardV.
external_order_idPedidoJá usado em outro pedido. Veja Reenviar com segurança.
walletPedidoNenhuma carteira ativa. Fale com a CardV.

Os erros de quote_token vêm com um code:

JSON
{"code": "quote_expired", "quote_token": "This quote expired. Refresh the price and confirm again."}
codeSignificado
quote_requiredNenhum quote_token foi enviado.
quote_expiredTem mais de 300 segundos. Consulte o preço de novo.
quote_invalidFoi alterado ou é de outra recarga. Consulte o preço de novo.
price_changedO seu preço mudou desde a consulta. Consulte de novo e confirme o novo preço.

HTTP 403 indica problema de credenciais, assinatura, IP ou aprovação. Veja Autenticação.

Dúvidas sobre a integração? Envie um e-mail para [email protected] com seu Merchant ID e o ID do pedido ou da requisição.