| Projeto | Integração Jornada do Site PetLove × HubSpot CRM |
| Documento | Análise Técnica V2 — Arquitetura HubSpot Direto (definitiva para V1) |
| Escopo | Dominio A — Jornada do Site (Wizard → Checkout → Ativação) |
| Versão | 2.0 (substitui V1.0 de 05/03 — remove opção middleware) |
| Data | 06/03/2026 |
| Autor | EPIC Digital — Equipe Técnica |
| Referência | Análise Técnica V1 (05/03) + Escopo Minimo V1 (05/03) + Brief Técnico v1.1 |
Este documento define a arquitetura definitiva da integração entre a Jornada do Site PetLove e o HubSpot CRM para a V1 do projeto. A abordagem escolhida e HubSpot Direto — sem middleware, sem servidor intermediario.
Na V1 anterior (05/03), foram apresentados dois caminhos possiveis: Fluxo A (Middleware Node.js) e Fluxo B (HubSpot Direto). Após avaliação conjunta com o escopo minimo aprovado, a decisao e implementar apenas o Fluxo B, posicionando o middleware como melhoria futura (V2).
O site da PetLove enviara dados diretamente para o HubSpot via Forms API ou Custom Code em Workflows. Toda a lógica de negocio — criação de contatos, pets, deals, associations e eventos — roda dentro do HubSpot, usando Custom Code Actions (Node.js serverless) para chamar as APIs PetLove quando necessário.
Este documento cobre o Dominio A — a Jornada do Site — em que o lead contrata um plano de saúde pet pelo site da PetLove, e os dados sao gravados no HubSpot. O dominio Zenvia (WhatsApp) esta documentado separadamente.
| O que | Status | Fonte |
|---|---|---|
| Health API funcionando emhttps://health-api.petlove.com.br | Confirmado | Testes exploratorios (25/02).Cloudflare + Laravel + Envoy. |
| 10 endpoints públicos não atualizados/válidos(species, races, regions, plans, campaign, etc.) | Desatualizado | curl.exe com User-Agent.9 retornaram 200 + 1 parcial (simulate). Dados podem estar desatualizados. |
| 3 endpoints hook BLOQUEADOS(/api/hook/customer, plans, is-active-customer) | Sem token | 403/401 — aceita Bearer, X-Api-Key,x-hook-token, x-api-token. |
| Enrollment API: 6 endpoints documentados(customer, location, plans, simulate, proposal, status) | Host desconhecido | OpenAPI 3.1 documenta paths.Todos retornam 404 no host público. |
| GET /api/plans aceita SOMENTE ID numerico(slugs retornam [] sem erro) | Pegadinha | Testes com 'sao-paulo' etc.Retorna 200 com array vazio. |
| GET /api/auth/find-account e público(retorna nome, tipo conta, recovery methods) | Atencao | Endpoint público que retornadados reais sem autenticação. |
| Enrollment API tem campo seller.sourceSellerId(UUID do vendedor NO HUBSPOT) | Documentado | OpenAPI + Enrollment.md.Ponto-chave de rastreabilidade. |
| Proposal status mapeia direto para Deal stages(PENDING_PAYMENT, ACTIVE, CANCELED, etc.) | Documentado | Enrollment.md — 9 statuscorrespondem a stages do HubSpot. |
O site da PetLove envia dados diretamente para o HubSpot (via HubSpot Forms ou API). A lógica de negocio (chamar a Enrollment API, calcular MRR, criar associations) roda em Workflows com Custom Code. Não ha middleware nem servico externo.
POR QUE HUBSPOT DIRETO: Entrega mais rapida (~20-30 dias uteis vs ~42 dias do middleware), sem dependência de infraestrutura adicional, 100% dos cenarios funcionais cobertos. A PetLove pode ajustar workflows sem depender da EPIC para mudancas simples. Middleware posicionado como melhoria V2.
Tres capacidades do HubSpot permitem eliminar o middleware:
O site pode enviar dados do wizard diretamente para o HubSpot usando HubSpot Forms (embedded ou popup) ou a Forms Submit API (POST server-side). Quando o form e submetido, o HubSpot cria ou atualiza o Contact automaticamente e pode disparar um Workflow.
Dentro de um Workflow, e possível rodar código Node.js ou Python como serverless function. O Custom Code pode chamar APIs externas (Enrollment API, Health API) e a API do HubSpot internamente.
| Limitação | Valor |
|---|---|
| Timeout por execução | 20 segundos (maximo) |
| Memória | 128 MB |
| Plano necessário | Operations Hub Professional ou Enterprise |
| Bibliotecas Node.js disponiveis | @hubspot/api-client, axios, lodash, redis, aws-sdk, googleapis |
Alem do Custom Code, o Workflow oferece ações nativas que substituem parte do que o middleware faria:
PASSO 1 Lead entra no site PetLove e completa o WIZARD
(escolhe especie, raca, plano, preenche dados pessoais)
↓
PASSO 2 SITE submete um HubSpot Form (embed ou API submit)
→ HUBSPOT cria/atualiza o Contact automaticamente
↓
PASSO 3 WORKFLOW dispara (trigger: form submitted)
↓
PASSO 4 CUSTOM CODE #1 (Node.js) roda:
a) Le dados do Contact (especie, raca, plano, CEP)
b) Cria Pet (Custom Object) via @hubspot/api-client
c) Cria Deal + Line Items
d) Cria Associations v4
↓
PASSO 5 Lead confirma checkout (outro form submit ou webhook)
↓
PASSO 6 CUSTOM CODE #2 (Node.js) roda:
a) Chama Enrollment API: simulate → preços reais
b) Chama Enrollment API: proposal → cria proposta
c) Atualiza Deal (stage, amount, MRR)
↓
PASSO 7 Após pagamento, lead preenche ativação (outro form/webhook)
↓
PASSO 8 CUSTOM CODE #3 (Node.js) roda:
a) Atualiza Pet (dados complementares + microchip)
b) Atualiza Deal → stage: Ativo
↓
PASSO 9 HUBSPOT tem tudo: contato, pet, negocio, vendedor.
O site da PetLove usa um HubSpot Form (embedded ou via Submit API) em vez de chamar um middleware. O form coleta: nome, email, telefone, CEP, especie, raca, plano desejado. Ao submeter, o HubSpot cria/atualiza o Contact automaticamente. Um Workflow e triggered pelo form submit.
Quando o lead vai para checkout (outro submit ou webhook), um segundo Custom Code chama a Enrollment API via axios: POST /proposal/simulate (preços reais), depois POST /proposal (submete proposta). Atualiza o Deal com amount, MRR e stage. ATENCAO: simulate + proposal + update Deal precisam caber em 20 segundos.
Após pagamento confirmado, o lead preenche ativação. Um terceiro Custom Code atualiza Pet (dados complementares + microchip) e muda Deal para 'Ativo'.
HubSpot Form / Submit API
_______________ _________________________________
| | | HUBSPOT (Operations Hub) |
| SITE PETLOVE | =====================>| |
| (frontend) | | 1. Form submit → Create Contact |
|_______________| | 2. Workflow triggered |
| 3. Custom Code #1: |
| - @hubspot/api-client |
_______________ | - Pet, Deal, LI, Assoc v4 |
| ENROLLMENT | | 4. Custom Code #2 (checkout):|
| API PetLove | <==== axios =========| - Enrollment: simulate |
| (host ?) | | + proposal |
|______________| | - Update Deal (MRR,stage) |
| 5. Custom Code #3 (ativação):|
_______________ | - Update Pet (microchip) |
| HEALTH API | | - Update Deal → Ativo |
| (público) | <==== axios =========| |
|______________| | Resultado: Contact+Deal+Pet+LI |
|_________________________________|
| Quem | Faz o que | Chama quem |
|---|---|---|
| Lead (visitante) | Preenche wizard, confirma checkout, completa ativação no site | → Site PetLove (frontend) |
| Site PetLove(frontend) | Submete HubSpot Forms (embed ou API) com dados do lead | → HubSpot (Form Submit) |
| HubSpotWorkflow + Custom Code | 1) Form submit cria Contact 2) Workflow triggera Custom Code 3) Custom Code cria Pet, Deal, LI, Assoc 4) Custom Code chama Enrollment API 5) Custom Code atualiza Deal stages |
→ Enrollment API (axios) → Health API (axios) → HubSpot (API interna) |
| Enrollment API(PetLove backend) | Simula, cria proposta, retorna status | — (só responde) |
| ID | Dependência | Responsável | Status | Impacto |
|---|---|---|---|---|
| D1 | URL da Enrollment API (enrollmentBaseUrl) Host real desconhecido — todos os 6 endpoints retornam 404 no host público. Discovery desde dez/2025, 3 meses sem entrega de API funcional. |
Tech Lead PetLove | BLOQUEADO | Bloqueia Custom Code #2 (checkout): simulate + proposal impossiveis sem URL. |
| D2 | Token para endpoints /api/hook/* (hookToken) 403/401 — nenhum formato de token funciona (Bearer, X-Api-Key, x-hook-token, x-api-token). |
Tech Lead PetLove | BLOQUEADO | Bloqueia /api/hook/customer e /api/hook/is-active-customer. |
| G4 | Evento de compra confirmada (Purchase Event) Como o HubSpot e notificado quando o pagamento e confirmado? Webhook? Polling? Não definido. |
Tech Lead PetLove | BLOQUEADO | Afeta transição checkout → ativação. Sem isso, Deal fica parado em "Proposta Enviada". |
| Z1 | Token Zenvia API v2 Token fornecido retorna HTTP 401 (Unauthorized). Pode estar expirado, revogado ou sem escopos. |
PetLove / Zenvia | BLOQUEADO | Bloqueia configuração de webhooks e validação end-to-end com dados reais. |
| DNS | DNS (lp + conteudo) Proxy Cloudflare ativo — Error 1034. CNAME deve estar DNS only. |
PetLove TI / HubSpot | BLOQUEADO | Bloqueia públicação de LPs e paginas de conteudo no HubSpot. |
| D3 | Ambiente de staging PetLove Staging disponível, pendente apenas configuração de VPN para acesso. |
Tech Lead PetLove | VPN pendente | Staging resolvido. Acesso depende de VPN (configuração pendente). |
| ID | Gate | Responsável | Status |
|---|---|---|---|
| GT1 | Aprovação deste documento (V2) — sem aprovação, cronograma não inicia. | PetLove | Gate |
| GT2 | Aprovação do fluxo de regras de negocio — fluxo minimo: lead → wizard → checkout → ativação. Sem aprovação, desenvolvemos algo errado. | PetLove | Gate |
| # | GAP | Impacto | Decisao de |
|---|---|---|---|
| G5 | Inside Sales — mesmo endpoint ou separado? | MEDIO — pode exigir workflow extra | PetLove Comercial |
| G6 | /api/subscription/simulate — formato de params? | BAIXO — alternativa na Enrollment API | Tech Lead PetLove |
Consequência do atraso: O desenvolvimento que seria distribuido em 4-5 semanas sera comprimido em ~3 semanas uteis (09/03 a 27/03). O time EPIC operara em overload. Horas adicionais decorrentes dessa compressao serao descontadas do saldo do contrato. Cada dia de atraso nos gates = 1 dia a mais no prazo final.
Endpoints PetLove que serao consumidos pelo Custom Code nos Workflows. Testados em 25/02/2026.
Host: https://health-api.petlove.com.br — Cloudflare + Laravel + Envoy. Requer User-Agent (ex: PostmanRuntime/7.36.0).
| # | Endpoint | Método | O que retorna | Status |
|---|---|---|---|---|
| 1 | GET /api/species | GET | Especies: Cachorro (1), Gato (2) | 200 |
| 2 | GET /api/races?specie={dog|cat} | GET | Racas por especie (~25 gato, ~200 cachorro) | 200 |
| 3 | GET /api/regions | GET | Regiões PetLove com IDs + coordenadas + plan_id | 200 |
| 4 | GET /api/location/states | GET | 27 estados brasileiros | 200 |
| 5 | GET /api/accredited-network/states | GET | 25 UFs com rede credenciada (faltam AP, RO) | 200 |
| 6 | GET /api/campaign | GET | Campanha ativa (imagens, datas, regulamento) | 200 |
| 7 | GET /api/plans?region={id} | GET | Planos por região (ID numerico!). Preço, cobertura, PDF. | 200 |
| 8 | GET /api/v1/partner_network/plans?lat=&long= | GET | Planos por geolocalização | 200 |
| 9 | GET /api/subscription/simulate | GET | Simulação descontos (formato params desconhecido) | parcial |
| 10 | GET /api/auth/find-account?username= | GET | Verifica existencia de conta (nome, recovery) | 200 |
| # | Endpoint | Método | O que retorna (provavel) | Status |
|---|---|---|---|---|
| 1 | GET /api/hook/customer | GET | Dados do cliente via hook | 403/401 |
| 2 | GET /api/hook/plans | GET | Planos via hook | 403/401 |
| 3 | POST /api/hook/is-active-customer | POST | Verifica assinatura ativa | 401 |
| # | Endpoint | Método | O que faz | Status |
|---|---|---|---|---|
| 1 | /api/enrollment/v1/customer/{email} | GET | Cliente completo: dados, pets, assinaturas, microchip | 404 |
| 2 | /api/enrollment/v1/location/{postalCode} | GET | Localidade por CEP: UF, cidade, região | 404 |
| 3 | /api/enrollment/v1/plans/{region} | GET | Planos por região: nome, preço, produto, cupons | 404 |
| 4 | POST /api/enrollment/v1/proposal/simulate | POST | Simula proposta: descontos, parcelas, addons | 404 |
| 5 | POST /api/enrollment/v1/proposal | POST | Submete proposta (customer + pets + seller + source) | 404 |
| 6 | GET /api/enrollment/v1/proposal/{id} | GET | Status proposta + paymentLink | 404 |
Extraidos do Enrollment.openapi.json (15 schemas). Definem o mapeamento PetLove → HubSpot para os Custom Codes.
| Campo PetLove | Tipo | Mapeia para HubSpot |
|---|---|---|
| id | string (uuid) | — (interno) |
| string (email) | Contact → email (dedupe key) | |
| name | string | Contact → firstname |
| surname | string | Contact → lastname |
| birthDate | string (date) | Contact → date_of_birth |
| phones[] | Phone[] | Contact → phone |
| addresses[].city | string | Contact → city |
| addresses[].state | string | Contact → state |
| addresses[].postalCode | string | Contact → zip |
| addresses[].region.id | integer | Referência para GET /plans |
| Campo PetLove | Tipo | Mapeia para HubSpot |
|---|---|---|
| name | string | Pet → nome_pet (primaryDisplay) |
| species | enum: cat/dog | Pet → especie |
| gender | enum: male/female | Pet → gênero |
| birthDate | string (date) | Pet → data_nascimento |
| microchip.number | integer (ISO 11784) | Pet → microchip |
| subscription.status | enum (9 valores) | Deal → stage (mapeado) |
| subscription.plan | Plan object | Deal → amount + Line Items |
| Status Enrollment | Significado | Deal Stage HubSpot | Trigger |
|---|---|---|---|
| PENDING_PAYMENT | Aguardando pagamento | Proposta Enviada | Proposta criada |
| PENDING_CONTRACT | Pagamento ok, contrato pendente | Venda Concluída | Checkout aprovado |
| PENDING_CHIP | Aguardando microchip | Ativação Pendente | Dados pet preenchidos |
| ACTIVE | Ativa | Ativo | Microchip definido |
| CANCELED | Cancelado | Cancelado | — |
| BLOCKED | Bloqueado | Bloqueado | — |
| SUSPENDED | Suspenso | Suspenso | — |
| Campo | Tipo | Relevância para integração |
|---|---|---|
| customer | Customer | Upsert Contact no HubSpot |
| proposalSubscriptions[] | { pet, plan, coupon } | Deal + Line Items + Pet |
| seller.sourceSellerId | string (uuid) | ID do vendedor NO HUBSPOT — rastreabilidade |
| source | string | 'Hubspot' — identifica origem da venda |
| submittedAt | string (date) | Deal → createdate |
| Propriedade | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| nome_pet | string | Sim | primaryDisplayProperty |
| especie | enumeration | Sim | cachorro / gato |
| raca | string | Não | Raca do pet |
| data_nascimento | date | Não | Data de nascimento |
| gênero | enumeration | Não | male / female |
| microchip | string | Não | Número do microchip |
| status_pet | enumeration | Não | Acompanha deal stage |
| De | Para | Tipo | Criado na fase |
|---|---|---|---|
| Contact | Deal | default + labeled | Wizard (Fase 1) — Custom Code #1 |
| Pet | Contact | custom (discovery) | Wizard (Fase 1) — Custom Code #1 |
| Pet | Deal | custom (discovery) | Wizard (Fase 1) — Custom Code #1 |
| Line Item | Deal | default | Wizard (Fase 1) — Custom Code #1 |
| Fase | Evento | Quando dispara | Custom Code |
|---|---|---|---|
| 1 — Wizard | pe{HubID}_lead_wizard_gerado | Lead completa o wizard | #1 |
| 2 — Checkout | pe{HubID}_tentativa_pagamento | Tentativa de pagamento | #2 |
| 2 — Checkout | pe{HubID}_venda_concluída | Checkout aprovado | #2 |
| 3 — Ativação | pe{HubID}_ativação_iniciada | Dados do pet preenchidos | #3 |
| 3 — Ativação | pe{HubID}_microchip_escolhido | Microchip definido | #3 |
| 3 — Ativação | pe{HubID}_ativação_concluída | Ativação concluída | #3 |
| ID | Item | Responsável | Observação |
|---|---|---|---|
| P1 | Evento de compra confirmada(server-side) | Health Track / Vindi | Direto do backend PetLove. NAO via HubSpot.Como o HubSpot e notificado? (Bloqueio G4) |
| P2 | Enrollment API (hosting) | Backend PetLove | Custom Code CONSOME; PetLove mantem.Host desconhecido (Bloqueio D1). |
| P3 | Health API (hosting) | Backend PetLove | Fonte de referência (especies, planos).Host: health-api.petlove.com.br |
| P4 | GTM → Google Analytics | Equipe dados PetLove | Sistema paralelo. Não e HubSpot. |
| P5 | Migração RD Station → HubSpot | Equipe dados PetLove | Carga legada. Deadline: 31/03. Não e integração. |
A arquitetura com middleware (servidor intermediario) foi avaliada na Análise Técnica V1. Embora ofereca beneficios adicionais, ela não e necessaria para a operação da V1 e adicionaria +25 a 43 dias ao cronograma.
O que o middleware traria como melhoria futura: