# Cartão com a NovaCorp

> Regras e comportamento do checkout quando a venda passa pela NovaCorp (acquirer novacorp).

Fonte: https://app.thronecorporate.com/docs/cartao/novacorp

## O que é igual às outras adquirentes

A integração é a mesma do [guia de cartão](/docs/cartao): `POST /elements/checkout` na moeda do comprador, Throne Elements na página, webhook `transaction.paid`. Campos, respostas, erros e formato do webhook não mudam.

**Para usar a NovaCorp**, mande `"acquirer": "novacorp"` na criação do checkout. Se a NovaCorp for a padrão da sua conta, o campo é opcional. Veja [Escolher a adquirente](/docs/cartao/escolher).

**A moeda funciona exatamente como nas outras adquirentes (Sterling, Imperium, Eminence, Apex e ShadowBank).** Você manda o valor na moeda do comprador (por exemplo, `"currency": "chf"`) e ele paga nessa moeda. A cotação que credita o seu saldo é fixada na criação, e o webhook traz `currency`, `native_amount_cents` e `fx_rate` no mesmo formato. Detalhes em [Moedas e limites](/docs/cartao/moeda).

Esta página cobre só o que é próprio da NovaCorp.

## Resumo

| Item | Na NovaCorp |
|---|---|
| Verificação do banco | Cada tentativa abre uma **janela de verificação**; a tela do banco aparece nela quando o banco pede |
| Navegador de app (Instagram, Facebook, Google, TikTok) | A própria aba vai para a página segura de pagamento e termina lá, **sem evento na sua página** |
| Valor máximo por venda | Varia com a moeda e com a cotação do dia. Hoje é o mais baixo das seis adquirentes. Veja [Limites](#limites) |
| Tentativas por checkout | 6, contadas no servidor. Recarregar a página não devolve tentativas |
| Validade do checkout | 24 horas |
| Fechamento por recusa | Logo depois da 6ª recusa. Com tentativas sobrando, `failed` a partir de 10 minutos depois da última recusa, sem nova tentativa e com o comprador fora da página; pode levar alguns minutos a mais |
| Parcelas | À vista |
| Idioma do checkout | Pelo país do comprador; Brasil e Portugal veem em inglês |

## Limites

| Limite | Na NovaCorp |
|---|---|
| Mínimo por venda | Varia com a moeda e com a cotação do dia, ou o mínimo próprio da NovaCorp, se houver |
| Máximo por venda | Depende da adquirente e varia com a moeda e com a cotação do dia. Consulte `GET /elements/acquirers?currency=` (campo `limits.max_amount_cents`) |
| Acima do máximo | `422 invalid_amount` com `max_amount_cents` na sua moeda e `alternatives`. Nada é criado |
| Capacidade de criação | Dividida entre todas as contas. Em pico ou instabilidade, `503 temporarily_unavailable` com `Retry-After` |

O máximo da NovaCorp é mais baixo que o das outras adquirentes. Para tíquetes altos, crie a venda com o `acquirer` de uma das `alternatives` ou peça ao suporte o [roteamento por valor](/docs/cartao/escolher#roteamento-por-valor).

## Como o comprador paga

### No computador

1. Preenche número, validade, CVV e nome impresso no cartão.
2. Clica em pagar. O Throne abre uma **janela de verificação** e o elemento mostra "Conclua a verificação na janela que abrimos".
3. Na janela, o comprador vê uma tela de espera no idioma do checkout e, quando o banco pede, a tela de verificação do próprio banco (código por SMS, aplicativo do banco, etc.).
4. Quando o resultado sai, a janela fecha e o elemento mostra o resultado.
5. Aprovado: o elemento dispara `throne-elements:paid`. Recusado: mostra quantas tentativas restam e o botão para tentar de novo; a venda continua `pending`.

Se o comprador fechar a janela sem concluir, o elemento continua confirmando com o banco por um tempo, porque o pagamento pode ter sido aprovado no último instante. Sem tentativa nova, ele avisa que a verificação não foi concluída e oferece nova tentativa. Se o comprador não concluiu no banco, nada foi cobrado.

A janela existe porque muitos bancos não deixam a tela de verificação aparecer dentro de outra página.

### No celular, em navegador comum

Em Safari, Chrome e outros navegadores comuns, a janela de verificação abre como uma nova aba. Quando o resultado sai, ela é fechada e o comprador volta para a aba da sua loja, já com o resultado. Os eventos chegam normalmente.

### Em navegador de app ou com a janela bloqueada

Instagram, Facebook, o app do Google, TikTok e outros apps abrem links num navegador próprio, que não abre uma segunda janela. O mesmo vale para um navegador comum que bloqueia a janela de verificação.

Nesses casos, **a própria aba sai da sua página** e vai para a página segura de pagamento. O comprador passa pela tela do banco e termina nessa página, que mostra o resultado. Uma recusa ali oferece nova tentativa na mesma página.

- A sua página **não recebe** `throne-elements:paid` nem outro evento.
- O comprador não volta sozinho para a sua loja.
- O pagamento é cobrado normalmente quando aprovado, e o webhook `transaction.paid` é enviado como em qualquer venda.

Por isso, nesta adquirente:

- libere o pedido pelo webhook ou pelo `GET`, nunca só pelo evento da página;
- envie a conversão da campanha pelo seu servidor ao receber `transaction.paid` ([como](/docs/webhooks#conversao-de-campanha-pelo-servidor)), senão as vendas que vêm de anúncio em app não aparecem na campanha;
- mande a confirmação do pedido por e-mail, pelo servidor.

Se o comprador voltar à sua página pelo botão voltar, o elemento pode montar de novo já pago e disparar `throne-elements:paid`. Isso não é garantido.

### O que o comprador vê

- **O endereço.** A janela de verificação e a página segura de pagamento mostram na barra o endereço da página de pagamento, não o da sua loja.
- **A confirmação do banco.** Quando o banco pede, a tela dele aparece na janela de verificação (ou na própria aba, no navegador de app). A fatura do cartão mostra a compra sem o nome da sua loja.

Avise ao lado do botão de pagar. Textos sugeridos:

```text Inglês
Secure payment. Your bank may ask you to confirm this purchase on a separate secure page.
```

```text Alemão
Sichere Zahlung. Ihre Bank kann Sie bitten, diesen Kauf auf einer separaten sicheren Seite zu bestätigen.
```

```text Espanhol
Pago seguro. Tu banco puede pedirte que confirmes esta compra en una página segura aparte.
```

## Requisitos da página

- **O clique no botão de pagar precisa ser do comprador.** A janela só abre a partir de um clique de verdade; não dispare o pagamento por código.
- **Não coloque o elemento dentro de um iframe com `sandbox`.** Se não der para tirar o `sandbox`, ele precisa incluir no mínimo `allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation`. Sem `allow-popups`, a janela não abre. Sem `allow-top-navigation-by-user-activation`, o pagamento em navegador de app não sai.
- **Não fixe a altura do container.** O elemento ajusta a altura quando mostra a espera e o resultado.
- Se a sua página envia o header `Cross-Origin-Opener-Policy: same-origin`, a janela pode perder o contato com o elemento. Com esse header, teste um pagamento completo no computador e no celular antes de publicar.

## Erros e o que fazer

Na criação do checkout:

| Situação | Resposta | O que fazer |
|---|---|---|
| Valor acima do máximo da NovaCorp | `422 invalid_amount`, com `max_amount_cents` e `alternatives` | Não repita. Crie com o `acquirer` de uma das `alternatives` ou divida o pedido |
| NovaCorp em pausa, instável ou sem capacidade | `503 temporarily_unavailable`, com `Retry-After` e `"retryable": true` | Espere o `Retry-After` e repita com uma `Idempotency-Key` nova, ou use outra adquirente habilitada |
| Criação recusada | `502 checkout_failed`, com `"retryable": false` | Não repita igual. Se continuar, fale com o suporte |
| Falha passageira de conexão | `502 checkout_failed`, com `"retryable": true` | Repita com uma `Idempotency-Key` nova |
| Sem resposta (timeout do seu lado) | Nenhuma | Repita com a **mesma** `Idempotency-Key` ([regra](/docs/comecar#como-repetir-uma-chamada-com-seguranca)) |

Na página, em `throne-elements:error` (`e.detail.code`):

| `code` | O que aconteceu | O que fazer |
|---|---|---|
| `declined` | O banco não autorizou | O comprador pode tentar de novo ou usar outro cartão. Vale sugerir que ele libere compras online e internacionais no app do banco |
| `window_closed` | O comprador fechou a janela sem concluir | Nada; o elemento oferece nova tentativa |
| `canceled` | O comprador cancelou a verificação | Nada; o elemento oferece nova tentativa |
| `popup_blocked` | A janela de verificação fechou antes do envio do cartão. Nada foi cobrado | Nada; o elemento avisa o comprador, que pode tentar de novo. Não é janela bloqueada: com a janela bloqueada, o pagamento segue pela própria aba, sem evento |
| `timeout` | A confirmação demorou mais que o esperado | Espere o webhook ou consulte o `GET`; não crie outro checkout |
| `attempts_exhausted` | Acabaram as 6 tentativas | Ofereça outro meio de pagamento ou um checkout novo |
| `closed` | O checkout fechou por recusa | Ofereça um checkout novo |
| `network` | Falha de conexão do comprador | O comprador pode tentar de novo |
| `expired`, `ended` | O checkout passou da validade ou foi encerrado | Crie um checkout novo |

A tabela completa dos códigos, nas seis adquirentes, está em [Throne Elements](/docs/cartao/elements#codigos-de-erro). No caminho de navegador de app, nenhum desses eventos chega à sua página.

## Quando chega o webhook

A confirmação da NovaCorp depende de o comprador voltar da tela do banco:

- **Comprador volta da tela do banco** (o caminho normal): o webhook `transaction.paid` sai pouco depois da aprovação.
- **Comprador fecha a tela do banco antes do fim**: a confirmação vem pela conferência automática do Throne, que pode levar alguns minutos.
- **"Pagamento em análise"**: o comprador pode ver essa tela enquanto a confirmação sai. A venda continua `pending` e termina `paid` ou `failed`.

Não cancele o pedido por falta de webhook antes da validade de 24 horas. Na dúvida, consulte `GET /transactions/{id}`.

## Depois da venda

- **Estorno**: não é feito pela API; fale com o suporte. A venda estornada fica `refunded`.
- **Contestação**: a venda vira `chargeback`. Se a contestação for revertida a seu favor, ela volta para `paid`.
- Nenhum desses eventos gera webhook. Acompanhe pelo `GET /transactions/{id}`.

## Testar

Use um cartão de verdade com valor baixo. Para ver como o comprador de outro país enxerga o checkout, abra o `checkout_url` da resposta com `?nl=` e o código do idioma (por exemplo, `?nl=de` para alemão): o formulário, os números e a tela de espera da verificação saem nesse idioma. Teste também dentro do navegador do Instagram ou do Facebook, no celular, e confira que o pedido é liberado pelo webhook. Roteiro completo em [Como testar](/docs/testar).

## Checklist

- [ ] Checkout criado no servidor, com `Idempotency-Key` nova por venda e timeout de 60 segundos.
- [ ] Moeda do comprador em `currency`, sem ajustar o valor no seu site.
- [ ] Máximo da NovaCorp conferido na moeda do seu público, com plano para `422 invalid_amount` (outra adquirente ou pedido dividido).
- [ ] Pagamento iniciado pelo clique do comprador, sem `sandbox` em volta do elemento (ou com a lista mínima acima).
- [ ] Aviso ao lado do botão sobre a página segura em que o banco pode pedir a confirmação.
- [ ] Tratamento de `e.detail.code` em `throne-elements:error`.
- [ ] Pedido liberado só com `transaction.paid` (assinatura validada) ou com o `GET`.
- [ ] Conversão de campanha enviada pelo servidor.
- [ ] Teste no navegador do Instagram ou do Facebook, no celular.
- [ ] Novo checkout para cada nova tentativa de compra depois de `failed` ou `expired`.
