Skip to main content
Dunning is the process of automatically retrying a failed subscription payment before giving up and canceling the subscription. Subscribd handles this entirely within the package: a ProcessDunning job is queued and scheduled hourly by the service provider, works through your configured retry sequence, and optionally cancels subscriptions that exhaust all retries.

How dunning works

When a payment fails, Subscribd marks the subscription as past_due and records the failure. On each subsequent scheduler run, the package checks whether enough time has passed since the last attempt and, if so, retries the charge. If the retry succeeds, the subscription returns to active. If all retries fail and cancel_after_final_retry is true, the subscription is canceled automatically.

Configure the retry schedule

Open config/subscribd.php and set the dunning block:
'dunning' => [
    'enabled'                  => true,
    'retries'                  => [24, 72, 168],  // hours between retry attempts
    'cancel_after_final_retry' => true,
],
The retries array defines the delay in hours between each attempt after the initial failure. The example above retries after 1 day, 3 days, and 7 days — three total retries. You can add or remove entries to suit your billing policy.

Configuration reference

KeyTypeDescription
enabledboolSet to false to disable dunning entirely
retriesint[]Hours to wait before each successive retry attempt
cancel_after_final_retryboolCancel the subscription when all retries are exhausted
Setting cancel_after_final_retry to false leaves subscriptions in past_due indefinitely. You are responsible for handling those subscriptions in your application if you disable automatic cancellation.

No manual scheduling required

The ProcessDunning job is registered with Laravel’s scheduler automatically by Subscribd’s service provider. As long as your application runs php artisan schedule:run on its normal cadence (typically every minute via cron), dunning retries fire without any additional configuration.
# Standard Laravel scheduler cron entry — no changes needed
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
The scheduler fires hourly and checks each past_due subscription against the retry schedule. Only subscriptions whose next retry time has elapsed are processed, so the job remains efficient even at scale.

Responding to dunning events

Use the PaymentFailed and SubscriptionCanceled events in your EventServiceProvider to notify customers at each stage. See the Webhooks guide for listener examples.