-
-
Save whitej031788/f5b519d39fbf618c086340dd26bfe3c6 to your computer and use it in GitHub Desktop.
Verify a Paddle webhook using Node/Express
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This is an example of a Node/Express service route that validates a Paddle webhook | |
This could be stripped of Express, and similar methods could be used in just a Node application using Node's routing mechanism | |
Library depandancies are crypto, php-serialize, and querystring if using Express | |
*/ | |
// npm install php-serialize | |
// npm install crypto | |
// npm install querystring | |
const express = require('express'); | |
const querystring = require('querystring'); | |
const crypto = require('crypto'); | |
const Serialize = require('php-serialize'); | |
const router = express.Router(); | |
const pubKey = `-----BEGIN PUBLIC KEY----- | |
... | |
-----END PUBLIC KEY-----` | |
function ksort(obj){ | |
let keys = Object.keys(obj).sort(); | |
let sortedObj = {}; | |
for (var i in keys) { | |
sortedObj[keys[i]] = obj[keys[i]]; | |
} | |
return sortedObj; | |
} | |
function validateWebhook(jsonObj) { | |
const mySig = Buffer.from(jsonObj.p_signature, 'base64'); | |
delete jsonObj.p_signature; | |
// Need to serailise array and assign to data object | |
jsonObj = ksort(jsonObj); | |
for (var property in jsonObj) { | |
if (jsonObj.hasOwnProperty(property) && (typeof jsonObj[property]) !== "string") { | |
if (Array.isArray(jsonObj[property])) { // is it an array | |
jsonObj[property] = jsonObj[property].toString(); | |
} else { //if its not an array and not a string, then it is a JSON obj | |
jsonObj[property] = JSON.stringify(jsonObj[property]); | |
} | |
} | |
} | |
const serialized = Serialize.serialize(jsonObj); | |
// End serailise data object | |
const verifier = crypto.createVerify('sha1'); | |
verifier.update(serialized); | |
verifier.end(); | |
let verification = verifier.verify(pubKey, mySig); | |
if (verification) { | |
return 'Yay! Signature is valid!'; | |
} else { | |
return 'The signature is invalid!'; | |
} | |
} | |
/* Validate a Paddle webhook to this endpoint, or wherever in your app you are listening for Paddle webhooks */ | |
router.post('/', function(req, res, next) { | |
res.send(validateWebhook(req.body)); | |
}); | |
module.exports = router; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment