Todos os artigos
Eventos de checkout, pedido, reembolso e assinatura passam por um relay seguro até um manipulador de webhook local.
Polarwebhooksbillinglocal testing

Teste webhooks da Polar localmente com a Polar CLI

Para testar webhooks Polar localmente, execute o gerenciador de webhook, instale e autentique o Polar CLI e, em seguida, use polar listen http://localhost:3000/api/webhooks/polar para retransmitir eventos assinados diretamente para sua máquina. Copie o segredo temporário impresso pelo ouvinte em POLAR_WEBHOOK_SECRET, verifique o corpo bruto antes de processá-lo e acione um evento de checkout, pedido, reembolso ou assinatura do sandbox.

Por que o Polar CLI é o fluxo de trabalho local mais simples

Um endpoint de webhook de produção normal deve ser acessível publicamente por HTTPS. A Polar oferece um ouvinte local específico, para que você não precise criar um endpoint permanente ou colar repetidamente URLs de retorno de chamada temporários em um painel. A CLI se conecta à sua organização, exibe um segredo de assinatura de sessão, recebe eventos e os encaminha para a URL local fornecida.

Oficial da Polar documentação do webhook local usa polar listen http://localhost:3000/. Aponte-o para o caminho completo quando seu aplicativo manipula webhooks abaixo de uma rota como /api/webhooks/polar. Isso detecta erros de caminho antes da produção e mantém o mesmo manipulador de aplicativos que você pretende implantar.

Instale a CLI e comece a ouvir

  1. Inicie seu aplicativo e confirme se sua rota POST está disponível localmente.
  2. Instale o Polar CLI usando o comando da documentação oficial.
  3. Corre polar login e autorizar a conta correta.
  4. Começar polar listen http://localhost:3000/api/webhooks/polar.
  5. Selecione a organização proprietária dos produtos sandbox.
  6. Copie o segredo da sessão exibido para POLAR_WEBHOOK_SECRET e reinicie seu aplicativo se o ambiente for carregado apenas na inicialização.
  7. Acione uma ação de sandbox e compare o status de entrega da CLI com seus logs locais.

O segredo do ouvinte faz parte da sessão local. Não presuma que é igual a um segredo de endpoint do painel nem reutilize um valor de produção. Se você se reconectar e receber um segredo diferente, atualize o ambiente local antes de testar novamente.

Crie um manipulador Next.js App Router

Polar segue a especificação padrão de Webhooks. Uma entrega inclui webhook-id, webhook-timestampe webhook-signature. A verificação deve usar o corpo exato da solicitação bruta; ligando request.json() primeiro e serializar o objeto novamente pode alterar os bytes assinados.

// app/api/webhooks/polar/route.ts
import { Webhook } from 'standardwebhooks';

export const runtime = 'nodejs';

export async function POST(request: Request) {
  const rawBody = await request.text();
  const secret = process.env.POLAR_WEBHOOK_SECRET;
  if (!secret) {
    return new Response('Webhook secret is not configured', { status: 500 });
  }

  const headers = {
    'webhook-id': request.headers.get('webhook-id') ?? '',
    'webhook-timestamp': request.headers.get('webhook-timestamp') ?? '',
    'webhook-signature': request.headers.get('webhook-signature') ?? '',
  };

  try {
    const encodedSecret = Buffer.from(secret.trim(), 'utf8').toString('base64');
    const payload = new Webhook(encodedSecret).verify(rawBody, headers);
    await acceptPolarEvent(headers['webhook-id'], payload);
    return Response.json({ received: true });
  } catch {
    return new Response('Invalid signature', { status: 403 });
  }
}

Polar documentação de entrega invoca uma armadilha comum de verificação personalizada: as bibliotecas padrão de Webhooks esperam um segredo codificado em Base64, enquanto o Polar fornece uma string secreta normal. Os ajudantes do Polar SDK lidam com essa conversão automaticamente. Ao usar standardwebhooks diretamente, codifique em Base64 o segredo Polar completo, conforme mostrado acima.

