From d6643c32f96daac898bc6ada2ce50c31625c64f6 Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Tue, 29 Jan 2019 19:55:32 -0800 Subject: [PATCH] working on new tables for payments --- app/config/associate.js | 17 +++--- app/config/db.config.js | 3 ++ app/controllers/stripe.controller.js | 35 ++++++++++-- app/models/donor.model.js | 4 ++ app/models/paymentplan.model.js | 24 +++++++++ bin/DROP-FORCE.js | 80 +++++++++++++++++++++++++++- package.json | 2 +- server.js | 2 +- 8 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 app/models/paymentplan.model.js diff --git a/app/config/associate.js b/app/config/associate.js index 92ddebf..634eefb 100644 --- a/app/config/associate.js +++ b/app/config/associate.js @@ -1,5 +1,13 @@ module.exports = models => { - const { Donor, Grant, Cause, Region, Organization, Charge } = models; + const { + Donor, + Grant, + Cause, + Region, + Organization, + Charge, + PaymentPlan + } = models; Donor.hasMany(Grant, { foreignKey: 'donor_id' }); @@ -20,12 +28,9 @@ module.exports = models => { foreignKey: 'grant_id', otherKey: 'organization_id' }); + Grant.hasMany(Charge, { foreignKey: 'grant_id' }); - Donor.hasMany(Charge, { - foreignKey: 'user_id' - }); - - Organization.hasMany(Charge, { + Donor.hasOne(PaymentPlan, { foreignKey: 'user_id' }); }; diff --git a/app/config/db.config.js b/app/config/db.config.js index de9f31c..a3e4194 100644 --- a/app/config/db.config.js +++ b/app/config/db.config.js @@ -5,6 +5,7 @@ const Sequelize = require('sequelize'), RegionModel = require('../models/region.model.js'), OrganizationModel = require('../models/organization.model.js'), UserModel = require('../models/user.model.js'), + PaymentPlanModel = require('../models/paymentplan.model'), ChargeModel = require('../models/charge.model'); associate = require('./associate'); @@ -42,6 +43,7 @@ const Region = RegionModel(sequelize, Sequelize); const Organization = OrganizationModel(sequelize, Sequelize); const User = UserModel(sequelize, Sequelize); const Charge = ChargeModel(sequelize, Sequelize); +const PaymentPlan = PaymentPlanModel(sequelize, Sequelize); db.Donor = Donor; db.Grant = Grant; db.Cause = Cause; @@ -49,6 +51,7 @@ db.Region = Region; db.Organization = Organization; db.User = User; db.Charge = Charge; +db.PaymentPlan = PaymentPlan; // make associations with created models associate(db); diff --git a/app/controllers/stripe.controller.js b/app/controllers/stripe.controller.js index 2eee659..33c84e1 100644 --- a/app/controllers/stripe.controller.js +++ b/app/controllers/stripe.controller.js @@ -6,16 +6,45 @@ 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) => { +exports.grantCharge = (req, res, next) => { const { stripeToken, amount, monthly } = req.body; - console.log(req.body); const user = req.user; findStripeId(user.id) .then(stripeId => { if (!stripeId) { - stripe.customers.create({}); + return stripe.customers + .create({ + source: stripeToken, + email: user.email + }) + .then(customer => { + Donor.update( + { stripe_id: customer.id }, + { where: { id: user.id } } + ); + return customer.id; + }); } + return stripeId; + }) + .then(stripeId => { + // return stripe.charges.create({ + // amount, + // currency: 'usd', + // customer: stripeId + // });s + stripe.plans + .create({ + product: 'prod_CbvTFuXWh7BPJH', + currency: 'usd', + interval: 'month', + amount: 10000 + }) + .then(); + }) + .then(chargeResponse => { + res.status(200).json(chargeResponse); }) .catch(error => next(error)); // if (!monthly) { diff --git a/app/models/donor.model.js b/app/models/donor.model.js index d25d2ed..703bdb3 100644 --- a/app/models/donor.model.js +++ b/app/models/donor.model.js @@ -5,6 +5,10 @@ module.exports = (sequelize, DataTypes) => { primaryKey: true, autoIncrement: true }, + stripe_id: { + type: DataTypes.UUID, + defaultValue: null + }, first_name: { type: DataTypes.STRING, allowNull: false diff --git a/app/models/paymentplan.model.js b/app/models/paymentplan.model.js new file mode 100644 index 0000000..ec6b142 --- /dev/null +++ b/app/models/paymentplan.model.js @@ -0,0 +1,24 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + const PaymentPlan = sequelize.define('payment_plans', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + autoIncrement: true + }, + plan_id: { + type: DataTypes.UUID, + allowNull: false + }, + subscription_id: { + type: DataTypes.UUID, + allowNull: false + }, + amount: { + type: DataTypes.INTEGER, + allowNull: false + } + }); + + return PaymentPlan; +}; diff --git a/bin/DROP-FORCE.js b/bin/DROP-FORCE.js index 3508f65..5f08af3 100644 --- a/bin/DROP-FORCE.js +++ b/bin/DROP-FORCE.js @@ -1,4 +1,30 @@ -const db = require('../app/config/db.config.js'); +//require dependencies +const express = require('express'), + app = express(), + bodyParser = require('body-parser'), + port = process.env.PORT, + db = require('../app/config/db.config.js'), + morgan = require('morgan'); + +app.use(morgan('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); + +//handle CORS errors +app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header( + 'Access-Control-Allow-Headers', + 'Origin, X-Requested-With, Content-Type, Accept, Authorization' + ); + + if (req.method == 'OPTIONS') { + res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, PATCH'); + return res.status(200).json({}); + } + + next(); +}); //verify connection to db db.sequelize @@ -11,7 +37,57 @@ db.sequelize }); //force: true will drop the table if it already exists -const drop_tables = true; +const drop_tables = false; db.sequelize.sync({ force: drop_tables }).then(() => { console.log(`Drop and Resync with { force: ${drop_tables} }`); }); + +//main route for api; perhaps for api docs frontend +app.get('/', function(req, res, next) { + res.send('Welcome to the Ucharify API'); +}); + +//donor routes +app.use('/api/donors', require('./app/routes/donor.route.js')); +//organization routes +app.use('/api/org', require('./app/routes/organization.route')); +//auth route +app.use('/api/auth', require('./app/routes/auth.route.js')); +//general routes +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) => { + const error = new Error('Not found'); + error.status = 404; + next(error); +}); + +//General error handler for anything +app.use((error, req, res, next) => { + //can log the error internally + // console.log(error); + + if (req.app.get('env') !== 'development' && req.app.get('env') !== 'test') { + delete error.stack; + } + + //status is set from other logic depending on the error itself + res.status(error.status || 500); + res.json({ + error: error.message + }); +}); + +// Create a Server +var server = app.listen(port, function() { + var host = server.address().address; + var port = server.address().port; + + //server is successful + console.log(`App listening at port: ${port}`); +}); diff --git a/package.json b/package.json index ec53fd3..496b9c1 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "start": "PORT=4200 & set JWT_KEY=secretkey & node server.js", "dev": "nodemon bin/dev.js", - "drop": "node bin/DROP-FORCE.js" + "drop": "nodemon bin/DROP-FORCE.js" }, "repository": { "type": "git", diff --git a/server.js b/server.js index 73ec13d..35d9835 100644 --- a/server.js +++ b/server.js @@ -37,7 +37,7 @@ db.sequelize }); //force: true will drop the table if it already exists -const drop_tables = false; +const drop_tables = true; db.sequelize.sync({ force: drop_tables }).then(() => { console.log(`Drop and Resync with { force: ${drop_tables} }`); });