Skip to main content

Django subscription management with Midtrans payment gateway integration

Project description

Django Subscription Midtrans

Python Django DRF Celery License PyPI

A production-ready Django package for subscription billing with Midtrans Core API integration. Provides a complete subscription management system including recurring payments, invoicing, wallet top-ups, webhook handling, and admin dashboard.

Note: This package uses the Midtrans Core API (server-side charge via /v2/charge, /v1/subscriptions, /v1/invoices), not Midtrans Snap.

Features

  • Subscription Plans — Configurable interval billing (daily/weekly/monthly), trial periods, max billing cycles, feature flags per plan
  • Payment Methods — Credit Card, Bank Transfer (BCA/BNI/BRI/Permata/CIMB), GoPay, ShopeePay, QRIS, E-Channel (Mandiri Bill), Wallet
  • Automatic Billing — Celery Beat periodic tasks handle recurring charges, payment retries, grace periods, expiration
  • Invoice System — Auto-generated invoices with line items, tax/discount support, PDF-ready data
  • Wallet & Top-Up — Internal wallet balance system with top-up via any payment method
  • Webhook Processing — Secure Midtrans notification handler with SHA-512 signature verification, duplicate detection
  • Admin Dashboard — Django Unfold admin with status badges, inline editing, bulk actions, Midtrans sync
  • Notification System — Email, webhook, and in-app notification logging with queued delivery
  • Access Middleware — Path-based subscription enforcement with grace period support
  • Django Signals — 20+ signals for all subscription/payment lifecycle events
  • REST API — Full DRF ViewSet API for plans, subscriptions, payments, invoices, wallet, notifications
  • Testing — Comprehensive test suite with factories, mocked Midtrans responses

Architecture

Layer Components
Admin UI Django Unfold Admin
REST API DRF ViewSets + Serializers
Service Layer SubscriptionService, WalletService
Data / Integration Models/ORM, MidtransClient, Celery Tasks (Beat)
External Midtrans Core API (v2/charge, v1/subscriptions)

For detailed Mermaid diagrams, see the Architecture Diagrams documentation.

Quick Start

Installation

From PyPI:

pip install django-subscription-midtrans

From source:

git clone https://github.com/rissets/django-subscription-midtrans.git
cd django-subscription-midtrans
pip install -e ".[dev]"

Step 1: Add to INSTALLED_APPS

INSTALLED_APPS = [
    # Django Unfold (must be before django.contrib.admin)
    "unfold",
    "unfold.contrib.filters",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",

    # Third-party
    "rest_framework",
    "django_celery_beat",

    # Subscription package
    "subscriptions",
]

Step 2: Configure Environment Variables

Create a .env file in your project root:

# Django
DJANGO_SECRET_KEY=
DJANGO_DEBUG=True
DJANGO_ALLOWED_HOSTS=*,localhost,127.0.0.1

# Database (default: SQLite, configure for PostgreSQL in production)
# DB_ENGINE=django.db.backends.postgresql
# DB_NAME=subscription_db
# DB_USER=
# DB_PASSWORD=
# DB_HOST=localhost
# DB_PORT=5432

# Celery / Redis
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/0

# Midtrans Credentials (get from https://dashboard.midtrans.com)
MIDTRANS_SERVER_KEY=
MIDTRANS_CLIENT_KEY=
MIDTRANS_MERCHANT_ID=
MIDTRANS_IS_PRODUCTION=False

# Webhook URL (must be publicly accessible)
# For local dev, use ngrok: ngrok http 8000
MIDTRANS_NOTIFICATION_URL=

Step 3: Add Settings

# settings.py
from decouple import config

# Midtrans
MIDTRANS_SERVER_KEY = config("MIDTRANS_SERVER_KEY", default="")
MIDTRANS_CLIENT_KEY = config("MIDTRANS_CLIENT_KEY", default="")
MIDTRANS_MERCHANT_ID = config("MIDTRANS_MERCHANT_ID", default="")
MIDTRANS_IS_PRODUCTION = config("MIDTRANS_IS_PRODUCTION", default=False, cast=bool)
MIDTRANS_API_BASE_URL = (
    "https://api.midtrans.com" if MIDTRANS_IS_PRODUCTION
    else "https://api.sandbox.midtrans.com"
)
MIDTRANS_NOTIFICATION_URL = config("MIDTRANS_NOTIFICATION_URL", default="")

