# Hotmart -> Meta CAPI (Borrello / Passo a Passo da Radiestesia)

Postback da Hotmart -> Meta Conversions API. Corrige o tracking de Purchase
que hoje o pixel do browser reporta na emissao (pix/boleto/tentativa), fazendo
o evento **Purchase** so estourar quando a venda for de fato **APPROVED**.

## URLs

- Publica: `https://hotmart-webhook.agentesclimb.us/borrello`  (metodo POST)
- Health: `https://hotmart-webhook.agentesclimb.us/health`     (GET)
- Local (VPS): `http://127.0.0.1:8950/`
- Log: `/opt/mia/logs/hotmart_capi_borrello.log`
- Service: `hotmart-capi-borrello.service` (Restart=always)

## Pixel

Meta Pixel Matriz Borrello: **464623303880507**

## O QUE PRECISA DO RENATO (BLOQUEADORES)

### 1) System User Token do Meta (CAPI)

Enquanto o token nao for setado, o webhook aceita eventos mas roda em
**STUB_MODE**: valida HOTTOK, dedupa e loga o evento CAPI montado, mas nao
envia pro Meta.

Como gerar:

1. `business.facebook.com` -> **Configuracoes do negocio**
2. Aba **Usuarios** -> **Usuarios do sistema**
3. Selecionar (ou criar) um Usuario do Sistema com role **Admin**
4. **Adicionar ativos** -> escolher o Pixel `464623303880507` -> permissao total
5. **Gerar novo token** com escopos:
   - `ads_management`
   - `business_management`
6. Copiar o token (aparece uma vez so)
7. Salvar em `/opt/mia/config/meta_capi_borrello.env`:
   ```
   META_CAPI_TOKEN=EAAG...token_aqui
   ```
8. `sudo systemctl restart hotmart-capi-borrello`
9. Confirmar: `curl -s https://hotmart-webhook.agentesclimb.us/health` deve
   voltar `"capi_token_configured": true` e `"stub_mode": false`.

### 2) HOTTOK do webhook Hotmart

Painel Hotmart do produto Passo a Passo:

1. `app-vlc.hotmart.com` -> **Ferramentas** -> **Webhook** (ou "Notificacoes/Postback")
2. **Adicionar nova configuracao**
3. URL: `https://hotmart-webhook.agentesclimb.us/borrello`
4. Metodo: **POST**
5. Versao: **2.0.0** (postback JSON)
6. Formato: **JSON**
7. Eventos a marcar:
   - `PURCHASE_APPROVED`  (obrigatorio — venda paga)
   - `PURCHASE_REFUNDED`  (sinal negativo -> Meta desaprende)
   - `PURCHASE_CHARGEBACK` (idem)
   - Opcional: `PURCHASE_COMPLETE`, `PURCHASE_CANCELED` (o webhook ignora)
8. Salvar. A Hotmart vai gerar um **HOTTOK** (token de validacao).
9. Copiar o HOTTOK e colar em `/opt/mia/config/hotmart_borrello.env`:
   ```
   HOTMART_HOTTOK=abc123def456...
   ```
10. `sudo systemctl restart hotmart-capi-borrello`
11. Confirmar: `curl -s .../health` deve voltar `"hottok_configured": true`.

## Teste rapido do endpoint

```bash
# Health
curl -s https://hotmart-webhook.agentesclimb.us/health | python3 -m json.tool

# POST com hottok errado (deve dar 401)
curl -s -X POST https://hotmart-webhook.agentesclimb.us/borrello \
  -H "Content-Type: application/json" \
  -H "X-HOTMART-HOTTOK: fake" \
  -d '{"event":"PURCHASE_APPROVED"}'

# POST com hottok certo (200)
curl -s -X POST https://hotmart-webhook.agentesclimb.us/borrello \
  -H "Content-Type: application/json" \
  -H "X-HOTMART-HOTTOK: SEU_HOTTOK_AQUI" \
  -d '{
    "event": "PURCHASE_APPROVED",
    "data": {
      "purchase": {"transaction": "HP-TESTE-123", "status": "APPROVED",
                   "order_date": '"$(date +%s)000"',
                   "price": {"value": 197.00, "currency_value": "BRL"}},
      "buyer":    {"email": "teste@ex.com", "name": "Fulano Teste",
                   "checkout_phone": "+5511987654321"},
      "product":  {"id": "1437935", "name": "Passo a Passo"}
    }
  }'
```

## Validacao no Meta

Enquanto valida a integracao, usar `META_TEST_EVENT_CODE` no env:

1. `business.facebook.com` -> **Events Manager** -> pixel 464623303880507
2. Aba **Testar eventos** -> copiar o **codigo de teste** (`TEST12345`)
3. `/opt/mia/config/meta_capi_borrello.env`:
   ```
   META_TEST_EVENT_CODE=TEST12345
   ```
4. `sudo systemctl restart hotmart-capi-borrello`
5. Simular postback (curl acima) — evento vai aparecer ao vivo em "Testar eventos".
6. Confirmado: **APAGAR** `META_TEST_EVENT_CODE` do env e reiniciar (senao
   os eventos entram como teste e nao contam otimizacao real).

## Backfill retroativo (vendas ja aprovadas)

Depois do token CAPI configurado, rodar UMA vez pra reenviar as vendas
do periodo da campanha:

```bash
# Ultimos 15 dias (default)
/opt/mia/venvs/hotmart_capi/bin/python \
  /opt/mia/workspace/clientes/borrello/hotmart_capi/backfill_capi.py \
  --start 2026-08-05 --end 2026-08-20

# Dry-run (so lista, nao envia)
/opt/mia/venvs/hotmart_capi/bin/python \
  /opt/mia/workspace/clientes/borrello/hotmart_capi/backfill_capi.py \
  --dry-run

# Reenviar tudo (bypass dedupe)
/opt/mia/venvs/hotmart_capi/bin/python \
  /opt/mia/workspace/clientes/borrello/hotmart_capi/backfill_capi.py \
  --start 2026-08-05 --force
```

Sai um resumo `fetched / sent_ok / sent_fail / deduped / skipped`.

## Dedupe

- Chave: `event_id` = **transaction_id** da Hotmart.
- Storage: SQLite em `dedupe.db` no mesmo diretorio do app.
- Sinal negativo (refund/chargeback) usa `event_id = "refund_<transaction>"` /
  `"chargeback_<transaction>"` pra nao colidir com o Purchase original.

### ATENCAO — Purchase duplicado com o pixel do checkout Hotmart

A landing (`passoapasso.franciscoborrello.com.br`) **NAO** dispara
`fbq('track','Purchase')` — so `InitiateCheckout`. Confirmado por grep no
`landing-v10/index.html`.

Os ~56 Purchases fantasmas que aparecem no Meta vem do **pixel embutido pela
propria Hotmart no checkout dela** (configurado em
`app-vlc.hotmart.com > Ferramentas > Pixel do Facebook`). Esse pixel dispara
Purchase na **emissao** (pix/boleto gerado ou tentativa de cartao) e **nao
expoe controle de `eventID`** — logo a gente NAO consegue deduplicar com o
CAPI que estamos mandando.

**Acao obrigatoria depois de ativar o CAPI:**

1. `app-vlc.hotmart.com` -> **Ferramentas** -> **Pixel do Facebook**
2. Localizar o pixel `464623303880507` (ou o produto Passo a Passo)
3. **Desativar o disparo do evento Purchase** (deixa outros eventos se
   houverem).
4. Se nao for possivel desativar so o Purchase, **remover o pixel inteiro da
   configuracao Hotmart** — o CAPI passa a ser a UNICA fonte de Purchase e
   fica 100% confiavel.

Ate essa acao ser feita, os Purchases do Meta serao **soma dos dois** (pixel
fake da Hotmart + CAPI real da VPS). Depois, so o CAPI conta.

## Mapeamento de status

| Hotmart event         | Acao                                                   |
| --------------------- | ------------------------------------------------------ |
| PURCHASE_APPROVED     | envia Purchase com value positivo                      |
| PURCHASE_REFUNDED     | envia Purchase com value **negativo** (Meta desaprende)|
| PURCHASE_CHARGEBACK   | envia Purchase com value **negativo**                  |
| PURCHASE_BILLET_PRINTED, PURCHASE_OUT_OF_SHOPPING_CART, PURCHASE_EXPIRED, PURCHASE_DELAYED, PURCHASE_CANCELED, PURCHASE_COMPLETE | ignorado (200 OK) |

## PII / LGPD

Todo dado do comprador (email, telefone, nome, sobrenome, pais) e hasheado
SHA256 **no proprio processo, antes** de sair pro Meta. Nada de PII em claro
sai da VPS.

## Troubleshooting

```bash
# Status do service
sudo systemctl status hotmart-capi-borrello

# Logs em tempo real
sudo journalctl -u hotmart-capi-borrello -f
tail -f /opt/mia/logs/hotmart_capi_borrello.log

# Ver eventos ja processados
sqlite3 /opt/mia/workspace/clientes/borrello/hotmart_capi/dedupe.db \
  "SELECT event_id, event_name, meta_status, datetime(received_at, 'unixepoch')
   FROM processed_events ORDER BY received_at DESC LIMIT 20"

# Reset completo (cuidado — apaga historico de dedupe)
rm /opt/mia/workspace/clientes/borrello/hotmart_capi/dedupe.db
sudo systemctl restart hotmart-capi-borrello
```

## Arquivos

- `app.py`                        webhook Flask + traducao CAPI
- `backfill_capi.py`              script one-shot pra vendas antigas
- `requirements.txt`              flask, requests, python-dotenv
- `hotmart-capi-borrello.service` unit systemd
- `dedupe.db`                     SQLite de idempotencia (auto-criado)

## Configs relacionadas

- `/opt/mia/config/meta_capi_borrello.env`  token CAPI + pixel + test code
- `/opt/mia/config/hotmart_borrello.env`    creds Hotmart + HOTTOK + product_id
- Traefik router: `hotmart-capi-borrello-https@file` em
  `/etc/easypanel/traefik/config/custom.yaml`
- DNS: `hotmart-webhook.agentesclimb.us` (Cloudflare A -> 72.61.51.166)
