> Índice da documentação para agentes: https://gaio.social/developers/llms.txt

# Pixel de vendas

Credite as vendas do seu site e do seu checkout aos cliques nos links da Gaio: o que o pixel capta sozinho, os eventos que o site envia e como o seu servidor informa os pedidos.

## Como funciona

O pixel de vendas credita cada venda ao clique num link da Gaio que trouxe o comprador. Um link da Gaio é um link que a Gaio envia por você, numa automação, no chat ao vivo ou no Inbox: cada vez que alguém toca nele, a Gaio registra um clique, com um identificador próprio. O pixel leva esse clique do link até a venda:

1. A pessoa toca no link. A Gaio registra o clique e a leva ao destino com o clique no endereço.
2. No seu site, o pixel (`gaio.js`) guarda o clique num cookie e conta as páginas vistas, os leads e os checkouts iniciados dessa pessoa.
3. No checkout, o clique segue com o pedido: num parâmetro do link da Hotmart ou da Kiwify, ou lido pelo seu servidor, num checkout próprio.
4. A venda chega à Gaio com o clique: pela página de obrigado, pelo webhook da Hotmart ou da Kiwify, ou pelo seu servidor.

O último clique da Gaio nos 7 dias antes da venda leva o crédito, e a venda conta no dia desse clique. A página de Analytics mostra as vendas e a receita por post, automação, origem, link e pessoa da equipe.

O pixel vem com a página de Analytics: ele aparece nas contas que têm a página liberada, em **Configurações › Integrações › Pixel de vendas**, para quem tem a permissão de integrações.

### O clique no endereço

O link leva o clique de um jeito para cada destino:

- **Um dos seus sites**, ou um subdomínio dele: no fragmento do endereço, `#gcid=` seguido de 22 letras e números, como `https://loja.com.br/curso#gcid=0QWe8GOZPz5vtkmnzDJHxA`. O fragmento não chega ao seu servidor, então não atrapalha cache nem redirecionamento. O pixel o guarda e o tira da barra de endereço.
- **Um checkout da Hotmart** (`pay.hotmart.com` ou `go.hotmart.com`), com a Hotmart conectada: no parâmetro `src`.
- **Um checkout da Kiwify** (`pay.kiwify.com.br`), com a Kiwify conectada: no parâmetro `s1`.

Um endereço que já tem fragmento (`#planos`), ou um checkout com o parâmetro já preenchido (por um link de afiliado, por exemplo), vai como está, sem o clique. Uma mensagem enviada antes de o site ser cadastrado leva o link sem o clique; os envios seguintes já o levam.

## Instalar

### Cadastre os sites

Em **Configurações › Integrações › Pixel de vendas**, em **Seus sites**, cadastre o domínio de cada site em que o pixel vai rodar, como `loja.com.br`: até 10 sites. Um site vale também para os subdomínios: `loja.com.br` cobre `www.loja.com.br` e `checkout.loja.com.br`.

O pixel descarta o que chega de uma página fora desses domínios, e os links da Gaio só levam o clique para eles: cadastre os sites antes de enviar os links.

### Cole o código

O código aparece em **Instale o pixel** depois que o primeiro site é salvo. Escolha em **Seu site é** o tipo do site, copie o código e cole no `<head>` de todas as páginas, ou no Google Tag Manager, como uma tag HTML personalizada que dispara em todas as páginas:

```html
<script>
!function(w,d,u){w.gaio=w.gaio||function(){(w.gaio.q=w.gaio.q||[]).push(arguments)};var s=d.createElement('script');s.async=1;s.src=u;d.head.appendChild(s)}(window,document,'https://s.gaio.social/g.js');
gaio('init','px_…');
</script>
```

O `px_…` é o id público do pixel da conta: copie o código do console, com ele já preenchido. O código cria a função `gaio` na hora e carrega o `gaio.js` sem bloquear a página. O que você chama antes de o script carregar espera numa fila, então dá para chamar `gaio('track', …)` em qualquer ponto da página depois do código. O `init` vale uma vez por página: o código instalado duas vezes não conta nada em dobro.

Para uma loja, o `init` diz a plataforma:

| Seu site é | O `init` |
| --- | --- |
| Site próprio ou landing page | `gaio('init', 'px_…')` |
| Loja Shopify | `gaio('init', 'px_…', { platform: 'shopify' })`, e um pixel personalizado no checkout (veja [Lojas](https://gaio.social/developers/pixel.md#lojas-shopify-woocommerce-e-yampi)) |
| Loja WooCommerce | `gaio('init', 'px_…', { platform: 'woocommerce' })` |
| Loja Yampi | `gaio('init', 'px_…', { platform: 'yampi' })` |

A plataforma só diz de onde vêm as compras que a página informa. Ela muda como a compra do navegador se junta à do servidor: veja [Compra: pelo navegador ou pelo servidor?](https://gaio.social/developers/pixel.md#compra-pelo-navegador-ou-pelo-servidor).

## O que o pixel capta sozinho

Com o código instalado, sem nada mais:

| Evento | Quando |
| --- | --- |
| `PageView` | Uma página carrega, para quem tem um clique da Gaio. |
| `InitiateCheckout` | Quem tem um clique toca num link para um checkout da Hotmart ou da Kiwify. Na mesma hora, o pixel põe o clique no link, em `src` na Hotmart e em `s1` na Kiwify, se o parâmetro estiver livre. |
| `Purchase` | A página empurra o evento `purchase` do GA4 no `window.dataLayer`, para qualquer visitante. |

Quem tem um clique é quem chegou por um link da Gaio nos últimos 7 dias, naquele navegador. Para os outros visitantes, o pixel não envia `PageView` nem `InitiateCheckout`.

- O pixel só vê links `<a href>`, inclusive os que a página acrescenta depois de carregar. Um botão que leva ao checkout por JavaScript (`location.href = …`) não leva o clique nem conta o início do checkout: use um link.
- Num site de página única (SPA), o pixel conta só a página que carregou. Para contar as outras, chame `gaio('track', 'PageView')` a cada troca de rota.

### A compra do `dataLayer`

O pixel lê o `purchase` do GA4 que a página empurra no `dataLayer`, antes ou depois de o `gaio.js` carregar. É o evento que o Google Tag Manager e a maioria das lojas já enviam na página de obrigado. O GA4 em si não precisa estar instalado: basta o `push`.

```js
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: '1042',
    value: 497.9,
    currency: 'BRL'
  }
});
```

O `gtag('event', 'purchase', { transaction_id: '1042', value: 497.9, currency: 'BRL' })` também vale. Dos parâmetros, o pixel usa três:

- `transaction_id`: o id do pedido, texto ou número. Obrigatório.
- `value`: o valor do pedido na unidade da moeda, zero ou mais: `497.9` são R$ 497,90. Obrigatório.
- `currency`: o código ISO 4217 da moeda. Sem ele, `BRL`.

Sem `transaction_id` ou sem `value`, o evento não é uma compra para o pixel. Os itens e o resto do `ecommerce` são ignorados, e o `dataLayer` não traz o comprador: para enviar o e-mail e o telefone, use [`gaio('track', 'Purchase', …)`](https://gaio.social/developers/pixel.md#purchase).

## Eventos que você envia

Chame `gaio('track', '<evento>')` numa página com o código do pixel:

| Evento | Quando enviar |
| --- | --- |
| `Lead` | A pessoa deixou o contato: um formulário enviado com sucesso, um cadastro, uma inscrição. Uma vez por envio. |
| `InitiateCheckout` | A pessoa começou a compra no seu próprio site: abriu o checkout ou tocou em "Finalizar compra". Uma vez por compra iniciada. |
| `Purchase` | Na página de obrigado de um pedido **já pago**, como um cartão aprovado. Nunca para um Pix ou boleto gerado e ainda não pago. |
| `PageView` | Só num site de página única (SPA), a cada troca de rota. |

```js
gaio('track', 'Lead');
gaio('track', 'InitiateCheckout');
gaio('track', 'Purchase', { order_id: '1042', value: 497.9, currency: 'BRL' });
gaio('track', 'PageView');
```

- `PageView`, `Lead` e `InitiateCheckout` só saem para quem tem um clique da Gaio. Para os outros visitantes, a chamada não faz nada: você pode chamá-la sempre, sem perguntar de onde a pessoa veio.
- Cada chamada desses três conta uma vez: chamar duas vezes conta dois. Não chame `InitiateCheckout` para um link da Hotmart ou da Kiwify, que o pixel já conta sozinho.
- `Purchase` sai para todo comprador, com ou sem clique. As vendas sem clique mostram, na página de Analytics, que parte das vendas veio da Gaio.
- O nome do evento vai como na tabela, com as maiúsculas. Outro nome é ignorado.

### Lead

Chame depois que o envio do formulário deu certo, e não no clique do botão, que conta também o envio que falhou:

```js
const response = await fetch('/api/contato', { method: 'POST', body: new FormData(form) });

if (response.ok) {
  gaio('track', 'Lead');
}
```

O `Lead` não leva dados: o pixel não guarda o que foi preenchido.

### Purchase

```js
gaio('track', 'Purchase', {
  order_id: '1042',
  value: 497.9,
  currency: 'BRL',
  email: 'comprador@exemplo.com',
  phone: '+55 11 91234-5678'
});
```

| Campo | O que é |
| --- | --- |
| `order_id` | O id do pedido no seu sistema, texto ou número, até 128 caracteres. Obrigatório. É por ele que o mesmo pedido conta uma vez só. |
| `value` | O valor do pedido na unidade da moeda, zero ou mais: `497.9` são R$ 497,90. Obrigatório. |
| `currency` | O código ISO 4217 da moeda, como `BRL`. Sem ele, `BRL`. |
| `email` | O e-mail do comprador. Opcional. |
| `phone` | O telefone do comprador, com o código do país. Opcional. |

- Sem `order_id` ou sem `value`, a chamada é ignorada. Uma moeda que não é um código de 3 letras descarta a compra.
- O e-mail e o telefone saem do navegador só como hash SHA-256: o e-mail sem espaços nas pontas e em minúsculas, o telefone só com os dígitos. Numa página sem `https`, o navegador não calcula o hash, e eles não saem.
- Abrir de novo a página de obrigado não conta a venda duas vezes: o pedido é um só pelo `order_id`.
- A compra que o navegador informa entra como **paga**, na hora em que chega. Por isso ela é só para um pedido já pago, a não ser que o seu servidor também informe o pedido (veja a seção seguinte).

## Compra: pelo navegador ou pelo servidor?

A compra que o navegador informa, por `gaio('track', 'Purchase')` ou pelo `dataLayer`, entra como paga na hora: o navegador não sabe o que acontece com o pedido depois. Um Pix ou um boleto gerado na página de obrigado ainda não foi pago, e pode nunca ser. Informado pelo navegador, ele conta como venda e assim fica.

Pelo servidor, ou pelos checkouts conectados, a venda acompanha o pedido: entra pendente, conta quando é paga e deixa de contar quando é cancelada, reembolsada ou contestada.

| Onde você vende | Como a venda chega |
| --- | --- |
| Hotmart ou Kiwify | Pelo webhook do checkout: conecte-o (veja [Checkouts conectados](https://gaio.social/developers/pixel.md#checkouts-conectados-hotmart-e-kiwify)). Não informe a compra pela página: ela contaria a mesma venda outra vez, como outro pedido. |
| Loja Shopify, WooCommerce ou Yampi | Pela página de obrigado da loja (veja [Lojas](https://gaio.social/developers/pixel.md#lojas-shopify-woocommerce-e-yampi)). |
| Checkout próprio, só com cartão | Pela página de obrigado, com `gaio('track', 'Purchase', …)` depois da aprovação, ou pelo servidor. |
| Checkout próprio, com Pix ou boleto | Pelo servidor (veja [Checkout próprio](https://gaio.social/developers/pixel.md#checkout-próprio-pedidos-pelo-servidor)). |

### A página e o servidor no mesmo pedido

Quando a página e o servidor informam o mesmo pedido, com o mesmo `order_id` e o `init` sem `platform`, a Gaio guarda um pedido só, e o status dele é sempre o do servidor. A compra que a página informa vale só até chegar o primeiro envio do servidor, e depois não muda mais o status, nem quando a página de obrigado é aberta de novo. O que a página ainda pode acrescentar é o clique, se o envio do servidor veio sem `gcid`.

Por isso a página pode continuar informando a compra, pelo `dataLayer` ou por `gaio('track', 'Purchase')`. Envie o `pending` assim que o pedido é criado: um Pix gerado conta como pago só no intervalo até esse envio chegar.

Com uma plataforma de loja no `init` (`platform: 'woocommerce'`, por exemplo), a compra do navegador e a do servidor ficam em plataformas diferentes e viram dois pedidos. Num site cujo servidor informa os pedidos, use o `init` sem `platform`.

## Checkouts conectados: Hotmart e Kiwify

A Hotmart e a Kiwify enviam as vendas para a Gaio pelo webhook delas. Em **Configurações › Integrações › Pixel de vendas**, em **Checkouts**, clique em **Conectar Hotmart** ou **Conectar Kiwify** e siga os passos:

- **Hotmart**: em **Ferramentas → Webhook (API e notificações)**, copie o hottok de verificação e cole na Gaio. Depois, cadastre na Hotmart um webhook com o endereço que a Gaio mostra, na versão 2.0.0, para os seus produtos, com os eventos de compra aprovada, completa, cancelada, expirada, reembolsada, chargeback, boleto impresso e atrasada.
- **Kiwify**: em **Apps → Webhooks**, crie um webhook e cole na Gaio o token que ele mostra. Depois, cole no mesmo webhook o endereço que a Gaio mostra, com os eventos de compra aprovada, recusada, reembolsada, chargeback, boleto gerado e Pix gerado.

O webhook acompanha o pedido inteiro:

| Status na Gaio | Hotmart | Kiwify |
| --- | --- | --- |
| `pending`, esperando o pagamento | Boleto impresso, compra atrasada | Boleto ou Pix gerado |
| `paid`, pago | Compra aprovada, compra completa | Compra aprovada |
| `canceled`, não vai ser pago | Compra cancelada, compra expirada | Compra recusada |
| `refunded`, reembolsado | Compra reembolsada | Compra reembolsada |
| `chargeback`, contestado | Chargeback | Chargeback |

Só o pedido pago conta como venda, e um reembolso ou um chargeback depois tira a venda do total. Na Hotmart, o valor é o preço da oferta, sem os juros do parcelamento.

O clique chega ao checkout no parâmetro `src` (Hotmart) ou `s1` (Kiwify): posto pelo link da Gaio, quando ele leva direto ao checkout, ou pelo pixel, quando a pessoa passa pelo seu site e toca no link do checkout. Não use esses parâmetros para outra coisa nos links da Gaio e do seu site: um parâmetro já preenchido fica como está, e o clique não vai.

Quando você gerar um novo token na Hotmart ou na Kiwify, troque-o na Gaio em **Trocar token**: o endereço do webhook continua o mesmo.

## Checkout próprio: pedidos pelo servidor

Se o checkout é seu, ou seja, o seu sistema cria o pedido e recebe o pagamento, o seu servidor informa à Gaio cada pedido e cada mudança de status dele. É o caminho para vender por Pix e boleto: o pedido entra pendente e só conta como venda quando é pago.

### Conectar o checkout

Em **Configurações › Integrações › Pixel de vendas**, em **Checkouts**, conecte o **Checkout próprio**. A Gaio cria um segredo, que começa com `gpx_`, e mostra uma única vez o segredo e o endereço do conector:

```
https://s.gaio.social/hooks/<id do conector>
```

Guarde o segredo no servidor que envia os pedidos, numa variável de ambiente, como uma senha: é com ele que o servidor [assina cada envio](https://gaio.social/developers/pixel.md#assinar-o-envio). Ele nunca vai para o navegador. Se você perdê-lo, [gere outro](https://gaio.social/developers/pixel.md#trocar-o-segredo).

Os exemplos desta seção leem o endereço de `GAIO_PIXEL_URL` e o segredo de `GAIO_PIXEL_SECRET`.

### Levar o clique até o pedido

Para a venda ser creditada, o pedido leva o clique que trouxe o comprador, no campo `gcid`. O pixel guarda o clique no cookie `_gaio_gcid`, por 7 dias, no domínio do seu site, que os subdomínios compartilham. Leia o cookie quando o pedido é criado e guarde o clique com o pedido:

- **Checkout no mesmo domínio do site** (`loja.com.br/checkout` ou `checkout.loja.com.br`): o cookie chega no cabeçalho `Cookie` da requisição que cria o pedido.

```js
const gcid = /(?:^|;\s*)_gaio_gcid=([0-9A-Za-z]{22})/.exec(request.headers.cookie ?? '')?.[1];
```

- **Checkout em outro domínio**: o cookie de `loja.com.br` não chega a `pagamento.com`, e o clique precisa ir até lá. Se os links da Gaio levam direto ao checkout, cadastre o domínio do checkout como site e instale o código do pixel nele: os links passam a levar o clique, e o pixel o guarda no cookie desse domínio. Se a pessoa passa pelo site antes, leia o cookie no site e acrescente o clique ao link do checkout, como `#gcid=<clique>` se o checkout tem o pixel, ou num parâmetro seu, que o checkout guarda com o pedido.

```js
const gcid = document.cookie
  .split('; ')
  .find((pair) => pair.startsWith('_gaio_gcid='))
  ?.slice('_gaio_gcid='.length);
```

Envie o `gcid` exatamente como veio. Sem ele, o pedido é guardado, mas não é creditado a nenhum clique.

### O corpo do pedido

O servidor envia um `POST` para o endereço do conector, com `Content-Type: application/json`, o [cabeçalho `Gaio-Signature`](https://gaio.social/developers/pixel.md#assinar-o-envio) e o pedido em JSON: um envio quando o pedido é criado e um a cada mudança de status.

```json
{
  "order_id": "1042",
  "status": "pending",
  "status_at": "2026-10-29T14:05:00-03:00",
  "ordered_at": "2026-10-29T14:05:00-03:00",
  "value": 497.9,
  "currency": "BRL",
  "payment_method": "pix",
  "gcid": "0QWe8GOZPz5vtkmnzDJHxA",
  "buyer": {
    "email": "comprador@exemplo.com",
    "phone": "+55 11 91234-5678"
  }
}
```

| Campo | O que é |
| --- | --- |
| `order_id` | O id do pedido no seu sistema, texto ou número. Obrigatório. O mesmo em todos os envios do pedido. |
| `status` | `pending`, `paid`, `canceled`, `refunded` ou `chargeback` (veja [Status do pedido](https://gaio.social/developers/pixel.md#status-do-pedido)). Obrigatório. |
| `status_at` | Quando o pedido passou a esse status, em ISO 8601 com o fuso: `2026-10-29T14:05:00-03:00` ou `2026-10-29T17:05:00Z`. Obrigatório. Um horário sem fuso é recusado. |
| `ordered_at` | Quando o pedido foi feito, no mesmo formato. Sem ele, vale o `status_at`. |
| `value` | O valor do pedido na unidade da moeda, zero ou mais: `497.9` são R$ 497,90. Obrigatório. |
| `currency` | O código ISO 4217 da moeda, como `BRL`. Obrigatório. |
| `payment_method` | Como o pedido é pago, como `pix`, `boleto` ou `credit_card`. Opcional. |
| `gcid` | O clique, exatamente como veio (veja [Levar o clique até o pedido](https://gaio.social/developers/pixel.md#levar-o-clique-até-o-pedido)). Opcional. Um valor que não é um clique é recusado. |
| `buyer` | O comprador: `email` e `phone`, com o código do país. Opcional. A Gaio guarda os dois só como hash SHA-256. |

- Envie o mesmo `ordered_at` em todos os envios do pedido: o clique que leva o crédito é procurado nos 7 dias antes dele. Sem `ordered_at`, um boleto pago dias depois procura o clique a partir do pagamento.
- Envie o `gcid`, o `value` e o `buyer` em todos os envios. Creditado a um clique, o pedido fica com ele, e o valor acompanha o status mais recente.
- Campos que a Gaio não conhece são ignorados.

### Assinar o envio

O cabeçalho `Gaio-Signature` prova que foi o seu servidor que enviou aquele corpo, há pouco tempo. É o mesmo formato com que a Gaio assina os webhooks dela (veja [Conferir a assinatura](https://gaio.social/developers/webhooks.md#conferir-a-assinatura)), mas aqui quem assina é o seu servidor, e quem confere é a Gaio:

```
Gaio-Signature: t=1793293500,v1=5f8c…
```

- `t` é o momento do envio, em segundos desde 1970 (Unix).
- `v1` é o HMAC-SHA256, em hexadecimal, de `<t>.<corpo>`: o valor de `t`, um ponto e o corpo exatamente como vai na requisição. A chave do HMAC é o segredo inteiro, com o `gpx_`.

Para assinar:

1. Escreva o pedido em JSON uma vez, e assine e envie esse mesmo texto. Um JSON escrito de novo muda espaços, ordem e acentos, e a assinatura não bate.
2. Calcule o HMAC-SHA256 de `<t>.<corpo>` com o segredo.
3. Envie `t=<t>,v1=<hex>` no `Gaio-Signature`.

A Gaio recusa um `t` a mais de 5 minutos do relógio dela: mantenha o relógio do servidor sincronizado e assine de novo a cada tentativa, com um `t` novo. O cabeçalho pode trazer mais de um `v1` (`t=…,v1=…,v1=…`), e basta um bater.

Os exemplos abaixo usam só a biblioteca padrão.

### Node.js

Com o `fetch` do Node.js 18 ou mais novo:

```js
import { createHmac } from 'node:crypto';

export async function sendOrderToGaio(order) {
  const body = JSON.stringify(order);
  const timestamp = Math.floor(Date.now() / 1000);
  const signature = createHmac('sha256', process.env.GAIO_PIXEL_SECRET)
    .update(`${timestamp}.${body}`)
    .digest('hex');

  const response = await fetch(process.env.GAIO_PIXEL_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Gaio-Signature': `t=${timestamp},v1=${signature}`
    },
    body
  });

  if (!response.ok) {
    throw new Error(`A Gaio respondeu ${response.status}: ${await response.text()}`);
  }
}

await sendOrderToGaio({
  order_id: '1042',
  status: 'paid',
  status_at: '2026-10-29T14:09:12-03:00',
  ordered_at: '2026-10-29T14:05:00-03:00',
  value: 497.9,
  currency: 'BRL',
  payment_method: 'pix',
  gcid: '0QWe8GOZPz5vtkmnzDJHxA'
});
```

### Python

```python
import hashlib
import hmac
import json
import os
import time
import urllib.error
import urllib.request


def send_order_to_gaio(order: dict) -> None:
    body = json.dumps(order).encode()
    timestamp = str(int(time.time()))
    secret = os.environ["GAIO_PIXEL_SECRET"].encode()
    signature = hmac.new(secret, timestamp.encode() + b"." + body, hashlib.sha256).hexdigest()

    request = urllib.request.Request(
        os.environ["GAIO_PIXEL_URL"],
        data=body,
        method="POST",
        headers={
            "Content-Type": "application/json",
            "Gaio-Signature": f"t={timestamp},v1={signature}",
        },
    )

    try:
        with urllib.request.urlopen(request, timeout=10):
            pass
    except urllib.error.HTTPError as error:
        raise RuntimeError(f"A Gaio respondeu {error.code}: {error.read().decode()}") from error


send_order_to_gaio({
    "order_id": "1042",
    "status": "paid",
    "status_at": "2026-10-29T14:09:12-03:00",
    "ordered_at": "2026-10-29T14:05:00-03:00",
    "value": 497.9,
    "currency": "BRL",
    "payment_method": "pix",
    "gcid": "0QWe8GOZPz5vtkmnzDJHxA",
})
```

### curl

Para um teste à mão, com o `openssl`:

```bash
BODY='{"order_id":"1042","status":"pending","status_at":"2026-10-29T14:05:00-03:00","value":497.9,"currency":"BRL","payment_method":"pix"}'
T=$(date +%s)
SIGNATURE=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$GAIO_PIXEL_SECRET" | awk '{print $NF}')

curl "$GAIO_PIXEL_URL" \
  -H "Content-Type: application/json" \
  -H "Gaio-Signature: t=$T,v1=$SIGNATURE" \
  --data-binary "$BODY"
```

### Respostas

Um corpo que não é JSON é recusado antes de tudo. Num JSON, a Gaio confere a assinatura antes de ler o pedido. As respostas:

| Status | Quando |
| --- | --- |
| `200` | O pedido foi guardado. |
| `400` | O corpo não é um pedido que a Gaio lê. A mensagem diz o que corrigir: repetir o mesmo envio dá o mesmo erro. |
| `401` | A assinatura falta, não bate ou tem um `t` a mais de 5 minutos. Confira o segredo e o relógio do servidor. |
| `404` | O endereço não é de um conector: o checkout foi desconectado. |

O erro vem em JSON, com o motivo em `message`:

```json
{
  "type": "error",
  "message": "status_at must be an ISO 8601 time with its zone."
}
```

As mensagens do `400`, e o que corrigir em cada uma:

- `Malformed body payload.` ou `The body must be a JSON object.`: o corpo não é um objeto JSON.
- `Malformed path parameters.`: o id do conector no endereço está incompleto ou errado. Copie o endereço de novo.
- `order_id is required.`: falta o `order_id`.
- `status must be one of pending, paid, canceled, refunded, chargeback.`: o `status` falta ou não é um desses, em minúsculas.
- `status_at is required.`: falta o `status_at`.
- `status_at must be an ISO 8601 time with its zone.`: o `status_at` não é uma data, ou não tem o fuso. O mesmo vale para o `ordered_at`.
- `value must be a number of at least zero, in the currency units.`: o `value` falta, não é um número ou é negativo.
- `currency must be an ISO 4217 code, such as BRL.`: a `currency` falta ou não tem 3 letras.
- `gcid must be the click id the link brought, as it came.`: o `gcid` não é um clique. Veio mudado, cortado ou de outra ferramenta.

A Gaio não tenta de novo por você. Numa resposta `5xx` ou numa falha de rede, tente de novo, com espera crescente entre as tentativas e uma assinatura nova em cada uma. Repetir um envio que já deu certo não muda nada.

### Status do pedido

| Status | Quando enviar |
| --- | --- |
| `pending` | O pedido foi criado e espera o pagamento: o Pix ou o boleto foi gerado. |
| `paid` | O pagamento foi confirmado. Só o pedido `paid` conta como venda. |
| `canceled` | O pedido não vai ser pago: o Pix ou o boleto venceu, o cartão foi recusado, o pedido foi cancelado. |
| `refunded` | O pagamento foi devolvido. |
| `chargeback` | O comprador contestou o pagamento no cartão. |

Como cada pagamento anda:

- **Pix**: `pending` quando o Pix é gerado; depois, `paid` quando o pagamento é confirmado, ou `canceled` quando o Pix vence.
- **Boleto**: `pending` quando o boleto é gerado; depois, `paid` na compensação, ou `canceled` no vencimento.
- **Cartão**: `paid` direto, quando o pagamento é aprovado.
- **Depois do pagamento**: `refunded` ou `chargeback`, se acontecer, com o mesmo `order_id`.

O pedido fica com o status do envio de `status_at` mais recente, e não com o do envio que chegou por último. Assim, um envio repetido ou atrasado não muda nada: envie no `status_at` o momento em que o status mudou, e não o do envio. Com o mesmo `status_at`, vale o status que vem depois nesta ordem: `pending`, `canceled`, `paid`, `refunded`, `chargeback`.

A venda conta no dia do clique: um boleto pago na quinta, de um clique na segunda, conta na segunda. Um reembolso semanas depois tira a venda daquele dia.

### Trocar o segredo

Em **Checkouts**, clique em **Gerar novo segredo** no checkout próprio. A Gaio cria outro segredo e o mostra uma única vez; o endereço continua o mesmo.

O segredo anterior para de valer na hora: diferente dos webhooks da Gaio, não há um tempo em que os dois valem. Os envios assinados com ele passam a receber `401`. Para trocar:

1. Gere o novo segredo.
2. Passe o servidor para ele.
3. Envie de novo, assinados com o novo segredo, os pedidos que receberam `401` nesse meio-tempo.

Se o segredo vazou, gere outro logo: quem tem o segredo consegue enviar pedidos em nome do seu checkout.

## Lojas: Shopify, WooCommerce e Yampi

Numa loja, escolha a plataforma em **Seu site é**, e o código já sai com ela no `init`. A venda vem da página de obrigado da loja: o pixel lê o `purchase` do GA4 que a loja empurra no `dataLayer` (veja [A compra do dataLayer](https://gaio.social/developers/pixel.md#a-compra-do-datalayer)). Se a loja não empurra o `purchase`, chame [`gaio('track', 'Purchase', …)`](https://gaio.social/developers/pixel.md#purchase) nessa página.

- **WooCommerce e Yampi**: o código do pixel no `<head>` de todas as páginas da loja basta.
- **Shopify**: o checkout da Shopify não roda o código do tema. Cole o código do pixel no tema, que guarda o clique nas páginas da loja, e cole também o pixel personalizado que o console mostra em **Configurações → Eventos do cliente → Adicionar pixel personalizado** da Shopify, e conecte o pixel. Ele informa a compra no evento `checkout_completed`, com o id e o total do pedido e o clique guardado no cookie.

A compra da página de obrigado entra paga. Se a loja empurra o `purchase` também para um Pix ou boleto gerado e ainda não pago, ele conta como venda. Quando isso pesa nas vendas da loja, informe os pedidos pelo servidor, como um [checkout próprio](https://gaio.social/developers/pixel.md#checkout-próprio-pedidos-pelo-servidor), e use o `init` sem `platform`: o status que o servidor envia vale sobre a compra da página (veja [A página e o servidor no mesmo pedido](https://gaio.social/developers/pixel.md#a-página-e-o-servidor-no-mesmo-pedido)).

## Testar a instalação

A página do pixel, em **Teste a instalação**, mostra o que a Gaio recebeu por último: os eventos do site e os pedidos, cada um marcado **Clique da Gaio**, quando foi creditado a um clique, ou **Sem clique**.

1. Em **Links de teste**, abra o seu site. O link de teste leva um clique de teste no fragmento, como `https://loja.com.br/#gcid=000000001VgEh72lXvTXkG`, e o pixel o trata como um clique da Gaio. O mesmo `#gcid=` funciona em qualquer página do site.
2. Navegue: veja páginas, envie um formulário, comece um checkout.
3. Clique em **Atualizar**. Os eventos aparecem em **Eventos do site** em alguns segundos, marcados **Sem clique**: o clique de teste não veio de um link, e nada dele é creditado.
4. Os pedidos do navegador, dos checkouts conectados e do seu servidor aparecem em **Pedidos**, com o status.

Para testar o servidor, envie um pedido com o clique de teste, `"gcid": "000000001VgEh72lXvTXkG"`. Não há modo de teste: um pedido enviado fica na conta. Para testar sem somar uma venda, envie o pedido `pending` e depois `canceled`, com o mesmo `order_id`. Do mesmo jeito, uma compra de teste pelo navegador entra paga e conta nas vendas sem clique: teste a página de obrigado com um pedido de verdade.

O clique de teste fica no cookie por 7 dias, como um clique de verdade, até um clique novo substituí-lo. Apague o cookie `_gaio_gcid` para voltar a navegar como um visitante sem clique.

Quando nada aparece:

- **A página não está num site cadastrado**, nem num subdomínio de um. Isso inclui `localhost` e um endereço de IP: teste no site publicado.
- **O navegador é automatizado** e se identifica assim, como o Chrome headless do Playwright ou do Puppeteer: o pixel descarta. Teste num navegador comum.
- **O visitante não tem clique**: o site foi aberto sem o link de teste, então a página vista, o lead e o checkout iniciado não saem. Só a compra sai sem clique.
- **O código não está na página**, ou o `px_…` é de outra conta: confira se `window.gaio.loaded` é `true` no console do navegador.

## Perguntas frequentes

### Quanto tempo vale um clique?

7 dias. A venda é creditada ao último clique da Gaio nos 7 dias antes do pedido, e conta no dia desse clique. Um clique novo substitui o anterior no cookie do navegador.

### Um pedido em outra moeda entra na receita?

O pedido conta como venda, mas a receita da página de Analytics soma só os pedidos em reais (`BRL`).

### Recarregar a página de obrigado conta a venda duas vezes?

Não: o pedido é um só pelo `order_id`, ou pelo `transaction_id` do `dataLayer`. Quando o servidor também informa o pedido, vale o status que ele enviou, e a página aberta de novo não o muda (veja [A página e o servidor no mesmo pedido](https://gaio.social/developers/pixel.md#a-página-e-o-servidor-no-mesmo-pedido)).

### O pixel deixa o meu site mais lento ou pode quebrá-lo?

O `gaio.js` carrega sem bloquear a página, e nada que ele faz lança erro no código do site. Os eventos saem por `navigator.sendBeacon`, que não espera resposta.

### Os botões de link que a API da Gaio envia levam o clique?

Não: a API envia o endereço do botão como está, sem passar por um link da Gaio, e um toque nele não gera clique.

### Que dados o pixel guarda?

Das pessoas que chegaram por um link da Gaio: as páginas vistas, sem os parâmetros nem o fragmento do endereço, os leads, sem o que foi preenchido, e os checkouts iniciados, com o clique. Dos compradores: o pedido, o valor, o status e o meio de pagamento, e o e-mail e o telefone só como hash SHA-256. O endereço IP não é guardado. O corpo que o seu servidor envia fica guardado como chegou por 30 dias, para ser lido de novo se preciso, e depois é excluído.

O [acordo de tratamento de dados](https://gaio.social/legal/dpa) tem os detalhes, e pede que o seu site informe, na política de privacidade ou no aviso de cookies, que usa o pixel da Gaio para medir as vendas.
