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.1

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.1
File Size Uploaded
django_gocardless_billing-0.1.1.tar.gz 19.5 kB Details

Built distribution (wheel)

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

Total release size: 41.1 kB

Release files / django_gocardless_billing-0.1.1.tar.gz

Download URL django_gocardless_billing-0.1.1.tar.gz
Size 19.5 kB
Tags Source
SHA-256 checksum
How to use checksums
35921c6bc84b20bc1deac6bd97109e254f3d53e8876f58ec4d2d65ad6905d9aa
BLAKE2b-256 checksum
How to use checksums
eb9e6fedbfbcc487d76397fdfee5d68b8fba71f46e441c2b4972cfc3b754713f
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.1-py3-none-any.whl

Download URL django_gocardless_billing-0.1.1-py3-none-any.whl
Size 21.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fb6de371fd57a824f9758858f02e91f4df9c1f8d44225df8a9602f6e0b02b086
BLAKE2b-256 checksum
How to use checksums
f092c1c45b90ee872ae046a3f7a3853a948b350e7fbfd8bed42886a3ddb775df
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

This release

0.1.1 This release

2 release files

0.1.0

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