Prefira um adaptador de estrutura oficial quando disponível

A Polar publica adaptadores que combinam verificação de assinatura com manipuladores de carga digitada. O oficial Documentação do adaptador expresso fornece retornos de chamada granulares para eventos de checkout, pedido, reembolso, benefício e assinatura. Um adaptador reduz a chance de implementar incorretamente a análise de cabeçalho ou a codificação secreta.

import express from 'express';
import { Webhooks } from '@polar-sh/express';

const app = express();
app.use(express.json());
app.post('/webhooks/polar', Webhooks({
  webhookSecret: process.env.POLAR_WEBHOOK_SECRET,
  onOrderPaid: async (event) => {
    await queueOrderPaid(event.data);
  },
  onSubscriptionActive: async (event) => {
    await queueSubscriptionActive(event.data);
  },
}));
app.listen(3000);

Siga a ordem de middleware documentada do adaptador para a versão que você instalar. Se você usar um verificador genérico, preserve explicitamente o corpo bruto. Não misture um adaptador que leia o fluxo com um middleware que o consuma primeiro.

Quais eventos polares você deve testar?

Eventos de check-out

Os eventos de checkout ajudam a rastrear uma sessão antes que ela se torne um pedido pago. Teste a conclusão bem-sucedida e os estados abandonados ou atualizados sem conceder acesso apenas porque um checkout foi criado. O pedido pago ou assinatura ativa deve permanecer o sinal de titularidade oficial.

Pedido pago e reembolsado

Para um evento com pedido pago, mapeie o cliente e o produto Polar para sua conta interna e conceda o benefício adquirido exatamente uma vez. Os eventos de reembolso devem reverter apenas o direito afetado de acordo com sua política de reembolso. Armazene IDs de provedores para que o suporte possa reconciliar o evento com a Polar.

Eventos do ciclo de vida da assinatura

Criação de testes, ativação, atualizações, cancelamento, revogação e qualquer comportamento vencido que seu produto suporta. Uma solicitação de cancelamento pode não significar que o acesso termine imediatamente. Armazene o status e as datas de vigência em vez de reduzir o ciclo de vida a um is_active bandeira.

Subsídios de benefícios

Se a sua integração usa benefícios Polar, teste a criação, atualização e revogação da concessão independentemente dos eventos de cobrança. Faça com que os manipuladores convirjam para o estado desejado, de modo que receber a mesma concessão duas vezes não provisione recursos duplicados.

Torne cada evento idempotente

A entrega em rede não é uma transação exatamente única. Um manipulador pode comprometer seu trabalho de banco de dados e perder a resposta, fazendo com que o remetente tente novamente. Usar webhook-id como uma chave de entrega exclusiva e reivindique-a na mesma transação que atualiza o estado do seu aplicativo.

await db.transaction(async (tx) => {
  const firstDelivery = await tx.webhookReceipts.insertIfAbsent({
    provider: 'polar',
    deliveryId: webhookId,
  });
  if (!firstDelivery) return;

  await applyPolarEvent(tx, payload);
  await tx.outbox.enqueue('polar-event-accepted', { webhookId });
});

Retorne uma resposta 2xx para uma duplicata que já foi concluída. Não deduplique apenas por ID de cliente ou assinatura porque muitos eventos legítimos têm como alvo o mesmo recurso. O guia de repetição e idempotência do webhook aborda os padrões de caixa de entrada e saída com mais detalhes.

Mantenha o trabalho de reconhecimento curto

Verifique a solicitação, persista ou coloque um trabalho durável na fila e retorne sucesso. Email, geração de licença, acesso a repositórios, análises e chamadas de API de terceiros devem ser executados de forma assíncrona. O reconhecimento rápido reduz novas tentativas, enquanto uma gravação durável evita que os eventos desapareçam se o processo for encerrado após o retorno.

Tipos de eventos desconhecidos devem ser registrados e confirmados após verificação de assinatura válida. A Polar pode adicionar tipos de eventos ao longo do tempo; aplicar cada valor desconhecido converte uma adição de esquema inofensiva em repetidas falhas de entrega.

