Allow users to cancel subscriptions.

master
Nick Sergeant 2014-05-23 09:13:43 -04:00
parent 70741db210
commit 552e168a5f
5 changed files with 100 additions and 34 deletions

View File

@ -4,6 +4,7 @@ from accounts import views
urlpatterns = patterns('',
url(r'^stats/$', views.stats, name='account-stats'),
url(r'^cancel-subscription/$', views.cancel_subscription, name='cancel-subscription'),
url(r'^stripe-account-details/$', views.stripe_account_details, name='stripe-account-details'),
url(r'^', views.account, name='account-detail'),
)

View File

@ -13,6 +13,24 @@ def account(request):
return {}
@login_required
@ajax_request
def cancel_subscription(request):
if request.user.profile.stripe_id is None:
return {}
else:
stripe.api_key = STRIPE_SECRET_KEY
customer = stripe.Customer.retrieve(request.user.profile.stripe_id)
customer.delete()
profile = request.user.profile
profile.is_pro = False
profile.stripe_id = None
profile.save()
return { 'deleted': True }
@login_required
@ajax_request
def stripe_account_details(request):

File diff suppressed because one or more lines are too long

View File

@ -39,6 +39,18 @@ if (typeof angular !== 'undefined') {
// Services.
app.factory('AccountStorage', function($http) {
return {
cancelSubscription: function() {
var promise = $http({
method: 'GET',
url: '/account/cancel-subscription/',
headers: {
'Authorization': 'ApiKey ' + window.user + ':' + window.api_key
}
});
return promise;
},
getAccount: function() {
var promise = $http({
@ -85,8 +97,23 @@ if (typeof angular !== 'undefined') {
});
// Controllers.
controllers.BillingController = function($scope) {
controllers.BillingController = function($scope, AccountStorage) {
$scope.section = 'Billing';
$scope.cancelSubscription = function() {
if (confirm('Are you sure you want to cancel your subscription?\n\nYou will no longer be able to create new Snipts. Your existing snipts will still be accessible. This action is effective immediately and we unfortunately cannot issue any refunds.')) {
$scope.cancelled = true;
$scope.cancelling = true;
AccountStorage.cancelSubscription().then(function(response) {
if (response.data.deleted) {
$scope.cancelling = false;
} else {
$scope.cancelling = false;
$scope.cancelled = false;
}
});
}
};
};
controllers.BloggingController = function($scope) {
$scope.fields = [

View File

@ -1,34 +1,54 @@
<div ng-show="!user.is_pro">
<p class="alert alert-info">
You're not a Pro yet, so we have nothing to show you here.<br />
<br /><a href="/pro/">Signup for Pro &raquo;</a>
<div ng-show="cancelled">
<div ng-show="cancelling">
<p class="alert alert-info group">
Sit tight, we're cancelling your subscription...
</p>
</div>
<div ng-show="!cancelling">
<p class="alert alert-info group">
You have successfully cancelled your subscription.<br />You will no longer be billed.
</p>
<p style="padding: 15px; padding-top: 0; margin-top: 0; line-height: 21px;">
We're very sorry to see you go. Mind dropping us a quick email to <a href="mailto:support@snipt.net">support@snipt.net</a>
to let us know why you cancelled? We'd really appreciate it.
</p>
</div>
</div>
<div ng-show="user.is_pro">
<div class="def" data-title="Plan" ng-show="user.stripeAccount.status != 'inactive'">
{[{ user.stripeAccount.name || 'Loading...' }]}
</div>
<div class="def" data-title="Plan" ng-show="user.stripeAccount.status == 'inactive'">
One-time payment
</div>
<div class="def" data-title="Price" ng-show="user.stripeAccount.status != 'inactive'">
<span ng-show="user.stripeAccount">${[{ user.stripeAccount.amount / 100 }]}.00 USD / {[{ user.stripeAccount.interval }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<div class="def" data-title="Card" ng-show="user.stripeAccount.status != 'inactive'">
<span ng-show="user.stripeAccount">xxxx-xxxx-xxxx-{[{ user.stripeAccount.last4 || 'Loading...' }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<div class="def" data-title="Status" ng-show="user.stripeAccount.status != 'inactive'">
{[{ user.stripeAccount.status || 'Loading...' }]}
</div>
<div class="def" data-title="Pro since">
<span ng-show="user.stripeAccount">{[{ user.stripeAccount.created * 1000 |date:'fullDate' }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<div class="def" data-title="Next bill date" ng-show="user.stripeAccount.status != 'inactive'">
<span ng-show="user.stripeAccount">{[{ user.stripeAccount.nextBill * 1000 |date:'fullDate' }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<p class="alert alert-info" ng-show="user.stripeAccount.status != 'inactive'">Need to cancel? <a href="mailto:nick@snipt.net">Email Nick</a>.</p>
<div ng-show="!cancelled">
<div ng-show="!user.is_pro">
<p class="alert alert-info">
You're not a Pro yet, so we have nothing to show you here.<br />
<br /><a class="btn btn-success" href="/pro/">Signup for Pro &raquo;</a>
</p>
</div>
<div ng-show="user.is_pro">
<div class="def" data-title="Plan" ng-show="user.stripeAccount.status != 'inactive'">
{[{ user.stripeAccount.name || 'Loading...' }]}
</div>
<div class="def" data-title="Plan" ng-show="user.stripeAccount.status == 'inactive'">
One-time payment
</div>
<div class="def" data-title="Price" ng-show="user.stripeAccount.status != 'inactive'">
<span ng-show="user.stripeAccount">${[{ user.stripeAccount.amount / 100 }]}.00 USD / {[{ user.stripeAccount.interval }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<div class="def" data-title="Card" ng-show="user.stripeAccount.status != 'inactive'">
<span ng-show="user.stripeAccount">xxxx-xxxx-xxxx-{[{ user.stripeAccount.last4 || 'Loading...' }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<div class="def" data-title="Status" ng-show="user.stripeAccount.status != 'inactive'">
{[{ user.stripeAccount.status || 'Loading...' }]}
</div>
<div class="def" data-title="Pro since">
<span ng-show="user.stripeAccount">{[{ user.stripeAccount.created * 1000 |date:'fullDate' }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<div class="def" data-title="Next bill date" ng-show="user.stripeAccount.status != 'inactive'">
<span ng-show="user.stripeAccount">{[{ user.stripeAccount.nextBill * 1000 |date:'fullDate' }]}</span>
<span ng-show="!user.stripeAccount">Loading...</span>
</div>
<p class="alert alert-info group" style="padding-right: 8px;" ng-show="user.stripeAccount.status != 'inactive'">
<a ng-click="cancelSubscription()" class="btn btn-danger pull-right">Cancel subscription</a>
</p>
</div>
</div>