Throne

Pix

Pix com a Shadow Pix

Regras e comportamento do Pix quando a conta é atendida pela Shadow Pix: faixa de R$ 10,00 a R$ 5.000,00, timeout de 60 segundos na emissão, prazo do código no banco, dedução por pedido, confirmação pelo webhook e saque por Pix.

Ver em Markdown

O que é a Shadow Pix#

A Shadow Pix é uma das adquirentes de Pix do Throne. Ela atende as duas pontas do Pix da sua conta:

  • entrada: a cobrança com QR Code e copia e cola, criada em POST /transactions com payment_method: "pix";
  • saída: o saque por Pix, pedido em POST /withdrawals.

A sua integração não muda. São os mesmos endpoints, o mesmo corpo, os mesmos status e o mesmo webhook do guia Cobrar com Pix e do guia Saldo e saques. Esta página reúne só o que é específico desta adquirente: a faixa de valor, o prazo do código, o tempo da emissão, o que fazer quando a emissão não se confirma e o que o comprador vê no banco.

Se a sua conta usa outra adquirente de Pix, nada aqui se aplica. Leia o guia de Pix e pronto.

Você não escolhe a adquirente de Pix#

No cartão existe o campo acquirer, que escolhe a adquirente em cada chamada (como escolher). No Pix esse campo não existe.

A adquirente de entrada e a adquirente de saída são apontadas na sua conta, uma de cada vez, e quem aponta é o Throne. O que isso significa na prática:

  • POST /transactions com payment_method: "pix" ignora qualquer campo de adquirente que você mandar. Não há erro: o campo simplesmente não existe nessa chamada.
  • A mesma adquirente de entrada atende a API, a tela Depositar do painel e os links de pagamento.
  • A adquirente que paga os seus saques pode ser outra, diferente da que emite as suas cobranças. Isso não muda uma linha do seu código.
  • Para trocar, fale com o suporte. Não é uma configuração do painel do seller.

Dica Não escreva no seu código nada que dependa do nome da adquirente de Pix. Trate a faixa de valor como configuração sua, num lugar só, e você troca de adquirente sem mexer na integração.

Faixa de valor#

É a única regra desta página capaz de quebrar uma integração que já funcionava.

O quê Valor
Mínimo de uma cobrança R$ 10,00 (1000)
Máximo de uma cobrança R$ 5.000,00 (500000)
Mínimo de um saque R$ 10,00 (1000), e o mínimo da sua conta pode ser maior

A faixa do guia de Pix (de 100 a 5000000) é a faixa que a API aceita no corpo da chamada. A faixa desta adquirente é mais estreita e vale por cima dela. Um valor aceito na validação do corpo pode, ainda assim, não virar cobrança.

Fora da faixa, a cobrança não é emitida. Nada é cobrado e nenhum QR Code é gerado. A resposta é 502 acquirer_error, sem o campo retry_same_key:

JSON
{
  "error": "acquirer_error",
  "message": "Não foi possível gerar a cobrança agora. Tente de novo em instantes, com uma Idempotency-Key nova."
}

Atenção Antes de repetir qualquer 502, olhe o campo retry_same_key. Sem ele, como aqui, nada foi criado e a chave nova é segura. Com "retry_same_key": true, a cobrança pode existir do outro lado, e chave nova gera um segundo código pagável para o mesmo pedido. Esse caso está em o que fazer num 502.

Confira o valor antes de repetir: repetir o mesmo valor falha de novo, quantas vezes você tentar.

O que acontece com a Idempotency-Key daquela tentativa: a tentativa não vira venda nenhuma (não existe venda failed para consultar depois) e a chave é liberada na hora, sem ficar presa. Corrija o valor e repita com uma chave nova, como a mensagem pede.

Atenção Cuidado com os links de pagamento. POST /payment-links aceita de 100 a 5000000 e essa validação não conhece a faixa da adquirente. Um link de R$ 7,00 ou de R$ 8.000,00 é criado sem erro nenhum e só falha quando o comprador clica para pagar. Crie links dentro de R$ 10,00 a R$ 5.000,00.

Criar a cobrança#

Idêntico ao guia de Pix. Nenhum campo novo, nenhum campo a menos:

cURL
curl -X POST https://app.thronecorporate.com/api/v1/transactions \
  --max-time 60 \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "payment_method": "pix",
    "amount_cents": 4990,
    "customer": {
      "name": "Maria Souza",
      "document": "12345678909",
      "email": "maria@exemplo.com",
      "phone": "+5511988887777"
    },
    "metadata": { "loja_pedido_id": "PED-1042" }
  }'

Os campos de customer são os do guia de Pix: name, document e email obrigatórios, phone opcional. Mande os dados do seu comprador, como em qualquer cobrança Pix.

A resposta é a de sempre, 201 com status: "pending", payment_data.qr_code_payload (o copia e cola) e payment_data.qr_code_image_base64 (o PNG do QR Code, gerado pelo Throne). fee_cents e net_amount_cents saem da taxa da sua conta.

O timeout do seu cliente aqui é 60 segundos#

O padrão da casa para esta chamada é 20 segundos (tempo de resposta e timeouts). Nesta adquirente use 60.

O motivo: quando a adquirente responde "ocupado", ou quando a conexão com ela cai, o Throne repete a emissão com a mesma chave, dentro da sua chamada, em vez de criar uma segunda cobrança. Essa janela tem teto de 40 segundos. Um timeout de 20 segundos corta você no meio dela, e o pior não é a espera perdida: a cobrança pode nascer depois que o seu cliente já desistiu.

  • Sem resposta, repita a MESMA chamada, igual, com a MESMA Idempotency-Key. Se a cobrança nasceu, você recebe a original.
  • Pode vir 409 idempotency_key_processing em vez da cobrança. Significa que a primeira chamada ainda está rodando. Espere alguns segundos e repita igual.
  • Pode vir 502 com "retry_same_key": true. A emissão não se confirmou e a cobrança pode existir. A saída está em o que fazer num 502.
  • Nunca com uma chave nova. Chave nova é cobrança nova: duas cobranças para o mesmo pedido, e as duas pagáveis ao mesmo tempo (veja o prazo do código).

Dois detalhes desta adquirente que vale conhecer:

  • O metadata fica no Throne. Ele volta na consulta e no webhook, como sempre, e não viaja para a adquirente. O mesmo vale para items e shipping_address.
  • Não existe descrição de produto no Pix. Nada do que você manda aparece no aplicativo do banco do comprador (veja o que o comprador vê).

O prazo do código#

Aqui há uma diferença de verdade com o guia de Pix, e ela vale uma leitura atenta.

O prazo que você manda não chega à adquirente. Todo código que ela emite fica pagável no banco por cerca de 2 dias, contados da emissão, seja qual for o seu prazo.

Campo O que é Quanto dura
expires_at da cobrança O seu prazo, o que vale na consulta e no painel O que você mandou, ou 1 hora quando não manda nada
payment_data.expires_at O menor entre o seu prazo e o fim do código na adquirente Igual ao expires_at quando o seu prazo é de até 2 dias. Cerca de 2 dias depois da emissão quando você manda mais que isso

Os dois campos só mostram o mesmo instante quando o seu prazo é o menor. Se você mandar mais de 2 dias, eles não coincidem: o expires_at continua com o que você mandou e o payment_data.expires_at mostra quando o código deixa de ser pagável. Para o código, vale o payment_data.expires_at.

Com prazo de até 2 dias, o código continua pagável no banco depois dele, e nenhum campo mostra isso. Os dois campos ficam no seu prazo, e o código segue vivo até completar cerca de 2 dias da emissão.

Pix pago fora do prazo ainda vira paid e ainda gera transaction.paid, como já está no guia de Pix. Nesta adquirente a janela é de 2 dias, então o caso deixa de ser raro.

O que fazer com isso:

  • Trate transaction.paid atrasado como pagamento normal, mesmo horas depois. Nunca como erro.
  • Nunca crie uma segunda cobrança para um pedido que já tem uma pending. Guarde o id da primeira e mostre sempre o mesmo qr_code_payload (GET /transactions/{id}). O código anterior segue pagável por cerca de 2 dias mesmo depois do expires_at: duas cobranças do mesmo pedido são dois códigos vivos ao mesmo tempo, e o comprador pode pagar os dois.
  • Prazo acima de 2 dias não estica o código. Ele deixa de ser pagável no payment_data.expires_at, e não no seu expires_at. Pare de mostrar o QR Code nesse instante.
  • Deduplique por PEDIDO, não só por data.transaction_id. Dois transaction.paid de duas cobranças diferentes do mesmo pedido têm transaction_id diferentes e passam direto pela sua dedução. Antes de liberar, confira no seu banco se aquele pedido já está pago.
  • Um Pix pago duas vezes não volta sozinho. Não existe estorno de Pix pela API. A devolução é manual, pelo suporte, e demora.
  • Se o seu pedido tem prazo curto, controle do seu lado: pare de mostrar o QR Code e feche o pedido no seu sistema quando quiser. Só deixe decidido o que você faz se o pagamento chegar depois disso, porque ele pode chegar.
  • Não existe webhook de expiração. Uma cobrança não paga continua pending.

