# 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.

Fonte: https://app.thronecorporate.com/docs/pix/shadowpix

## 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](/docs/pix) e do guia [Saldo e saques](/docs/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](/docs/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](/docs/cartao/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](/docs/pix#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.

> [!TIP]
> 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](/docs/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."
}
```

> [!WARNING]
> **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`](#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.

> [!WARNING]
> **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](/docs/pix#criar-a-cobranca). Nenhum campo novo, nenhum campo a menos:

```bash 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](/docs/comecar#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`](#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](#o-prazo-do-codigo)).

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-que-o-comprador-ve)).

## O prazo do código

Aqui há uma diferença de verdade com o [guia de Pix](/docs/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](/docs/webhooks).
2. **Consulta** `GET /transactions/{id}` mostrando `status: "paid"`.

> [!WARNING]
> **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](/docs/saques), sem campo novo:

```bash 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](https://app.thronecorporate.com/painel/withdraw).
- **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](/docs/saques#antes-do-primeiro-saque).

> [!WARNING]
> 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](/docs/saques#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](/docs/pix#erros-comuns), 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`](#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](/docs/errors).

> [!WARNING]
> **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](#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`](#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](/docs/testar).