# Celery
CELERY_BROKER_URL = config("CELERY_BROKER_URL", default="redis://localhost:6379/0")
CELERY_RESULT_BACKEND = config("CELERY_RESULT_BACKEND", default="redis://localhost:6379/0")
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"

# REST Framework
REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 20,
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
        "rest_framework.authentication.BasicAuthentication",
    ],
}

# Subscription Settings (all optional, these are defaults)
SUBSCRIPTION_SETTINGS = {
    "PROTECTED_PATHS": [],
    "SUBSCRIPTION_REQUIRED_REDIRECT": "/pricing/",
    "GRACE_PERIOD_DAYS": 3,
    "PAYMENT_EXPIRY_MINUTES": 60,
    "AUTO_GENERATE_INVOICE": True,
    "AUTO_RETRY_FAILED_PAYMENTS": True,
    "MAX_RETRY_ATTEMPTS": 3,
    "RETRY_INTERVAL_DAYS": 1,
    "INVOICE_NUMBER_PREFIX": "INV",
    "SEND_EMAIL_NOTIFICATIONS": True,
    "EXPIRY_REMINDER_DAYS": [7, 3, 1],
}

Step 4: Include URLs

# urls.py
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/subscriptions/", include("subscriptions.urls")),
]

Step 5: Run Migrations and Setup

# Apply database migrations
python manage.py migrate

# Create periodic Celery tasks
python manage.py setup_periodic_tasks

# Seed sample subscription plans (optional, for development)
python manage.py seed_plans

# Create admin superuser
python manage.py createsuperuser

Step 6: Start Services

You need 4 processes running:

# Terminal 1: Redis (message broker)
redis-server

# Terminal 2: Django development server
python manage.py runserver

# Terminal 3: Celery worker (processes async tasks)
celery -A config worker -l info

# Terminal 4: Celery beat (schedules periodic tasks)
celery -A config beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler

Development Setup

Prerequisites

  • Python 3.10+
  • Redis server
  • Git

Clone & Install

git clone https://github.com/rissets/django-subscription-midtrans.git
cd django-subscription-midtrans

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # macOS/Linux
# .venv\Scripts\activate   # Windows

# Install dependencies
pip install -r requirements.txt

# Copy environment file
cp .env.example .env
# Edit .env with your Midtrans sandbox credentials

Midtrans Sandbox Setup

  1. Register at https://dashboard.sandbox.midtrans.com
  2. Get your Server Key and Client Key from Settings → Access Keys
  3. Add them to your .env file
  4. For webhooks, expose your local server:
    # Install ngrok: https://ngrok.com
    ngrok http 8000
    # Copy the HTTPS URL and set MIDTRANS_NOTIFICATION_URL in .env
    

Run the Example App

The project includes a full example application demonstrating all features:

# Apply migrations
python manage.py migrate

# Seed plans and periodic tasks
python manage.py seed_plans --reset
python manage.py setup_periodic_tasks --reset

# Create a superuser for admin access
python manage.py createsuperuser

# Start all services (in separate terminals)
redis-server
python manage.py runserver
celery -A config worker -l info
celery -A config beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler

Then visit:

Test Credentials (Sandbox)

Payment Method Test Details
Credit Card Card: 4811 1111 1111 1114, Exp: 01/29, CVV: 123, OTP: 112233
BCA VA Use the VA number from the response, simulate payment in Midtrans dashboard
BNI VA Use the VA number from the response
GoPay Use the QR code or deeplink from the response
QRIS Scan the QR code with any QRIS-compatible app (sandbox mode)

Running Tests

# Run all subscription tests
python manage.py test subscriptions

# Run specific test module
python manage.py test subscriptions.tests.test_models
python manage.py test subscriptions.tests.test_services
python manage.py test subscriptions.tests.test_views
python manage.py test subscriptions.tests.test_client
python manage.py test subscriptions.tests.test_middleware

# Run with verbosity
python manage.py test subscriptions -v 2

Documentation

