Allow year sub purchases on top of monthly subs

Monthly sub is cancelled, terminal sub of 1 year + remaining month is
added.
This commit is contained in:
Matt Lott 2015-08-27 09:45:05 -07:00
parent 5faeb82d17
commit e10c5d9646
3 changed files with 116 additions and 39 deletions

View file

@ -33,7 +33,7 @@ module.exports = class SubscriptionSaleView extends RootView
getRenderData: ->
c = super()
c.hasSubscription = me.get('stripe')?.sponsorID or me.get('stripe')?.subscriptionID
c.hasSubscription = me.get('stripe')?.sponsorID
c.heroes = @heroes.models
c.payButtonText = @payButtonText
c.saleEndDate = @saleEndDate

View file

@ -120,56 +120,77 @@ class SubscriptionHandler extends Handler
purchaseYearSale: (req, res) ->
return @sendForbiddenError(res) unless req.user?
return @sendForbiddenError(res) if req.user?.get('stripe')?.sponsorID
return @sendForbiddenError(res) if req.user?.get('stripe')?.subscriptionID
cancelSubscriptionImmediately = (user, subscription, done) =>
return done() unless user and subscription
stripe.customers.cancelSubscription subscription.customer, subscription.id, (err) =>
return done(err) if err
stripeInfo = _.cloneDeep(user.get('stripe') ? {})
delete stripeInfo.planID
delete stripeInfo.prepaidCode
delete stripeInfo.subscriptionID
user.set('stripe', stripeInfo)
user.save (err) =>
return done(err) if err
done()
StripeUtils.getCustomer req.user, req.body.stripe?.token, (err, customer) =>
if err
@logSubscriptionError(req.user, "Purchase year sale get customer: #{JSON.stringify(err)}")
return @sendDatabaseError(res, err)
metadata =
type: req.body.type
userID: req.user._id + ''
gems: subscriptions.basic.gems * 12
timestamp: parseInt(req.body.stripe?.timestamp)
description: req.body.description
StripeUtils.createCharge req.user, subscriptions.year_sale.amount, metadata, (err, charge) =>
if err
@logSubscriptionError(req.user, "Purchase year sale create charge: #{JSON.stringify(err)}")
return @sendDatabaseError(res, err)
findStripeSubscription customer.id, subscriptionID: req.user.get('stripe')?.subscriptionID, (subscription) =>
stripeSubscriptionPeriodEndDate = new Date(subscription.current_period_end * 1000) if subscription
StripeUtils.createPayment req.user, charge, (err, payment) =>
cancelSubscriptionImmediately req.user, subscription, (err) =>
if err
@logSubscriptionError(req.user, "Purchase year sale create payment: #{JSON.stringify(err)}")
@logSubscriptionError(user, "Purchase year sale Stripe cancel subscription error: #{JSON.stringify(err)}")
return @sendDatabaseError(res, err)
metadata =
type: req.body.type
userID: req.user._id + ''
gems: subscriptions.basic.gems * 12
timestamp: parseInt(req.body.stripe?.timestamp)
description: req.body.description
# Add terminal subscription to User
stripeInfo = _.cloneDeep(req.user.get('stripe') ? {})
endDate = new Date()
if _.isString(stripeInfo.free) and new Date() < new Date(stripeInfo.free)
# Extend end date by remaining terminal subscription
endDate = new Date(stripeInfo.free)
endDate.setUTCFullYear(endDate.getUTCFullYear() + 1)
stripeInfo.free = endDate.toISOString().substring(0, 10)
req.user.set('stripe', stripeInfo)
# Add year's worth of gems to User
purchased = _.clone(req.user.get('purchased'))
purchased ?= {}
purchased.gems ?= 0
purchased.gems += parseInt(charge.metadata.gems)
req.user.set('purchased', purchased)
req.user.save (err, user) =>
StripeUtils.createCharge req.user, subscriptions.year_sale.amount, metadata, (err, charge) =>
if err
@logSubscriptionError(req.user, "User save error: #{JSON.stringify(err)}")
@logSubscriptionError(req.user, "Purchase year sale create charge: #{JSON.stringify(err)}")
return @sendDatabaseError(res, err)
try
msg = "Year subscription purchased by #{req.user.get('email')} #{req.user.id}"
hipchat.sendHipChatMessage msg, ['tower']
catch error
@logSubscriptionError(req.user, "Year sub sale HipChat tower msg error: #{JSON.stringify(error)}")
@sendSuccess(res, user)
StripeUtils.createPayment req.user, charge, (err, payment) =>
if err
@logSubscriptionError(req.user, "Purchase year sale create payment: #{JSON.stringify(err)}")
return @sendDatabaseError(res, err)
# Add terminal subscription to User with extensions for existing subscriptions
stripeInfo = _.cloneDeep(req.user.get('stripe') ? {})
endDate = new Date()
if stripeSubscriptionPeriodEndDate
endDate = stripeSubscriptionPeriodEndDate
else if _.isString(stripeInfo.free) and new Date() < new Date(stripeInfo.free)
endDate = new Date(stripeInfo.free)
endDate.setUTCFullYear(endDate.getUTCFullYear() + 1)
stripeInfo.free = endDate.toISOString().substring(0, 10)
req.user.set('stripe', stripeInfo)
# Add year's worth of gems to User
purchased = _.clone(req.user.get('purchased'))
purchased ?= {}
purchased.gems ?= 0
purchased.gems += parseInt(charge.metadata.gems)
req.user.set('purchased', purchased)
req.user.save (err, user) =>
if err
@logSubscriptionError(req.user, "User save error: #{JSON.stringify(err)}")
return @sendDatabaseError(res, err)
try
msg = "Year subscription purchased by #{req.user.get('email')} #{req.user.id}"
hipchat.sendHipChatMessage msg, ['tower']
catch error
@logSubscriptionError(req.user, "Year sub sale HipChat tower msg error: #{JSON.stringify(error)}")
@sendSuccess(res, user)
subscribeUser: (req, user, done) ->
if (not req.user) or req.user.isAnonymous() or user.isAnonymous()

