Python SDK — Django integration
The Django adapter ships in the same wheel as paylera-fastapi — install
with the django extra and import from paylera_django. It’s a thin
URL-pattern factory that delegates to the same RelayCore the FastAPI
router uses, so the wire shape stays identical across frameworks.
pip install "paylera-fastapi[django]"Requires Django 4.2 or newer.
Wire it into urls.py
from django.conf import settingsfrom django.http import HttpRequestfrom django.urls import include, pathfrom paylera_django import paylera_relay_urlsfrom paylera_fastapi import PayleraCustomerIdentity
def identify(request: HttpRequest) -> PayleraCustomerIdentity: user = request.user if not user.is_authenticated: return PayleraCustomerIdentity() return PayleraCustomerIdentity( customer_id=getattr(user, "paylera_customer_id", None), email=user.email, name=user.get_full_name(), )
urlpatterns = [ path( "api/paylera/", include(paylera_relay_urls( api_token=settings.PAYLERA_API_TOKEN, identify=identify, auto_create_customer=True, csrf=True, )), ),]paylera_relay_urls(...) returns a list[URLPattern] you can drop into
include(...). The router names every pattern (paylera-attach,
paylera-check, …) so you can reverse() them in tests.
Routes
| Method | Path | URL name |
|---|---|---|
GET | csrf-token | paylera-csrf-token |
POST | attach | paylera-attach |
POST | check | paylera-check |
POST | track | paylera-track |
GET | entitlements | paylera-entitlements |
GET | me | paylera-me |
GET | plans | paylera-plans (anonymous-friendly) |
GET | invoices | paylera-invoices |
POST | billing-portal | paylera-billing-portal |
POST | subscriptions/<sub_id>/upgrade | paylera-subscription-upgrade |
POST | subscriptions/<sub_id>/cancel | paylera-subscription-cancel |
CSRF
The factory installs the Paylera double-submit-cookie middleware
(Paylera-CSRF-Token header + paylera_csrf cookie). That’s separate from
Django’s built-in CSRF — you don’t need @csrf_exempt on these views, and
you shouldn’t reuse Django’s csrftoken cookie for the relay. The two
middlewares coexist if you mount Django’s CSRF on the rest of your app.
Tune with paylera_fastapi.PayleraCsrfOptions:
from paylera_fastapi import PayleraCsrfOptions
paylera_relay_urls( ..., csrf=PayleraCsrfOptions( cookie_path="/api/paylera", cookie_secure=True, cookie_samesite="strict", ),)Auth — read request.user
identify runs after Django’s middleware chain, so request.user is
already populated by your auth backend. The example above maps an
authenticated user; an anonymous user falls back to an empty identity, which
means routes that need a customer (everything except /plans) will return
401.
Webhook receiver
paylera_webhook_urls is the inbound twin:
from paylera_django import paylera_webhook_urlsfrom paylera_fastapi import InvoicePaidEvent
async def handle_invoice_paid(event: InvoicePaidEvent) -> None: # event.data.id, event.data.amount_paid, ... typed ...
urlpatterns += [ path("webhooks/paylera/", include(paylera_webhook_urls( signing_secret=settings.PAYLERA_WEBHOOK_SECRET, accepted_secrets=[settings.PAYLERA_WEBHOOK_SECRET_PREVIOUS] if settings.PAYLERA_WEBHOOK_SECRET_PREVIOUS else None, handlers={"invoice.paid": handle_invoice_paid}, ))),]Handlers can be async or sync; the dispatcher accepts both. See webhooks for the verification rules.
Settings
Add to settings.py (read from environment in production):
import os
PAYLERA_API_TOKEN = os.environ["PAYLERA_API_TOKEN"]PAYLERA_WEBHOOK_SECRET = os.environ["PAYLERA_WEBHOOK_SECRET"]PAYLERA_WEBHOOK_SECRET_PREVIOUS = os.environ.get("PAYLERA_WEBHOOK_SECRET_PREVIOUS", "")No INSTALLED_APPS entry is required — paylera_django is an adapter
package, not a Django app.
Async views
The factory always wraps handlers with async_to_sync so they work under
WSGI or ASGI. If you’re on ASGI (Daphne / Uvicorn / Hypercorn) and want true
concurrency for webhook delivery, mount under asgi.application and your
async handlers will run on the running event loop.
Full example
A runnable Django 4.2 project is at
examples/python/django-app/
in the monorepo. manage.py runserver 8001 boots a service with both the
relay (/api/paylera/) and webhook receiver (/webhooks/paylera/) mounted.