Skip to main content
Use o WebSocket quando o seu sistema não tem um endereço HTTPS público para receber webhooks: um bot do Discord ou do Telegram, um worker numa VPS, um processo atrás de NAT ou um script. Ele entrega os mesmos eventos dos webhooks, com o mesmo data, assim que acontecem. A API continua sendo quem cria cobranças, saques e envios. O WebSocket só avisa que algo aconteceu.

Sem endereço público?

Use o WebSocket. O seu servidor abre a conexão para a WyzeCash, então não precisa de porta aberta nem de domínio.

Tem um servidor HTTPS?

Prefira os webhooks: assinatura X-Bukio-Signature e reenvio automático quando a sua URL cai.
Conecte só do seu servidor. A chave de API vai junto, então nunca use o WebSocket no navegador, no app ou em código público. Guarde a chave numa variável de ambiente.

Começar

1

Tenha uma chave de API

Crie em Integrações e API › Chaves de API uma chave bk_live_… com a permissão de consulta dos eventos que você quer ouvir (veja a tabela em Inscrições, mais abaixo). Ex.: payments:get para ouvir as cobranças.
2

Conecte no endereço

Abra uma conexão em wss://bukio-backend-production.up.railway.app/v1/ws a partir do seu servidor.
3

Entre com a chave

No cabeçalho Authorization ao conectar ou na primeira mensagem, em até 10 segundos (veja Entrar com a chave).
4

Inscreva-se

Mande subscribe com um padrão (payment.*) ou com o código de uma cobrança (BKY-…).
5

Trate os eventos

Responda o ping, guarde o id de cada evento para não processar duas vezes e, se cair, conecte de novo mandando o último id em since.

Testar em 1 minuto

  1. Conecte com a sua chave e inscreva-se em payment.*.
  2. Crie uma cobrança Pix pequena com POST /v1/payments (pela API ou pelo painel).
  3. Chega payment.created. Pague com o seu banco e chega payment.paid.
Os eventos são da conta, não da chave: uma conexão recebe os eventos de tudo o que acontece na conta (criado pela API, pelo painel, pelo app ou por um link de pagamento), desde que a chave tenha a permissão de consulta daquele tipo de evento.

Endereço

Como as mensagens funcionam

Toda mensagem sua é um JSON com o campo action. Toda mensagem do servidor tem o campo event.

O que você manda

O que o servidor manda

Entrar com a chave

Escolha um dos dois jeitos:
Use quando a sua biblioteca deixa mandar cabeçalhos (o pacote ws do Node e o websockets do Python deixam).
A chave nunca vai no endereço (nada de ?token=): endereço aparece em log de proxy e de servidor. Quando a chave é aceita, chega:
Conexão aberta continua sendo conferida. A cada minuto o servidor confere a chave e a conta: chave apagada ou vencida, conta bloqueada ou verificação obrigatória pendente derrubam a conexão. Chave apagada no painel derruba as conexões dela na hora.

Inscrições

Por padrão

Resposta:
Regras:
  • Também vale um evento só: { "action": "subscribe", "pattern": "payment.paid" }.
  • Com *, chegam só os tipos que a chave pode consultar; os outros ficam de fora, sem erro.
  • Pedir um padrão sem a permissão (ex.: withdrawal.* numa chave só de cobranças) dá FORBIDDEN.
  • Padrão fora da lista dá INVALID_ACTION.
  • Inscrever-se duas vezes no mesmo padrão não duplica nada.
  • No máximo 100 inscrições por conexão (padrões e cobranças somados).
  • Prefira o mínimo que você usa (payment.* em vez de *).

Por cobrança

Para acompanhar uma cobrança (ex.: a tela de “aguardando pagamento” do seu bot), mande o código dela:
Resposta:

Parar de ouvir

Resposta: { "event": "unsubscribed", "pattern": "payment.*" }. A conexão continua aberta e você pode se inscrever em outra coisa.

O evento

Todo evento chega assim:
O evento só sai depois de gravado de vez. Uma operação que voltou atrás no meio do caminho nunca gera evento.
O provedor por trás de cada operação nunca aparece no evento, igual aos webhooks.

Eventos

São os mesmos 13 eventos dos webhooks. O webhook.test (botão “Enviar teste”) não vai pelo WebSocket.
O Pix Copia e Cola e o QR Code não vêm no evento: eles estão na resposta do POST /v1/payments.
Cartão aprovado já é venda: libere o pedido. availableAt diz quando o valor entra no saldo disponível.
amount é o valor devolvido neste estorno, que pode ser parcial.
withdrawal.requested com status: "processing" quer dizer “saindo”. Só withdrawal.completed confirma.

Ping

Qualquer mensagem sua conta, mas o jeito simples é responder todo ping. Faça isso antes de ir para produção.

Caiu? Pegue o que perdeu

A conexão pode cair (rede, reinício do seu servidor ou do nosso). O que aconteceu enquanto ela estava fora não se perde:
1

Guarde o id do último evento

A cada evento recebido, guarde o id (evt_…) num lugar que sobreviva ao reinício (banco, Redis, arquivo).
2

Conecte de novo esperando um pouco mais a cada vez

1 s, 2 s, 4 s, 8 s, 16 s e no máximo 30 s. Volte para 1 s quando conectar.
3

Entre e inscreva-se de novo mandando o since

Chega de novo, em ordem, tudo o que veio depois desse evento e entra nessa inscrição: até 24 horas e até 500 eventos.
O servidor não reenvia nada sozinho e o ack não muda isso: quem pede o que perdeu é você, com o since. Ficou fora mais de 24 horas? Consulte a API (GET /v1/payments, GET /v1/withdrawals, GET /v1/statement) para pôr o seu sistema em dia.

Fluxo completo

Exemplos

O SDK wyzecash entra com a chave, responde o ping, conecta de novo sozinho (esperando cada vez mais, até 30 s) e pede o que perdeu com o since. Chave inválida ou apagada (código 1008) não reconecta.
No Node 22+, Bun e Deno o SDK usa o WebSocket que já vem. No Node 20, passe o do pacote ws: wyzecash.realtime({ WebSocket }).

Erros

Chegam assim:

Códigos de fechamento

Limites

Segurança

  • Só do servidor. A chave nunca vai para navegador, app ou repositório.
  • Conexão criptografada. Sempre wss://.
  • A chave nunca no endereço. Só no cabeçalho Authorization ou na mensagem authenticate.
  • Permissão por tipo de evento. Uma chave só de cobranças não ouve saques. Dê à chave do bot só o que ele precisa.
  • IP liberado vale aqui também. Se a chave tem IPs liberados, a conexão só entra desses IPs.
  • Apagou a chave, a conexão cai na hora.

Antes de ir para produção

  • A conexão roda no servidor e a chave está numa variável de ambiente.
  • O ping é respondido.
  • O id de cada evento é guardado e repetidos são ignorados.
  • Ao cair, conecta de novo esperando cada vez mais e manda o since.
  • O código 1008 para de reconectar e avisa você.
  • O pedido é liberado só em payment.paid, conferindo o data.amount.
  • Depois de mais de 24 horas fora, o sistema consulta a API.

WebSocket, webhook ou consulta?

Pode usar os dois juntos: o id do evento é o mesmo, então o seu controle de repetidos vale para os dois.

No painel

Em Integrações e API › WebSocket você vê as conexões abertas agora (chave, IP, há quanto tempo, inscrições e eventos entregues), quantos eventos saíram hoje, quantos foram reenviados pelo since e o último evento.