> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abacatepay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# abacatepay.js

> Referência do script que mostra o formulário de cartão no seu site e gera o token ctok_: opções, métodos, eventos, erros e exemplo em React.

O **abacatepay.js** é o script que coloca o formulário de cartão no seu site. Ele cuida de três coisas:

* desenha os campos do cartão num iframe seguro (o número e o CVV nunca passam pelo seu código);
* faz a autenticação 3DS quando o banco do cliente exige, numa janela que abre e fecha sozinha;
* devolve o token `ctok_`, que o seu backend usa para [criar a cobrança](/pages/transparents/card).

<Note>
  Quer o fluxo completo, do formulário à cobrança? Siga o [passo a passo](/pages/guides/cartao-transparente). Esta página é a referência do script.
</Note>

## Instalação

Coloque a tag no `<head>` da página de pagamento:

```html theme={null}
<script src="https://abacatepay.com/abacatepay.js"></script>
```

O script cria o objeto global `AbacatePay`. Use sempre esse endereço: não copie o arquivo para o seu servidor, porque ele é atualizado por nós. Não existe pacote npm do abacatepay.js; em React, Vue ou Next.js, carregue a mesma tag (veja o [exemplo em React](#exemplo-em-react)).

## Uso básico

```html theme={null}
<div id="cartao"></div>
<button id="pagar" disabled>Pagar</button>

<script type="module">
  const botao = document.getElementById('pagar')

  const checkout = AbacatePay.create({
    publicKey: 'pk_sua_chave_publica',
    amount: 10000, // centavos: o mesmo valor que o backend vai cobrar
    onCardChange: ({ canTokenize }) => {
      botao.disabled = !canTokenize
    },
  })

  await checkout.mount('#cartao')

  botao.addEventListener('click', async () => {
    botao.disabled = true
    const { token } = await checkout.tokenize({
      name: 'Maria Silva',
      email: 'maria@exemplo.com',
      taxId: '529.982.247-25',
    })
    // envie o token para o seu backend em até 60 segundos
  })
</script>
```

<Tip>
  Use `<script type="module">` (ou uma função `async`) para poder usar `await`. Num `<script>` comum, `await` fora de função é erro de sintaxe e nada acontece.
</Tip>

***

## `AbacatePay.create(opções)`

Cria o checkout. Não desenha nada ainda: isso é papel do `mount()`.

| Opção | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `publicKey` | `string` | Sim | Sua [chave pública](/pages/transparents/public-key) (`pk_...`) |
| `amount` | `number` | Sim | Valor total em centavos, inteiro, a partir de `100`. Precisa ser igual ao `amount` da cobrança |
| `locale` | `'pt'` \| `'en'` \| `'es'` | Não | Idioma do formulário. Padrão: `'pt'` |
| `icons` | `boolean` | Não | Mostra os ícones das bandeiras nos campos. Padrão: `false` |
| `theme` | `object` | Não | Aparência dos campos. Veja [Aparência](#aparência) |
| `onReady` | `() => void` | Não | Chamada quando o formulário está pronto para digitar |
| `onCardChange` | `(estado) => void` | Não | Chamada a cada mudança nos campos. Veja [`onCardChange`](#oncardchange) |
| `onSuccess` | `(resultado) => void` | Não | Chamada quando o `tokenize()` dá certo, com o mesmo resultado que ele devolve |
| `onError` | `(erro) => void` | Não | Chamada quando o `mount()` ou o `tokenize()` falham, com o mesmo erro que eles rejeitam |

`create()` lança um erro na hora se `publicKey` estiver vazia ou se `amount` for menor que `100`.

Os callbacks são opcionais. Você pode usar só `await` com `try`/`catch` nos métodos, ou só os callbacks, ou os dois.

***

## Métodos

### `checkout.mount(alvo)`

Desenha o formulário dentro do elemento. Aceita um seletor CSS (`'#cartao'`) ou o próprio elemento. O conteúdo que estiver dentro dele é substituído.

Devolve uma `Promise` que resolve quando o formulário está pronto e rejeita com um [erro](#erros) se algo falhar, por exemplo uma chave pública inválida. Chame uma vez por checkout.

### `checkout.tokenize(cliente, endereço?)`

Valida o cartão, faz o 3DS quando o banco exige e devolve o token. Chame no clique do botão de pagar, nunca antes: o token vale só 60 segundos.

**`cliente`** (obrigatório):

| Campo | Obrigatório | Descrição |
| - | - | - |
| `name` | Sim | Nome do cliente |
| `email` | Sim | E-mail válido |
| `taxId` | Sim | CPF ou CNPJ válido, com ou sem máscara |
| `cellphone` | Não | Celular. Não é exigido aqui, mas é obrigatório na cobrança |

**`endereço`** (opcional): endereço de cobrança do cartão. Em produção ele é enviado ao banco na autenticação 3DS. Se enviar, mande os cinco campos: `street`, `number`, `city`, `state` (sigla com 2 letras) e `zipCode`.

```js theme={null}
const resultado = await checkout.tokenize(
  { name: 'Maria Silva', email: 'maria@exemplo.com', taxId: '529.982.247-25', cellphone: '11999999999' },
  { street: 'Av. Paulista', number: '1000', city: 'São Paulo', state: 'SP', zipCode: '01310-100' },
)
```

**Resultado:**

```json theme={null}
{
  "token": "ctok_9fK2mQ7xLp4vR8sT1wYz3nBc",
  "expiresIn": 60,
  "brand": "VISA",
  "lastFour": "4242"
}
```

| Campo | Descrição |
| - | - |
| `token` | Token `ctok_` para mandar ao seu backend. Uso único |
| `expiresIn` | Segundos até o token expirar (`60`) |
| `brand` | Bandeira do cartão |
| `lastFour` | Últimos 4 dígitos, para mostrar ao cliente |

Para pagar de novo depois de uma recusa, chame `tokenize()` outra vez: cada chamada gera um token novo.

### `checkout.destroy()`

Remove o formulário. Use quando o cliente sai da tela de pagamento sem recarregar a página (SPA).

### Propriedades

| Propriedade | Descrição |
| - | - |
| `checkout.canTokenize` | `true` quando o cartão está completo e válido |
| `checkout.isComplete` | `true` quando todos os campos foram preenchidos |
| `checkout.isValid` | `true` quando os dados digitados são válidos |

***

## `onCardChange`

Recebe o estado do formulário a cada mudança:

```js theme={null}
onCardChange: ({ canTokenize, isComplete, isValid, errors }) => {
  botao.disabled = !canTokenize
}
```

| Campo | Descrição |
| - | - |
| `canTokenize` | `true` quando já dá para chamar `tokenize()`. É o que você usa para liberar o botão |
| `isComplete` | Todos os campos preenchidos |
| `isValid` | Dados válidos |
| `errors` | Erros por campo, quando houver: `number`, `expiry`, `cvc`, `name` |

***

## Erros

Os erros do abacatepay.js têm `name` igual a `AbacatePayError`, uma `message` e um `code`:

```js theme={null}
try {
  const { token } = await checkout.tokenize(cliente)
} catch (error) {
  console.log(error.code, error.message) // ex.: THREE_DS_FAILED 3DS authentication failed
}
```

| `code` | Quando acontece | O que fazer |
| - | - | - |
| `NOT_MOUNTED` | `tokenize()` antes de o `mount()` terminar | Espere o `mount()` |
| `PAYER_INVALID` | Faltou `name`, `email` ou `taxId` no `tokenize()`, ou faltou `publicKey`/`amount` no `create()` | Envie os campos obrigatórios |
| `CARD_INCOMPLETE` | Algum campo do cartão está vazio | Peça para completar. Use `canTokenize` para só liberar o botão quando estiver tudo certo |
| `CARD_INVALID` | Dados do cartão inválidos | Peça para conferir o cartão |
| `THREE_DS_FAILED` | O banco não autenticou o cliente, ou ele fechou ou cancelou a confirmação | Deixe tentar de novo ou usar outro cartão |
| `PROVIDER_LOAD` | O formulário seguro não carregou | Veja se um bloqueador ou a CSP do site barrou o script |
| `MOUNT_TARGET` | O elemento do `mount()` não existe na página | Confira o seletor e chame `mount()` depois de o elemento existir |
| `API` | A API recusou. O motivo está em `error.message` | Veja a tabela de mensagens abaixo |
| `NETWORK` | Falha de rede | Tente de novo |
| `UNKNOWN` | Erro inesperado | Tente de novo; se repetir, fale com o suporte |

Mensagens mais comuns com `code: 'API'`:

| `error.message` | Causa |
| - | - |
| `Invalid or revoked public key` | Chave pública errada ou trocada |
| `CARD_TRANSPARENTS is not available for this store` | Sua conta ainda não tem cartão liberado |
| `payer.taxId must be a valid CPF or CNPJ` | CPF ou CNPJ inválido |
| `Property 'payer.email' should be email` | E-mail inválido |
| `Não foi possível processar o pagamento com este cartão` | O cartão não pôde ser validado. Peça outro cartão |
| `Too many requests. Try again shortly.` | Muitas tentativas em um minuto. Aguarde um minuto |

***

## 3DS

Em produção, alguns bancos pedem que o cliente confirme a compra (código por SMS, aprovação no app do banco). Quando isso acontece, o `tokenize()` abre uma janela por cima da página, com o título **Autenticação do cartão**, e só resolve depois que o cliente termina. Você não precisa fazer nada além de esperar a `Promise`.

Se o cliente não confirmar, o `tokenize()` rejeita com `THREE_DS_FAILED`.

## Dev mode

Com a [chave pública de teste](/pages/transparents/public-key#teste-e-produção), o abacatepay.js mostra um formulário de teste: campos simples, já preenchidos com o cartão `4242 4242 4242 4242`, sem 3DS e sem cobrança real. Para simular recusas, troque o número pelos [cartões de teste](/pages/devmode#testando-pagamentos-com-cartão).

## Aparência

O `theme` é repassado ao formulário seguro. Em `styles`, cada chave é um seletor CSS de dentro do formulário e o valor é um objeto de estilos:

```js theme={null}
AbacatePay.create({
  publicKey: 'pk_sua_chave_publica',
  amount: 10000,
  locale: 'pt',
  icons: true,
  theme: {
    styles: {
      input: { color: '#111', fontSize: '16px' },
    },
  },
})
```

O `theme` vale para o formulário seguro de produção. O formulário de teste do Dev mode tem visual fixo.

***

## Exemplo em React

Coloque a tag do script no `index.html` (no Next.js, use `<Script src="https://abacatepay.com/abacatepay.js" strategy="beforeInteractive" />` no layout raiz). O componente cobra pelo mesmo backend do [passo a passo](/pages/guides/cartao-transparente) (`POST /pagar`):

```jsx PagamentoCartao.jsx theme={null}
'use client'

import { useEffect, useRef, useState } from 'react'

export function PagamentoCartao({ publicKey, amount, cliente }) {
  const area = useRef(null)
  const checkout = useRef(null)
  const [podePagar, setPodePagar] = useState(false)
  const [mensagem, setMensagem] = useState('')

  useEffect(() => {
    let cancelado = false
    const host = area.current.appendChild(document.createElement('div')) // um por montagem (StrictMode)
    const instancia = window.AbacatePay.create({
      publicKey,
      amount,
      onCardChange: ({ canTokenize }) => setPodePagar(canTokenize),
    })
    checkout.current = instancia
    instancia.mount(host).catch((error) => !cancelado && setMensagem(error.message))
    return () => {
      cancelado = true
      instancia.destroy()
      host.remove()
    }
  }, [publicKey, amount])

  async function pagar() {
    setPodePagar(false) // evita cobrança em dobro
    try {
      const { token } = await checkout.current.tokenize(cliente)
      const resposta = await fetch('/pagar', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ token, cliente }),
      })
      const { success, status, error } = await resposta.json()
      setMensagem(success ? `Pagamento recebido (${status})` : error)
      if (success) return
    } catch (error) {
      setMensagem(error.message)
    }
    setPodePagar(checkout.current.canTokenize)
  }

  return (
    <div>
      <div ref={area} />
      <button type="button" onClick={pagar} disabled={!podePagar}>Pagar</button>
      {mensagem && <p role="alert">{mensagem}</p>}
    </div>
  )
}
```

Uso:

```jsx theme={null}
<PagamentoCartao
  publicKey="pk_sua_chave_publica"
  amount={10000}
  cliente={{ name: 'Maria Silva', email: 'maria@exemplo.com', taxId: '529.982.247-25', cellphone: '11999999999' }}
/>
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.