Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

235
Visualizações
Encoding request body with HMAC sha256 and base64

How to encode a request body using HMAC sha 256 and base64.

The request object that i receives from xero webhook.

HEADER:
   "x-xero-signature" : HASH_VALUE
PAYLOAD:
  {
     "events": [],
     "lastEventSequence": 0,
     "firstEventSequence": 0,
     "entropy": "S0m3r4Nd0mt3xt"
  } 

The note from xero documentation says "If the payload is hashed using HMACSHA256 with your webhook signing key and base64 encoded, it should match the signature in the header. This is a correctly signed payload. If the signature does not match the hashed payload it is an incorrectly signed payload."

And I followed this example : https://devblog.xero.com/using-xero-webhooks-with-node-express-hapi-examples-7c607b423379

const express = require("express");
const router = express.Router();
const base64 = require('base-64');
const crypto = require('crypto')
const bodyParser = require('body-parser')
const xero_webhook_key = '00fRRlJBYiYN4ZGjmTtG+g/pulyb1Eru68YYL3PFoLsa78dadfQtGrOMuISuVBHxpXeEYo0Yy1Gc+hHMhDkSI/EEcgtrA==';

let options = {
    type: 'application/json'
  };
let itrBodyParser = bodyParser.raw(options);

router.post("/", itrBodyParser, async (req, res, next) =>{
//     console.log('::::WebhookPost:::');
const reSign = req.headers['x-xero-signature'];
 console.log(req.headers['x-xero-signature']);
 console.log('::::::::');
 console.log(req.body);
    console.log("Body: "+JSON.stringify(req.body))
    console.log(req.body.toString());
    console.log("Xero Signature: "+ reSign);
    console.log('Server key::::',xero_webhook_key);
    // Create our HMAC hash of the body, using our webhooks key
    let hmac = crypto.createHmac("sha256", xero_webhook_key).update(req.body.toString()).digest('base64');
    console.log("Resp Signature: ",hmac)

    if (req.headers['x-xero-signature'] == hmac) {
        res.statusCode = 200
    } else {
        res.statusCode = 401
    }
    console.log("Response Code: "+res.statusCode)
    return res.send();
 

});
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Hey I recently did a video on implementing webhooks with Xero, let me know if this gets you unstuck. I found that trying to pass itrBodyParser on the route the way you have wasn't working for me so I switched it with an app.use statement on my specific webhooks endpoint. If you prefer a written guide over video, here's the blog post

over 4 years ago · Santiago Trujillo Relatório

0

I solved it using this solution.! I was using express framework and the request were not getting as raw request also .toString of didn't worked as mentioned in xero documentation.

 const server = http.createServer(async (req, resp) => {
  try {
      console.log(`::::Webhook::: ${webhookPort}`);
      console.log("::::x-xero-signature:::");
      console.log(req.headers["x-xero-signature"]);
      console.log(`--------------------------------------`);
      if (req.method === "POST") {
        if(req.headers["x-xero-signature"]){
          const rData = await new Promise((resolve, reject) => {
            return collectRequestData(req, (result) => {
                
                console.log(result);
                let hmac = crypto
                  .createHmac("sha256", xero_webhook_key)
                  .update(result)
                  .digest("base64");
                  console.log("Resp Signature: ", hmac);
                 
               
                return resolve({
                  hmac,result
                });
              });
          });
           console.log(">>Resp Signature: ", rData);
           console.log('>>x-xero-signature:::',req.headers["x-xero-signature"]);
           if(rData.result){
             const result = JSON.parse(rData.result);
             console.log('result:::',result);
             for(let { resourceId } of result.events) {
              console.log('::INVOICE ID = ',resourceId);
                getInvoiceData(resourceId);
             }
           }

           if(rData.hmac == req.headers["x-xero-signature"] ){
            console.log('::YES');
              resp.statusCode = 200;
          }else{
            console.log('::NO');
            resp.statusCode = 401;
          }
        }
        resp.end();
      }

        console.log("::::Webhookgetsssss:::");
        resp.message = 'Get API'
        resp.end();
     
  } catch (error) {
    resp.statusCode = 200;
    resp.end();
  }
      
     
  });
  server.listen(webhookPort);

function collectRequestData(request, callback) {
    let body = "";
    request.on("data", (chunk) => {
      body += chunk.toString();
    });
    request.on("end", () => {
      callback(body);
    });
  }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda