Garu

2026-05-18

v0.10.1 — `/api/customers` agora aceita api-key

customersapib2b2c

Quem integra Garu via api-key e tentou cadastrar um cliente via POST /api/customers recebia 401 Unauthorized. O endpoint estava marcado como JWT-only — sobra da época em que /clientes era só uma página do painel. Quando a v0.7.0 fechou o ciclo de cobranças recorrentes com cartão e a v0.10.0 trouxe o portal-config por produto, todos os outros controllers parceiros (/api/scheduled-charges, /api/subscriptions, /api/subscription-prices, /api/checkout/sessions, /api/products/:id/portal-config) passaram a aceitar api-key. /api/customers foi criado depois e ficou de fora.

A v0.10.1 corrige a omissão.

O que mudou

Todas as rotas de /api/customers aceitam api-key

POST, GET, GET /:id, PUT /:id, PATCH /:id/billing-email-override, DELETE /:id — todas passam a aceitar tanto Authorization: Bearer <jwt> quanto Authorization: Bearer sk_live_... / sk_test_....

# Cadastrar um cliente para usar como customerId em scheduled-charges
curl -X POST https://garu.com.br/api/customers \
  -H "Authorization: Bearer $GARU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Marcelo Silva",
    "email": "aluno@example.com",
    "document": "12345678901",
    "phone": "11999999999",
    "personType": "fisica"
  }'
# → 201 { "id": 12345, ... }

# Em seguida, criar uma cobrança recorrente cobrada no cartão do aluno —
# Garu manda link de tokenização por e-mail, ciclos seguintes cobram silenciosamente.
curl -X POST https://garu.com.br/api/scheduled-charges \
  -H "Authorization: Bearer $GARU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": 12345,
    "amount": 297.50,
    "type": "recurring",
    "methods": ["card"],
    "dueDate": "2026-06-01",
    "recurrence": { "interval": "month", "intervalCount": 1 }
  }'

A resolução de seller continua igual: a api-key carrega o sellerId no payload, e todas as rotas de /api/customers operam exclusivamente dentro do scope desse seller.

Defesa contra regressão

Adicionamos um teste de introspecção que percorre cada controller parceiro e valida que toda rota tem o guard certo (JwtOrApiKeyGuard para os híbridos, ApiKeyGuard para checkout/sessions). Se um controller novo for criado sem api-key, o teste falha em CI. Foi isso que faltou pegar em abril, quando CustomersController nasceu já com a omissão.

Migração

Aditivo, sem breaking change. JWT continua funcionando exatamente como antes — quem usa o painel não nota nada. Quem integra via api-key e estava bloqueado no POST /api/customers agora consegue chamar normalmente.