O que o comprador vê#

  • O nome do recebedor é definido pelo Throne, é o mesmo para todas as contas e não pode ser alterado. Não é o nome da sua loja, nem o seu CNPJ, nem nada que você mande na chamada.
  • Não aparece nome de produto nem descrição. O comprador vê valor e recebedor, e nada mais.
  • O valor aparece exato, sem acréscimo e sem arredondamento.

Avise o comprador na sua própria página, antes de ele abrir o aplicativo do banco: diga que o nome do recebedor é diferente do nome da sua loja. É o assunto que mais gera dúvida e desistência no pagamento por Pix. Uma linha de texto ao lado do QR Code resolve.

Confirmar o pagamento#

A cobrança nasce pending. Sempre. A resposta da criação diz que o QR Code existe, não que alguém pagou. O pagamento chega depois, pelo webhook.

Libere o pedido só por um destes dois caminhos:

  1. Webhook transaction.paid (recomendado). Chega logo depois da confirmação do pagamento. Deduplique pelo data.transaction_id (o mesmo pagamento pode chegar mais de uma vez) e pelo seu pedido, pelo motivo da seção anterior. Veja Webhooks.
  2. Consulta GET /transactions/{id} mostrando status: "paid".

Atenção Nunca libere pedido pela resposta da criação. O 201 sai antes de o comprador abrir o aplicativo do banco. Um pedido liberado no 201 é um pedido entregue de graça.

O ciclo é o do guia de Pix, sem nada a mais: pending enquanto espera, paid quando o pagamento é confirmado. Uma cobrança não paga fica pending, inclusive depois do prazo.

Saque por Pix#

Igual ao guia de Saldo e saques, sem campo novo:

cURL
curl -X POST https://app.thronecorporate.com/api/v1/withdrawals \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "amount_cents": 50000,
    "totp_code": "123456",
    "destination": { "key": "12345678909", "key_type": "cpf" }
  }'

O que vale nesta adquirente:

  • Os cinco tipos de chave funcionam: cpf, cnpj, email, phone (formato internacional, +5511999998888) e evp (a chave aleatória, com hífens). Um key_type fora dessa lista é recusado na validação do corpo.
  • Mínimo de R$ 10,00 na adquirente. O mínimo da sua conta costuma ser maior: o padrão do Throne é R$ 50,00, e o seu aparece no painel, na tela Saque.
  • Só Pix. Esta adquirente não paga saque em cripto. Um pedido com destination.address numa conta que não tem cripto configurado termina failed e o valor volta inteiro para o saldo.
  • O saque nasce requested e passa por processing. Quase sempre termina completed ou failed, e nem todo saque gera webhook: consulte GET /withdrawals/{id}. O failure_reason do GET vem em linguagem pronta para mostrar ao seu cliente.
  • Um saque recusado (failed) devolve o valor inteiro, taxa incluída, para o saldo.
  • Um saque pode ficar em processing sem desfecho. Quando o envio à adquirente não se confirma (por exemplo: ela não responde, responde erro de servidor ou aceita o pedido sem devolver o identificador dele), o Throne não reenvia e não devolve o valor no escuro: reenviar pagaria duas vezes, porque o Pix pode ter saído. O saque continua processing, e o valor segue reservado e fora do seu saldo disponível.
  • Com um saque em processing, consulte GET /withdrawals/{id}, porque esse desfecho pode chegar sem webhook. Não trate processing como falha e não peça o mesmo saque de novo: o valor só volta ao saldo quando o saque termina failed. Se ele continuar processing uma hora depois do pedido, abra um pedido no suporte com o id do saque.

As regras de segurança do saque não mudam: permissão withdrawals:write na chave, IPs de saque cadastrados e totp_code em cada pedido. Leia antes do primeiro saque.

