PIX via Pagar.me e o webhook de pagamento

Ordem avulsa em vez de recorrência, criação de usuário só na confirmação, idempotência e o gap de HMAC.

Atualizado em 24/08/20268 min de leituraPagamentos e ciclo de vida

POST /subscription/baita/pix (público) → createBaitaPixService. Body obrigatório: name, password, gender, birthDate, whitelabelId, planId. Opcionais: email, cpfCnpj, telephone, endereço, origin e UTMs.

  • PIX não é assinatura recorrente no gateway: é uma ordem avulsa (createOrder, endpoint /orders da Pagar.me v5), com a recorrência gerenciada inteiramente pela Urbis via cron.
  • Nenhum usuário é criado nesse passo — todos os dados (incluindo senha já hasheada com bcrypt) viajam no metadata da order e só viram usuário quando o webhook confirma o pagamento.
  • generatePixOrderService é independente e reutilizável: usado pela criação de usuário, pela assinatura logada e pelo cron de renovação.

POST /subscription/pagarme/webhook

handlePixWebhookService é o coração do fluxo PIX Baita.

  • Status pending → 200 sem ação; failed → grava log de erro e retorna 200; paid → processa.
  • Idempotência: antes de processar, busca subscription existente por subscriptionIdInGateway === chargeId OU metadata.orderId === orderId. Se existir, retorna 200 "já processado".

Sub-fluxo A — renovação (metadata tem userId)

Cancela a recorrência anterior no gateway → cria nova Subscription (desativa a anterior e atualiza nextInvoiceDate) → recria a tag de jornada digital preservando a tag PDV se user.origin contém 'pdv' → upsert no Salesforce (DE principal + campos de recompra).

Sub-fluxo B — novo cadastro (sem userId)

Extrai dados do metadata (senha já hasheada, endereço, origin, gênero, nascimento) → deriva codeType pelo título do plano ('completo' → lotteryAndIncentives, senão onlyLottery) → cria user + subscription + userAccessGrant + tags de jornada (TAG_USUARIO_JORNADA_BAITA se origin === 'baita', senão TAG_USUARIO_JORNADA_DIGITAL) → Salesforce → Metryca (lead, com UTMs do metadata) → e-mail de boas-vindas.

🔒 Gap de segurança conhecido e não corrigido: este webhook é @Public() e não valida assinatura/HMAC da Pagar.me — diferente de POST /subscription/move/webhook, que valida HMAC-SHA256 com timingSafeEqual. A proteção efetiva é só a idempotência.
pix
pagarme
webhook
assinatura
idempotência
segurança

Este artigo foi útil?

Artigos relacionados

Voltar para a Documentação Baita