-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't get webhook.verify to work #13
Comments
I have similar issue. @krjo are you fixed this issue? |
I asked Recharge Support how to validate by nodejs and got next example
It means that current library has incorrect code for hash generation. |
Here's my middleware function to validate Recharge webhooks for those coming in the future. You'll need:
app.use(
bodyParser.json({
verify: (req: Request, res: Response, buf: Buffer) => {
req.rawBody = buf;
},
}),
);
export const validateRechargeWebhook = (req: Request, res: Response, next: NextFunction) => {
const { rawBody } = req;
if (!rawBody) {
throw createError.Forbidden();
}
const generatedHash = crypto
.createHash('sha256')
.update(process.env.RECHARGE_API_CLIENT_SECRET)
.update(Buffer.from(rawBody))
.digest('hex');
if (generatedHash !== req.headers['x-recharge-hmac-sha256']) {
throw createError.Forbidden();
}
next();
}; |
Another middleware example, for NextJS, using the Web Crypto API: async function generateHash(body: string): Promise<string> {
const msgUint8 = new TextEncoder().encode(
process.env.X_RECHARGE_ACCESS_SECRET + body,
); // encode as (utf-8) Uint8Array
const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8); // hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
// convert bytes to hex string
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
}
export default async function validateWebhook(
hmac: string | null,
body: any,
): Promise<boolean> {
return (await generateHash(JSON.stringify(body))) === hmac;
} |
Using express, I managed to validate the webhook using as middleware: app.use(bodyParser.raw({ type: 'application/json' })) And the validation function: import * as crypto from 'crypto'
function validateRechargeWebhook(req, res, next) {
const secret = process.env.RECHARGE_API_CLIENT_SECRET ?? ''
const payload = Buffer.from(req.body).toString()
const webhookHmac = req.header('X-Recharge-Hmac-Sha256')
const hash = crypto
.createHash('sha256')
.update(secret, 'utf-8')
.update(payload, 'utf-8')
.digest('hex')
if (hash === webhookHmac) {
console.log('Webhook validated successfully!')
next()
} else {
console.log(
'Oops! There may be some third party interference going on.'
)
res.status(401).send()
}
} |
Having trouble with webhook.verify using express. I think your webhook method arguments might be backwards in the readme, but I tried the following with no luck:
recharge.webhook.validate(req.body, process.env.API_CLIENT_SECRET).then((webhook) => console.log(webhook)).catch((err) => console.error(err));
recharge.webhook.validate(req, process.env.API_CLIENT_SECRET).then((webhook) => console.log(webhook)).catch((err) => console.error(err));
recharge.webhook.validate(process.env.API_CLIENT_SECRET, req).then((webhook) => console.log(webhook)).catch((err) => console.error(err));
recharge.webhook.validate(process.env.API_CLIENT_SECRET, req.body).then((webhook) => console.log(webhook)).catch((err) => console.error(err));
The text was updated successfully, but these errors were encountered: