From e3b7a1699e3f2070e7fc29fea8eee115116c0ca9 Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Tue, 29 Jan 2019 10:32:21 -0800 Subject: [PATCH] adding charges table and starting the endpoint for charging for a grant --- app/config/associate.js | 10 +++++- app/config/config.js | 10 +++--- app/config/db.config.js | 5 ++- app/controllers/stripe.controller.js | 22 +++++++++++++ ...dding-stripe-customer-id-to-donor-table.js | 20 +++++++++++ .../20190129174646-create-charges.js | 33 +++++++++++++++++++ app/models/charge.model.js | 10 ++++++ app/routes/donor.route.js | 1 + app/routes/stripe.route.js | 11 +++++++ bin/DROP-FORCE.js | 17 ++++++++++ package-lock.json | 10 ++++++ package.json | 6 ++-- server.js | 2 ++ 13 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 app/controllers/stripe.controller.js create mode 100644 app/migrations/20190129172059-adding-stripe-customer-id-to-donor-table.js create mode 100644 app/migrations/20190129174646-create-charges.js create mode 100644 app/models/charge.model.js create mode 100644 app/routes/stripe.route.js create mode 100644 bin/DROP-FORCE.js diff --git a/app/config/associate.js b/app/config/associate.js index 95ecf1c..92ddebf 100644 --- a/app/config/associate.js +++ b/app/config/associate.js @@ -1,5 +1,5 @@ module.exports = models => { - const { Donor, Grant, Cause, Region, Organization } = models; + const { Donor, Grant, Cause, Region, Organization, Charge } = models; Donor.hasMany(Grant, { foreignKey: 'donor_id' }); @@ -20,4 +20,12 @@ module.exports = models => { foreignKey: 'grant_id', otherKey: 'organization_id' }); + + Donor.hasMany(Charge, { + foreignKey: 'user_id' + }); + + Organization.hasMany(Charge, { + foreignKey: 'user_id' + }); }; diff --git a/app/config/config.js b/app/config/config.js index 6495891..ae09b23 100644 --- a/app/config/config.js +++ b/app/config/config.js @@ -2,11 +2,11 @@ require('dotenv/config'); module.exports = { development: { - username: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - database: process.env.DB_DB, - host: process.env.DB_HOST, - dialect: process.env.DB_DIALECT + username: 'root', + password: 'water', + database: 'base', + host: 'localhost', + dialect: 'mysql' }, test: { username: 'root', diff --git a/app/config/db.config.js b/app/config/db.config.js index 0c8b96a..de9f31c 100644 --- a/app/config/db.config.js +++ b/app/config/db.config.js @@ -5,7 +5,8 @@ const Sequelize = require('sequelize'), RegionModel = require('../models/region.model.js'), OrganizationModel = require('../models/organization.model.js'), UserModel = require('../models/user.model.js'), - associate = require('./associate'); + ChargeModel = require('../models/charge.model'); +associate = require('./associate'); const connection_uri = process.env.JAWSDB_MARIA_URL; @@ -40,12 +41,14 @@ const Cause = CauseModel(sequelize, Sequelize); const Region = RegionModel(sequelize, Sequelize); const Organization = OrganizationModel(sequelize, Sequelize); const User = UserModel(sequelize, Sequelize); +const Charge = ChargeModel(sequelize, Sequelize); db.Donor = Donor; db.Grant = Grant; db.Cause = Cause; db.Region = Region; db.Organization = Organization; db.User = User; +db.Charge = Charge; // make associations with created models associate(db); diff --git a/app/controllers/stripe.controller.js b/app/controllers/stripe.controller.js new file mode 100644 index 0000000..60273ef --- /dev/null +++ b/app/controllers/stripe.controller.js @@ -0,0 +1,22 @@ +const db = require('../config/db.config.js'), + errorMaker = require('../helpers/error.maker'); + +const stripe = require('stripe')('sk_test_n8NCvCFjD1xFhGiEq6SI8CXj'); + +const { Donor, Organization } = db; + +// Subscribe user to plan or one time charge +exports.grantCharge = async (req, res, next) => { + const { stripeToken, amount, monthly } = req.body; + console.log(req.body); + + // if (!monthly) { + // const charge = stripe.charges.create({ + // amount, + // currency: 'usd', + // description: 'One time payment for grant', + // source: stripeToken, + // statement_descriptor: 'One time payment for grant' + // }); + // } +}; diff --git a/app/migrations/20190129172059-adding-stripe-customer-id-to-donor-table.js b/app/migrations/20190129172059-adding-stripe-customer-id-to-donor-table.js new file mode 100644 index 0000000..938a1cb --- /dev/null +++ b/app/migrations/20190129172059-adding-stripe-customer-id-to-donor-table.js @@ -0,0 +1,20 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.addColumn('donors', 'stripe_id', { + type: Sequelize.UUID, + defaultValue: null + }); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + } +}; diff --git a/app/migrations/20190129174646-create-charges.js b/app/migrations/20190129174646-create-charges.js new file mode 100644 index 0000000..aa50cf7 --- /dev/null +++ b/app/migrations/20190129174646-create-charges.js @@ -0,0 +1,33 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('charges', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + amount: { + allowNull: false, + type: Sequelize.INTEGER + }, + description: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + defaultValue: new Date() + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + defaultValue: new Date() + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('charges'); + } +}; diff --git a/app/models/charge.model.js b/app/models/charge.model.js new file mode 100644 index 0000000..8d477bd --- /dev/null +++ b/app/models/charge.model.js @@ -0,0 +1,10 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + const Charge = sequelize.define('charges', { + id: { type: DataTypes.UUID, primaryKey: true, allowNull: false }, + description: DataTypes.STRING, + amount: DataTypes.INTEGER + }); + + return Charge; +}; diff --git a/app/routes/donor.route.js b/app/routes/donor.route.js index d4171f4..7d3806f 100644 --- a/app/routes/donor.route.js +++ b/app/routes/donor.route.js @@ -17,6 +17,7 @@ router.get('/grants/', checkAuth(roles.DONOR), controllers.grant.findByDonorId); /** POST Create grants with following body: * - list of id's of selected causes and regions * - FINAL list of id's of selected organizations + * - monthly true or false * - donor_id * */ router.post( diff --git a/app/routes/stripe.route.js b/app/routes/stripe.route.js new file mode 100644 index 0000000..5917869 --- /dev/null +++ b/app/routes/stripe.route.js @@ -0,0 +1,11 @@ +const express = require('express'), + router = express.Router(), + checkAuth = require('../middleware/check-auth'), + roles = require('../helpers/roles'); + +const controller = require('../controllers/stripe.controller'); + +// POST create one time or monthly charge for grant +router.post('/donor/grant', checkAuth(roles.DONOR), controller.grantCharge); + +module.exports = router; diff --git a/bin/DROP-FORCE.js b/bin/DROP-FORCE.js new file mode 100644 index 0000000..3508f65 --- /dev/null +++ b/bin/DROP-FORCE.js @@ -0,0 +1,17 @@ +const db = require('../app/config/db.config.js'); + +//verify connection to db +db.sequelize + .authenticate() + .then(() => { + console.log('Connection has been established successfully.'); + }) + .catch(err => { + console.error('Unable to connect to the database:', err); + }); + +//force: true will drop the table if it already exists +const drop_tables = true; +db.sequelize.sync({ force: drop_tables }).then(() => { + console.log(`Drop and Resync with { force: ${drop_tables} }`); +}); diff --git a/package-lock.json b/package-lock.json index 309bef7..637e5bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -663,6 +663,16 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "stripe": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-6.22.0.tgz", + "integrity": "sha512-pz/vUPftp+k6qXycGEWOV5rVNL8CYZs7cD5za0cofS68S/RfNVIDsRNteK1HH8dj20+vFN1MFoZFav1Ki6VGSA==", + "requires": { + "lodash.isplainobject": "^4.0.6", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1" + } + }, "terraformer": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/terraformer/-/terraformer-1.0.9.tgz", diff --git a/package.json b/package.json index 9ad9e1f..ec53fd3 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "PORT=4200 & set JWT_KEY=secretkey & node server.js", - "dev": "nodemon bin/dev.js" + "dev": "nodemon bin/dev.js", + "drop": "node bin/DROP-FORCE.js" }, "repository": { "type": "git", @@ -25,7 +26,8 @@ "jsonwebtoken": "^8.4.0", "morgan": "^1.9.1", "mysql2": "^1.6.4", - "sequelize": "^4.42.0" + "sequelize": "^4.42.0", + "stripe": "^6.22.0" }, "devDependencies": { "dotenv": "^6.2.0" diff --git a/server.js b/server.js index 7bfb5f2..73ec13d 100644 --- a/server.js +++ b/server.js @@ -57,6 +57,8 @@ app.use('/api/auth', require('./app/routes/auth.route.js')); app.use('/api', require('./app/routes/general.route.js')); //admin routes app.use('/admin', require('./app/routes/admin.route')); +//stripe routes +app.use('/api/stripe', require('./app/routes/stripe.route')); //404 not found error handling on any other routes app.use((req, res, next) => {