title: HMAC hashing with Base64 encoding with Javascript
body: <p>I am working with Payeezy API to handle payment on a webapp, their API for purchase requires a HMAC of payload signed using api secret. An excerpt from the docs: </p>
  
  <blockquote>
    <p>Construct the data param by appending the parameters below in the same order as shown. a. apikey - API key of the developer. b. nonce - secure random number. c. timestamp - epoch timestamp in milliseconds. d. token - Merchant Token. e. payload - Actual body content passed as post request. Compute HMAC SHA256 hash on the above data param using the key below f. apiSecret - Consumer Secret token for the given api key Calculate the base64 of the hash which would be our required Authorization header value.</p>
  </blockquote>
  
  <p>I found a library called jshashes on NPM and I tried to use their library to hash my header params, my code looks like this: </p>
  
  <pre><code>const payload = {
          "merchant_ref": "1-Sale",
          "transaction_type": "purchase",
          "method": "credit_card",
          "amount": amount * 100,
          "partial_redemption": "false",
          "currency_code": "USD",
          "credit_card": {
            "type": type,
            "cardholder_name": cardholder_name,
            "card_number": card_number,
            "exp_date": exp_date,
            "cvv": cvv
          }
        }
        const data = apikey + nounce + timestamp + token + JSON.stringify(payload)
        const sha256 = new Hashes.SHA256()
        const shaData = sha256.b64_hmac(apiSecret, data)
  </code></pre>
  
  <p>The outcome compared to the sample hashed value looks like this:</p>
  
  <pre><code>//mine
  beWtpCGDv/iBoAUDAThGFXIge9eli/Xtl7JIBuR1bd4= 
  
  
  //payeezy sample 
  NmUzMTNmYWU0YjExM2UxMmM0NjllZGI1NThjY2M5MmUzMzE3NTFlZmQ1NDQxYzAzMTgwMmIwNDQ0MWVmYTdhMw== 
  </code></pre>
  
  <p>from the looks of the character counts I could tell that my hashing process is not correct but I can't figure out where went wrong. </p>
  
  <p>I've seen similar questions being asked here but none answered, any help is appreciated.</p>
  
  <p>ADDITION, I tried crypto library on Node.js:</p>
  
  <pre><code>const data = apikey + nounce + timestamp + token + JSON.stringify(payload)
  
    const hmac = crypto.createHmac('sha512', apiSecret)
  
    hmac.on('readable', () =&gt; {
      const data = hmac.read()
      if (data) {
        console.log(data.toString('base64'));
      }
    })
  
    hmac.write(data)
    hmac.end()
  </code></pre>
  
  <p>Same result, with only half the character length compared to the sample hashed value</p>
  
  <p>UPDATE: After I used SHA512 on the data it finally returned a string that looks to have the same character length as the sample, but the validation is still not passing... </p>