mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
Added renewals of subscriptions
This commit is contained in:
parent
ef5e5cd82a
commit
98c99b3336
@ -32,6 +32,7 @@ namespace Teknik.BillingCore
|
||||
public abstract Subscription GetSubscription(string subscriptionId);
|
||||
public abstract Subscription CreateSubscription(string customerId, string priceId);
|
||||
public abstract Subscription EditSubscriptionPrice(string subscriptionId, string priceId);
|
||||
public abstract Subscription RenewSubscription(string subscriptionId);
|
||||
public abstract bool CancelSubscription(string subscriptionId, bool atEndOfPeriod);
|
||||
|
||||
public abstract CheckoutSession CreateCheckoutSession(string customerId, string priceId, string successUrl, string cancelUrl);
|
||||
|
@ -11,6 +11,8 @@ namespace Teknik.BillingCore.Models
|
||||
public string Id { get; set; }
|
||||
public string CustomerId { get; set; }
|
||||
public SubscriptionStatus Status { get; set; }
|
||||
public DateTime BillingPeriodEnd { get; set; }
|
||||
public bool CancelAtBillingEnd { get; set; }
|
||||
public List<Price> Prices { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
}
|
||||
|
@ -230,6 +230,27 @@ namespace Teknik.BillingCore
|
||||
return null;
|
||||
}
|
||||
|
||||
public override Models.Subscription RenewSubscription(string subscriptionId)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(subscriptionId))
|
||||
{
|
||||
var subscriptionService = new SubscriptionService();
|
||||
var subscription = subscriptionService.Get(subscriptionId);
|
||||
if (subscription != null)
|
||||
{
|
||||
var subscriptionOptions = new SubscriptionUpdateOptions()
|
||||
{
|
||||
CancelAtPeriodEnd = false
|
||||
};
|
||||
subscriptionOptions.AddExpand("latest_invoice.payment_intent");
|
||||
var result = subscriptionService.Update(subscriptionId, subscriptionOptions);
|
||||
if (result != null)
|
||||
return ConvertSubscription(result);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool CancelSubscription(string subscriptionId, bool atEndOfperiod)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(subscriptionId))
|
||||
@ -454,6 +475,8 @@ namespace Teknik.BillingCore
|
||||
Id = subscription.Id,
|
||||
CustomerId = subscription.CustomerId,
|
||||
Status = status,
|
||||
BillingPeriodEnd = subscription.CurrentPeriodEnd,
|
||||
CancelAtBillingEnd = subscription.CancelAtPeriodEnd,
|
||||
Prices = prices,
|
||||
ClientSecret = subscription.LatestInvoice?.PaymentIntent?.ClientSecret
|
||||
};
|
||||
|
@ -386,6 +386,8 @@ namespace Teknik.Areas.Users.Controllers
|
||||
Storage = price.Storage,
|
||||
Price = price.Amount,
|
||||
Interval = price.Interval.ToString(),
|
||||
BillingPeriodEnd = sub.BillingPeriodEnd,
|
||||
Canceled = sub.CancelAtBillingEnd
|
||||
};
|
||||
model.Subscriptions.Add(subView);
|
||||
}
|
||||
@ -1499,7 +1501,7 @@ namespace Teknik.Areas.Users.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult CancelSubscription(string subscriptionId, string productId)
|
||||
public IActionResult CancelSubscription(string subscriptionId)
|
||||
{
|
||||
// Get Subscription Info
|
||||
var billingService = BillingFactory.GetBillingService(_config.BillingConfig);
|
||||
@ -1508,13 +1510,6 @@ namespace Teknik.Areas.Users.Controllers
|
||||
if (subscription == null)
|
||||
return Json(new { error = "Invalid Subscription Id" });
|
||||
|
||||
if (!subscription.Prices.Exists(p => p.ProductId == productId))
|
||||
return Json(new { error = "Subscription does not relate to product" });
|
||||
|
||||
var product = billingService.GetProduct(productId);
|
||||
if (product == null)
|
||||
return Json(new { error = "Product does not exist" });
|
||||
|
||||
var result = billingService.CancelSubscription(subscriptionId, true);
|
||||
|
||||
if (result)
|
||||
@ -1522,5 +1517,25 @@ namespace Teknik.Areas.Users.Controllers
|
||||
|
||||
return Json(new { error = "Unable to cancel subscription" });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult RenewSubscription(string subscriptionId)
|
||||
{
|
||||
// Get Subscription Info
|
||||
var billingService = BillingFactory.GetBillingService(_config.BillingConfig);
|
||||
|
||||
var subscription = billingService.GetSubscription(subscriptionId);
|
||||
if (subscription == null)
|
||||
return Json(new { error = "Invalid Subscription Id" });
|
||||
|
||||
var result = billingService.RenewSubscription(subscriptionId);
|
||||
|
||||
if (result != null &&
|
||||
!result.CancelAtBillingEnd)
|
||||
return Json(new { result = true });
|
||||
|
||||
return Json(new { error = "Unable to cancel subscription" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,5 +19,9 @@ namespace Teknik.Areas.Users.ViewModels
|
||||
public string Interval { get; set; }
|
||||
|
||||
public long Storage { get; set; }
|
||||
|
||||
public DateTime BillingPeriodEnd { get; set; }
|
||||
|
||||
public bool Canceled { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
}
|
||||
|
||||
<script>
|
||||
var cancelSubscriptionURL = '@Url.SubRouteUrl("billing", "User.Action", new { action = "CancelSubscription" })';
|
||||
var cancelSubscriptionURL = '@Url.SubRouteUrl("account", "User.Action", new { action = "CancelSubscription" })';
|
||||
var renewSubscriptionURL = '@Url.SubRouteUrl("account", "User.Action", new { action = "RenewSubscription" })';
|
||||
</script>
|
||||
|
||||
@if (Config.BillingConfig.Enabled)
|
||||
@ -28,7 +29,7 @@
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<h2>Active Subscriptions</h2>
|
||||
<h2>Current Subscriptions</h2>
|
||||
<hr />
|
||||
</div>
|
||||
</div>
|
||||
@ -41,8 +42,24 @@
|
||||
foreach (var subscription in Model.Subscriptions)
|
||||
{
|
||||
<li class="list-group-item" id="@subscription.SubscriptionId">
|
||||
<div class="pull-left">
|
||||
<h4 class="list-group-item-heading pull-left">@subscription.ProductName: <strong>@(StringHelper.GetBytesReadable(subscription.Storage))</strong> for <strong>@($"${subscription.Price:0.00} / {subscription.Interval}")</strong></h4>
|
||||
<button role="button" class="btn btn-danger cancel-subscription-button pull-right" data-subscription-id="@subscription.SubscriptionId" data-product-id="@subscription.ProductId">Cancel Subscription</button>
|
||||
<p>
|
||||
@if (subscription.Canceled)
|
||||
{
|
||||
@:<strong>Canceled</strong> -
|
||||
}
|
||||
Billing period ends @(subscription.BillingPeriodEnd.ToShortDateString()).
|
||||
</p>
|
||||
</div>
|
||||
@if (subscription.Canceled)
|
||||
{
|
||||
<button role="button" class="btn btn-primary renew-subscription-button pull-right" data-subscription-id="@subscription.SubscriptionId">Renew Subscription</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button role="button" class="btn btn-danger cancel-subscription-button pull-right" data-subscription-id="@subscription.SubscriptionId">Cancel Subscription</button>
|
||||
}
|
||||
<div class="clearfix"></div>
|
||||
</li>
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
/* globals cancelSubscriptionURL */
|
||||
/* globals cancelSubscriptionURL, renewSubscriptionURL */
|
||||
$(document).ready(function () {
|
||||
$('.cancel-subscription-button').click(function () {
|
||||
disableButton('#cancel_subscription', 'Canceling Subscription...');
|
||||
|
||||
var subscriptionId = $(this).data('subscription-id');
|
||||
var productId = $(this).data('product-id');
|
||||
|
||||
confirmDialog('Confirm', 'Back', 'Are you sure you want to cancel your subscription? Your plan will be canceled, but is still available until the end of your billing period.', function (result) {
|
||||
confirmDialog('Confirm', 'Back', 'Are you sure you want to cancel your subscription?<br /><br />Your plan will be canceled, but is still available until the end of your billing period.', function (result) {
|
||||
if (result) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: cancelSubscriptionURL,
|
||||
data: AddAntiForgeryToken({ subscriptionId: subscriptionId, productId: productId }),
|
||||
data: AddAntiForgeryToken({ subscriptionId: subscriptionId }),
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
@ -38,4 +37,42 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.renew-subscription-button').click(function () {
|
||||
disableButton('#renew_subscription', 'Renewing Subscription...');
|
||||
|
||||
var subscriptionId = $(this).data('subscription-id');
|
||||
|
||||
confirmDialog('Renew', 'Back', 'Are you sure you want to renew your subscription?', function (result) {
|
||||
if (result) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: renewSubscriptionURL,
|
||||
data: AddAntiForgeryToken({ subscriptionId: subscriptionId }),
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
xhrFields: {
|
||||
withCredentials: true
|
||||
},
|
||||
success: function (response) {
|
||||
if (response.result) {
|
||||
$("#top_msg").css('display', 'inline', 'important');
|
||||
$("#top_msg").html('<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>Subscription renewed successfully!</div>');
|
||||
}
|
||||
else {
|
||||
$("#top_msg").css('display', 'inline', 'important');
|
||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>');
|
||||
}
|
||||
},
|
||||
error: function (response) {
|
||||
$("#top_msg").css('display', 'inline', 'important');
|
||||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response.responseText) + '</div>');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
enableButton('#renew_subscription', 'Renew Subscription');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user