Properly handle stripe hook with sig verification
parent
e2e0fa2a00
commit
bf6c35ea50
10
app.js
10
app.js
|
@ -272,7 +272,6 @@ app.enable('trust proxy');
|
|||
app.use(helmet());
|
||||
app.set('port', process.env.PORT || 1111);
|
||||
app.use(logger('dev'));
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(cookieParser(config.secretCookie));
|
||||
app.use(session({
|
||||
|
@ -287,6 +286,15 @@ app.use(session({
|
|||
store: store
|
||||
}));
|
||||
|
||||
app.use(bodyParser.json({
|
||||
// Only on Stripe URL's which need the rawBody
|
||||
verify: (req, res, buf) => {
|
||||
if(req.originalUrl === '/stripe/subscription_update'){
|
||||
req.rawBody = buf.toString();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// Set locales from session
|
||||
app.use(i18n.init);
|
||||
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
"publicKey": "pk_test_this_is_not_real",
|
||||
"stripeCurrency": "usd",
|
||||
"stripeDescription": "expressCart payment",
|
||||
"stripeLogoURL": "http://localhost:1111/images/stripelogo.png"
|
||||
"stripeLogoURL": "http://localhost:1111/images/stripelogo.png",
|
||||
"stripeWebhookSecret": ""
|
||||
}
|
|
@ -16,6 +16,9 @@
|
|||
"stripeLogoURL": {
|
||||
"type": "string",
|
||||
"format": "uri-template"
|
||||
},
|
||||
"stripeWebhookSecret": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
|
@ -7614,7 +7614,8 @@
|
|||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"quick-lru": {
|
||||
"version": "1.1.0",
|
||||
|
@ -8726,13 +8727,18 @@
|
|||
"dev": true
|
||||
},
|
||||
"stripe": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/stripe/-/stripe-5.10.0.tgz",
|
||||
"integrity": "sha512-AUDmXfNAAY/oOfW87HPO4bDzNWJp8iQd0blVWwwEgPxO1DmEC//foI0C9rhr2ZNsuF6kLypPfNtGB9Uf+RCQzQ==",
|
||||
"version": "7.12.0",
|
||||
"resolved": "https://registry.npmjs.org/stripe/-/stripe-7.12.0.tgz",
|
||||
"integrity": "sha512-h/NMB7E+0WgDuEOdfrS9giYmTfQRvOoKHdYaKzo9V0hxilXopVJd3ZZQ47193rAOHjIhmuCDtQRb3gEEm24gKg==",
|
||||
"requires": {
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"qs": "~6.5.1",
|
||||
"safe-buffer": "^5.1.1"
|
||||
"qs": "^6.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"qs": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz",
|
||||
"integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"superagent": {
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
"sanitize-html": "^1.20.1",
|
||||
"sitemap": "^1.6.0",
|
||||
"strip-bom": "^3.0.0",
|
||||
"stripe": "^5.10.0",
|
||||
"stripe": "^7.12.0",
|
||||
"uglifycss": "0.0.27"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -115,13 +115,27 @@ router.post('/checkout_action', (req, res, next) => {
|
|||
// Subscription hook from Stripe
|
||||
router.all('/subscription_update', async (req, res, next) => {
|
||||
const db = req.app.db;
|
||||
const stripeSigSecret = common.getPaymentConfig().stripeWebhookSecret;
|
||||
const stripeSig = req.headers['stripe-signature'];
|
||||
|
||||
if(!req.body.data.object.customer){
|
||||
return res.status(400).json({ message: 'Customer not found' });
|
||||
let hook;
|
||||
if(stripeSigSecret){
|
||||
try{
|
||||
hook = await stripe.webhooks.constructEvent(req.rawBody, stripeSig, stripeSigSecret);
|
||||
console.info('Stripe Webhook received');
|
||||
}catch(err){
|
||||
return res.status(400).send(`Webhook Error: ${err.message}`);
|
||||
}
|
||||
|
||||
if(!hook.data.object.customer){
|
||||
return res.status(400).json({ message: 'Customer not found' });
|
||||
}
|
||||
}else{
|
||||
hook = req.body;
|
||||
}
|
||||
|
||||
const order = await db.orders.findOne({
|
||||
orderCustomer: req.body.data.object.customer,
|
||||
orderCustomer: hook.data.object.customer,
|
||||
orderType: 'Subscription'
|
||||
});
|
||||
|
||||
|
@ -130,7 +144,7 @@ router.all('/subscription_update', async (req, res, next) => {
|
|||
}
|
||||
|
||||
let orderStatus = 'Paid';
|
||||
if(req.body.type === 'invoice.payment_failed'){
|
||||
if(hook.type === 'invoice.payment_failed'){
|
||||
orderStatus = 'Declined';
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue