merging create grant and stripe calls

This commit is contained in:
Arjun Patel
2019-02-02 19:33:44 -08:00
parent 49c470ab47
commit 226f5c1149
9 changed files with 112 additions and 27 deletions
+8 -2
View File
@@ -28,9 +28,15 @@ module.exports = models => {
foreignKey: 'grant_id', foreignKey: 'grant_id',
otherKey: 'organization_id' otherKey: 'organization_id'
}); });
Grant.hasMany(Charge, { foreignKey: 'grant_id' }); Grant.hasMany(Charge, { foreignKey: 'grant_id' });
Donor.hasOne(PaymentPlan, { Donor.hasMany(PaymentPlan, {
foreignKey: 'user_id' foreignKey: 'subscription_id',
sourceKey: 'subscription_id'
});
Grant.hasOne(PaymentPlan, {
foreignKey: 'grant_id'
}); });
}; };
+8 -5
View File
@@ -28,12 +28,15 @@ exports.create = (req, res, next) => {
]).then(result => grant); ]).then(result => grant);
}); });
}) })
.then(function(grant) { .then(function(grants) {
// transaction committed // transaction committed
res.status(201).json({ // res.status(201).json({
grant, // grant,
message: 'Grant Created' // message: 'Grant Created'
}); // });
req.grant = grants.dataValues;
next();
}) })
.catch(function(error) { .catch(function(error) {
// transaction rollback // transaction rollback
+2 -1
View File
@@ -1,5 +1,6 @@
module.exports = { module.exports = {
donor: require('./donor.controller'), donor: require('./donor.controller'),
grant: require('./grant.controller'), grant: require('./grant.controller'),
organization: require('./organization.controller') organization: require('./organization.controller'),
stripe: require('./stripe.controller')
}; };
@@ -1,5 +1,5 @@
const db = require('../config/db.config.js'), const db = require('../../config/db.config.js'),
errorMaker = require('../helpers/error.maker'); errorMaker = require('../../helpers/error.maker');
const stripe = require('stripe')('sk_test_n8NCvCFjD1xFhGiEq6SI8CXj'); const stripe = require('stripe')('sk_test_n8NCvCFjD1xFhGiEq6SI8CXj');
@@ -7,16 +7,20 @@ const { Donor, Charge, PaymentPlan } = db;
// Subscribe user to plan or one time charge // Subscribe user to plan or one time charge
exports.grantCharge = async (req, res, next) => { exports.grantCharge = async (req, res, next) => {
const { stripeToken, grant_id, amount, monthly } = req.body; const { stripeToken, monthly } = req.body;
const { grant_id } = req.grant;
const amount = req.body.amount * 100; //stripe standards
const user = req.user; const user = req.user;
const product_id = 'prod_ER3jOog6QMX1GP'; const product_id = 'prod_ER3jOog6QMX1GP',
default_plan_id = 'default_plan'; // main Grants product
try { try {
const donors = await Donor.findAll({ where: { id: user.id } }); const donors = await Donor.findAll({ where: { id: user.id } });
// check if already a stripe customer // check if already a stripe customer
let { stripe_id, subscription_id } = donors[0]; let { stripe_id, subscription_id } = donors[0];
console.log(stripeToken);
if (!stripe_id) { if (!stripe_id) {
const customer = await stripe.customers.create({ const customer = await stripe.customers.create({
@@ -62,31 +66,63 @@ exports.grantCharge = async (req, res, next) => {
if (!subscription_id) { if (!subscription_id) {
let subscription = await stripe.subscriptions.create({ let subscription = await stripe.subscriptions.create({
customer: stripe_id, customer: stripe_id,
items: [{ plan: plan.id }] items: [{ plan: default_plan_id }]
}); });
subscription_id = subscription.id;
await Donor.update( await Donor.update(
{ subscription_id: subscription.id }, { subscription_id: subscription.id },
{ where: { id: user.id } } { where: { id: user.id } }
); );
} else }
await stripe.subscriptionItems.create({
subscription: subscription_id, const sub_item = await stripe.subscriptionItems.create({
plan: plan.id subscription: subscription_id,
}); plan: plan.id
});
result = await PaymentPlan.create({ result = await PaymentPlan.create({
plan_id: plan.id, plan_id: plan.id,
amount, amount,
grant_id: grant_id grant_id,
subscription_id,
sub_item_id: sub_item.id
}); });
} }
res.status(200).json({ return res.status(200).json({
message: 'Successfully charged or subscribed', message: 'Successfully charged or subscribed',
result grant: req.grant
}); });
} catch (error) { } catch (error) {
next(error); next(error);
} }
}; };
// Delete grant's stripe plan under subscription
exports.deleteGrant = async (req, res, next) => {
const { grant_id } = req.body;
try {
const paymentPlans = await PaymentPlan.findAll({ where: { grant_id } });
// check if there are plans for that grant
if (!paymentPlans.length) {
res.status(400).json({
message: 'Not a valid grant'
});
} else {
const plan = paymentPlans[0];
await stripe.subscriptionItems.del(plan.sub_item_id);
res.status(201).json({
message: 'Removed monthly subscription plan',
plan
});
}
} catch (error) {
next(error);
}
};
@@ -0,0 +1,20 @@
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn('payment_plans', 'sub_item_id', {
type: Sequelize.UUID,
unique: true
});
},
down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
+4 -2
View File
@@ -7,11 +7,13 @@ module.exports = (sequelize, DataTypes) => {
}, },
stripe_id: { stripe_id: {
type: DataTypes.UUID, type: DataTypes.UUID,
defaultValue: null defaultValue: null,
unique: true
}, },
subscription_id: { subscription_id: {
type: DataTypes.UUID, type: DataTypes.UUID,
defaultValue: null defaultValue: null,
unique: true
}, },
first_name: { first_name: {
type: DataTypes.STRING, type: DataTypes.STRING,
+4
View File
@@ -14,6 +14,10 @@ module.exports = (sequelize, DataTypes) => {
amount: { amount: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false allowNull: false
},
sub_item_id: {
type: DataTypes.UUID,
unique: true
} }
}); });
+12 -2
View File
@@ -20,10 +20,20 @@ router.get('/grants/', checkAuth(roles.DONOR), controllers.grant.findByDonorId);
* - monthly true or false * - monthly true or false
* - donor_id * - donor_id
* */ * */
router.post('/grants/', checkAuth(roles.DONOR), controllers.grant.create); router.post(
'/grants/',
checkAuth(roles.DONOR),
controllers.grant.create,
controllers.stripe.grantCharge
);
// DELECT a grant of a donor // DELECT a grant of a donor
router.delete('/grants/', checkAuth(roles.DONOR), controllers.grant.delete); router.delete(
'/grants/',
checkAuth(roles.DONOR),
controllers.stripe.deleteGrant,
controllers.grant.delete
);
// POST to get suggested organizations to distribute to // POST to get suggested organizations to distribute to
// running "the algorithm" // running "the algorithm"
+4 -1
View File
@@ -3,9 +3,12 @@ const express = require('express'),
checkAuth = require('../middleware/check-auth'), checkAuth = require('../middleware/check-auth'),
roles = require('../helpers/roles'); roles = require('../helpers/roles');
const controller = require('../controllers/stripe.controller'); const controller = require('../controllers/donor/stripe.controller');
// POST create one time or monthly charge for grant // POST create one time or monthly charge for grant
router.post('/donor/grant', checkAuth(roles.DONOR), controller.grantCharge); router.post('/donor/grant', checkAuth(roles.DONOR), controller.grantCharge);
// DELETE grant's plan under subscription
router.delete('/donor/grant', checkAuth(roles.DONOR), controller.deleteGrant);
module.exports = router; module.exports = router;