Celery Tasks

All tasks are defined in subscriptions.tasks and are designed to run via Celery Beat (periodic scheduling).

Setup

Run the management command to register periodic tasks in Django Celery Beat:

python manage.py setup_periodic_tasks

Start the Celery worker and beat scheduler:

# Worker
celery -A config worker -l info

# Beat (periodic scheduler)
celery -A config beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler

Task Reference

process_due_subscriptions

Schedule: Every hour
Retries: 3 (60s delay)

Processes all subscriptions due for billing. Creates a charge via Midtrans for each due subscription. Skips native Midtrans subscriptions (they handle billing internally). Expires subscriptions that have reached max_cycles.

process_expired_subscriptions

Schedule: Every 6 hours

Finds subscriptions marked as cancel_at_period_end=True whose period has ended, and cancels them.

process_past_due_expiration

Schedule: Every 6 hours

Expires subscriptions that have been past_due beyond the grace period (GRACE_PERIOD_DAYS).

retry_failed_payments

Schedule: Every 3 hours

Retries failed payments for past-due subscriptions. Respects:

  • AUTO_RETRY_FAILED_PAYMENTS — Enable/disable

  • MAX_RETRY_ATTEMPTS — Maximum retries (default: 3)

  • RETRY_INTERVAL_DAYS — Days between retries (default: 1)

mark_overdue_invoices

Schedule: Daily at midnight

Marks invoices past their due_date as overdue and creates notification log entries.

send_expiry_reminders

Schedule: Daily at 9:00 AM

Sends reminder notifications for subscriptions expiring within EXPIRY_REMINDER_DAYS (default: 7, 3, and 1 days). Prevents duplicate reminders for the same day.

sync_midtrans_subscriptions

Schedule: Every 6 hours

Syncs subscription status from Midtrans API for all subscriptions with a midtrans_subscription_id. Ensures local state matches Midtrans.

process_wallet_billing

Schedule: Every hour
Retries: 3 (60s delay)

Processes billing for wallet-paid subscriptions. Debits the user’s wallet for due subscriptions. If insufficient balance, marks the subscription as past_due.

check_pending_payment_status

Schedule: On-demand (not periodic)

Checks the status of a specific pending payment from Midtrans. Useful when webhook notifications are missed.

from subscriptions.tasks import check_pending_payment_status

check_pending_payment_status.delay(str(payment.id))

send_pending_email_notifications

Schedule: Every 5 minutes

Processes queued email notifications and sends them via Django’s send_mail(). Batches up to 100 notifications per run.

Task Summary Table

Task

Schedule

Description

process_due_subscriptions

Every hour

Bill due subscriptions

process_expired_subscriptions

Every 6 hours

Cancel subscriptions at period end

process_past_due_expiration

Every 6 hours

Expire past-due beyond grace period

retry_failed_payments

Every 3 hours

Retry failed charges

mark_overdue_invoices

Daily midnight

Mark overdue invoices

send_expiry_reminders

Daily 9 AM

Send expiry reminders

sync_midtrans_subscriptions

Every 6 hours

Sync with Midtrans API

process_wallet_billing

Every hour

Bill wallet subscriptions

send_pending_email_notifications

Every 5 min

Send queued emails

Customizing Schedules

After setup_periodic_tasks, you can modify schedules in the Django admin under “Periodic Tasks” (Celery section).

You can also override the setup command or add custom tasks by subclassing the management command.