Razorpay signature verification not happening as SHA256 Digest is wrong NodeJS
Asked Answered
U

6

9

I am making an app in which after a successful payment I create a digest which I verify using the suggest way of Razorpay signature verification.

My backend is in NodeJS and here is how I am creating the digest.

const crypto = require("crypto");

 var generatedSignature = crypto
      .createHmac(
        "SHA256",
        razorpay_order_id + "|" + razorpay_payment_id
      )
      .update(key_secret)
      .digest("hex");  

var isSignatureValid = generatedSignature == payload.razorpay_signature // false

Is my way of creating signature wrong?

Ursas answered 13/6, 2019 at 3:35 Comment(0)
P
14

You can use the following code. Hope this makes a more understandable code.

const crypto = require("crypto");
const hmac = crypto.createHmac('sha256', RAZORPAY_KEY_SECRET);

hmac.update(razorpayOrderId + "|" + razorpayPaymentId);
let generatedSignature = hmac.digest('hex');

let isSignatureValid = generatedSignature == payload.razorpay_signature;

Refer this link for more https://nodejs.org/api/crypto.html#crypto_class_hmac

Pallette answered 16/8, 2019 at 8:23 Comment(1)
to the point answer. It really help a lot. Thank YouPipit
B
2

2022 Update:

Just checked razorpay documentation:

Suggested approach:

const razorpay = require("razorpay");
const isValid = razorpay.validateWebhookSignature(reqBody, signature, mySecret);

Documentation Link: https://razorpay.com/docs/payments/payment-gateway/server-integration/nodejs/#subscribe-to-webhook-events

Barrier answered 2/2, 2022 at 20:53 Comment(1)
isValid would always be null or undefined, since razorpay signature verifications return void. Just wrap them in TRY_CATCH(exception handling) because if the signature is not verified it throws an errorThelen
D
1

You just have to change the createHmac and update like below swapping parameters in them.

const crypto = require("crypto");

var generatedSignature = crypto
  .createHmac(
    "SHA256",
    key_secret
  )
  .update(razorpay_order_id + "|" + razorpay_payment_id)
  .digest("hex");  

 var isSignatureValid = generatedSignature == payload.razorpay_signature;
Daedalus answered 30/6, 2019 at 21:39 Comment(0)
D
0

enter image description hereGoing through the official razorpay npm module, found this function that does the job for you. Might as well utilise this.

file name & directory: node_modules/razorpay/dist/utils/razorpay-utils.js, function name: validateWebhookSignature

Takes in 'body' -- hashing sequence, 'signature' -- razorpay returned signature, 'key_secret' -- from razorpay dashboard

This uses the same crypto.hmac_256 function as mentioned previously on this thread.

UPDATE: Tested using this function, returns false ==> signature not matching.

Read on GitHub that the signature won't match using test key. It'll work when using live key.

Will update this thread when I try using production keys. Cheers!

Di answered 13/4, 2020 at 11:35 Comment(1)
Tested this. Returns false ==> hash not matching.Di
O
0
const crypto=require('crypto');
const json = JSON.stringify(req.body); // req.body is entire body payload 
const expectedSignature = 
crypto.createHmac('sha256',secretKey).update(json).digest('hex');
// secretKey is configured key provided by us while creating webhook


//--- Or Use razorpay static method 

/*
@params body string (body is req.body data)
@params razorpayHeaderSignature string (x-razorpay-signature of header section 
provided by webhook)
@params secretKey (secretKey is configured key provided by us while creating webhook)
*/

const json = JSON.stringify(req.body); // req.body is entire body payload 
Razorpay.validateWebhookSignature(body, razorpayHeaderSignature, secretKey);

NOTE - IN request body don't use some of the special characters like '/' etc. It causes verification of signature to fail.

Organizer answered 25/1, 2021 at 18:50 Comment(0)
S
0

The below solution worked for me

     import crypto from 'crypto';

     const signature = req.headers['x-razorpay-signature'];
     const generatedSignature = crypto
      .createHmac('sha256', RAZOR_PAY_WEBHOOK_SECRET)
      .update(JSON.stringify(req.body))
      .digest('hex');

    if (signature === generatedSignature) {
      console.log('request is legit');
    }
    else{
      console.log('Wrong Signature!');
    }
Sethsethi answered 24/5, 2021 at 11:22 Comment(1)
Can you please add a sample valid signature, a sample request body, and the generated signature to your question?Gyatt

© 2022 - 2024 — McMap. All rights reserved.