From dfc5a2c435e30cade0acd4cd01edd653fa6bc8f7 Mon Sep 17 00:00:00 2001 From: Tyler McIntyre Date: Mon, 31 Mar 2014 16:00:51 -0400 Subject: [PATCH] stripe API added --- app.js | 8 ++ controllers/api.js | 123 +++++++++++++++++++++++++++- package.json | 1 + views/api/index.jade | 2 + views/api/stripe/customers.jade | 30 +++++++ views/api/stripe/index.jade | 13 +++ views/api/stripe/newsubscriber.jade | 67 +++++++++++++++ views/api/stripe/onetime.jade | 67 +++++++++++++++ 8 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 views/api/stripe/customers.jade create mode 100644 views/api/stripe/index.jade create mode 100644 views/api/stripe/newsubscriber.jade create mode 100644 views/api/stripe/onetime.jade diff --git a/app.js b/app.js index 6fabeb9619..eb12a53710 100755 --- a/app.js +++ b/app.js @@ -126,6 +126,14 @@ app.get('/api/paypal', apiController.getPayPal); app.get('/api/paypal/success', apiController.getPayPalSuccess); app.get('/api/paypal/cancel', apiController.getPayPalCancel); app.get('/api/steam', apiController.getSteam); + +app.get('/api/stripe', apiController.getStripe); +app.get('/api/stripe/onetime', apiController.getStripeOnetime); +app.post('/api/stripe/onetime', apiController.postStripeOnetime); +app.get('/api/stripe/newsubscriber', apiController.getStripeNewSubscriber); +app.post('/api/stripe/newsubscriber', apiController.postStripeNewSubscriber); +app.get('/api/stripe/customers', apiController.getStripeCustomers); + app.get('/api/scraping', apiController.getScraping); app.get('/api/twilio', apiController.getTwilio); app.post('/api/twilio', apiController.postTwilio); diff --git a/controllers/api.js b/controllers/api.js index 71bca54b8f..de5ae378e3 100644 --- a/controllers/api.js +++ b/controllers/api.js @@ -13,6 +13,7 @@ var foursquare = require('node-foursquare')({ secrets: secrets.foursquare }); var Github = require('github-api'); var Twit = require('twit'); var paypal = require('paypal-rest-sdk'); +var stripe = require('stripe')(secrets.stripe.apiKey); var twilio = require('twilio')(secrets.twilio.sid, secrets.twilio.token); var Linkedin = require('node-linkedin')(secrets.linkedin.clientID, secrets.linkedin.clientSecret, secrets.linkedin.callbackURL); var clockwork = require('clockwork')({key: secrets.clockwork.apiKey}); @@ -384,6 +385,126 @@ exports.getSteam = function(req, res, next) { }); }); }; +exports.getStripe = function(req, res, next) { + //Create a token for the CC + res.render('api/stripe/index', { + title: 'Stripe API' + }); +}; + +exports.getStripeOnetime = function(req, res, next) { + //Create a token for the CC + res.render('api/stripe/onetime', { + title: 'Stripe API' + }); +}; + +exports.postStripeOnetime = function(req, res, next) { + stripe.tokens.create({ + card: { + "number": req.body.ccNumber, + "exp_month": req.body.expMonth, + "exp_year": req.body.expYear, + "cvc": req.body.cvc + } + }, function(err, token) { + if (err) { + req.flash('errors', { msg: err.message }); + return res.redirect('/api/stripe/onetime'); + } + //Create a new customer + stripe.customers.create({ + card: token.id, + description: req.body.customerName, + email: req.body.email + }).then(function(customer) { + //charge the customer + stripe.charges.create({ + amount: req.body.chargeAmount * 100, // amount in cents + currency: "usd", + customer: customer.id + }, function(err, charge) { + if (err) { + req.flash('errors', { msg: err.message }); + return res.redirect('/api/stripe/onetime'); + }else{ + req.flash('success', { msg: 'Charged Successfully'}); + res.render('api/stripe/onetime', { + title: 'Stipe API', + customer: customer, + charge: charge + }); + } + }); + }); + }); +}; + + +exports.getStripeNewSubscriber = function(req, res, next) { + stripe.plans.list(function(err, plans) { + res.render('api/stripe/newsubscriber', { + title: 'Stripe API', + plans: _.pluck(plans.data, 'name') + }); + }); +}; + +exports.postStripeNewSubscriber = function(req, res, next) { + console.log(req.body.plantype); + + stripe.tokens.create({ + card: { + "number": req.body.ccNumber, + "exp_month": req.body.expMonth, + "exp_year": req.body.expYear, + "cvc": req.body.cvc + } + }, function(err, token) { + if (err) { + req.flash('errors', { msg: err.message }); + return res.redirect('/api/stripe/newsubscriber'); + } + //Create a new customer + stripe.customers.create({ + card: token.id, + description: req.body.customerName, + email: req.body.email + }).then(function(customer) { + //charge the customer + stripe.customers.createSubscription( + customer.id, + {plan: req.body.plantype}, + function(err, subscription) { + if (err) { + req.flash('errors', { msg: err.message }); + return res.redirect('/api/stripe/newsubscriber'); + }else{ + stripe.plans.list(function(err, plans) { + req.flash('success', { msg: 'Subscribed Successfully'}); + res.render('api/stripe/newsubscriber', { + title: 'Stipe API', + customer: customer, + subscription: subscription, + plans: _.pluck(plans.data, 'name') + }); + }); + } + } + ); + }); + }); +}; + +exports.getStripeCustomers = function(req, res, next) { + stripe.customers.list(function(err, customers) { + customersList = JSON.stringify(customers.data); + res.render('api/stripe/customers', { + title: 'Stripe API', + customers: customersList + }); + }); +}; /** * GET /api/twilio @@ -410,7 +531,7 @@ exports.postTwilio = function(req, res, next) { }; twilio.sendMessage(message, function(err, responseData) { if (err) return next(err.message); - req.flash('success', { msg: 'Text sent to ' + responseData.to + '.'}) + req.flash('success', { msg: 'Text sent to ' + responseData.to + '.'}); res.redirect('/api/twilio'); }); }; diff --git a/package.json b/package.json index b927bf0d5e..50021ca6c6 100755 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "passport-twitter": "~1.0.2", "paypal-rest-sdk": "~0.6.4", "request": "~2.34.0", + "stripe": "~2.4.4", "tumblr.js": "~0.0.4", "twilio": "~1.6.0", "twit": "~1.1.12", diff --git a/views/api/index.jade b/views/api/index.jade index b82ce1c104..cc405c7da9 100644 --- a/views/api/index.jade +++ b/views/api/index.jade @@ -28,6 +28,8 @@ block content a(href='/api/paypal') PayPal li a(href='/api/steam') Steam + li + a(href='/api/stripe') Stripe li a(href='/api/twilio') Twilio li diff --git a/views/api/stripe/customers.jade b/views/api/stripe/customers.jade new file mode 100644 index 0000000000..25f6961139 --- /dev/null +++ b/views/api/stripe/customers.jade @@ -0,0 +1,30 @@ +extends ../../layout + +block content + .page-header + h2 + i.fa.fa-dollar + | Stripe API + + .btn-group.btn-group-justified + a.btn.btn-primary(href='/api/stripe') + i.fa.fa-home + | All API Calls + a.btn.btn-primary(href='https://stripe.com/docs/api', target='_blank') + i.fa.fa-code + | API Reference + a.btn.btn-primary(href='https://manage.stripe.com/account/apikeys', target='_blank') + i.fa.fa-gear + | API Keys + br + .row + .col-sm-12 + if customers + h2 Customers + pre + |!{JSON.stringify(customer)} + h2 Payment + pre + |!{JSON.stringify(charge)} + else + h2 No Customers API \ No newline at end of file diff --git a/views/api/stripe/index.jade b/views/api/stripe/index.jade new file mode 100644 index 0000000000..aac8975e7d --- /dev/null +++ b/views/api/stripe/index.jade @@ -0,0 +1,13 @@ +extends ../../layout + +block content + h2 Stripe API + + ol + li + a(href='/api/stripe/onetime') One Time Charges + li + a(href='/api/stripe/newsubscriber') New Subscriber + li + a(href='/api/stripe/customers') List All Customers + diff --git a/views/api/stripe/newsubscriber.jade b/views/api/stripe/newsubscriber.jade new file mode 100644 index 0000000000..d50f83431f --- /dev/null +++ b/views/api/stripe/newsubscriber.jade @@ -0,0 +1,67 @@ +extends ../../layout + +block content + .page-header + h2 + i.fa.fa-dollar + | Stripe API + + .btn-group.btn-group-justified + a.btn.btn-primary(href='/api/stripe') + i.fa.fa-home + | All API Calls + a.btn.btn-primary(href='https://stripe.com/docs/api', target='_blank') + i.fa.fa-code + | API Reference + a.btn.btn-primary(href='https://manage.stripe.com/account/apikeys', target='_blank') + i.fa.fa-gear + | API Keys + br + .row + .col-sm-4 + form(role='form', method='POST') + input(type='hidden', name='_csrf', value=_csrf) + br + .form-group + label(for='customerName') Customer Name + input#customerName.form-control(type='text', name='customerName', placeholder='Customer Name') + label(for='customerEmail') Email address + input#customerEmail.form-control(type='email', name='email', placeholder='Enter email') + label(for='planselect') Select a Plan + select.form-control#planselect(name='plantype') + option(selected='selected', disabled='disabled') Select a Plan + each name in plans + option #{name} + .form-group + label(for='ccnumber') Credit Card Number + input#ccnumber.form-control(type='text', size='20', name='ccNumber') + + label(for='CVC') CVC + input#CVC.form-control(type='text', size='4', name='cvc') + + label(for='exp-month') Expiration (MM/YYYY) + input#exp-month.form-control(type='text', size='2', name='expMonth') + input#exp-year.form-control(type='text', size='4', name='expYear') + button.btn.btn-primary(type='submit') Submit Payment + .col-sm-7.col-sm-offset-1 + if subscription + h2 Customer + pre + |!{JSON.stringify(customer)} + h2 Subscription + pre + |!{JSON.stringify(subscription)} + else + h2 Stripe New Subscriber API + p + | This API is to create a new subscription for a user. The API tokenizes the credit card, creates a new user, then it creates a subscription for the user. + br + br + | You must create your subscription plans + a(href='https://manage.stripe.com/test/plans') here + | and then they will automatically populate in the dropdown list. You can create free trials too. + br + br + | Test Credit Card: 4242424242424242 + br + | Any CVC & valid experation date. \ No newline at end of file diff --git a/views/api/stripe/onetime.jade b/views/api/stripe/onetime.jade new file mode 100644 index 0000000000..4aa47d5b65 --- /dev/null +++ b/views/api/stripe/onetime.jade @@ -0,0 +1,67 @@ +extends ../../layout + +block content + .page-header + h2 + i.fa.fa-dollar + | Stripe API + + .btn-group.btn-group-justified + a.btn.btn-primary(href='/api/stripe') + i.fa.fa-home + | All API Calls + a.btn.btn-primary(href='https://stripe.com/docs/api', target='_blank') + i.fa.fa-code + | API Reference + a.btn.btn-primary(href='https://manage.stripe.com/account/apikeys', target='_blank') + i.fa.fa-gear + | API Keys + br + .row + .col-sm-4 + form(role='form', method='POST') + input(type='hidden', name='_csrf', value=_csrf) + br + .form-group + label(for='customerName') Customer Name + input#customerName.form-control(type='text', name='customerName', placeholder='Customer Name') + label(for='customerEmail') Email address + input#customerEmail.form-control(type='email', name='email', placeholder='Enter email') + label(for='chargeAmount') Enter Charge + .input-group + span.input-group-addon $ + input.form-control(type='text',name='chargeAmount') + span.input-group-addon .00 + + .form-group + label(for='ccnumber') Credit Card Number + input#ccnumber.form-control(type='text', size='20', name='ccNumber') + + label(for='CVC') CVC + input#CVC.form-control(type='text', size='4', name='cvc') + + label(for='exp-month') Expiration (MM/YYYY) + input#exp-month.form-control(type='text', size='2', name='expMonth') + input#exp-year.form-control(type='text', size='4', name='expYear') + button.btn.btn-primary(type='submit') Submit Payment + .col-sm-7.col-sm-offset-1 + if charge + h2 Customer + pre + |!{JSON.stringify(customer)} + h2 Payment + pre + |!{JSON.stringify(charge)} + else + h2 Stripe Charge API + p + | Please note that this API does not use Stripe.js for its form. It tokenizes the credit card on the backend. After it generates the token it creates a new user and adds the token to that account. Finally it charges the user the amount entered in the box. + br + br + | This is for a one-time charge, and not a reoccuring charge / subscription. Also, the form does not do any validation on the client side, I would suggest using something like + a(href='http://jquerycreditcardvalidator.com/') this. + br + br + | Test Credit Card: 4242424242424242 + br + | Any CVC & valid experation date. \ No newline at end of file