# Shopee — Estado da Implementação

> **Status geral: CONGELADA** (abril 2026)
>
> A integração automática da Shopee foi **suspensa** após esgotarmos as rotas técnicas realistas. O código existente foi mantido para referência, mas **nenhuma oferta Shopee é publicada** no fluxo atual. As plataformas ativas em produção são **Amazon** e **Mercado Livre**.

---

## 1. Por que foi congelada

A Shopee bloqueia **todas** as formas de leitura programática de produto a partir de um IP de servidor. O diagnóstico abaixo foi confirmado em abril/2026 com múltiplas URLs reais (`https://s.shopee.com.br/9zu3NGQruE` entre outras) e cookie de sessão renovado.

### Rotas testadas e status final

| Rota | Endpoint | Resultado |
|---|---|---|
| API autenticada v4 | `/api/v4/item/get` + cookie de sessão | ⛔ `HTTP 403`, body `{"action_type":2,"error":90309999}` |
| API pública v2 | `/api/v2/item/get` sem cookie | ⛔ `HTTP 403`, mesmo erro `90309999` |
| Scraping HTML canônico | `/product/{shop}/{item}` | ⛔ Página retorna `200` mas é **shell SPA vazia** (`"shopid":0`, sem `__NEXT_DATA__`, `initialState`, `__PRELOADED_STATE__`, `og:*` ou JSON-LD) |
| API oficial Shopee Affiliates BR | — | ⛔ **Não existe como autosserviço** no programa brasileiro |

O erro `90309999` + `action_type: 2` é a **verificação de dispositivo** da Shopee: ela exige que a requisição venha de um navegador real com fingerprint reconhecido, o que PHP de servidor nunca consegue fornecer. O `is_login: true` confirma que o cookie era aceito — o bloqueio **não era de autenticação**.

### O que **não** resolveria

- ❌ Renovar o cookie de sessão (já testado com cookie fresco — mesmo `action_type: 2`)
- ❌ Outros headers, `x-api-source`, `x-shopee-language`, CSRF extra
- ❌ Endpoint alternativo `/api/v4/pdp/get_pc`
- ❌ Regex/scraping mais esperto — não há dados no HTML para extrair
- ❌ Pedir API de afiliados pelo painel web — a URL `affiliate.shopee.com.br/open_api` retorna só a shell do SPA; não há seção de desenvolvedor autosserviço para afiliados BR

---

## 2. Únicas saídas técnicas que funcionariam

Ambas estão **fora de escopo atual** e dependem de decisão futura:

### A. Playwright / navegador headless
- Script Node.js abre Chromium real, espera o JS renderizar, lê dados do DOM ou intercepta a resposta da API que roda dentro do próprio browser
- Requer: Node.js + `playwright` + Chromium no servidor XAMPP
- Aproveitaria a infra prevista para `docs/AMAZON_SITESTRIPE_PLAYWRIGHT.md`
- Esforço alto, manutenção frequente (seletores mudam)

### B. API oficial de Afiliados Shopee (via e-mail)
- Não há cadastro autosserviço; o acesso é liberado pela equipe Shopee após solicitação por e-mail na Central de Ajuda do painel de afiliados
- Endpoint real: `POST https://open-api.affiliate.shopee.com.br/graphql`
- Autenticação: header `Authorization: SHA256 Credential={AppId}, Timestamp={ts}, Signature={sha256(AppId+ts+payload+Secret)}`
- Query `productOfferV2` retornaria dados do produto + `offerLink` (link afiliado já pronto)
- Esforço médio, depende da Shopee aprovar o acesso

---

## 3. Comportamento do sistema hoje

| Onde | O que acontece |
|---|---|
| `AmazonAffiliateController::searchShopeeProduct()` | Retorna HTTP 422 com mensagem clara de que Shopee está **desabilitada** — sem tentar API nem scraping |
| Pipeline Telegram (`TelegramProcessPending`) | URLs Shopee são marcadas como `skipped` no banco e **ignoradas** no batch — não travam o processamento das outras |
| Dashboard `/admin` | Continua mostrando o card Shopee, mas o contador fica em zero para ofertas novas (as antigas ficam como histórico) |
| Interface `/admin/amazon-affiliate` | URL Shopee colada retorna a mesma mensagem de "integração desabilitada" do backend |

---

## 4. Arquivos que ficam no repositório (congelados)

Mantidos para referência e para facilitar retomar o trabalho no futuro:

| Arquivo | Papel |
|---|---|
| `app/Services/Affiliate/ShopeeAffiliateService.php` | Serviço completo com API v4, API v2 e scraping HTML (todos ineficazes no momento) |
| `app/Console/Commands/ShopeeSaveCookie.php` | Grava cookie em `storage/app/shopee_session_cookie.txt` |
| `app/Console/Commands/ShopeeScrapDebug.php` | Diagnóstico passo a passo (etapas 1 a 5) — útil para validar se a Shopee mudou de comportamento no futuro |
| `config/shopee.php` | Base URL, cookie e timeout |
| `.env.example` (entradas Shopee) | `SHOPEE_SESSION_COOKIE`, `SHOPEE_TIMEOUT` |

**Nada é apagado.** Todo o código fica exatamente como está, mas o ponto de entrada (`searchShopeeProduct`) corta o fluxo antes de fazer chamadas inúteis para a Shopee.

---

## 5. Como retomar (quando fizer sentido)

Se no futuro quiser desbloquear a Shopee, a retomada tem duas formas:

### Via Playwright
1. Instalar Node.js + `playwright` + Chromium
2. Criar `scripts/shopee-scrape.mjs` que abre `https://shopee.com.br/product/{shopId}/{itemId}`, espera o JS renderizar, lê dados do DOM
3. Criar comando Artisan `shopee:scrape {url}` que invoca o script e devolve JSON
4. Em `ShopeeAffiliateService::getProductByUrl()`, adicionar como tentativa 0 (antes de v4/v2/HTML) e **remover** o corte de Shopee no controller

### Via API oficial
1. Solicitar `AppID` e `Secret` pela Central de Ajuda do painel de afiliados Shopee
2. Criar `ShopeeAffiliateService::fetchViaOfficialApi($shopId, $itemId)` com assinatura SHA256
3. Mapear campos do `productOfferV2.nodes[0]` para o formato interno
4. `generateAffiliateLink()` passa a retornar `offerLink` do mesmo payload
5. **Remover** o corte de Shopee no controller

Em qualquer dos dois casos, o diagnóstico atual está todo preservado no `ShopeeScrapDebug` — basta rodar `php artisan shopee:scrape-debug` para checar se o bloqueio `90309999` continua ativo.

---

## 6. Lições registradas

- Cookies `is_login: true` **não** garantem acesso à API — a Shopee tem camada separada de fingerprint
- A home de afiliados BR não tem seção de Open API autosserviço (documentação de terceiros que sugere isso está descrevendo versões asiáticas do programa)
- A página `/product/{shop}/{item}` vem como SPA completa — não adianta caçar outras chaves `og:` ou JSON embutido; os dados simplesmente **não existem no HTML inicial**
- Tentar variantes de header (`x-api-source`, `af`, `device_id`) não contorna o `action_type: 2`
