Scheduled Subscription Cancellation Processor
Scheduled Subscription Cancellation Processor
Introduced in: v1.0.36
Workflow Type: State Machine
Schedule: 0 6 * * * — runs once daily at 06:00 UTC
Overview
The Scheduled Subscription Cancellation Processor is an autonomous daily workflow that finalizes pending subscription cancellations, updates customer statuses, and automatically triggers win-back campaigns for churned customers. No manual intervention is required at any stage.
Trigger
The workflow runs on a cron schedule:
0 6 * * *
This evaluates once every 24 hours at 06:00 UTC.
Processing Logic
The workflow follows a deterministic state machine sequence:
Step 1 — Identify Overdue Cancellations
The processor queries the subscriptions table for all records matching:
cancelAt <= NOW()
AND status != 'cancelled'
This captures any subscription whose scheduled cancellation date has been reached but has not yet been formally closed — including cases where cancelAt was set in the past (e.g. due to a missed run or a backdated cancellation request).
Step 2 — Transition Subscription Status
Each matched subscription is transitioned:
status → 'cancelled'
The update is applied atomically per record to prevent partial state.
Step 3 — Evaluate Customer Status
After cancelling a subscription, the workflow checks whether the associated customer retains any other subscriptions with an active status.
- No remaining active subscriptions → customer status is updated to reflect full cancellation.
- Other active subscriptions exist → customer status is left unchanged.
This ensures customers with multiple subscriptions are not incorrectly marked as churned.
Step 4 — Trigger Win-Back Campaign
For every customer whose status transitions to cancelled (Step 3), the workflow emits a winBackCampaign creation event. This event is consumed by the marketing automation pipeline to initiate a re-engagement sequence.
Entities
| Entity | Role |
|---|---|
subscriptions | Primary target — records are read and status is updated |
customers | Secondary target — status updated when fully churned |
winBackCampaigns | Output — campaign creation events emitted for churned customers |
Behavior Summary
Every day at 06:00 UTC:
FOR each subscription WHERE cancelAt <= NOW() AND status != 'cancelled':
SET subscription.status = 'cancelled'
IF customer has no other active subscriptions:
UPDATE customer.status → cancelled
EMIT winBackCampaign creation event
Notes
- The daily sweep is idempotent — re-running it on already-cancelled subscriptions produces no side effects because the
status != 'cancelled'filter excludes them. - Win-back campaigns are only created for customers who become fully churned. Partial cancellations (where the customer retains at least one active subscription) do not trigger a campaign.
- If the 06:00 UTC run is missed, the next scheduled execution will catch up on all overdue cancellations because the filter uses
<= NOW()rather than an exact date match.