View file

@ -1501,3 +1501,59 @@ describe 'Subscriptions', ->
expect(payment).toBeDefined()
expect(payment.get('gems')).toEqual(3500*12)
done()
it 'year_sale with monthly sub', (done) ->
stripe.tokens.create {
card: { number: '4242424242424242', exp_month: 12, exp_year: 2020, cvc: '123' }
}, (err, token) ->
loginNewUser (user1) ->
subscribeUser user1, token, null, ->
User.findById user1.id, (err, user1) ->
expect(err).toBeNull()
stripeInfo = user1.get('stripe')
stripe.customers.retrieveSubscription stripeInfo.customerID, stripeInfo.subscriptionID, (err, subscription) ->
expect(err).toBeNull()
expect(subscription).not.toBeNull()
stripeSubscriptionPeriodEndDate = new Date(subscription.current_period_end * 1000)
stripe.tokens.create {
card: { number: '4242424242424242', exp_month: 12, exp_year: 2020, cvc: '123' }
}, (err, token) ->
requestBody =
stripe:
token: token.id
timestamp: new Date()
request.put {uri: "#{subscriptionURL}/-/year_sale", json: requestBody, headers: headers }, (err, res) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
User.findById user1.id, (err, user1) ->
expect(err).toBeNull()
stripeInfo = user1.get('stripe')
expect(stripeInfo).toBeDefined()
return done() unless stripeInfo
endDate = stripeSubscriptionPeriodEndDate
endDate.setUTCFullYear(endDate.getUTCFullYear() + 1)
expect(stripeInfo.free).toEqual(endDate.toISOString().substring(0, 10))
expect(stripeInfo.customerID).toBeDefined()
expect(user1.get('purchased')?.gems).toEqual(3500+3500*12)
Payment.findOne 'stripe.customerID': stripeInfo.customerID, (err, payment) ->
expect(err).toBeNull()
expect(payment).toBeDefined()
expect(payment.get('gems')).toEqual(3500*12)
done()
it 'year_sale with sponsored sub', (done) ->
stripe.tokens.create {
card: { number: '4242424242424242', exp_month: 12, exp_year: 2020, cvc: '123' }
}, (err, token) ->
loginNewUser (user1) ->
user1.set('stripe', {sponsorID: 'dummyID'})
user1.save (err, user1) ->
expect(err).toBeNull()
requestBody =
stripe:
token: token.id
timestamp: new Date()
request.put {uri: "#{subscriptionURL}/-/year_sale", json: requestBody, headers: headers }, (err, res) ->
console.log err
expect(err).toBeNull()
done()