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

# Checkout Transparente

> Receba PIX, boleto e cartão dentro da sua própria interface, sem redirecionar o cliente

## Visão Geral

No **checkout transparente** o cliente paga sem sair da sua tela. Você chama a API, recebe o código PIX (ou a linha do boleto, ou o resultado da autorização do cartão) e exibe tudo com a sua marca, no seu layout.

É o caminho para quem constrói produto whitelabel, marketplace, ou simplesmente não quer que o cliente veja uma página de terceiro no meio da compra.

### Qual caminho usar?

| Cenário                                          | Solução                                                     |
| ------------------------------------------------ | ----------------------------------------------------------- |
| Quero receber rápido, sem programar              | [Link de pagamento](/api-reference/produtos/link-pagamento) |
| Quero pré-preencher dados e rastrear pedidos     | [Checkout Session](/guias/checkout-sessions)                |
| Quero o pagamento acontecendo na minha interface | **Checkout transparente**                                   |
| Vendo com a marca do meu cliente (whitelabel)    | **Checkout transparente**                                   |

<Note>
  As três opções coexistem. Nada do que você já integrou deixa de funcionar.
</Note>

## Como funciona

<Steps>
  <Step title="Crie o produto uma vez">
    A cobrança sempre aponta para um produto — é dele que saem preço, métodos aceitos e parcelamento. Crie com [`POST /api/v1/products`](/api-reference/produtos/criar) e guarde o `uuid`.
  </Step>

  <Step title="Colete os dados do cliente na sua interface">
    Nome, e-mail, CPF/CNPJ e telefone são obrigatórios. Endereço é opcional.
  </Step>

  <Step title="Crie a cobrança">
    `POST /api/v1/charges` com o `productId`, o `paymentMethod` e o `customer`. A resposta traz os dados de pagamento.
  </Step>

  <Step title="Exiba o pagamento">
    Renderize o QR Code a partir do `pix.code`, ou mostre a linha digitável e o link do PDF do boleto.
  </Step>

  <Step title="Confirme o pagamento">
    Receba o [webhook](/api-reference/webhooks) de pagamento confirmado, ou consulte [`GET /api/v1/charges/{uuid}`](/api-reference/cobrancas/detalhes).
  </Step>
</Steps>

## PIX na prática

```javascript theme={null}
const response = await fetch('https://garu.com.br/api/v1/charges', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.GARU_API_KEY}`,
    'Content-Type': 'application/json',
    'X-Idempotency-Key': `pedido-${orderId}`
  },
  body: JSON.stringify({
    productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
    paymentMethod: 'pix',
    customer: {
      name: 'Maria Silva',
      email: 'maria@exemplo.com.br',
      document: '12345678909',
      phone: '11987654321'
    }
  })
});

const charge = await response.json();

// charge.uuid    → guarde para consultar o status depois
// charge.pix.code → o copia-e-cola, pronto para virar QR Code
```

### Renderizando o QR Code

A Garu devolve o **código EMV** (copia-e-cola), não uma imagem. Isso é de propósito: uma imagem viria hospedada num domínio de terceiro, e num checkout whitelabel isso apareceria para o seu cliente.

Gere o QR no seu próprio front, com a biblioteca que já usa:

<CodeGroup>
  ```jsx React theme={null}
  import QRCode from 'react-qr-code';

  <QRCode value={charge.pix.code} size={200} />;
  ```

  ```html HTML + JS theme={null}
  <div id="qr"></div>
  <script type="module">
    import QRCode from 'https://esm.sh/qrcode';
    QRCode.toCanvas(document.getElementById('qr'), charge.pix.code);
  </script>
  ```

  ```python Python theme={null}
  import qrcode

  img = qrcode.make(charge["pix"]["code"])
  img.save("pix.png")
  ```
</CodeGroup>

Ofereça também o botão de **copiar código** — boa parte das pessoas paga colando no app do banco, sem escanear nada.

## Boleto

```javascript theme={null}
const charge = await createCharge({ paymentMethod: 'boleto', /* ... */ });

// charge.boleto.barcodeLine → linha digitável
// charge.boleto.pdfUrl      → PDF servido pelo domínio da Garu
```

O `pdfUrl` é uma URL pública, que **não exige chave de API** — pode ser entregue direto ao seu cliente, por e-mail ou como botão de download. Ela aponta para `garu.com.br`, nunca para o domínio do adquirente.

## Cartão de crédito

<Warning>
  **Servidor-para-servidor, sempre.** Este endpoint recebe o número do cartão e o CVV em texto claro. Chame-o exclusivamente do seu backend — nunca do navegador nem de um app, onde a sua chave de API e os dados do cartão ficariam expostos.

  Processar dados de cartão no seu servidor coloca a sua operação no escopo do **PCI DSS** (provavelmente SAQ D). Isso é uma decisão de negócio, não um detalhe técnico. Se você prefere não assumir esse escopo, use PIX e boleto no checkout transparente e mande o cartão para a página hospedada da Garu, que já é PCI-compliant.
</Warning>

```javascript theme={null}
const charge = await createCharge({
  paymentMethod: 'creditCard',
  productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  customer: { /* ... */ },
  card: {
    number: '4111111111111111',
    holderName: 'MARIA SILVA',
    expirationDate: '2030-12',
    cvv: '123',
    installments: 2
  }
});

// charge.status       → "captured" quando aprovado
// charge.card.last4   → "1111"
// charge.amount       → 349.00  (preço do produto)
// charge.chargedTotal → 358.52  (o que o cliente pagou, com acréscimo do parcelamento)
```

A Garu nunca armazena o número do cartão nem o CVV. A resposta devolve só bandeira, últimos 4 dígitos e código de autorização.

### Parcelamento: `amount` não é `chargedTotal`

<Note>
  Em venda parcelada os dois valores **divergem, e isso é esperado**: `amount` é o preço do produto, `chargedTotal` é o que foi efetivamente cobrado, já com o acréscimo.

  Um produto de R$ 349,00 vendido em 2× tem `chargedTotal: 358.52` — cerca de R$ 179,26 por parcela. Se você exibir R\$ 179,26 como o total da compra, vai mostrar um número errado ao seu cliente e não vai conseguir reconciliar o recebimento depois.
</Note>

## Idempotência

Mande sempre um `X-Idempotency-Key` único por cobrança. Se a requisição sofrer timeout e você reenviar, a chave garante que volta a **mesma cobrança** em vez de nascer uma segunda. Vale por 24 horas.

```javascript theme={null}
headers: { 'X-Idempotency-Key': `pedido-${orderId}` }
```

## Juntando com Checkout Sessions

Dá para combinar os dois: crie a [Checkout Session](/guias/checkout-sessions) para levar `metadata`, `client_reference_id` e atribuição de afiliado, e depois passe o token dela na criação da cobrança. O cliente nunca sai da sua interface e você mantém o rastreamento.

```javascript theme={null}
const charge = await createCharge({
  productId,
  paymentMethod: 'pix',
  customer,
  checkoutSessionToken: session.id
});
```

A session é marcada como concluída e fica amarrada à cobrança.

## Confirmando o pagamento

PIX e boleto são assíncronos: a cobrança nasce pendente e só depois vira paga. Duas formas de saber:

<Card title="Webhooks (recomendado)" icon="bolt" href="/api-reference/webhooks">
  A Garu chama o seu endpoint no instante em que o pagamento é confirmado. É a opção mais rápida e a que menos consome recurso dos dois lados.
</Card>

<Card title="Consulta pontual" icon="magnifying-glass" href="/api-reference/cobrancas/detalhes">
  `GET /api/v1/charges/{uuid}` devolve o status atual. Útil para reconciliação, ou para atualizar a tela enquanto o cliente ainda está nela.
</Card>

## Referência completa

<CardGroup cols={2}>
  <Card title="Criar cobrança" icon="plus" href="/api-reference/cobrancas/criar" />

  <Card title="Consultar cobrança" icon="magnifying-glass" href="/api-reference/cobrancas/detalhes" />

  <Card title="Listar cobranças" icon="list" href="/api-reference/cobrancas/listar" />

  <Card title="Estornar cobrança" icon="rotate-left" href="/api-reference/cobrancas/reembolsar" />
</CardGroup>
