Port most of the user related apis.
This commit is contained in:
parent
0e3fe8f3b1
commit
85eb585a85
5 changed files with 461 additions and 11 deletions
95
endpoints/api/subscribe.py
Normal file
95
endpoints/api/subscribe.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
import logging
|
||||
import stripe
|
||||
|
||||
from endpoints.api import request_error, log_action
|
||||
from data import model
|
||||
from data.plans import PLANS
|
||||
from util.http import abort
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def carderror_response(exc):
|
||||
return {'carderror': exc.message}, 402
|
||||
|
||||
|
||||
def subscription_view(stripe_subscription, used_repos):
|
||||
return {
|
||||
'currentPeriodStart': stripe_subscription.current_period_start,
|
||||
'currentPeriodEnd': stripe_subscription.current_period_end,
|
||||
'plan': stripe_subscription.plan.id,
|
||||
'usedPrivateRepos': used_repos,
|
||||
}
|
||||
|
||||
|
||||
def subscribe(user, plan, token, require_business_plan):
|
||||
plan_found = None
|
||||
for plan_obj in PLANS:
|
||||
if plan_obj['stripeId'] == plan:
|
||||
plan_found = plan_obj
|
||||
|
||||
if not plan_found or plan_found['deprecated']:
|
||||
logger.warning('Plan not found or deprecated: %s', plan)
|
||||
abort(404)
|
||||
|
||||
if (require_business_plan and not plan_found['bus_features'] and not
|
||||
plan_found['price'] == 0):
|
||||
logger.warning('Business attempting to subscribe to personal plan: %s',
|
||||
user.username)
|
||||
return request_error(message='No matching plan found')
|
||||
|
||||
private_repos = model.get_private_repo_count(user.username)
|
||||
|
||||
# This is the default response
|
||||
response_json = {
|
||||
'plan': plan,
|
||||
'usedPrivateRepos': private_repos,
|
||||
}
|
||||
status_code = 200
|
||||
|
||||
if not user.stripe_id:
|
||||
# Check if a non-paying user is trying to subscribe to a free plan
|
||||
if not plan_found['price'] == 0:
|
||||
# They want a real paying plan, create the customer and plan
|
||||
# simultaneously
|
||||
card = token
|
||||
|
||||
try:
|
||||
cus = stripe.Customer.create(email=user.email, plan=plan, card=card)
|
||||
user.stripe_id = cus.id
|
||||
user.save()
|
||||
log_action('account_change_plan', user.username, {'plan': plan})
|
||||
except stripe.CardError as e:
|
||||
return carderror_response(e)
|
||||
|
||||
response_json = subscription_view(cus.subscription, private_repos)
|
||||
status_code = 201
|
||||
|
||||
else:
|
||||
# Change the plan
|
||||
cus = stripe.Customer.retrieve(user.stripe_id)
|
||||
|
||||
if plan_found['price'] == 0:
|
||||
if cus.subscription is not None:
|
||||
# We only have to cancel the subscription if they actually have one
|
||||
cus.cancel_subscription()
|
||||
cus.save()
|
||||
log_action('account_change_plan', user.username, {'plan': plan})
|
||||
|
||||
else:
|
||||
# User may have been a previous customer who is resubscribing
|
||||
if token:
|
||||
cus.card = token
|
||||
|
||||
cus.plan = plan
|
||||
|
||||
try:
|
||||
cus.save()
|
||||
except stripe.CardError as e:
|
||||
return carderror_response(e)
|
||||
|
||||
response_json = subscription_view(cus.subscription, private_repos)
|
||||
log_action('account_change_plan', user.username, {'plan': plan})
|
||||
|
||||
return response_json, status_code
|
Reference in a new issue