Middleware

SubscriptionPaymentMiddleware

Used to redirect users from subcription-locked request destinations.

Rules:

  • "(app_name)" means everything from this app is exempt
  • "[namespace]" means everything with this name is exempt
  • "namespace:name" means this namespaced URL is exempt
  • "name" means this URL is exempt
  • The entire djstripe namespace is exempt
  • If settings.DEBUG is True, then django-debug-toolbar is exempt
  • A 'fn:' prefix means the rest of the URL is fnmatch'd.

Examples:

DJSTRIPE_SUBSCRIPTION_REQUIRED_EXCEPTION_URLS = (
    "[blogs]",  # Anything in the blogs namespace
    "products:detail",  # A ProductDetail view you want shown to non-payers
    "home",  # Site homepage
    "fn:/accounts*",  # anything in the accounts/ URL path
)

Methods

djstripe.middleware.SubscriptionPaymentMiddleware.check_subscription(self, request)

Redirect to the subscribe page if the user lacks an active subscription.

Source code in djstripe/middleware.py
def check_subscription(self, request):
    """Redirect to the subscribe page if the user lacks an active subscription."""
    from .settings import SUBSCRIPTION_REDIRECT, subscriber_request_callback

    subscriber = subscriber_request_callback(request)

    if not subscriber_has_active_subscription(subscriber):
        if not SUBSCRIPTION_REDIRECT:
            raise ImproperlyConfigured("DJSTRIPE_SUBSCRIPTION_REDIRECT is not set.")
        return redirect(SUBSCRIPTION_REDIRECT)

djstripe.middleware.SubscriptionPaymentMiddleware.is_matching_rule(self, request)

Check according to the rules defined in the class docstring.

Source code in djstripe/middleware.py
def is_matching_rule(self, request):
    """Check according to the rules defined in the class docstring."""
    # First, if in DEBUG mode and with django-debug-toolbar, we skip
    #   this entire process.
    from .settings import SUBSCRIPTION_REQUIRED_EXCEPTION_URLS

    if settings.DEBUG and request.path.startswith("/__debug__"):
        return True

    exempt_urls = list(SUBSCRIPTION_REQUIRED_EXCEPTION_URLS) + ["[djstripe]"]

    # Second we check against matches
    match = resolve(
        request.path, getattr(request, "urlconf", settings.ROOT_URLCONF)
    )
    if "({0})".format(match.app_name) in exempt_urls:
        return True

    if "[{0}]".format(match.namespace) in exempt_urls:
        return True

    if "{0}:{1}".format(match.namespace, match.url_name) in exempt_urls:
        return True

    if match.url_name in exempt_urls:
        return True

    # Third, we check wildcards:
    for exempt in [x for x in exempt_urls if x.startswith("fn:")]:
        exempt = exempt.replace("fn:", "")
        if fnmatch.fnmatch(request.path, exempt):
            return True

    return False

djstripe.middleware.SubscriptionPaymentMiddleware.process_request(self, request)

Check the subscriber's subscription status.

Returns early if request does not outlined in this middleware's docstring.

Source code in djstripe/middleware.py
def process_request(self, request):
    """Check the subscriber's subscription status.

    Returns early if request does not outlined in this middleware's docstring.
    """
    if self.is_matching_rule(request):
        return

    return self.check_subscription(request)