Abuja Digital Studio · Est. 2018
Start a Project
Reference

Dunning

OSubscribeorravo.com/docs/osubscribe/dunning

Dunning

When a charge fails, OSub_Dunning opens a run on wp_osub_dunning_runs and schedules retries according to the configured policy.

Default retry schedule

Four retries at days 1, 3, 5, and 7 after the original failure. OSub_Dunning_Policy::next_retry_at() computes each retry time using:

  • A base offset (1, 3, 5, 7 days)
  • Day-of-week heuristics that push retries away from weekends and onto post-payday windows for insufficient_funds declines
  • Time-of-day push to mid-morning local time, when issuer fraud systems are more lenient

Per-failure-reason policy

Different decline reasons get different treatment. Soft declines (insufficient_funds, try_again_later) retry on the standard schedule. Hard declines (card_declined, expired_card) skip ahead to a payment-method-update magic link.

Run outcomes

Each dunning run carries an outcome column:

  • recovering - retries in flight
  • recovered - a retry succeeded; the subscription returns to active
  • exhausted - all retries failed; final action runs

Final action

When retries exhaust, OSub_Dunning::exhaust() performs the configured final action. Two options:

  • pause - pause the subscription with reason dunning_exhausted
  • cancel (default) - transition to cancelled with reason dunning_exhausted

Magic-link recovery

Every failed charge attaches a magic link via OSub_Magic_Links. The customer clicks the link, lands on a hosted payment-method-update page, swaps to a working card, and the worker picks up the next retry.

Tick cleanup

OSub_Dunning::tick() runs hourly. It walks recovering runs older than 60 days with no progress and marks them exhausted, so the table does not grow unbounded.

Recovery rate

OSub_Analytics::dunning_recovery_rate($days) returns the percentage of dunning runs that ended in recovered over the window. Surfaced on the Dashboard and the Reports page.

ML pipeline

OSub_ML_Pipeline collects features (decline reason, attempt number, day-of-week, hour) on every retry outcome. The collected data feeds a future model that picks the next retry time per customer.

Dunning · OSubscribe Docs | Orravo