BlendFi
Webhooks

Testes no sandbox

Acione webhooks contra um listener local usando test_helpers, debug de divergências de assinatura, exercite cada tipo de evento sem pagamentos reais.

No sandbox, você pode acionar cada evento de webhook a partir de um endpoint test_helpers em vez de esperar Pix ou USDT reais se moverem. Esta página cobre o loop: registre um endpoint de sandbox, exponha localmente, dispare test_helpers e veja as entregas chegarem.

O loop

  1. Registre um endpoint de sandbox apontando para o seu listener local (via uma ferramenta de túnel; veja abaixo).
  2. Rode o seu handler localmente com o segredo do ambiente sandbox carregado.
  3. Dispare um test_helper para avançar o estado de uma conversão ou submissão de KYC.
  4. Receba o webhook e verifique como em produção.
  5. Itere. Cada test_helper dispara imediatamente; as entregas chegam segundos depois.

Expondo o seu listener local

Endpoints de webhook precisam ser HTTPS, então localhost no seu laptop não serve diretamente. Use uma ferramenta de túnel:

FerramentaNotas
cloudflaredGrátis, HTTPS automático, sem cadastro. cloudflared tunnel --url http://localhost:3000
ngrokMais popular; HTTPS por padrão. ngrok http 3000
localtunnelAlternativa open-source. lt --port 3000

Qualquer que você escolher, você ganha uma URL HTTPS como https://something.trycloudflare.com que faz proxy para localhost. Use isso como o url ao criar o endpoint de sandbox.

# Registre um endpoint de sandbox apontando para o seu túnel
curl -X POST $BLENDFI_BASE/v1/webhook_endpoints \
  -H "Authorization: Bearer $BLENDFI_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "content-type: application/json" \
  -d '{
    "url": "https://something.trycloudflare.com/blendfi-webhooks",
    "event_types": [
      "conversion.created",
      "conversion.completed",
      "conversion.failed",
      "conversion.standby",
      "user.kyc_approved"
    ],
    "description": "local-dev"
  }'

A resposta inclui o secret em texto plano: armazene como BLENDFI_WEBHOOK_SECRET no seu env local antes de rodar o handler.

Avançando um ciclo de vida de conversão

Cada POST em test_helpers/conversions/... avança o estado e dispara o evento de webhook correspondente.

Onramp (Pix → USDT)

CID=cnv_01J…
H="-H Authorization:Bearer\ $BLENDFI_KEY"
I="-H Idempotency-Key:$(uuidgen)"

# 1. Aceite a cotação cria a conversão (dispara conversion.created)
curl -X POST $BLENDFI_BASE/v1/quotes/$QUOTE_ID/accept $H $I

# 2. Simula o pagamento Pix → conversion.completed (caminho feliz)
curl -X POST $BLENDFI_BASE/v1/test_helpers/conversions/$CID/simulate-onramp-pix-paid $H $I

Para exercitar falhas:

# Janela expira sem pagamento → conversão termina em expired
curl -X POST $BLENDFI_BASE/v1/test_helpers/conversions/$CID/expire $H $I

# Liquidação on-chain falha após o pagamento → conversion.failed
curl -X POST $BLENDFI_BASE/v1/test_helpers/conversions/$CID/fail-crypto $H $I

Offramp (USDT → Pix)

# 1. Aceite a cotação cria a conversão (dispara conversion.created)
curl -X POST $BLENDFI_BASE/v1/quotes/$QUOTE_ID/accept $H $I

# 2. Simula depósito exato dentro da janela → conversion.completed
curl -X POST $BLENDFI_BASE/v1/test_helpers/conversions/$CID/deposit $H $I \
  -H "content-type: application/json" \
  -d '{"amount":"100.00"}'

Para exercitar standby e liquidação manual:

# Depósito com valor menor → conversion.standby (under_funded)
curl -X POST $BLENDFI_BASE/v1/test_helpers/conversions/$CID/deposit $H $I \
  -H "content-type: application/json" \
  -d '{"amount":"97.50"}'

# Liquide manualmente pelo valor recebido → conversion.completed
curl -X POST $BLENDFI_BASE/v1/conversions/$CID/liquidate $H $I

# Pix de saída falha → conversion.failed (failure_reason: pix_send_failed)
curl -X POST $BLENDFI_BASE/v1/test_helpers/conversions/$CID/fail-pix $H $I

Avançando um ciclo de vida de KYC

Os test_helpers de KYC forçam o veredicto da análise:

USER=usr_01J…

# Força aprovado → dispara user.kyc_approved
curl -X POST $BLENDFI_BASE/v1/test_helpers/users/$USER/kyc $H $I \
  -H "content-type: application/json" \
  -d '{"status":"approved"}'

# Força rejeitado → dispara user.kyc_rejected
curl -X POST $BLENDFI_BASE/v1/test_helpers/users/$USER/kyc $H $I \
  -H "content-type: application/json" \
  -d '{"status":"rejected"}'

# Força expirado → dispara user.kyc_expired
curl -X POST $BLENDFI_BASE/v1/test_helpers/users/$USER/kyc $H $I \
  -H "content-type: application/json" \
  -d '{"status":"expired"}'

Inspecionando entregas

Toda entrega (bem-sucedida, com falha ou em andamento) é consultável:

# Todas as entregas de um endpoint
curl "$BLENDFI_BASE/v1/webhook_endpoints/we_01J.../deliveries" \
  -H "Authorization: Bearer $BLENDFI_KEY"

# Uma entrega específica
curl $BLENDFI_BASE/v1/webhook_deliveries/del_01J... \
  -H "Authorization: Bearer $BLENDFI_KEY"

Cada linha de entrega carrega o status de resposta que o seu endpoint retornou, a latência e o último erro, se houver. Ao debugar divergências de assinatura, este é o loop de feedback mais rápido: dispare um test_helper, leia a lista de entregas imediatamente e veja o que o seu endpoint respondeu.

Padrões comuns de debug

  • Divergência de assinatura em um evento acionado por test_helper. Confirme que BLENDFI_WEBHOOK_SECRET bate com o segredo retornado na criação do endpoint. Confira a captura do body bruto antes de qualquer middleware.
  • Endpoint não recebe nada. Confira a lista de entregas; se a BlendFi mostrar failed com erro de conexão, a sua URL de túnel pode ter rotacionado.
  • Payload parece velho. O snapshot de data é capturado no momento da mudança de estado. Se você precisa do estado atual, use GET /v1/conversions/:id.

Sem dinheiro real no sandbox

As conversões de sandbox nunca tocam um banco Pix real ou uma exchange real. Os test_helpers são a única forma de avançar o estado delas. Os eventos disparados são idênticos bit a bit aos eventos de produção para a mesma transição.

Próximos passos

Nesta página