Para testar webhooks de sandbox do PayPal no host local, execute seu ouvinte localmente, exponha sua rota através de um túnel HTTPS público, registre esse URL em um aplicativo de sandbox e acione uma transação de sandbox real ou um evento simulado no Simulador de Webhooks do PayPal. Mantenha a verificação de assinatura ativada: eventos de simulador e eventos de sandbox associados ao aplicativo têm uma importante diferença de verificação explicada abaixo.
Por que o PayPal não pode enviar diretamente para localhost
PayPal entrega notificações de webhook de seus próprios servidores. Um endereço como http://localhost:3000/api/paypal aponta para a máquina do PayPal da perspectiva do PayPal, não da sua. Um túnel localhost fornece ao processo local um endereço HTTPS público enquanto sai do aplicativo em seu computador.
A documentação oficial do PayPal Webhooks Simulator diz que seu ouvinte deve ser acessível por HTTPS na porta 443. Um túnel lida com esse endpoint TLS público e encaminha a solicitação para qualquer porta local, como 3000 ou 8080.
Escolha o caminho de teste correto do PayPal
Eventos simulados de simulador para desenvolvimento de ouvinte
O simulador pode enviar eventos representativos, incluindo capturas de pagamento, reembolsos e eventos de cobrança, sem criar uma transação. Esta é a maneira mais rápida de confirmar roteamento, análise JSON, códigos de resposta e envio de eventos. Os eventos simulados não estão vinculados a um aplicativo REST, não aparecem no visualizador de eventos do webhook do aplicativo, não podem ser reenviados e não representam transações reais.
Eventos reais de sandbox para comportamento de ponta a ponta
Para uma integração realista, crie um aplicativo REST no painel do desenvolvedor do PayPal, adicione o endpoint do túnel como um webhook, selecione os tipos de eventos necessários e conclua uma verificação de sandbox ou operação de API. Esses eventos pertencem ao aplicativo sandbox e exercem as mesmas credenciais de aplicativo, ID de webhook, visualizador de eventos e fluxo de trabalho de reenvio que você usará antes da produção.
Configure um webhook do PayPal em localhost
- Inicie seu aplicativo e confirme se a rota funciona localmente:
curl -i -X POST http://localhost:3000/api/webhooks/paypal -H 'content-type: application/json' -d '{"event_type":"LOCAL.PING"}'. - Execute
npx portpreview 3000e copie o URL HTTPS gerado. - Crie o retorno de chamada completo, por exemplo
https://your-subdomain.portpreview.dev/api/webhooks/paypal. - Para testes simulados, cole-o no Simulador de Webhooks e selecione um evento. Para testar o aplicativo, adicione-o nas configurações de webhook do seu aplicativo REST sandbox.
- Envie um evento e inspecione o método de entrada, cabeçalhos do PayPal, corpo bruto, logs do manipulador e resposta HTTP.
Inscreva-se apenas nos eventos que seu aplicativo manipula. Uma assinatura ampla cria ruído e facilita a execução acidental de lógica de negócios para um evento que você nunca modelou.
A practical Express listener
import express from 'express';
const app = express();
app.use(express.json({ verify: (req, _res, buf) => {
req.rawBody = Buffer.from(buf);
}}));
app.post('/api/webhooks/paypal', async (req, res) => {
const event = req.body;
// Verify first; do not fulfill an order from untrusted JSON.
const verified = await verifyPayPal(req.headers, event);
if (!verified) return res.status(401).send('invalid signature');
// Claim the event ID atomically so retries cannot duplicate work.
const firstDelivery = await claimEvent(event.id);
if (!firstDelivery) return res.sendStatus(200);
if (event.event_type === 'PAYMENT.CAPTURE.COMPLETED') {
await markOrderPaid(event.resource.id);
}
return res.sendStatus(200);
});
app.listen(3000);
Mantenha o trabalho de confirmação curto. Armazene o evento, retorne uma resposta 2xx e execute e-mail lento ou trabalho de atendimento em uma fila. O ID do evento é a chave de idempotência natural; impor uma restrição de banco de dados exclusiva em vez de depender de um conjunto na memória.
Verifique as assinaturas do PayPal corretamente
PayPal envia metadados de transmissão em cabeçalhos, incluindo PAYPAL-AUTH-ALGO, PAYPAL-CERT-URL, PAYPAL-TRANSMISSION-ID, PAYPAL-TRANSMISSION-SIG e PAYPAL-TRANSMISSION-TIME. Para eventos associados ao aplicativo, você pode enviar esses valores, o ID do webhook e o evento para a API sandbox /v1/notifications/verify-webhook-signature. Uma resposta HTTP bem-sucedida não é suficiente; requer que verification_status seja igual a SUCCESS. O PayPal também documenta a verificação criptográfica local em seu guia de integração do webhook.
Advertência do simulador: O endpoint de verificação de postback do PayPal não oferece suporte a eventos simulados de simulador. O PayPal documenta o ID literal do webhook WEBHOOK_ID para autoverificação de uma assinatura de simulador. Não confunda esse valor especial com o ID real do webhook atribuído a um aplicativo sandbox. Se seu objetivo imediato é testar a própria API de postback, gere uma transação de sandbox real em vez de um evento de simulador simulado.
Valide se qualquer URL de certificado segue as regras documentadas do PayPal antes de baixá-lo, retenha a representação exata do evento exigida pelo método de verificação e nunca registre tokens de acesso, segredos do cliente, assinaturas ou cargas completas de pagamento.
Teste os eventos que trocam dinheiro ou acesso
PAYMENT.CAPTURE.COMPLETED: conceder atendimento somente após verificar os identificadores esperados do pedido, valor, moeda e status de captura.PAYMENT.CAPTURE.REFUNDED: reverter direitos com segurança e apoiar reembolsos parciais.- Eventos de pedido de checkout: distinguem a aprovação de uma captura concluída; a aprovação por si só não é prova de que os fundos foram capturados.
- Eventos de assinatura: ativação de teste, suspensão, cancelamento, falha no pagamento e entrega fora de ordem em sua máquina de estado de faturamento.
Os eventos do provedor são notificações, não comandos de banco de dados inquestionáveis. Para transições confidenciais, recupere o recurso do PayPal referenciado com credenciais de API autenticadas e compare-o com seu próprio registro de pedido.
Solucionar problemas de entregas locais com falha
O simulador não pode conectar
Confirme se o URL começa com https://, inclui o caminho exato do webhook e ainda aponta para um túnel em execução. Teste você mesmo o URL público com curl. Um 404 geralmente significa que o caminho ou rota da estrutura está errado; um 502 geralmente significa que o túnel não pode alcançar o processo local.
O manipulador retorna 401
Primeiro determine se o evento veio do simulador ou de um aplicativo sandbox registrado. Verifique o ID do webhook e o método de verificação de acordo. Em seguida, verifique se os proxies preservaram todos os cabeçalhos PAYPAL-* e se você não está misturando credenciais ativas com api-m.sandbox.paypal.com.
PayPal tenta novamente ou marca falha na entrega
Retorne um 2xx somente após o evento ter sido aceito de forma duradoura. Evite redirecionamentos, páginas de erro HTML, middleware de autenticação e longos trabalhos síncronos na rota. Use o visualizador de eventos para eventos reais do aplicativo e o resultado do simulador para diagnósticos de entrega simulados. Consulte o guia de nova tentativa e idempotência para padrões de processamento duráveis.
Lista de verificação de segurança antes de entrar no ar
- Use sandbox separado e credenciais de cliente ativo, IDs de webhook e segredos de endpoint.
- Verifique cada assinatura antes de analisar campos de negócios ou alterar o estado.
- Desduplicar por ID de evento do PayPal e tornar as transações de cumprimento atômicas.
- Permita apenas
POST, limite o tamanho da solicitação, aplique limites de taxa e mantenha o URL do túnel privado quando possível. - Redigir dados e credenciais do comprador dos registros; gire qualquer coisa exposta durante a depuração.
- Substitua o URL do túnel temporário por um endpoint de produção estável e repita a assinatura e tente novamente os testes.
Para o evento completo e esquemas de verificação, use a referência principal da API Webhooks do PayPal. Para obter detalhes independentes da estrutura sobre corpos brutos e comparações seguras, leia o guia de verificação de assinatura do webhook.