Atenção Um saque repetido por engano é dinheiro saindo duas vezes. Nunca gere uma Idempotency-Key nova para um saque cujo resultado você não conhece. A ordem certa está em repetir um pedido de saque.

Estorno#

Estorno de Pix não é feito pela API, nesta adquirente nem em nenhuma outra. Não existe endpoint de estorno de Pix no Throne. Se precisar devolver um valor ao comprador, fale com o suporte. A devolução é manual e demora, então vale mais evitar a cobrança dobrada do que contar com o estorno.

Erros#

Os erros são os do guia de Pix, com uma diferença que pesa: no 502, quem diz se a chave nova é segura é o campo retry_same_key. Os que mais aparecem nesta adquirente:

Status error O que aconteceu O que fazer
(sem resposta) Timeout do seu lado, conexão cortada ou resposta sem o JSON da API. A cobrança pode ter sido criada Repita a MESMA chamada, igual, com a MESMA Idempotency-Key. Nunca com chave nova: chave nova cria uma segunda cobrança para o mesmo pedido, e os dois códigos ficam pagáveis juntos por cerca de 2 dias. Se vier 409 ou 502, leia a linha dele abaixo
502 acquirer_error, com "retry_same_key": true A emissão não se confirmou. A cobrança pode existir do outro lado. Nada fica gravado na sua conta e a chave é liberada para a repetição do mesmo corpo Repita a MESMA chamada, com a MESMA Idempotency-Key e o MESMO corpo. Nunca com chave nova. Veja o que fazer num 502
502 acquirer_error, sem retry_same_key Nada foi cobrado para este pedido e nenhum código dele existe. O motivo mais comum é valor fora de R$ 10,00 a R$ 5.000,00. O mesmo 502 sai quando a adquirente mostra que a chave já está ligada a uma cobrança de outro pedido Confira o valor e repita com uma Idempotency-Key nova. Não insista com a mesma chave: ligada a outro pedido, ela devolve sempre este erro
422 pix_not_enabled O recebimento por Pix não está habilitado nesta conta. Nada foi criado Fale com o suporte. O saque por Pix continua funcionando
422 (validação) Campo do corpo inválido. O mais comum é faltar customer ou customer.document Corrija o campo indicado em errors
409 idempotency_key_processing A primeira chamada com essa chave ainda está rodando. A emissão pode levar até 40 segundos Espere alguns segundos e repita igual. Não troque a chave por causa deste 409
409 idempotency_key_race Duas chamadas ao mesmo tempo com a mesma chave, ou uma chave cuja primeira chamada recebeu um 4xx Depois de um 4xx, nada foi criado: use uma chave nova. Se foram duas chamadas ao mesmo tempo, espere alguns segundos e repita a mesma chamada, igual, porque a outra pode ter criado a cobrança
422 idempotency_key_mismatch A mesma chave voltou com um corpo diferente (valor corrigido, nome do comprador reescrito) Use uma chave nova, e só depois de ter certeza de que a tentativa anterior não criou cobrança
429 rate_limit_exceeded Mais de 10 cobranças por segundo Espere o Retry-After e repita com uma chave nova

Lista completa em Erros.

Atenção Nesta rota, o 502 desta página vale por cima de qualquer regra geral. Onde outra página tratar o 502 como "nada foi criado, repita com uma chave nova", isso vale só para o 502 sem retry_same_key. Com "retry_same_key": true, siga a seção abaixo.

O que fazer num 502#

Todo 502 desta rota traz o mesmo error, acquirer_error. Quem separa os dois desfechos é o campo retry_same_key:

  • Sem retry_same_key: nada foi cobrado. A cobrança foi recusada antes de ser criada, aqui ou na adquirente. O motivo mais comum é valor fora de R$ 10,00 a R$ 5.000,00. Confira o valor, corrija e repita com uma Idempotency-Key nova. O mesmo 502 sai quando a adquirente mostra que a chave que você mandou já está ligada, do lado dela, a uma cobrança de outro pedido, o que acontece com chave reaproveitada. Nenhuma cobrança deste pedido existe lá, e repetir com essa chave devolve sempre este mesmo erro. Use uma chave nova: um UUID v4 por cobrança.
  • Com "retry_same_key": true: a cobrança pode existir. O pedido saiu daqui e o desfecho ficou em aberto. Por exemplo: a adquirente seguiu "ocupada" até o fim da janela de 40 segundos, a conexão caiu no meio do envio, ela devolveu erro de servidor, ou devolveu a cobrança sem o copia e cola.

A resposta do segundo caso é esta:

JSON
{
  "error": "acquirer_error",
  "message": "A cobrança pode ter sido criada e não foi confirmada. Repita esta chamada com a mesma Idempotency-Key e o mesmo corpo da primeira tentativa. Não use uma chave nova para este pedido: ela pode gerar uma segunda cobrança.",
  "retry_same_key": true
}

Com "retry_same_key": true, a ordem é esta:

  1. Não crie outra cobrança. Chave nova é código novo. Os dois ficam pagáveis ao mesmo tempo por cerca de 2 dias e um Pix pago duas vezes não volta pela API (veja Estorno).
  2. Repita em seguida a MESMA chamada, com a MESMA Idempotency-Key. A chave é liberada no instante do 502, então a repetição roda de novo e leva à adquirente a mesma chave da primeira tentativa. Se a cobrança tinha nascido, ela volta em 201, com o mesmo copia e cola. Se não tinha, nasce agora. Nos dois casos, uma só. Se o comprador já tinha pago aquele código, a repetição também volta em 201, mas com o qr_code_payload vazio: a venda foi registrada e não há nada para pagar de novo. Não mostre QR Code nenhum. O pagamento se confirma pelo caminho de sempre, o webhook transaction.paid ou um GET com status: "paid".
  3. Repita com o MESMO corpo. Com outro valor ou outro nome do comprador, a repetição é recusada aqui mesmo, com 422 idempotency_key_mismatch, e não chega à adquirente. Para mudar o pedido, resolva antes esta tentativa.
  4. Não tente consultar a venda. A tentativa que falhou não deixa venda nenhuma no Throne: não há id para o GET /transactions/{id} e nunca existe uma venda failed para ler depois. A repetição é a consulta.
  5. Se a repetição também voltar 502 com retry_same_key, pare e abra um pedido no suporte com a Idempotency-Key daquela tentativa, antes de criar qualquer cobrança nova para o pedido. Faça o mesmo se ela voltar 502 sem o campo: a repetição foi recusada, mas isso não descarta a cobrança da primeira tentativa, e só o suporte confirma que ela não existe. É a mesma ordem do saque sem desfecho.

O código e a mensagem que a adquirente devolveu ficam no nosso registro interno e não aparecem na resposta, nem no metadata da venda, nem no webhook: não tente ler o motivo pela API. Quem precisa do motivo exato pede ao suporte com a Idempotency-Key.

Checklist#

  • Cobranças sempre dentro de R$ 10,00 a R$ 5.000,00, conferido no seu código antes da chamada.
  • Links de pagamento criados dentro da mesma faixa.
  • Pedido liberado só pelo webhook transaction.paid ou por um GET com status: "paid". Nunca pela resposta da criação.
  • Webhook deduplicado pelo data.transaction_id e pelo seu pedido.
  • Um pedido com cobrança pending reaproveita o mesmo qr_code_payload, em vez de criar outra cobrança.
  • transaction.paid atrasado tratado como pagamento normal, não como erro.
  • Com prazo acima de 2 dias, QR Code escondido no payment_data.expires_at, e não no expires_at.
  • Aviso ao comprador, ao lado do QR Code, de que o nome do recebedor é diferente do nome da sua loja.
  • Timeout de 60 segundos no cliente HTTP da criação, e Idempotency-Key nova só para cobrança nova: a MESMA chave em toda repetição da mesma cobrança.
  • Tratamento de 502 que lê o campo retry_same_key: com true, repete a mesma chamada com a mesma chave e o mesmo corpo, e nunca gera chave nova. Veja o que fazer num 502.
  • Um 201 com qr_code_payload vazio tratado como cobrança já paga: nenhum QR Code na tela, e o pedido liberado como qualquer outro, pelo transaction.paid ou por um GET com status: "paid".
  • Para saque: permissão withdrawals:write, IPs de saque cadastrados, totp_code em cada pedido e GET /withdrawals/{id} consultado até completed ou failed. Um saque que continua processing uma hora depois do pedido vai ao suporte com o id, e nunca é pedido de novo.
  • Uma cobrança de valor baixo paga de verdade, de ponta a ponta, antes de abrir ao público. Veja Como testar.