Full Sphinx documentation is available in the docs/ directory:

cd docs
pip install -r requirements.txt
make html
# Open docs/_build/html/index.html

API Reference

Plans

Method Endpoint Auth Description
GET /api/subscriptions/plans/ No List all active plans
GET /api/subscriptions/plans/{slug}/ No Get plan details by slug

Subscriptions

Method Endpoint Auth Description
GET /api/subscriptions/subscriptions/ Yes List user's subscriptions
POST /api/subscriptions/subscriptions/ Yes Create subscription
GET /api/subscriptions/subscriptions/{id}/ Yes Get subscription detail
GET /api/subscriptions/subscriptions/active/ Yes Get active subscription
POST /api/subscriptions/subscriptions/{id}/cancel/ Yes Cancel subscription
POST /api/subscriptions/subscriptions/{id}/pause/ Yes Pause subscription
POST /api/subscriptions/subscriptions/{id}/resume/ Yes Resume subscription
POST /api/subscriptions/subscriptions/{id}/change-plan/ Yes Change subscription plan
GET /api/subscriptions/subscriptions/{id}/sync/ Yes Sync with Midtrans

Payments

Method Endpoint Auth Description
GET /api/subscriptions/payments/ Yes List user's payments
GET /api/subscriptions/payments/{id}/ Yes Get payment detail
POST /api/subscriptions/payments/charge/ Yes Create charge for subscription
POST /api/subscriptions/payments/{id}/refund/ Yes Refund a payment
GET /api/subscriptions/payments/{id}/check-status/ Yes Check Midtrans status

Invoices

Method Endpoint Auth Description
GET /api/subscriptions/invoices/ Yes List user's invoices
GET /api/subscriptions/invoices/{id}/ Yes Get invoice detail

Wallet

Method Endpoint Auth Description
GET /api/subscriptions/wallet/me/ Yes Get user's wallet
GET /api/subscriptions/wallet/transactions/ Yes List wallet transactions

Top-Ups

Method Endpoint Auth Description
GET /api/subscriptions/topups/ Yes List user's top-ups
POST /api/subscriptions/topups/ Yes Create a top-up
GET /api/subscriptions/topups/{id}/ Yes Get top-up detail

Notifications

Method Endpoint Auth Description
GET /api/subscriptions/notifications/ Yes List notifications
GET /api/subscriptions/notifications/unread/ Yes Get unread notifications
POST /api/subscriptions/notifications/{id}/mark-read/ Yes Mark notification as read

Webhook

Method Endpoint Auth Description
POST /api/subscriptions/webhook/notification/ No Midtrans webhook handler

API Usage Examples

Create Subscription (Bank Transfer - BCA)
curl -X POST http://localhost:8000/api/subscriptions/subscriptions/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{
    "plan_id": "<plan-uuid>",
    "payment_type": "bank_transfer",
    "customer_details": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com",
      "phone": "081234567890"
    }
  }'

Response:

{
  "id": "uuid",
  "plan": { "name": "Pro Monthly", "price": "299000.00" },
  "status": "pending",
  "payment_type": "bank_transfer",
  "payments": [{
    "order_id": "SUB-xxxxx",
    "status": "pending",
    "payment_details": {
      "bank": "bca",
      "va_number": "9898123456789"
    }
  }]
}
Create Subscription (GoPay)
curl -X POST http://localhost:8000/api/subscriptions/subscriptions/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{
    "plan_id": "<plan-uuid>",
    "payment_type": "gopay"
  }'

Response includes deeplink/QR for GoPay payment.

Create Subscription (QRIS)
curl -X POST http://localhost:8000/api/subscriptions/subscriptions/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{
    "plan_id": "<plan-uuid>",
    "payment_type": "qris"
  }'

Response includes QR code URL for scanning.

Create Subscription (Credit Card)
curl -X POST http://localhost:8000/api/subscriptions/subscriptions/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{
    "plan_id": "<plan-uuid>",
    "payment_type": "credit_card",
    "token": "<card-token-from-midtrans-js>"
  }'
Create Subscription (Wallet)
curl -X POST http://localhost:8000/api/subscriptions/subscriptions/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{
    "plan_id": "<plan-uuid>",
    "payment_type": "wallet"
  }'