Solucionar problemas de falhas de localhost do webhook Polar

A CLI se conecta, mas a rota retorna 404

Passe a rota local completa para polar listen, não apenas o porto. No Next.js App Router, certifique-se de que o arquivo tenha um nome route.ts e exportações POST. Um navegador GET retornando 404 não prova que a rota POST está faltando, então teste com curl -X POST.

Cada solicitação retorna 403

Confirme se o aplicativo carregou o segredo impresso pela sessão CLI atual. Preserve o corpo bruto e todos os três cabeçalhos dos Webhooks padrão. Se você usar a biblioteca genérica, codifique em Base64 o segredo Polar exatamente uma vez; se você usar um auxiliar do Polar SDK, passe o segredo original e deixe o SDK cuidar da codificação.

Nenhum evento aparece após uma finalização da compra

Verifique se a CLI está conectada à mesma organização e ambiente onde a ação ocorreu. Mantenha o terminal do ouvinte aberto, use recursos de sandbox e confirme se sua ação realmente atinge o estado do evento que você assinou.

Os eventos são processados duas vezes

Adicione uma restrição exclusiva para webhook-id e retornar sucesso para duplicatas. Verifique se ocorre uma exceção após a atualização do seu estado, mas antes da resposta. Mova os efeitos colaterais lentos para um trabalhador apoiado pela caixa de saída.

Uma solicitação capturada antiga falha na verificação

A verificação padrão dos Webhooks inclui um carimbo de data/hora para limitar ataques de repetição. Uma captura antiga deve falhar na janela de verificação normal. Para testes de lógica de negócios, verifique uma nova entrega uma vez e salve um dispositivo de carga útil limpo atrás do limite de autenticação.

Lista de verificação de segurança antes da produção

  • Use segredos de endpoint locais, de sandbox e de produção separados.
  • Verifique o corpo bruto, o carimbo de data/hora, o ID de entrega e a assinatura antes do processamento.
  • Mantenha tokens de API e segredos de webhook em variáveis de ambiente somente de servidor.
  • Desduplicar por webhook-id e validar identificadores de produtos, organizações e clientes.
  • Edite e-mails de clientes, dados de faturamento, metadados e cargas completas de registros compartilhados.
  • Aplique limites de tamanho de solicitação e monitore assinaturas inválidas repetidas.
  • Substitua o listener local por um endpoint HTTPS estável e teste um novo fluxo de sandbox antes de ativar produtos ativos.

A Polar CLI remove o loop de implantação, mas não deve remover os controles de produção. Mantenha a verificação de assinatura, a idempotência, a filtragem de eventos e o processamento durável ativados localmente para que o código testado seja o código enviado. Para obter detalhes de verificação independente da estrutura, leia o guia de verificação de assinatura do webhook e o geral fluxo de trabalho de depuração local.

Perguntas frequentes

Como posso testar os webhooks Polar localmente?
Execute seu manipulador local, autentique o Polar CLI, execute polar listen com o URL completo do webhook do localhost, copie o segredo exibido em POLAR_WEBHOOK_SECRET e acione um evento de sandbox.
Preciso de um túnel público para webhooks Polar?
Não ao usar o ouvinte CLI da Polar. Ele retransmite eventos da organização para o URL do host local que você fornece. Um endpoint de webhook de painel normal ainda precisa de um URL HTTPS acessível publicamente.
Por que minha assinatura do webhook Polar falha?
As causas comuns são o uso de um segredo de ouvinte antigo, a análise de JSON antes da verificação, a omissão de um cabeçalho Webhooks padrão ou o esquecimento de codificar em Base64 o segredo Polar ao usar um verificador genérico.
Como evito o processamento duplicado de webhooks Polar?
Armazene o webhook-id sob uma restrição de banco de dados exclusiva e aplique o evento na mesma transação. Retorna sucesso quando um ID de entrega já foi concluído.