Skip to content
CogniYukti

Recurring

A scheduled job should never move money out of the business.

Somebody downgrades mid-cycle. A perfectly symmetric system refunds the difference at three in the morning, with no approval, on a decision nobody reviewed.

The asymmetry here is deliberate, and it is the thing to explain to a customer before they ask.

Proration

Up is a charge now. Down is a credit on the next invoice.

Upgrading mid-cycle bills the difference for the days remaining, as its own document. Downgrading does not refund — the credit is held and appears as a negative line on the next cycle, and is cleared once applied so it cannot be taken twice.

Mid-cycle change
They upgradeThe difference for the days remaining is invoiced immediately, as its own document.
They downgradeNothing is refunded. The credit is held and appears as a negative line on the next cycle's invoice.
Deliberate, and worth explaining to a customer before they ask. Money leaving the business is a decision somebody makes — not something a scheduled job does at three in the morning.
Illustrative
  • An upgrade that is cheaper returns nothing

    And a downgrade that is more expensive does the same. The two refuse to do each other's job rather than producing a negative charge.

  • A scheduled job cannot raise a charge at all

    Only a request made by a person can, because minting an invoice needs somebody to attribute it to. Stated in the code as the reason.

  • Pausing gives the days back

    Resuming extends the period by exactly how long it was paused, rather than resuming into a period that quietly shrank.

  • Reactivation has a window, and refuses politely

    Past it, you are told to create a new subscription rather than being allowed to resurrect something whose terms have moved on.

  • Add-ons bill at the price when they were added

    Not at today's plan price.

Running the cycle

Retries that stop, and a plan that cannot change under a live subscription.

A failed charge retries a small number of times across about a week, pushing the next attempt forward each time rather than retrying every minute. After the last one it stops and the subscription is marked as needing attention. A successful charge on a subscription in that state brings it back.

And the parts of a plan that determine price cannot be edited while anybody is live on it — the price, the period, the code. Everything descriptive stays editable. The refusal names what to do instead.

  • A cycle cannot run twice for the same period

    Guaranteed in the database.

  • A trial ending rolls into the first real cycle in one pass

    Rather than waiting a day.

  • The reminder before a trial ends fires once

    Marked so it cannot repeat.

  • Every change writes both sides

    What it was and what it became, so the timeline can be replayed without reconstructing it from events.

What does the recurring revenue number count?

Monthly-normalised value of active subscriptions — trials are counted in the subscription count and deliberately kept out of the revenue figure. Customers are counted distinctly, not per subscription.

Does it convert currencies?

No. If you sell in several, read the number per currency rather than as a single total — a combined figure would be adding unlike units.

When is revenue recognised?

When an invoice is actually paid, not when it is raised — so revenue is never inflated against something that later voids. It spreads across the service period and catches up correctly after a missed run without ever over-recognising.

Can we bill a flat monthly retainer without a plan?

Not automatically. Recurrence lives in subscriptions and plans; a recurring invoice schedule outside that does not exist.