Cancel Subscription
curl -X POST http://localhost:8000/api/subscriptions/subscriptions/<uuid>/cancel/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{"reason": "Switching provider", "immediate": false}'
Top Up Wallet
curl -X POST http://localhost:8000/api/subscriptions/topups/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{
    "amount": 500000,
    "payment_type": "bank_transfer",
    "bank": "bca"
  }'
Refund Payment
curl -X POST http://localhost:8000/api/subscriptions/payments/<uuid>/refund/ \
  -H "Content-Type: application/json" \
  -b "sessionid=<your-session-id>" \
  -d '{"amount": 150000, "reason": "Partial refund"}'

Configuration Reference

All settings are configured via SUBSCRIPTION_SETTINGS dict in your Django settings:

SUBSCRIPTION_SETTINGS = {
    # Access Control
    "PROTECTED_PATHS": ["/api/premium/", "/pro-features/"],
    "SUBSCRIPTION_REQUIRED_REDIRECT": "/pricing/",
    
    # Grace Period
    "GRACE_PERIOD_DAYS": 3,  # Days after failed payment to keep access
    
    # Payment
    "PAYMENT_EXPIRY_MINUTES": 60,  # Payment token/VA expiry time
    
    # Invoicing
    "AUTO_GENERATE_INVOICE": True,  # Auto-create invoice on charge
    "INVOICE_NUMBER_PREFIX": "INV",  # Invoice number format: INV-2026-0001
    
    # Retry Logic
    "AUTO_RETRY_FAILED_PAYMENTS": True,
    "MAX_RETRY_ATTEMPTS": 3,
    "RETRY_INTERVAL_DAYS": 1,
    
    # Notifications
    "SEND_EMAIL_NOTIFICATIONS": True,
    "EXPIRY_REMINDER_DAYS": [7, 3, 1],  # Days before expiry to send reminders
}

Subscription Lifecycle

Subscription states and transitions:

From Event To
create_subscription() PENDING
PENDING Payment success ACTIVE
PENDING Plan has trial days TRIALING
PENDING Payment expired/failed EXPIRED
TRIALING Trial ends + payment success ACTIVE
TRIALING Trial ends + payment failed EXPIRED
ACTIVE Renewal payment failed PAST_DUE
ACTIVE User pauses PAUSED
ACTIVE User cancels (immediate) CANCELLED
ACTIVE Period ends + cancel_at_period_end CANCELLED
PAST_DUE Retry payment success ACTIVE
PAST_DUE Grace period expired EXPIRED
PAUSED User resumes ACTIVE
PAUSED User cancels CANCELLED

Two Subscription Modes

Mode Payment Types How It Works
Native Midtrans Subscription Credit Card, GoPay (with account_id) Uses /v1/subscriptions API — Midtrans handles automatic recurring billing
Manual Charge Subscription Bank Transfer, QRIS, ShopeePay, E-Channel, Wallet Each billing cycle creates a new /v2/charge — managed by Celery Beat

Celery Periodic Tasks

Task Schedule Description
process_due_subscriptions Every 1 hour Charges subscriptions with next_billing_date <= now
process_expired_subscriptions Every 6 hours Cancels subscriptions marked cancel_at_period_end
process_past_due_expiration Every 12 hours Expires subscriptions past grace period
retry_failed_payments Every 4 hours Retries failed charges (up to MAX_RETRY_ATTEMPTS)
process_wallet_billing Every 1 hour Deducts wallet balance for wallet-based subscriptions
mark_overdue_invoices Daily 1:00 AM Marks unpaid invoices as overdue
send_expiry_reminders Daily 9:00 AM Sends reminders N days before subscription expiry
sync_midtrans_subscriptions Every 6 hours Syncs native Midtrans subscription statuses
send_pending_email_notifications Every 5 min Processes queued email notifications

Webhook Setup

Configure Midtrans Dashboard

  1. Log in at Midtrans Dashboard (or sandbox)
  2. Go to Settings → Configuration
  3. Set Payment Notification URL: https://yourdomain.com/api/subscriptions/webhook/notification/
  4. Enable notifications for all transaction statuses

Local Development with ngrok

ngrok http 8000
# Example output: https://abc123.ngrok-free.app

# Set in .env:
# MIDTRANS_NOTIFICATION_URL=https://abc123.ngrok-free.app/api/subscriptions/webhook/notification/

Signature Verification

All incoming webhooks are verified using SHA-512:

SHA512(order_id + status_code + gross_amount + server_key) == signature_key

Invalid signatures are rejected and logged. Duplicate notifications are detected and skipped.

Django Signals

Connect to subscription events in your app:

from django.dispatch import receiver
from subscriptions.signals import (
    subscription_activated,
    payment_success,
    payment_failed,
    subscription_plan_changed,
)

@receiver(subscription_activated)
def on_subscription_activated(sender, subscription, **kwargs):
    # Grant access to premium features
    pass

@receiver(payment_success)
def on_payment_success(sender, payment, **kwargs):
    # Send receipt email
    pass

@receiver(payment_failed)
def on_payment_failed(sender, payment, **kwargs):
    # Notify user of failed payment
    pass

@receiver(subscription_plan_changed)
def on_plan_changed(sender, subscription, old_plan, new_plan, **kwargs):
    # Adjust user features
    pass

Available Signals

Signal Arguments Triggered When
subscription_created subscription New subscription created
subscription_activated subscription Subscription becomes active
subscription_cancelled subscription Subscription cancelled
subscription_paused subscription Subscription paused
subscription_resumed subscription Subscription resumed
subscription_expired subscription Subscription expired
subscription_renewed subscription Billing cycle renewed
subscription_plan_changed subscription, old_plan, new_plan Plan changed
payment_created payment New payment created
payment_success payment Payment settled
payment_failed payment Payment failed
payment_refunded payment Payment refunded
invoice_created invoice Invoice generated
invoice_paid invoice Invoice paid
invoice_overdue invoice Invoice past due date
invoice_voided invoice Invoice voided
webhook_received webhook_log Midtrans webhook received
webhook_processed webhook_log Webhook processed
topup_completed topup Wallet top-up completed
wallet_credited transaction Wallet balance increased
wallet_debited transaction Wallet balance decreased

Middleware

Protect routes based on subscription status:

# settings.py
MIDDLEWARE = [
    # ... other middleware
    "subscriptions.middleware.SubscriptionAccessMiddleware",
]

SUBSCRIPTION_SETTINGS = {
    "PROTECTED_PATHS": ["/api/premium/", "/dashboard/pro/"],
    "SUBSCRIPTION_REQUIRED_REDIRECT": "/pricing/",
}

Behavior:

  • API requests without active subscription → 403 JSON response
  • HTML requests without active subscription → redirect to pricing page
  • Staff users always bypass the check
  • Grace period is respected (users with PAST_DUE within grace period still have access)

Admin Dashboard

The package uses Django Unfold for a modern admin interface:

  • Plan Management — Create/edit plans, activate/deactivate, view subscriber counts
  • Subscription Management — Status badges, pause/resume/cancel actions, sync from Midtrans
  • Payment Tracking — View payments with fraud status, check/cancel/expire from admin
  • Invoice Management — View invoices with line items, mark paid, void
  • Webhook Logs — Audit trail of all Midtrans notifications
  • Wallet & Top-Up — View user wallets and transaction history

Access at: http://localhost:8000/admin/

Extending the Package

Custom Signal Handlers

# your_app/signals.py
from django.dispatch import receiver
from subscriptions.signals import subscription_activated

@receiver(subscription_activated)
def grant_premium_access(sender, subscription, **kwargs):
    user = subscription.user
    user.profile.is_premium = True
    user.profile.save()

Override Service Methods

from subscriptions.services import SubscriptionService

class CustomSubscriptionService(SubscriptionService):
    def activate_subscription(self, subscription):
        result = super().activate_subscription(subscription)
        send_welcome_package(subscription.user)
        return result

Proxy Models

from subscriptions.models import Subscription

class PremiumSubscription(Subscription):
    class Meta:
        proxy = True

    def has_feature(self, feature_name):
        return self.plan.features.get(feature_name, False)

Production Deployment

Environment Variables

DJANGO_SECRET_KEY=<strong-random-key>
DJANGO_DEBUG=False
DJANGO_ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com

