Agent Wranglers

Subscriptions Required

Give access from the subscription status

Decide access in one function from the stored subscription status, period end and first failed payment time, with a fixed grace period for failed renewals.

How to do it

Map each status to access in one place. Active and trialing give access. Past due gives access for a grace period, such as 7 days, while retries run. Count the grace from the time of the first failed renewal, stored from the failure event. Many providers move the period end forward when they bill the renewal, so a grace counted from it gives a free month. A cancelled subscription keeps access until the paid period ends. Unpaid or ended gives none. Every page, API and background job asks that one function.

Example

const GRACE_DAYS = 7
const DAY_MS = 24 * 60 * 60 * 1000

function hasAccess(subscription, now = new Date()) {
  const periodEnd = subscription.currentPeriodEnd.getTime()
  switch (subscription.status) {
    case 'active':
    case 'trialing':
      return true
    case 'past_due':
      return now.getTime() < subscription.firstFailedAt.getTime() + GRACE_DAYS * DAY_MS
    case 'canceled':
      return now.getTime() < periodEnd
    default:
      return false
  }
}
from datetime import datetime, timedelta, timezone

GRACE = timedelta(days=7)

def has_access(subscription, now: datetime | None = None) -> bool:
    now = now or datetime.now(timezone.utc)
    match subscription.status:
        case "active" | "trialing":
            return True
        case "past_due":
            return now < subscription.first_failed_at + GRACE
        case "canceled":
            return now < subscription.current_period_end
        case _:
            return False

How to check

A table test covers every status on the day before and the day after the period end and the grace end. A past due subscription whose period end lies a month ahead loses access 7 days after its failed payment. Search the code for direct reads of the status field outside that function. None are found.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers payments playbook: https://agentwranglers.se/playbook/payments/subscriptions/entitlements-from-status.