# Configuration ## SUBSCRIPTION_SETTINGS All settings are configured via a single `SUBSCRIPTION_SETTINGS` dictionary in your Django `settings.py`. ```python SUBSCRIPTION_SETTINGS = { # Grace period in days after subscription expires before disabling access "GRACE_PERIOD_DAYS": 3, # Auto-retry failed payments "AUTO_RETRY_FAILED_PAYMENTS": True, # Max retry attempts for failed subscription charges "MAX_RETRY_ATTEMPTS": 3, # Days between retry attempts "RETRY_INTERVAL_DAYS": 1, # Invoice auto-generation on each charge "AUTO_GENERATE_INVOICE": True, # Invoice number prefix "INVOICE_NUMBER_PREFIX": "INV", # Send email notifications via Celery "SEND_EMAIL_NOTIFICATIONS": True, # Days before expiry to send reminder notifications "EXPIRY_REMINDER_DAYS": [7, 3, 1], # Default currency code "CURRENCY": "IDR", # Default payment expiry in minutes "PAYMENT_EXPIRY_MINUTES": 60, # Paths requiring active subscription (middleware) "PROTECTED_PATHS": [], # Redirect URL for unauthenticated/unsubscribed users "SUBSCRIPTION_REQUIRED_REDIRECT": "/pricing/", } ``` ### Setting Reference | Setting | Type | Default | Description | |---------|------|---------|-------------| | `GRACE_PERIOD_DAYS` | `int` | `3` | Days after period end before access is revoked for past-due subscriptions | | `AUTO_RETRY_FAILED_PAYMENTS` | `bool` | `True` | Automatically retry failed payments via Celery task | | `MAX_RETRY_ATTEMPTS` | `int` | `3` | Maximum number of retry attempts for failed subscription charges | | `RETRY_INTERVAL_DAYS` | `int` | `1` | Number of days between retry attempts | | `AUTO_GENERATE_INVOICE` | `bool` | `True` | Generate an invoice automatically for each charge | | `INVOICE_NUMBER_PREFIX` | `str` | `"INV"` | Prefix for invoice numbers (e.g., `INV-202501-00001`) | | `SEND_EMAIL_NOTIFICATIONS` | `bool` | `True` | Enable email notifications via Celery task | | `EXPIRY_REMINDER_DAYS` | `list[int]` | `[7, 3, 1]` | Send reminder notifications N days before subscription expiry | | `CURRENCY` | `str` | `"IDR"` | Default currency code for new wallets | | `PAYMENT_EXPIRY_MINUTES` | `int` | `60` | Payment expiry window in minutes | | `PROTECTED_PATHS` | `list[str]` | `[]` | URL path prefixes that require an active subscription | | `SUBSCRIPTION_REQUIRED_REDIRECT` | `str` | `"/pricing/"` | Redirect URL for HTML requests when subscription is required | ## Midtrans Settings These settings configure the Midtrans payment gateway connection: ```python # settings.py from decouple import config 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_NOTIFICATION_URL = config("MIDTRANS_NOTIFICATION_URL", default="") # Computed: do not set manually MIDTRANS_API_BASE_URL = ( "https://api.midtrans.com" if MIDTRANS_IS_PRODUCTION else "https://api.sandbox.midtrans.com" ) ``` | Setting | Description | |---------|-------------| | `MIDTRANS_SERVER_KEY` | Server key from [Midtrans Dashboard](https://dashboard.midtrans.com) → Settings → Access Keys | | `MIDTRANS_CLIENT_KEY` | Client key for frontend tokenization | | `MIDTRANS_MERCHANT_ID` | Your Midtrans merchant ID | | `MIDTRANS_IS_PRODUCTION` | `False` for sandbox, `True` for production | | `MIDTRANS_NOTIFICATION_URL` | Webhook URL Midtrans will call for payment notifications | | `MIDTRANS_API_BASE_URL` | Auto-computed from `MIDTRANS_IS_PRODUCTION` | :::{warning} Never commit real Midtrans keys to version control. Always use environment variables. ::: ## Celery Settings Required Celery configuration: ```python 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_ACCEPT_CONTENT = ["json"] CELERY_TASK_SERIALIZER = "json" CELERY_RESULT_SERIALIZER = "json" CELERY_TIMEZONE = "Asia/Jakarta" CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" ``` ## REST Framework Settings Recommended DRF configuration: ```python REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination", "PAGE_SIZE": 20, "DEFAULT_FILTER_BACKENDS": [ "django_filters.rest_framework.DjangoFilterBackend", "rest_framework.filters.SearchFilter", "rest_framework.filters.OrderingFilter", ], "DEFAULT_PERMISSION_CLASSES": [ "rest_framework.permissions.IsAuthenticated", ], "DEFAULT_AUTHENTICATION_CLASSES": [ "rest_framework.authentication.SessionAuthentication", "rest_framework.authentication.BasicAuthentication", ], } ``` ## Environment Variables (.env) Complete `.env` template with all values empty by default: ```env # Django DJANGO_SECRET_KEY= DJANGO_DEBUG=True DJANGO_ALLOWED_HOSTS=*,localhost,127.0.0.1 # Database (optional, defaults to SQLite) DB_ENGINE=django.db.backends.sqlite3 DB_NAME= DB_USER= DB_PASSWORD= DB_HOST= DB_PORT= # Celery / Redis CELERY_BROKER_URL=redis://localhost:6379/0 CELERY_RESULT_BACKEND=redis://localhost:6379/0 # Midtrans MIDTRANS_SERVER_KEY= MIDTRANS_CLIENT_KEY= MIDTRANS_MERCHANT_ID= MIDTRANS_IS_PRODUCTION=False MIDTRANS_NOTIFICATION_URL= ```