feat(subscriptions): add paypal recurring cancelation. refactor stripe & paypal code to use auth.authWithUrl.
This commit is contained in:
@@ -16,10 +16,6 @@ var NO_TOKEN_OR_UID = { err: "You must include a token and uid (user id) in your
|
||||
var NO_USER_FOUND = {err: "No user found."};
|
||||
var NO_SESSION_FOUND = { err: "You must be logged in." };
|
||||
|
||||
/*
|
||||
beforeEach auth interceptor
|
||||
*/
|
||||
|
||||
api.auth = function(req, res, next) {
|
||||
var uid = req.headers['x-api-user'];
|
||||
var token = req.headers['x-api-key'];
|
||||
@@ -47,6 +43,15 @@ api.authWithSession = function(req, res, next) { //[todo] there is probably a mo
|
||||
});
|
||||
};
|
||||
|
||||
api.authWithUrl = function(req, res, next) {
|
||||
User.findOne({_id:req.query._id, apiToken:req.query.apiToken}, function(err,user){
|
||||
if (err) return next(err);
|
||||
if (_.isEmpty(user)) return res.json(401, NO_USER_FOUND);
|
||||
res.locals.user = user;
|
||||
next();
|
||||
})
|
||||
}
|
||||
|
||||
api.registerUser = function(req, res, next) {
|
||||
var confirmPassword, e, email, password, username, _ref;
|
||||
_ref = req.body, email = _ref.email, username = _ref.username, password = _ref.password, confirmPassword = _ref.confirmPassword;
|
||||
|
||||
+36
-13
@@ -312,7 +312,8 @@ function createSubscription(user, data) {
|
||||
planId:'basic_earned',
|
||||
customerId: data.customerId,
|
||||
dateUpdated: new Date,
|
||||
gemsBought: 0
|
||||
gemsBought: 0,
|
||||
paymentMethod: data.paymentMethod
|
||||
})
|
||||
.defaults({ // allow non-override if a plan was previously used
|
||||
dateCreated: new Date,
|
||||
@@ -324,6 +325,12 @@ function createSubscription(user, data) {
|
||||
ga.transaction(data.customerId, 5).item(5, 1, data.paymentMethod.toLowerCase() + '-subscription', data.paymentMethod + " > Stripe").send();
|
||||
}
|
||||
|
||||
function cancelSubscription(user, data){
|
||||
_.merge(user.purchased.plan, {planId:null, customerId:null, paymentMethod:null});
|
||||
user.markModified('purchased.plan');
|
||||
ga.event('unsubscribe', 'Stripe').send();
|
||||
}
|
||||
|
||||
function buyGems(user, data) {
|
||||
user.balance += 5;
|
||||
user.purchased.txnCount++;
|
||||
@@ -334,7 +341,7 @@ function buyGems(user, data) {
|
||||
/*
|
||||
Setup Stripe response when posting payment
|
||||
*/
|
||||
api.buyGems = function(req, res, next) {
|
||||
api.stripeCheckout = function(req, res, next) {
|
||||
var api_key = nconf.get('STRIPE_API_KEY');
|
||||
var stripe = require("stripe")(api_key);
|
||||
var token = req.body.id;
|
||||
@@ -367,13 +374,12 @@ api.buyGems = function(req, res, next) {
|
||||
}
|
||||
], function(err, saved){
|
||||
if (err) return res.send(500, err.toString()); // don't json this, let toString() handle errors
|
||||
res.send(200, saved);
|
||||
res.send(200);
|
||||
});
|
||||
};
|
||||
|
||||
api.cancelSubscription = function(req, res, next) {
|
||||
var api_key = nconf.get('STRIPE_API_KEY');
|
||||
var stripe = require("stripe")(api_key);
|
||||
api.stripeSubscribeCancel = function(req, res, next) {
|
||||
var stripe = require("stripe")(nconf.get('STRIPE_API_KEY'));
|
||||
var user = res.locals.user;
|
||||
if (!user.purchased.plan.customerId)
|
||||
return res.json(401, {err: "User does not have a plan subscription"});
|
||||
@@ -383,20 +389,17 @@ api.cancelSubscription = function(req, res, next) {
|
||||
stripe.customers.del(user.purchased.plan.customerId, cb);
|
||||
},
|
||||
function(response, cb) {
|
||||
_.merge(user.purchased.plan, {planId:null, customerId:null});
|
||||
user.markModified('purchased.plan');
|
||||
cancelSubscription(user);
|
||||
user.save(cb);
|
||||
}
|
||||
], function(err, saved){
|
||||
if (err) return res.send(500, err.toString()); // don't json this, let toString() handle errors
|
||||
res.send(200, saved);
|
||||
ga.event('unsubscribe', 'Stripe').send()
|
||||
res.redirect('/');
|
||||
});
|
||||
}
|
||||
|
||||
api.paypalSubscribe = function(req,res,next) {
|
||||
var uuid = req.query.uuid;
|
||||
if (!uuid) return next("UUID required");
|
||||
var uuid = res.locals.user._id;
|
||||
// Authenticate a future subscription of ~5 USD
|
||||
paypalRecurring.authenticate({
|
||||
RETURNURL: nconf.get('BASE_URL') + '/paypal/subscribe/success?uuid=' + uuid,
|
||||
@@ -432,8 +435,28 @@ api.paypalSubscribeSuccess = function(req,res,next) {
|
||||
});
|
||||
}
|
||||
|
||||
api.paypalSubscribeCancel = function(req, res, next) {
|
||||
var user = res.locals.user;
|
||||
if (!user.purchased.plan.customerId)
|
||||
return res.json(401, {err: "User does not have a plan subscription"});
|
||||
async.waterfall([
|
||||
function(cb) {
|
||||
paypalRecurring.modifySubscription(user.purchased.plan.customerId, 'cancel', cb);
|
||||
},
|
||||
function(response, cb) {
|
||||
cancelSubscription(user);
|
||||
user.save(cb);
|
||||
}
|
||||
], function(err, saved){
|
||||
if (err) return next(err);
|
||||
res.redirect('/');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
api.paypalCheckout = function(req, res, next) {
|
||||
var opts = {RETURNURL:nconf.get('BASE_URL') + '/paypal/checkout/success?uuid=' + req.query.uuid};
|
||||
var uuid = res.locals.user._id;
|
||||
var opts = {RETURNURL:nconf.get('BASE_URL') + '/paypal/checkout/success?uuid=' + uuid};
|
||||
paypalCheckout.pay(+new Date, 5, 'HabitRPG Gems', 'USD', opts, function(err, url) {
|
||||
if (err) return next(err);
|
||||
res.redirect(url);
|
||||
|
||||
@@ -234,7 +234,6 @@ module.exports.locals = function(req, res, next) {
|
||||
res.locals.habitrpg = {
|
||||
NODE_ENV: nconf.get('NODE_ENV'),
|
||||
BASE_URL: nconf.get('BASE_URL'),
|
||||
PAYPAL_MERCHANT: nconf.get('PAYPAL_MERCHANT'),
|
||||
GA_ID: nconf.get("GA_ID"),
|
||||
IS_MOBILE: /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(req.header('User-Agent')),
|
||||
STRIPE_PUB_KEY: nconf.get('STRIPE_PUB_KEY'),
|
||||
|
||||
@@ -85,6 +85,7 @@ var UserSchema = new Schema({
|
||||
mobileChat: Boolean,
|
||||
plan: {
|
||||
planId: String,
|
||||
paymentMethod: String, //enum: ['Paypal','Stripe', '']}
|
||||
customerId: String,
|
||||
dateCreated: Date,
|
||||
dateUpdated: Date,
|
||||
|
||||
@@ -299,16 +299,6 @@ module.exports = (swagger, v2) ->
|
||||
]
|
||||
action: user.unlock
|
||||
|
||||
"/user/buy-gems":
|
||||
spec: method: 'POST', description: "Do not use this route"
|
||||
middleware: auth.auth
|
||||
action:user.buyGems
|
||||
|
||||
"/user/cancel-subscription":
|
||||
spec: method: 'POST', description: "Do not use this route"
|
||||
middleware: auth.auth
|
||||
action:user.cancelSubscription
|
||||
|
||||
"/user/batch-update":
|
||||
spec:
|
||||
method: 'POST'
|
||||
|
||||
+7
-2
@@ -59,9 +59,14 @@ router.get('/static/extensions', function(req, res) {
|
||||
|
||||
// --------- PayPal --------
|
||||
|
||||
router.get('/paypal/checkout', user.paypalCheckout);
|
||||
router.get('/paypal/checkout', auth.authWithUrl, user.paypalCheckout);
|
||||
router.get('/paypal/checkout/success', user.paypalCheckoutSuccess);
|
||||
router.get('/paypal/subscribe', user.paypalSubscribe);
|
||||
router.get('/paypal/subscribe', auth.authWithUrl, user.paypalSubscribe);
|
||||
router.get('/paypal/subscribe/success', user.paypalSubscribeSuccess);
|
||||
router.get('/paypal/subscribe/cancel', auth.authWithUrl, user.paypalSubscribeCancel);
|
||||
|
||||
router.post("/stripe/checkout", auth.auth, user.stripeCheckout);
|
||||
//router.get("/stripe/subscribe", auth.authWithUrl, user.stripeSubscribe); // checkout route is used (above) with ?plan= instead
|
||||
router.get("/stripe/subscribe/cancel", auth.authWithUrl, user.stripeSubscribeCancel);
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user