### Start Trial Period Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Initiates a 14-day trial period for users who do not have an active subscription or trial. This endpoint requires a POST request. ```APIDOC ## POST /dashboard/subscription/trial/ ### Description Initiates a 14-day trial period for users without active subscriptions. ### Method POST ### Endpoint /dashboard/subscription/trial/ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) Redirects to the dashboard settings page with a success message. #### Response Example None ``` -------------------------------- ### Start Trial Period for User in Django Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Initiates a 14-day trial period for users who do not have an active subscription or trial. This Django view requires authentication and handles POST requests. It sets the subscription status to 'trial', calculates the trial end date, and provides user feedback before redirecting. ```python # apps/dashboard/views.py from django.shortcuts import redirect from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.utils import timezone from django.contrib import messages from .models import UserSettings @login_required @require_http_methods(['POST']) def start_trial(request): user_settings = UserSettings.objects.get(user=request.user) if user_settings.is_subscription_active or user_settings.is_trial_active: messages.warning(request, 'You already have an active subscription or trial.') return redirect('dashboard:subscription_plans') user_settings.subscription_status = 'trial' user_settings.trial_end_date = timezone.now() + timezone.timedelta(days=14) user_settings.save() messages.success(request, 'Trial period started successfully.') return redirect('dashboard:settings') # URL: POST /dashboard/subscription/trial/ -> dashboard:start_trial # Trial duration: 14 days ``` -------------------------------- ### Display Subscription Plans (Django Template) Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/dashboard/subscription_plans.html This Django template snippet iterates through available subscription plans, displaying their name, description, price, and interval. It also shows included features for each plan and provides options to subscribe or start a free trial. ```django {% extends "dashboard/base.html" %} {% block title %}Subscription Plans - SaaS Platform{% endblock %} {% block dashboard_content %} CHOOSE YOUR PLAN ---------------- Select the plan that best fits your needs {% if is_trial_active %} ### TRIAL PERIOD ACTIVE Your trial period ends on {{ trial_end_date|date:"F j, Y" }}. Choose a plan to continue using the service. {% endif %} {% for plan in plans %} {{ plan.name }} --------------- {{ plan.description }} ${{ plan.price }} /{{ plan.interval }} {% csrf_token %} {% if current_plan == plan %} CURRENT PLAN {% else %} SUBSCRIBE {% endif %} ### WHAT'S INCLUDED {% for feature in plan.features %}* {{ feature }} {% endfor %} {% endfor %} {% if not is_subscription_active and not is_trial_active %} {% csrf_token %} START 14-DAY FREE TRIAL {% endif %} {% endblock %} ``` -------------------------------- ### Create Stripe Subscription with Payment Intent in Django Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Handles the creation of a new Stripe subscription. It first checks if a Stripe customer exists for the user; if not, it creates one. Then, it creates a Stripe subscription using the provided price ID and payment behavior, expanding the latest invoice to get the payment intent client secret. The function returns a JSON response containing the subscription ID and client secret for frontend confirmation. ```python # apps/subscriptions/views.py import stripe from django.conf import settings from django.contrib.auth.decorators import login_required from django.http import JsonResponse from django.shortcuts import redirect from .models import StripeCustomer stripe.api_key = settings.STRIPE_SECRET_KEY @login_required def create_subscription(request): if request.method == 'POST': try: stripe_customer = StripeCustomer.objects.get(user=request.user) customer = stripe_customer.stripe_customer_id except StripeCustomer.DoesNotExist: customer = stripe.Customer.create( email=request.user.email, source=request.POST['stripeToken'] ) stripe_customer = StripeCustomer.objects.create( user=request.user, stripe_customer_id=customer.id ) subscription = stripe.Subscription.create( customer=customer, items=[{'price': settings.STRIPE_PRICE_ID}], payment_behavior='default_incomplete', expand=['latest_invoice.payment_intent'], ) stripe_customer.stripe_subscription_id = subscription.id stripe_customer.subscription_status = subscription.status stripe_customer.save() return JsonResponse({ 'subscription_id': subscription.id, 'client_secret': subscription.latest_invoice.payment_intent.client_secret, }) return redirect('subscription_page') # URL: POST /subscriptions/create/ -> subscriptions:create_subscription # POST data: stripeToken (from Stripe.js) # Returns: JSON with subscription_id and client_secret for frontend confirmation ``` -------------------------------- ### Django User Profile Management Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Allows users to view and update their profile information, including first and last names. Supports both GET requests for display and POST requests for updates, with success messages upon completion. ```python # apps/dashboard/views.py from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.contrib import messages @login_required @require_http_methods(['GET', 'POST']) def profile(request): if request.method == 'POST': user = request.user user.first_name = request.POST.get('first_name', '') user.last_name = request.POST.get('last_name', '') user.save() messages.success(request, 'Profile updated successfully.') return redirect('dashboard:profile') return render(request, 'dashboard/profile.html') # URL: GET/POST /dashboard/profile/ -> dashboard:profile # POST data: first_name, last_name # Success: Redirects with success message ``` -------------------------------- ### Environment Configuration (.env) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Lists the required environment variables for the Django application. This includes settings for Django itself (DEBUG, SECRET_KEY), database connection (optional PostgreSQL configuration), email services, and Stripe API keys. Users should copy `.env.example` to `.env` and fill in their specific values. ```bash # .env configuration # Django Settings DEBUG=True SECRET_KEY=your-secret-key-here ALLOWED_HOSTS=localhost,127.0.0.1 # Database (default SQLite, configure for PostgreSQL) # DB_ENGINE=django.db.backends.postgresql # DB_NAME=your_db_name # DB_USER=your_db_user # DB_PASSWORD=your_db_password # DB_HOST=localhost # DB_PORT=5432 # Email Configuration EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend EMAIL_HOST=smtp.gmail.com EMAIL_PORT=587 EMAIL_USE_TLS=True EMAIL_HOST_USER=your-email@gmail.com EMAIL_HOST_PASSWORD=your-app-password # Stripe Configuration STRIPE_PUBLIC_KEY=pk_test_xxx STRIPE_SECRET_KEY=sk_test_xxx STRIPE_WEBHOOK_SECRET=whsec_xxx STRIPE_PRICE_ID=price_xxx ``` -------------------------------- ### List Subscription Plans in Django Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Displays all active subscription plans available to users. It fetches active `SubscriptionPlan` objects and the current user's subscription details from `UserSettings`. The context passed to the template includes plans, current plan, and subscription status. ```python from django.shortcuts import render from django.contrib.auth.decorators import login_required from .models import UserSettings, SubscriptionPlan @login_required def subscription_plans(request): plans = SubscriptionPlan.objects.filter(is_active=True) user_settings = UserSettings.objects.get(user=request.user) context = { 'plans': plans, 'current_plan': user_settings.subscription_plan, 'subscription_status': user_settings.subscription_status, 'is_subscription_active': user_settings.is_subscription_active, 'is_trial_active': user_settings.is_trial_active, } return render(request, 'dashboard/subscription_plans.html', context) # URL: GET /dashboard/subscription/plans/ -> dashboard:subscription_plans # Context includes: plans queryset, current user subscription status ``` -------------------------------- ### Define Subscription Plan Database Model (Python) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Defines the 'SubscriptionPlan' model for storing details about different subscription tiers. Includes fields for name, slug, description, price, billing interval, features, and active status. Uses Django's ORM for database interaction. ```python # apps/dashboard/models.py from django.db import models class SubscriptionPlan(models.Model): name = models.CharField(max_length=100) # e.g., "Pro", "Enterprise" slug = models.SlugField(unique=True) # e.g., "pro-monthly" description = models.TextField() price = models.DecimalField(max_digits=10, decimal_places=2) interval = models.CharField( max_length=20, choices=[('monthly', 'Monthly'), ('yearly', 'Yearly')], default='monthly' ) features = models.JSONField(default=list) # ["Feature 1", "Feature 2"] is_active = models.BooleanField(default=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) # Example usage: # plan = SubscriptionPlan.objects.create( # name="Pro", # slug="pro-monthly", # description="Professional tier with all features", # price=29.99, # interval="monthly", # features=["Unlimited projects", "Priority support", "API access"] # ) ``` -------------------------------- ### Subscription Routes Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Endpoints for managing Stripe subscriptions and handling webhooks. ```APIDOC ## Subscription Routes ### Description Endpoints for managing Stripe subscriptions and processing webhook events. ### Method GET ### Endpoint /subscriptions/ ### Description Display the Stripe subscription page. ### Method POST ### Endpoint /subscriptions/create/ ### Description Create a new Stripe subscription. ### Method POST ### Endpoint /subscriptions/webhook/ ### Description Stripe webhook endpoint to receive payment events. ``` -------------------------------- ### Define User Settings Model with Subscription Status (Python) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Defines the 'UserSettings' model to store user-specific preferences, notification settings, API keys, and subscription details. Includes computed properties to easily check active subscription and trial status. Relates to the 'User' model and 'SubscriptionPlan' model. ```python # apps/dashboard/models.py from django.db import models from django.conf import settings from django.utils import timezone class UserSettings(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) # Notification preferences notify_comments = models.BooleanField(default=False) notify_updates = models.BooleanField(default=False) notify_marketing = models.BooleanField(default=False) # API settings api_key = models.CharField(max_length=64, blank=True, null=True) api_key_created_at = models.DateTimeField(null=True, blank=True) # Subscription settings subscription_plan = models.ForeignKey(SubscriptionPlan, on_delete=models.SET_NULL, null=True) subscription_status = models.CharField( max_length=20, choices=[('active', 'Active'), ('inactive', 'Inactive'), ('cancelled', 'Cancelled'), ('trial', 'Trial')], default='inactive' ) subscription_start_date = models.DateTimeField(null=True, blank=True) subscription_end_date = models.DateTimeField(null=True, blank=True) trial_end_date = models.DateTimeField(null=True, blank=True) @property def is_subscription_active(self): if self.subscription_status != 'active': return False if self.subscription_end_date and self.subscription_end_date < timezone.now(): return False return True @property def is_trial_active(self): if self.subscription_status != 'trial': return False if self.trial_end_date and self.trial_end_date < timezone.now(): return False return True # Example usage: # user_settings, created = UserSettings.objects.get_or_create(user=request.user) # if user_settings.is_subscription_active: # grant_premium_access() ``` -------------------------------- ### Dashboard Routes Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Authenticated routes for user-specific dashboard functionalities. ```APIDOC ## Dashboard Routes ### Description Authenticated routes for user dashboard functionalities, including profile, settings, and subscription management. ### Method GET ### Endpoint /dashboard/ ### Description Dashboard home page. ### Method GET/POST ### Endpoint /dashboard/profile/ ### Description User profile management. ### Method GET/POST ### Endpoint /dashboard/settings/ ### Description User settings configuration. ### Method POST ### Endpoint /dashboard/settings/generate-api-key/ ### Description Generate a new API key for the user. ### Method GET ### Endpoint /dashboard/subscription/plans/ ### Description View available subscription plans. ### Method POST ### Endpoint /dashboard/subscription/plans//subscribe/ ### Description Subscribe to a specific subscription plan. ### Method POST ### Endpoint /dashboard/subscription/cancel/ ### Description Cancel the current subscription. ### Method POST ### Endpoint /dashboard/subscription/trial/ ### Description Start a free trial. ``` -------------------------------- ### Subscribe to Plan in Django Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Handles the process of a user subscribing to a specific subscription plan. It validates the plan's existence and activity, checks if the user already has an active subscription, and then updates the user's settings with the new plan details and dates. Supports monthly and yearly billing intervals. ```python from django.shortcuts import get_object_or_404, redirect from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.utils import timezone from django.contrib import messages from .models import UserSettings, SubscriptionPlan @login_required @require_http_methods(['POST']) def subscribe_to_plan(request, plan_slug): plan = get_object_or_404(SubscriptionPlan, slug=plan_slug, is_active=True) user_settings = UserSettings.objects.get(user=request.user) if user_settings.is_subscription_active: messages.warning(request, 'You already have an active subscription.') return redirect('dashboard:subscription_plans') user_settings.subscription_plan = plan user_settings.subscription_status = 'active' user_settings.subscription_start_date = timezone.now() if plan.interval == 'monthly': user_settings.subscription_end_date = timezone.now() + timezone.timedelta(days=30) else: # yearly user_settings.subscription_end_date = timezone.now() + timezone.timedelta(days=365) user_settings.save() messages.success(request, f'Successfully subscribed to {plan.name} plan.') return redirect('dashboard:settings') # URL: POST /dashboard/subscription/plans//subscribe/ -> dashboard:subscribe_to_plan # Example: POST /dashboard/subscription/plans/pro-monthly/subscribe/ ``` -------------------------------- ### Django Template Navigation and Authentication Logic Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/base.html This Django template snippet demonstrates navigation links and conditional rendering based on user authentication status. It includes links to home, features, pricing, dashboard, profile, login, and signup pages. ```django [NAME]({% url 'landing:home' %}) [Features]({% url 'landing:features' %}) [Pricing]({% url 'landing:pricing' %}) {% if user.is_authenticated %} [Dashboard]({% url 'dashboard:home' %}) {{ user.username|first|upper }} [Profile](#) [Log out]({% url 'account_logout' %}) {% else %} [Log in]({% url 'account_login' %}) [Sign up]({% url 'account_signup' %}) {% endif %} [Features]({% url 'landing:features' %}) [Pricing]({% url 'landing:pricing' %}) {% if user.is_authenticated %} {{ user.username|first|upper }} {{ user.get_full_name|default:user.username }} {{ user.email }} [Dashboard]({% url 'dashboard:home' %}) [Profile](#) [Log out]({% url 'account_logout' %}) {% else %} [Log in]({% url 'account_login' %}) [Sign up]({% url 'account_signup' %}) {% endif %} ``` -------------------------------- ### Public Routes Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt These are the public-facing routes accessible without authentication. ```APIDOC ## Public Routes ### Description Publicly accessible routes for landing pages and information. ### Method GET ### Endpoint / ### Description Landing home page. ### Method GET ### Endpoint /features/ ### Description Features page. ### Method GET ### Endpoint /pricing/ ### Description Pricing page. ``` -------------------------------- ### Main URL Configuration (Django) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Defines the primary URL routing structure for the Django application. It includes paths for the Django admin, user authentication via django-allauth, landing pages, user dashboard, and subscription-related endpoints. This file serves as the entry point for all URL requests. ```python # core/urls.py - Main URL configuration from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('accounts/', include('allauth.urls')), path('', include('apps.landing.urls')), path('dashboard/', include('apps.dashboard.urls')), path('subscriptions/', include('apps.subscriptions.urls')), ] # Complete route map: # Public: # GET / -> Landing home # GET /features/ -> Features page # GET /pricing/ -> Pricing page # # Authentication (django-allauth): # GET /accounts/login/ -> Login # GET /accounts/signup/ -> Registration # GET /accounts/logout/ -> Logout # POST /accounts/password/reset/ -> Password reset # # Dashboard (login required): # GET /dashboard/ -> Dashboard home # GET/POST /dashboard/profile/ -> User profile # GET/POST /dashboard/settings/ -> User settings # POST /dashboard/settings/generate-api-key/ -> Generate API key # GET /dashboard/subscription/plans/ -> View plans # POST /dashboard/subscription/plans//subscribe/ -> Subscribe # POST /dashboard/subscription/cancel/ -> Cancel subscription # POST /dashboard/subscription/trial/ -> Start trial # # Subscriptions: # GET /subscriptions/ -> Stripe subscription page # POST /subscriptions/create/ -> Create Stripe subscription # POST /subscriptions/webhook/ -> Stripe webhook endpoint ``` -------------------------------- ### Django Landing Page Views Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Renders public-facing marketing pages like home, features, and pricing. These views do not require user authentication and serve HTML templates. ```python # apps/landing/views.py from django.shortcuts import render from django.views.decorators.http import require_http_methods @require_http_methods(['GET']) def home(request): features = [ { 'title': 'Intuitive Dashboard', 'description': 'Easy-to-use control panel with all your important metrics.', 'icon': 'chart-bar' }, { 'title': 'Secure Authentication', 'description': 'Robust authentication system with email verification.', 'icon': 'shield-check' } ] pricing = { 'monthly_price': '9.99', 'features': ['Full dashboard access', 'Priority support', 'API access'] } return render(request, 'landing/home.html', {'features': features, 'pricing': pricing}) # URL patterns (apps/landing/urls.py): # GET / -> landing:home # GET /pricing/ -> landing:pricing # GET /features/ -> landing:features ``` -------------------------------- ### Create Stripe Subscription Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Creates a new Stripe subscription and a payment intent for checkout completion. This endpoint accepts POST requests and returns subscription details. ```APIDOC ## POST /subscriptions/create/ ### Description Creates a new Stripe subscription with payment intent for checkout completion. ### Method POST ### Endpoint /subscriptions/create/ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **stripeToken** (string) - Required - The token generated by Stripe.js for payment. ### Request Example ``` { "stripeToken": "tok_visa" } ``` ### Response #### Success Response (200) Returns a JSON object containing the subscription ID and the client secret for the payment intent. #### Response Example ```json { "subscription_id": "sub_12345", "client_secret": "pi_12345_secret_67890" } ``` ``` -------------------------------- ### Display Stripe Subscription Page in Django Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Renders the subscription page, displaying the user's current subscription status and Stripe checkout options. It attempts to retrieve the user's existing Stripe subscription and customer information. If a StripeCustomer record does not exist, it renders the page without subscription details, only showing the Stripe public key for checkout initiation. ```python # apps/subscriptions/views.py import stripe from django.conf import settings from django.contrib.auth.decorators import login_required from django.shortcuts import render from .models import StripeCustomer stripe.api_key = settings.STRIPE_SECRET_KEY @login_required def subscription_page(request): try: stripe_customer = StripeCustomer.objects.get(user=request.user) subscription = stripe.Subscription.retrieve(stripe_customer.stripe_subscription_id) return render(request, 'subscriptions/subscription.html', { 'subscription': subscription, 'STRIPE_PUBLIC_KEY': settings.STRIPE_PUBLIC_KEY }) except StripeCustomer.DoesNotExist: return render(request, 'subscriptions/subscription.html', { 'STRIPE_PUBLIC_KEY': settings.STRIPE_PUBLIC_KEY }) # URL: GET /subscriptions/ -> subscriptions:subscription_page ``` -------------------------------- ### Django Subscription Module Structure Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/apps/subscriptions/README.md This illustrates the directory structure for the Django subscription module. It highlights key files responsible for models, views, URL routing, webhook handling, and templates. ```tree subscriptions/ ├── models.py # Subscription and customer models ├── views.py # Subscription views and logic ├── urls.py # URL routing ├── webhooks.py # Stripe webhook handlers └── templates/ └── subscription.html ``` -------------------------------- ### Authentication (django-allauth) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Endpoints related to user authentication, registration, and password management. ```APIDOC ## Authentication (django-allauth) ### Description Endpoints for user authentication, including login, signup, logout, and password reset. ### Method GET ### Endpoint /accounts/login/ ### Description User login page. ### Method GET ### Endpoint /accounts/signup/ ### Description User registration page. ### Method GET ### Endpoint /accounts/logout/ ### Description User logout. ### Method POST ### Endpoint /accounts/password/reset/ ### Description Initiate password reset process. ``` -------------------------------- ### Define StripeCustomer Model for Payment Linking (Python) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Defines the 'StripeCustomer' model to link Django users with their corresponding Stripe customer and subscription IDs. This is crucial for managing payment information and subscription states within the application. It facilitates associating user accounts with Stripe's payment infrastructure. ```python # apps/subscriptions/models.py (Assumed based on context) from django.db import models from django.conf import settings class StripeCustomer(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) stripe_customer_id = models.CharField(max_length=255, unique=True) stripe_subscription_id = models.CharField(max_length=255, unique=True) subscription_status = models.CharField(max_length=50, default='active') def __str__(self): return f"StripeCustomer for {self.user.email}" ``` -------------------------------- ### Environment Configuration for Stripe Keys Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/apps/subscriptions/README.md This snippet shows the necessary environment variables to configure the Stripe API keys and webhook secret for the Django application. These variables are crucial for secure communication with Stripe services. ```env STRIPE_PUBLIC_KEY=pk_test_... STRIPE_SECRET_KEY=sk_test_... STRIPE_WEBHOOK_SECRET=whsec_... STRIPE_PRICE_ID=price_... ``` -------------------------------- ### Manage User Settings in Django Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Handles user notification preferences and displays subscription status. It allows users to update their notification settings (comments, updates, marketing) via a POST request and renders the current subscription details. Dependencies include Django's authentication and rendering utilities. ```python from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from .models import UserSettings @login_required def settings(request): user_settings, created = UserSettings.objects.get_or_create(user=request.user) if request.method == 'POST': user_settings.notify_comments = request.POST.get('comments') == 'on' user_settings.notify_updates = request.POST.get('updates') == 'on' user_settings.notify_marketing = request.POST.get('marketing') == 'on' user_settings.save() return redirect('dashboard:settings') context = { 'notification_settings': { 'comments': user_settings.notify_comments, 'updates': user_settings.notify_updates, 'marketing': user_settings.notify_marketing, }, 'subscription': { 'plan': user_settings.subscription_plan, 'status': user_settings.subscription_status, 'is_active': user_settings.is_subscription_active, } } return render(request, 'dashboard/settings.html', context) # URL: GET/POST /dashboard/settings/ -> dashboard:settings # POST data: comments (on/off), updates (on/off), marketing (on/off) ``` -------------------------------- ### Stripe Subscription Page Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Displays the user's subscription status and provides a Stripe checkout interface. It retrieves the existing Stripe subscription if a customer record exists. ```APIDOC ## GET /subscriptions/ ### Description Displays subscription status and Stripe checkout for users. Retrieves existing Stripe subscription if customer exists. ### Method GET ### Endpoint /subscriptions/ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) Renders the subscription page template with subscription details and Stripe public key. #### Response Example None ``` -------------------------------- ### Stripe Payment Integration for Subscriptions (JavaScript) Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/subscriptions/subscription.html Client-side JavaScript code for integrating Stripe payments. It initializes Stripe, creates a card element, handles form submission, creates a payment method, and confirms the card payment. Requires Stripe.js and a valid Stripe public key. ```javascript const stripe = Stripe('{{ STRIPE_PUBLIC_KEY }}'); const elements = stripe.elements(); // Custom styling for the card element to match our minimalist design const style = { base: { fontFamily: '"Space Grotesk", sans-serif', fontSize: '16px', color: '#121212', '::placeholder': { color: '#4a4a4a', }, }, invalid: { color: '#121212', }, }; const card = elements.create('card', {style}); card.mount('#card-element'); const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const {error, paymentMethod} = await stripe.createPaymentMethod({ type: 'card', card: card, }); if (error) { const errorElement = document.getElementById('card-errors'); errorElement.textContent = error.message; } else { const response = await fetch('{% url "subscriptions:create_subscription" %}', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': '{{ csrf_token }}', }, body: JSON.stringify({ payment_method_id: paymentMethod.id, }) }); const data = await response.json(); const {error: confirmError} = await stripe.confirmCardPayment(data.client_secret); if (confirmError) { const errorElement = document.getElementById('card-errors'); errorElement.textContent = confirmError.message; } else { window.location.reload(); } } }); ``` -------------------------------- ### Django Protected Dashboard Home View Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Provides the main entry point for logged-in users to access their dashboard. Requires user authentication and redirects to the login page if the user is not authenticated. ```python # apps/dashboard/views.py from django.shortcuts import render from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods @login_required @require_http_methods(['GET']) def dashboard_home(request): return render(request, 'dashboard/home.html') # URL: GET /dashboard/ -> dashboard:home # Requires: Authentication # Redirects to: /accounts/login/ if not authenticated ``` -------------------------------- ### Django Template for User Signup Form Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/account/signup.html This Django template renders the user signup form. It extends a base template, includes CSRF token for security, and displays form errors if any. The form fields include email, password, and password confirmation. ```django {% extends "base.html" %} {% block title %}Sign Up - Django SaaS{% endblock %} {% block content %} CREATE ACCOUNT -------------- Or [sign in to your existing account]({% url 'account_login' %}) {% csrf_token %} {% if redirect_field_value %} {% endif %} Email address Password Confirm password {% if form.errors %} ### Error {% for field, errors in form.errors.items %} {% for error in errors %}* {{ error }} {% endfor %} {% endfor %} {% endif %} SIGN UP {% endblock %} ``` -------------------------------- ### Generate API Key in Django Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Generates a secure, URL-safe API key for authenticated users. This view uses Python's `secrets` module to create a 32-byte token, stores it with a creation timestamp, and redirects the user back to the settings page. It requires POST requests and uses Django's messages framework for feedback. ```python import secrets from django.utils import timezone from django.shortcuts import redirect from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.contrib import messages from .models import UserSettings @login_required @require_http_methods(['POST']) def generate_api_key(request): user_settings, created = UserSettings.objects.get_or_create(user=request.user) # Generate a new API key (43 characters, URL-safe) api_key = secrets.token_urlsafe(32) user_settings.api_key = api_key user_settings.api_key_created_at = timezone.now() user_settings.save() messages.success(request, 'API key generated successfully.') return redirect('dashboard:settings') # URL: POST /dashboard/settings/generate-api-key/ -> dashboard:generate_api_key # Returns: Redirect to settings page with new API key stored ``` -------------------------------- ### Django Template Content Block Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/base.html A standard Django template block for inserting main content. This is a placeholder where specific page content will be rendered. ```django {% block content %}{% endblock %} ``` -------------------------------- ### Django Template: Sign In Form Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/account/login.html This Django template renders the sign-in form for the SaaS application. It includes fields for email and password, a 'remember me' option, and handles form errors. It also provides links for account creation and password reset. ```html {% extends "base.html" %} {% block title %}Sign In - Django SaaS{% endblock %} {% block content %} SIGN IN ------- Or [create a new account]({% url 'account_signup' %}) {% csrf_token %} {% if redirect_field_value %} {% endif %} Email address Password Remember me [Forgot your password?]({% url 'account_reset_password' %}) {% if form.errors %} ### Error {% for field, errors in form.errors.items %} {% for error in errors %}* {{ error }} {% endfor %} {% endfor %} {% endif %} SIGN IN {% endblock %} ``` -------------------------------- ### Stripe Customer Model (Django) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Defines the StripeCustomer model for storing Stripe-specific customer information linked to a Django User. It includes fields for Stripe customer ID, subscription ID, and subscription status. This model is crucial for managing user subscriptions within the application. ```python from django.db import models from django.contrib.auth import get_user_model User = get_user_model() class StripeCustomer(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) stripe_customer_id = models.CharField(max_length=255) stripe_subscription_id = models.CharField(max_length=255, blank=True, null=True) subscription_status = models.CharField(max_length=50, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) ``` -------------------------------- ### Handle Stripe Webhook Events for Subscription Updates (Python) Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Processes incoming Stripe webhook events, specifically for subscription updates. It validates the webhook signature for security and updates the local database with the subscription status. Requires Stripe API keys and webhook secrets configured in Django settings. ```python # apps/subscriptions/views.py import stripe from django.conf import settings from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST from .models import StripeCustomer stripe.api_key = settings.STRIPE_SECRET_KEY @csrf_exempt @require_POST def stripe_webhook(request): payload = request.body sig_header = request.META.get('HTTP_STRIPE_SIGNATURE') try: event = stripe.Webhook.construct_event( payload, sig_header, settings.STRIPE_WEBHOOK_SECRET ) except ValueError: return HttpResponse(status=400) except stripe.error.SignatureVerificationError: return HttpResponse(status=400) if event['type'] == 'customer.subscription.updated': subscription = event['data']['object'] stripe_customer = StripeCustomer.objects.get( stripe_subscription_id=subscription.id ) stripe_customer.subscription_status = subscription.status stripe_customer.save() return HttpResponse(status=200) # URL: POST /subscriptions/webhook/ -> subscriptions:stripe_webhook # Configure in Stripe Dashboard: https://yourdomain.com/subscriptions/webhook/ # Events handled: customer.subscription.updated ``` -------------------------------- ### Django Template Navigation and Blocks Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/dashboard/base.html Django template snippets for structuring the SaaS platform's interface. Includes title blocks, navigation links, user profile display, and content blocks. ```django {% block title %}Dashboard - SaaS Platform{% endblock %} ``` ```django {% block extra_head %}{% endblock %} ``` ```django [Dashboard]({% url 'dashboard:home' %}) [Profile]({% url 'dashboard:profile' %}) [Settings]({% url 'dashboard:settings' %}) ``` ```django [\n{{ user.email }}\nLogout\n\n]({% url 'account_logout' %}) ``` ```django {% block dashboard_content %}{% endblock %} ``` ```django {% block extra_js %}{% endblock %} ``` -------------------------------- ### Django Template for Subscription Display Source: https://github.com/eriktaveras/django-saas-boilerplate/blob/main/templates/subscriptions/subscription.html A Django template snippet that conditionally displays subscription information or a premium plan signup form. It uses template tags for extending, loading static files, and conditional logic based on the 'subscription' object. ```django {% extends 'base.html' %} {% load static %} {% block content %} SUBSCRIPTION ============ {% if subscription %} SUBSCRIPTION STATUS ------------------- Status: {{ subscription.status }} Next billing date: {{ subscription.current_period_end|date:"F j, Y" }} {% if subscription.status == 'active' %} CANCEL SUBSCRIPTION {% endif %} {% else %} PREMIUM PLAN ------------ Access all premium features for only $9.99/month SUBSCRIBE NOW {% endif %} {% endblock %} ``` -------------------------------- ### Cancel Subscription Source: https://context7.com/eriktaveras/django-saas-boilerplate/llms.txt Cancels the user's active subscription by updating the subscription status to 'cancelled'. This endpoint requires a POST request. ```APIDOC ## POST /dashboard/subscription/cancel/ ### Description Cancels the user's active subscription by setting status to 'cancelled'. ### Method POST ### Endpoint /dashboard/subscription/cancel/ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) Redirects to the dashboard settings page with a success message. #### Response Example None ```