# PostgreSQL (recommended for production)
DB_ENGINE=django.db.backends.postgresql
DB_NAME=subscription_db
DB_USER=
DB_PASSWORD=
DB_HOST=localhost
DB_PORT=5432

# Redis
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/0

# Midtrans Production
MIDTRANS_SERVER_KEY=
MIDTRANS_CLIENT_KEY=
MIDTRANS_MERCHANT_ID=
MIDTRANS_IS_PRODUCTION=True
MIDTRANS_NOTIFICATION_URL=https://yourdomain.com/api/subscriptions/webhook/notification/

Production Checklist

  • Set DEBUG=False
  • Use PostgreSQL (not SQLite)
  • Set MIDTRANS_IS_PRODUCTION=True
  • Use production Midtrans keys (not sandbox)
  • Configure MIDTRANS_NOTIFICATION_URL to your public HTTPS URL
  • Run python manage.py collectstatic
  • Run python manage.py migrate
  • Run python manage.py setup_periodic_tasks
  • Use a process manager (systemd, supervisor) for Celery workers
  • Configure HTTPS (required by Midtrans for production)
  • Set up monitoring for Celery tasks and webhook logs

Systemd Services

Celery Worker
# /etc/systemd/system/celery-worker.service
[Unit]
Description=Celery Worker
After=network.target redis.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/project
ExecStart=/path/to/venv/bin/celery -A config worker -l info
Restart=always

[Install]
WantedBy=multi-user.target
Celery Beat
# /etc/systemd/system/celery-beat.service
[Unit]
Description=Celery Beat Scheduler
After=network.target redis.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/project
ExecStart=/path/to/venv/bin/celery -A config beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
Restart=always

[Install]
WantedBy=multi-user.target

Docker Compose

docker-compose.yml
version: "3.8"

services:
  web:
    build: .
    command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    env_file: .env
    depends_on:
      - db
      - redis

  db:
    image: postgres:16
    environment:
      POSTGRES_DB: ${DB_NAME:-subscription_db}
      POSTGRES_USER: ${DB_USER:-dbuser}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

  celery-worker:
    build: .
    command: celery -A config worker -l info
    env_file: .env
    depends_on:
      - db
      - redis

  celery-beat:
    build: .
    command: celery -A config beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
    env_file: .env
    depends_on:
      - db
      - redis

volumes:
  pgdata:

Project Structure

Directory Description
config/ Django project settings, Celery config, URL routing, WSGI
subscriptions/ Main reusable package (models, services, views, signals, tasks, admin, middleware, client)
subscriptions/tests/ Test suite with factories
subscriptions/management/commands/ seed_plans, setup_periodic_tasks management commands
example/ Example Django app with template-based views and template tags
templates/example/ HTML templates (Tailwind CSS)
docs/ Sphinx documentation

License

This project is licensed under the MIT License — see the LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Commit your changes: git commit -am 'Add my feature'
  4. Push to the branch: git push origin feature/my-feature
  5. Open a Pull Request

Resources

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_subscription_midtrans-0.1.3.tar.gz (61.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_subscription_midtrans-0.1.3-py3-none-any.whl (62.5 kB view details)

Uploaded Python 3

File details

Details for the file django_subscription_midtrans-0.1.3.tar.gz.

File metadata

File hashes

Hashes for django_subscription_midtrans-0.1.3.tar.gz
Algorithm Hash digest
SHA256 2b19f47f67afbce7e5766056b5d05a64d48412be4e359a5a9ff841e0ff5f0aa3
MD5 039d8761c1c73b2555367bb706bda1af
BLAKE2b-256 9a8e016cbe6ba83df61dadc996590806c2a6224a421185b3996a9dd83f75f9e8

See more details on using hashes here.

File details

Details for the file django_subscription_midtrans-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for django_subscription_midtrans-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 dc00523ef9c09cf3640dc178808832476f777e7b9989993b576831bb6e9e2410
MD5 bd1c03e60197c1f1a02b4cf74e4bdda7
BLAKE2b-256 b74bb5b85a22c6c5b13d10dd7682eed08079949b0a4ebe40d359a0faf38c750f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page