Throne

Começar

Limites e tempos

Limites por endpoint e por adquirente, tempo de resposta, Retry-After e o que fazer em cada caso.

Ver em Markdown

Resumo#

O quê Limite Passou do limite
Chamadas com chave válida Sem limite geral Não se aplica
POST /transactions (Pix) 10 por segundo por conta 429 rate_limit_exceeded, com Retry-After
POST /elements/checkout (cartão) Sem limite por conta. Cada adquirente tem uma capacidade de criação, dividida entre todas as contas 503 temporarily_unavailable, com Retry-After
POST /withdrawals 1 por minuto por conta, mais o limite diário da conta 429 rate_limited ou 429 daily_limit_exceeded
Chamadas sem credencial válida 10 por segundo por IP 429, com Retry-After
Valor de uma venda no cartão Mínimo e máximo por adquirente, que variam com a moeda e com a cotação do dia 422 invalid_amount, com o limite na moeda que você mandou
Validade do checkout de cartão 24 horas A venda vira expired
Validade da Idempotency-Key 24 horas, na conta inteira Não se aplica

Tempo de resposta#

Chamada Timeout recomendado no seu cliente HTTP
POST /elements/checkout e POST /elements/checkout/br 60 segundos
Todas as outras 20 segundos

A criação do checkout de cartão fala com a adquirente. Na maior parte das vezes a resposta sai em poucos segundos, mas em pico pode passar de 40 segundos. Não corte antes de 60 segundos: se você desistir de uma chamada que deu certo, perde um checkout criado.

Se o timeout estourar mesmo assim, repita com a mesma Idempotency-Key e o mesmo corpo. A regra completa está em como repetir com segurança.

Quando a resposta é 429 ou 503#

429 e 503 dizem que nada foi criado e que vale tentar de novo daqui a pouco.

  1. Leia o header Retry-After (em segundos) e espere pelo menos esse tempo.
  2. Repita com uma Idempotency-Key nova.
  3. Se vier de novo, aumente a espera a cada tentativa (recuo exponencial) e some uma variação aleatória. Assim várias repetições não chegam todas no mesmo segundo.
  4. Pare depois de poucas tentativas. Mostre ao comprador um "tente em instantes" ou ofereça outro meio de pagamento.

No cartão, o 503 traz também "retryable": true. Ele aparece quando a adquirente está sem capacidade, instável ou em pausa. Com mais de uma adquirente habilitada, você pode criar o checkout na outra, com o campo acquirer (como escolher).

Exemplo em Node.js, com timeout, repetição segura e recuo:

Node.js
import { randomUUID } from 'node:crypto';

const esperar = (s) => new Promise((r) => setTimeout(r, s * 1000));

async function criarCheckout(corpo, tentativas = 4) {
  let chave = randomUUID(); // guarde junto do pedido
  for (let i = 0; i < tentativas; i++) {
    let res;
    try {
      res = await fetch('https://app.thronecorporate.com/api/v1/elements/checkout', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${process.env.THRONE_PK}:${process.env.THRONE_SK}`,
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'Idempotency-Key': chave,
        },
        body: JSON.stringify(corpo),
        signal: AbortSignal.timeout(60000),
      });
    } catch {
      continue; // sem resposta (conexão caiu ou timeout): repete com a MESMA chave
    }

    if (res.status === 409) {
      const erro = await res.json().catch(() => ({}));
      if (erro.error === 'idempotency_key_processing') {
        await esperar(3); // a primeira chamada ainda está em andamento
        continue;
      }
      return res;
    }

    if (res.status !== 429 && res.status !== 503) {
      return res; // 201 ou um erro que não se resolve repetindo
    }

    // 429 ou 503: nada foi criado. Espera e repete com chave nova.
    const retryAfter = Number(res.headers.get('Retry-After')) || 1;
    await esperar(Math.max(retryAfter, Math.min(60, 2 ** i)) * (1 + Math.random() / 2));
    chave = randomUUID();
  }
  return null; // mostre "tente em instantes" ou outro meio de pagamento
}

Mínimo e máximo por venda no cartão#

O mínimo e o máximo de uma venda dependem da adquirente e variam com a moeda e com a cotação do dia. Um preço perto do máximo pode passar num dia e não passar no outro.

  • Consultar antes: GET /elements/acquirers?currency=chf mostra o mínimo e o máximo atuais de cada adquirente, já na moeda pedida. Os valores são indicativos e acompanham a cotação.
  • Acima do máximo: a resposta é 422 invalid_amount, com max_amount_cents na moeda que você mandou e alternatives com as outras adquirentes habilitadas que aceitam esse valor. Nada foi criado. Não repita o mesmo valor na mesma adquirente: divida o pedido ou crie com acquirer de uma das alternatives.
  • Abaixo do mínimo: a resposta é 422 invalid_amount, com o mínimo na sua moeda no message e no campo min_amount_cents.

Exemplo de resposta acima do máximo:

JSON
{
  "error": "invalid_amount",
  "message": "Valor acima do máximo aceito nesta adquirente: CHF 318,90.",
  "max_amount_cents": 31890,
  "currency": "CHF",
  "alternatives": ["sterling"]
}

As moedas aceitas e o efeito da cotação no máximo estão em Moedas e limites.

Capacidade de criação no cartão#

O Throne não limita quantos checkouts a sua conta cria. Cada adquirente, porém, tem uma capacidade de criação dividida entre todas as contas que usam ela. Num pico grande, ou quando a adquirente fica instável, a criação responde 503 temporarily_unavailable com Retry-After, sem criar nada.

Para gastar menos capacidade e vender mais:

  • Crie o checkout quando o comprador clicar em comprar, não quando a página carrega.
  • Guarde o transaction_id na sessão do comprador e reaproveite o mesmo checkout por até 24 horas, se ele voltar à página.
  • Não crie um checkout novo a cada recarga da página nem a cada tentativa de cartão: o mesmo checkout aceita várias tentativas.

Limites por comprador na página de pagamento#

A página de pagamento tem limites de uso por comprador, contra abuso e teste de cartão. Uma compra normal não chega perto deles. O que costuma esbarrar nos limites:

  • recarregar o elemento em laço;
  • abrir o mesmo checkout em muitas abas ao mesmo tempo;
  • tentar dezenas de cartões no mesmo checkout em poucos minutos.

Webhooks#

  • Responda 2xx em até 3 segundos.
  • Sem 2xx, o Throne tenta de novo, até 10 tentativas no total, com intervalos crescentes.

Detalhes em Webhooks.