Fluxo básico para receber notificações via webhooks
- Crie um serviço com um endpoint acessível dentro do seu sistema para receber as requisições de notificação dos eventos feitos pela Malga.
- Registre seu endpoint na Malga criando um webhook para receber notificações dos eventos desejados.
- A Malga enviará uma requisição HTTP para seu endpoint com os dados do objeto alterado sempre que o determinado evento registrado no seu webhook acontecer.
Criação de um webhook
Realize a criação e gestão de webhooks usando o Serviço de Webhooks.Evento de notificação enviado
Muitos dos eventos que ocorrem na sua integração com a Malga são síncronos e você recebe um retorno direto como resposta da sua requisição, como nos casos de criar um cliente, criar um cartão, etc. Porém, em determinados casos, a resposta que você recebe após realizar uma requisição não contempla o status final daquele objeto, sendo necessário registrar um webhook para receber respostas assíncronas da API da Malga para manter seu sistema atualizado, isso ocorre principalmente nos casos de cobrança através de PIX e Boleto, notificação de suspeita de fraude, liquidação financeira de transações, entre outros. Quando um determinado evento ocorre, a Malga então cria um objeto do tipoevent que é enviado através de uma requisição HTTP para o seu endpoint cadastrado. O evento é imutável dentro da estrutura de notificações da Malga, isso significa que os dados do objeto que sofreu alteração são gravados junto com o evento, representando o estado do objeto imediatamente após o evento que o alterou.
transaction
Exemplo de requisição de notificação de evento de uma transação enviada pela Malga para seu endpoint:Quando a cobrança é processada por um Fluxo Inteligente, o objeto
data inclui a propriedade paymentFlow:paymentFlow.id— identificador do fluxo que processou a cobrança.paymentFlow.metadata— o mesmo objeto demetadataque você enviou empaymentFlow.metadatana criação da cobrança, usado nas regras condicionais do fluxo.
paymentFlow só é enviada quando a cobrança passa por um Fluxo Inteligente. Cobranças que não acionam um fluxo não trazem esse campo, mesmo que metadata tenha sido informado apenas para o roteamento.seller
Na propriedade data, você terá acesso a dois objetos aninhados: origin e seller. Dentro do objeto seller, você poderá visualizar o estado atual do vendedor com informações de todos os provedores. Já na propriedade origin, você receberá o nome do provedor que originou a emissão do evento. Por exemplo, se o valor de origin for SANDBOX, significa que somente o provedor SANDBOX sofreu modificação de status. Confira o exemplo abaixo para entender melhor como funciona:Dentro de
seller.bankAccount, os identificadores bank (COMPE) e ispb podem estar ambos preenchidos ou apenas um deles, conforme o cadastro do recebedor. Consulte a seção sobre bank e ispb para detalhes.subscription
Exemplo de requisição de notificação de evento de uma assinatura enviada pela Malga para seu endpoint:purchase
Os eventospurchase.* notificam o andamento de uma Venda com múltiplos cartões. São sete eventos, listados em Eventos Purchase, e todos existem somente na versão 1.1 do webhook.
Cadastro do webhook
Cadastre um evento específico ou use"event": "*" para receber todos os eventos da conta na versão 1.1. Com o curinga, o seu endpoint também recebe transaction.*, seller.* e subscription.*: filtre pelo campo object e responda 200 aos objetos que você não processa.
Como a notificação chega
O corpo tem sempre a mesma estrutura, para qualquer evento de Venda. O nome do evento chega dividido em dois campos:purchase.paid é entregue como "object": "purchase" e "event": "paid". Concatene object e event para montar o nome. O campo apiVersion é uma string ("1.1").
O campo id identifica a notificação, não a Venda, e é igual ao header X-Idempotency-Key. O data traz o conteúdo do evento e varia conforme o evento, como mostram os exemplos a seguir.
Exemplo de requisição de notificação do evento purchase.created enviada pela Malga para seu endpoint:
orderId e sessionId chegam como null quando você não os informa na criação. O id de cada item de payments é o identificador do cartão dentro da Venda, e não o chargeId da cobrança, que só existe depois da autorização. O paymentMethodSnapshot traz a referência do cartão (cardId ou tokenId) e, quando conhecidos, brand e last4. Ele nunca traz o número do cartão.
purchase.charge_authorized
Refere-se a um único cartão da Venda. Neste evento, o identificador da Venda vem empurchaseId, e não em id. O status é o do cartão e pode ser pre_authorized ou authorized, inclusive em Vendas com capture: true. Uma Venda pode gerar mais de um evento deste tipo, portanto não trate o primeiro como o desfecho.
Desfechos da Venda
Os eventospurchase.pre_authorized, purchase.paid, purchase.failed, purchase.cancelled e purchase.void_failed trazem o mesmo resumo da Venda, sem a lista de cartões. Só o status muda.
purchase.pre_authorized — todos os cartões ficaram pré-autorizados em uma Venda criada com capture: false:
purchase.paid — todos os cartões foram capturados:
purchase.failed — a Venda foi recusada de forma definitiva. O evento não traz o motivo da recusa: consulte payments[].declineReason em GET /v1/purchases/{id}. A Malga compensa automaticamente os cartões que já tinham sido cobrados, cancelando a pré-autorização ou estornando a captura.
purchase.cancelled — o cancelamento das pré-autorizações foi concluído. O estorno de uma Venda paid não gera este evento:
purchase.void_failed — a liberação ou o estorno de um cartão não concluiu depois das tentativas automáticas. Trate este evento como alerta operacional: há valor retido sem desfecho automático. Consulte a Venda em GET /v1/purchases/{id} para identificar o cartão afetado, que permanece pre_authorized ou authorized, e acione o suporte da Malga com o id da Venda.
Em casos de abandono da Venda ou de esgotamento das tentativas, os eventos
purchase.failed e purchase.void_failed podem trazer apenas id e status no data. Modele o seu parser de forma tolerante: campos ausentes são esperados.Corpo reduzido
Em parte dos cenários, os eventospurchase.paid, purchase.cancelled e purchase.charge_authorized são entregues com o data reduzido:
200 e use a notificação como sinal de que algo mudou: consulte as Vendas que você ainda tem como não terminais. Nunca descarte a notificação nem a trate como erro.
Como processar os eventos de Venda
- Use o evento como gatilho e leia o estado em
GET /v1/purchases/{id}. Odatapode ser um retrato antigo, no caso de uma retentativa, ou reduzido. Nunca grave o estado da Venda a partir dodata. - Extraia o identificador da Venda de
data.ide, na falta dele, dedata.purchaseId. Se nenhum dos dois existir, faça a reconciliação por varredura. - Libere o pedido pelo status da Venda, nunca pelo status de um cartão isolado. Enquanto houver cartão pendente, a Venda continua
pending. - Não presuma ordem entre os eventos de uma mesma Venda. O
purchase.paidpode chegar antes de umpurchase.charge_authorized. - Deduplique pelo campo
idda notificação, igual ao headerX-Idempotency-Key. - Se a Venda trouxer o campo
pendingReviewna consulta, interrompa a consulta automática e acione o suporte da Malga. - O estorno de uma Venda
paidnão gera eventopurchase.*e a Venda permanecepaid. Acompanhe o valor estornado empayments[].refundedAmount, na consulta da Venda.
Boas práticas para receber notificações
Tentativas e Retentativas de envio de notificações A Malga fará a tentativa de envio de uma determinada notificação para seu webhook, em caso de problemas no processamento do serviço, passamos a realizar novas tentativas de entrega das notificações com um escalonamento de tempo entre as tentativas. Para concluir o processamento da notificação, o seu serviço deve retornar um HTTP STATUS 200 (OK) ou 201 (CREATED) dentro do tempo máximo de espera, caso contrário, será entendido que o endpoint não o recebeu corretamente e o evento será marcado para retentativa.A Malga mantém o registro de todas as notificações enviadas, incluindo os dados da requisição (Request) e da resposta do servidor externo (Response), pelo período de 45 dias.Quando uma notificação ultrapassa o número máximo de tentativas de entrega, a mensagem é marcada como perdida e permanece armazenada para reprocessamento futuro mediante solicitação.Se o seu webhook apresentar 50 ou mais falhas de entrega em um período de 24 horas, a Malga envia um e-mail de resumo para o contato com papel de proprietário cadastrado na sua conta.
event que registra o objeto e o tipo do evento de atualização, bem como a data da ocorrência. Cada evento possui um identificador único que deve ser utilizado do lado do cliente para evitar duplicidade de processamento. O identificador é enviado no objeto event no corpo da requisição e também no header x-idempotency-key do request, sendo o mesmo valor.
Os eventos são enviados através de uma requisição HTTP para o seu endpoint exatamente na ordem em que eles ocorreram no sistema da Malga, porém recomendamos que seja utilizada a data de criação do evento, também enviada no objeto event, para garantir uma ordem cronológica no processamento dos eventos do lado do cliente. Caso você receba um evento com data de criação inferior à data de criação de um outro evento já processado pelo seu sistema, os dados do objeto enviado no evento estarão desatualizados, ficando a seu critério tomar ou não alguma ação com esse evento.
Testando notificação via webhooks
Para testar sua integração com os webhooks da Malga, você pode desenvolver direto seu sistema ou utilizar algum serviço como request.bin ou pipedream.com para validar inicialmente os eventos enviados. Basta gerar um novo endpoint nestes serviços e cadastrar um webhook na Malga com o endpoint gerado que todos os eventos enviados ficarão registrados nestes serviços para consulta e debug. Permitimos no ambiente de sandboxsandbox-api.malga.io a atualização manual de transações criadas para os status de authorized, voided e charged_back, dessa forma você consegue criar uma transação e simular o evento desejado.
Requisição para atualizar manualmente uma transação em sandbox
Segurança Webhook
A partir da versão 1.1 do webhook a Malga passou a assinar todos os eventos para garantir a segurança do recebimento do evento. Utilizamos uma chave privada do tipo Ed25519 para assinar os eventos. No momento do cadastro do webhook, você recebe a chave pública de mesmo tipo para verificar se a assinatura enviada bate com o payload recebido. Todo evento recebido deve ser verificado e caso a assinatura não seja reconhecida, por medidas de segurança, você deve descartar o evento.Como verificar a assinatura do evento?
Enviamos 2 headers:- X-Plug-Date contendo a data que o evento foi gerado. O formato segue o padrão UTC Unix Timestamp.
- X-Plug-Signature contendo um hash em hexadecimal de 64 bits.
Exemplos de validação da signature
Os exemplos estão disponíveis nesse repositório github: https://github.com/plughacker/plug-sample-signature-verify/ Veja um trecho de cada linguagem:- Node.js
- Golang
- Python
- C#
- Java
- PHP
- Ruby
Eventos suportados para notificação via webhooks
Eventos Transaction
Eventos Seller
Eventos de revisão cadastral
Estes eventos acompanham os processos de revisão cadastral que o provedor abre para os seus recebedores. Entenda o fluxo em Revisão cadastral.
O objeto
data traz o estado do processo, o que há para coletar e a origem no provedor:
Quando o provedor abre o processo sem informar ainda o que pedir,
requestedFields vem ausente e requestedFieldsPending vem true. O aviso é enviado mesmo assim, porque o prazo já está correndo.