91 lines
3.5 KiB
C#
91 lines
3.5 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using PlotLine.Data;
|
|
using PlotLine.Models;
|
|
using PlotLine.Services;
|
|
using PlotLine.ViewModels;
|
|
|
|
namespace PlotLine.Controllers;
|
|
|
|
[AllowAnonymous]
|
|
public sealed class PricingController(
|
|
ICurrentUserService currentUser,
|
|
IUserRepository users,
|
|
ISubscriptionService subscriptions,
|
|
IStripeBillingService stripeBilling,
|
|
IConfiguration configuration) : Controller
|
|
{
|
|
[HttpGet("pricing", Name = PublicRouteNames.Pricing)]
|
|
public async Task<IActionResult> Index()
|
|
{
|
|
const string description = "Compare PlotDirector plans and choose the right subscription for organising your novel, series, characters, plot threads, timelines, and story details.";
|
|
ViewData["SeoTitle"] = "Pricing | PlotDirector";
|
|
ViewData["SeoDescription"] = description;
|
|
ViewData["SeoKeywords"] = "novel planning software, writing software, story planning app, author tools, plot tracking, character tracking, story timeline, novel organisation, fiction writing software, series writing software, continuity tracking, plot threads, story bible";
|
|
ViewData["CanonicalUrl"] = PublicSeo.AbsoluteUrl(configuration, "/pricing");
|
|
ViewData["StructuredData"] = new[]
|
|
{
|
|
PublicSeo.WebPageJsonLd(configuration, "WebPage", "Pricing", "/pricing", description)
|
|
};
|
|
|
|
UserSubscriptionDetail? currentSubscription = null;
|
|
if (currentUser.UserId is int userId)
|
|
{
|
|
currentSubscription = await subscriptions.GetCurrentSubscriptionAsync(userId);
|
|
}
|
|
|
|
return View(new PricingViewModel
|
|
{
|
|
Plans = await subscriptions.GetActiveSubscriptionLevelsAsync(),
|
|
CurrentSubscriptionLevelID = currentSubscription?.SubscriptionLevelID,
|
|
IsSignedIn = currentUser.UserId.HasValue
|
|
});
|
|
}
|
|
|
|
[HttpGet]
|
|
public IActionResult StartTrial()
|
|
{
|
|
if (!currentUser.UserId.HasValue)
|
|
{
|
|
return RedirectToAction("Register", "Account");
|
|
}
|
|
|
|
return RedirectToAction("Subscription", "ManageAccount");
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<IActionResult> Checkout(int id, string billingInterval = "Monthly")
|
|
{
|
|
if (!currentUser.UserId.HasValue)
|
|
{
|
|
var returnUrl = Url.Action(nameof(Checkout), "Pricing", new { id, billingInterval }) ?? "/pricing";
|
|
return RedirectToAction("Login", "Account", new { returnUrl });
|
|
}
|
|
|
|
var user = await users.GetByIdAsync(currentUser.UserId.Value);
|
|
if (user is null)
|
|
{
|
|
return RedirectToAction("Login", "Account");
|
|
}
|
|
|
|
var request = new StripeCheckoutRequest
|
|
{
|
|
SubscriptionLevelID = id,
|
|
BillingInterval = string.Equals(billingInterval, "Annual", StringComparison.OrdinalIgnoreCase)
|
|
? "Annual"
|
|
: "Monthly"
|
|
};
|
|
|
|
var successUrl = Url.Action("SubscriptionSuccess", "ManageAccount", null, Request.Scheme) ?? string.Empty;
|
|
var cancelUrl = Url.Action(nameof(Index), "Pricing", null, Request.Scheme) ?? string.Empty;
|
|
var result = await stripeBilling.StartCheckoutOrChangePlanAsync(user, request, successUrl, cancelUrl);
|
|
if (result.Succeeded && !string.IsNullOrWhiteSpace(result.RedirectUrl))
|
|
{
|
|
return Redirect(result.RedirectUrl);
|
|
}
|
|
|
|
TempData["PricingMessage"] = result.Message;
|
|
return RedirectToAction(nameof(Index));
|
|
}
|
|
}
|