Skip to main content

django-gocardless-billing

A reusable Django app for GoCardless Direct Debit billing. Handles webhook intake, idempotency, async Celery processing, Billing Request flows, subscriptions, and Django signals — so each of your SaaS projects gets UK Direct Debit billing in minutes, not days.

Companion package to django-stripe-billing.

Full configuration guide (env vars, Dashboard, production, Celery): see CONFIGURATION.md.

Features

  • Billing Request + Flow — create_billing_request_flow() (instant first payment + BACS mandate)
  • Subscriptions — create_subscription_for_mandate() after mandate activation
  • Webhook receiver — signature verification, idempotency, audit trail
  • Async processing — optional Celery task with exponential backoff
  • Django signals — connect custom logic per event type without touching the package
  • Outgoing webhooks — Zapier / Make / n8n integration per event type
  • Admin — GoCardlessWebhookEvent with status badges
  • Python 3.10+, Django 4.2+

Quick Start

1. Install

pip install django-gocardless-billing
# Optional: async webhook processing
pip install django-gocardless-billing[celery]

2. Add to INSTALLED_APPS

INSTALLED_APPS = [
    ...
    'django_gocardless_billing',
]

3. Configure

GOCARDLESS_BILLING = {
    'GOCARDLESS_ACCESS_TOKEN': env('GOCARDLESS_ACCESS_TOKEN_SANDBOX'),
    'GOCARDLESS_WEBHOOK_SECRET': env('GOCARDLESS_WEBHOOK_SECRET_SANDBOX'),
    'GOCARDLESS_MODE': 'sandbox',  # 'sandbox' or 'live'
    'ENVIRONMENT': env('ENVIRONMENT', default='production'),
    'SUCCESS_URL': 'https://myapp.com/gocardless/success/',
    'EXIT_URL': 'https://myapp.com/subscribe/',
    'PROJECT_SLUG': 'my_saas',
    'PLAN_RESOLVER': 'myapp.billing.resolve_gocardless_plan',
    'OUTGOING_WEBHOOK_URLS': {
        'gocardless.payments.confirmed': env('WEBHOOK_GC_PAYMENT_CONFIRMED', ''),
        'gocardless.payments.failed': env('WEBHOOK_GC_PAYMENT_FAILED', ''),
    },
}

Zero-config migration: If you already have top-level GOCARDLESS_ACCESS_TOKEN, GOCARDLESS_WEBHOOK_SECRET, GOCARDLESS_MODE, or REDIRECT_DOMAIN, the package reads them automatically.

4. Implement PLAN_RESOLVER

# myapp/billing.py
def resolve_gocardless_plan(plan_id: str) -> dict:
  return {
      'amount': 1999,           # pence
      'currency': 'GBP',
      'interval_unit': 'monthly',  # or 'yearly'
      'name': 'Pro Monthly',
      'description': 'Pro Monthly — first payment',
  }

5. Add URL

urlpatterns = [
    path('webhooks/', include('django_gocardless_billing.urls')),
    # Exposes: POST /webhooks/gocardless/
]

6. Run migrations

python manage.py migrate

Creating a Billing Request Flow

from django_gocardless_billing.checkout import create_billing_request_flow

billing_request, flow = create_billing_request_flow(
    user=request.user,
    plan_id='pro_monthly',
    customer_id=profile.gocardless_customer_id or None,
    on_customer_created=lambda cid: save_customer_id(profile, cid),
)
return redirect(flow.authorisation_url, code=303)

Connecting Business Logic via Signals

from django.dispatch import receiver
from django_gocardless_billing.signals import payment_confirmed, payment_failed

@receiver(payment_confirmed)
def on_payment_confirmed(sender, event, **kwargs):
    metadata = event.get('metadata') or {}
    plan_id = metadata.get('plan_id')
    # Update UserProfile, grant access, send emails, etc.

@receiver(payment_failed)
def on_payment_failed(sender, event, **kwargs):
    ...

Register receivers in your app's AppConfig.ready().


Available Signals

Signal GoCardless event
billing_request_fulfilled billing_requests.fulfilled
mandate_active mandates.active
payment_confirmed payments.confirmed
payment_failed payments.failed
subscription_created subscriptions.created
subscription_cancelled subscriptions.cancelled / finished

Each signal receives event (a plain dict) in kwargs.


Architecture

django_gocardless_billing/
├── conf.py           # GOCARDLESS_BILLING settings + legacy fallback
├── client.py         # GoCardless Pro SDK client
├── models.py         # GoCardlessWebhookEvent
├── signals.py        # Django signals
├── webhooks.py       # HandlerRegistry + built-in handlers
├── checkout.py       # create_billing_request_flow()
├── subscriptions.py  # create_subscription_for_mandate()
├── plans.py          # PLAN_RESOLVER integration
├── profile.py        # Direct Debit profile readiness
├── tasks.py          # Celery / sync processing
├── views.py          # HTTP webhook receiver
└── urls.py           # path('gocardless/', ...)

See CONFIGURATION.md for full setup (sandbox/live, webhooks, production). See INTEGRATION.md for migration paths from in-app GoCardless code.

Development

cd django-gocardless-billing
pip install -e ".[dev]"
pytest

License

MIT

Metadata

Release files for django-gocardless-billing 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-gocardless-billing 0.1.0
File Size Uploaded
django_gocardless_billing-0.1.0.tar.gz 19.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-gocardless-billing 0.1.0
File Interpreter ABI Platform
django_gocardless_billing-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 41.1 kB

Release files / django_gocardless_billing-0.1.0.tar.gz

Download URL django_gocardless_billing-0.1.0.tar.gz
Size 19.5 kB
Tags Source
SHA-256 checksum
How to use checksums
06153d4447972c16084b507e3038752d3c001bc4de10eb1acd1d154028776930
BLAKE2b-256 checksum
How to use checksums
a3d72168f804a6852054fdf8b705012eec09a0a54649dc1e9c32192787ab0d67
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / django_gocardless_billing-0.1.0-py3-none-any.whl

Download URL django_gocardless_billing-0.1.0-py3-none-any.whl
Size 21.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5b416af4e788f7e5c5ec64c4d971c48f7df6fad689aae01da0fd0112cc4cba87
BLAKE2b-256 checksum
How to use checksums
de5f80b0f2070cd52386e065ef73405229ff1b6868737e0c8f4ab3abd9c855d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page