All Docs
FeaturesSaaS FactoryUpdated February 19, 2026

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

EntityRole
subscriptionsPrimary target — records are read and status is updated
customersSecondary target — status updated when fully churned
winBackCampaignsOutput — 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.