Make Stripe configurable

This commit is contained in:
Mark Veidemanis 2022-10-13 18:20:30 +01:00
parent e631811090
commit 1bf938c33e
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
6 changed files with 100 additions and 6 deletions

View File

@ -38,3 +38,5 @@ if DEBUG:
"127.0.0.1",
"10.0.2.2",
]
SETTINGS_EXPORT = ["STRIPE_ENABLED"]

View File

@ -72,6 +72,7 @@ TEMPLATES = [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"core.util.django_settings_export.settings_export",
],
},
},

View File

@ -1,9 +1,10 @@
import logging
import stripe
from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.conf import settings
from core.lib.customers import get_or_create, update_customer_fields
logger = logging.getLogger(__name__)
@ -37,7 +38,9 @@ class User(AbstractUser):
"""
if settings.STRIPE_ENABLED:
if not self.stripe_id: # stripe ID not stored
self.stripe_id = get_or_create(self.email, self.first_name, self.last_name)
self.stripe_id = get_or_create(
self.email, self.first_name, self.last_name
)
to_update = {}
if self.email != self._original.email:

View File

@ -201,10 +201,12 @@
<a class="navbar-item" href="{% url 'home' %}">
Home
</a>
{% if user.is_authenticated %}
<a class="navbar-item" href="{% url 'billing' %}">
Billing
</a>
{% if settings.STRIPE_ENABLED %}
{% if user.is_authenticated %}
<a class="navbar-item" href="{% url 'billing' %}">
Billing
</a>
{% endif %}
{% endif %}
{% if user.is_superuser %}
<div class="navbar-item has-dropdown is-hoverable">

View File

@ -0,0 +1,78 @@
"""
Export Django settings to templates
https://github.com/jakubroztocil/django-settings-export
"""
from django.conf import settings as django_settings
from django.core.exceptions import ImproperlyConfigured
__version__ = '1.2.1'
VARIABLE_NAME = getattr(django_settings,
'SETTINGS_EXPORT_VARIABLE_NAME',
'settings')
class SettingsExportError(ImproperlyConfigured):
"""Base error indicating misconfiguration."""
class UndefinedSettingError(SettingsExportError):
"""An undefined setting name included in SETTINGS_EXPORT."""
class UnexportedSettingError(SettingsExportError):
"""An unexported setting has been accessed from a template."""
def settings_export(request):
"""
The template context processor that adds settings defined in
`SETTINGS_EXPORT` to the context. If SETTINGS_EXPORT_VARIABLE_NAME is not
set, the context variable will be `settings`.
"""
variable_name = getattr(django_settings,
'SETTINGS_EXPORT_VARIABLE_NAME',
'settings')
return {
variable_name: _get_exported_settings()
}
class ExportedSettings(dict):
def __getitem__(self, item):
"""Fail loudly if accessing a setting that is not exported."""
try:
return super(ExportedSettings, self).__getitem__(item)
except KeyError:
if hasattr(self, item):
# Let the KeyError propagate so that Django templates
# can access the existing attribute (e.g. `items()`).
raise
raise UnexportedSettingError(
'The `{key}` setting key is not accessible'
' from templates: add "{key}" to'
' `settings.SETTINGS_EXPORT` to change that.'
.format(key=item)
)
def _get_exported_settings():
exported_settings = ExportedSettings()
for key in getattr(django_settings, 'SETTINGS_EXPORT', []):
try:
value = getattr(django_settings, key)
except AttributeError:
raise UndefinedSettingError(
'"settings.%s" is included in settings.SETTINGS_EXPORT '
'but it does not exist. '
% key
)
exported_settings[key] = value
return exported_settings

View File

@ -30,6 +30,8 @@ class Billing(LoginRequiredMixin, View):
template_name = "billing.html"
async def get(self, request):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
plans = await sync_to_async(list)(Plan.objects.all())
user_plans = await sync_to_async(list)(request.user.plans.all())
context = {"plans": plans, "user_plans": user_plans}
@ -38,6 +40,8 @@ class Billing(LoginRequiredMixin, View):
class Order(LoginRequiredMixin, View):
async def get(self, request, plan_name):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
plan = Plan.objects.get(name=plan_name)
try:
cast = {
@ -63,6 +67,8 @@ class Order(LoginRequiredMixin, View):
class Cancel(LoginRequiredMixin, View):
async def get(self, request, plan_name):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
plan = Plan.objects.get(name=plan_name)
try:
subscriptions = stripe.Subscription.list(
@ -88,6 +94,8 @@ class Signup(CreateView):
class Portal(LoginRequiredMixin, View):
async def get(self, request):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
session = stripe.billing_portal.Session.create(
customer=request.user.stripe_id,
return_url=request.build_absolute_uri(reverse("billing")),