Skip to Content

Subscription Dunning & Fa

74.55 74.55

Instant digital delivery after payment confirmation.
License: OPL-1, every download is watermarked.
Terms and Conditions
Compatible with Odoo 18.0 · 19.0
OPL-1 license · Odoo 18.0 & 19.0
Subscription Dunning & Fa for Odoo — preview banner

Subscription Dunning & Fa

Smart retry, card-expiry nudges and involuntary-churn recovery for failed renewals (BYOK PSP)

Failed card renewals are silent revenue leaks: a declined charge quietly cancels a subscription and the customer churns without ever meaning to. Chasing those failures by hand is slow and most teams simply lose the revenue. This module adds a full dunning engine on top of Odoo invoicing for SaaS and subscription businesses, with configurable retry back-off, soft/hard decline routing, card-expiry nudges and escalating recovery campaigns that suspend or cancel only when every attempt is exhausted. A cron drives it hands-free, and it runs on your own payment-provider keys (BYOK) so no card data is ever stored or proxied in Odoo.

Key Features

Configurable retry plans with back-off

gb.dunning.plan sets max_attempts, grace_days and ordered gb.dunning.plan.step rows with per-step delay_hours. get_delay_for_attempt returns the wait before each retry, falling back to an exponential 6h/24h/72h/168h schedule when no explicit steps are defined.

Soft vs hard decline routing

classify_reason matches the PSP reason code against the plan's soft_decline_reasons (insufficient funds, issuer unavailable) and hard_decline_reasons (lost/stolen card, do-not-honor). Soft declines are rescheduled while a hard decline aborts retries immediately, so effort goes where it can succeed.

Card-expiry nudges

gb.dunning.campaign stores card_last4, card_exp_month and card_exp_year. _is_card_expiring compares against the plan's expiry_nudge_days, and _send_expiry_nudge emails the customer before the token expires, setting card_expiry_warned so the reminder is sent once.

Per-invoice recovery campaigns

Each failed account.move out_invoice drives a campaign through draft, active, recovered, suspended and cancelled states on mail.thread. run_retry charges, logs the outcome and either marks recovered or schedules the next_attempt_date until max_attempts or the grace_deadline is reached.

Configurable exhaustion action

When all retries fail, _finalise_exhausted applies the plan's final_action: suspend the campaign (when auto_suspend is on), cancel it, or schedule a mail todo activity for manual review. Recovery never silently drops a customer without the action you chose.

Full attempt log and KPIs

Every cycle writes a gb.dunning.attempt with attempt_number, success/failed state, reason_code and charged amount; _compute_reason_class tags each as success/soft/hard. Campaigns roll up attempt_count, failed_count and recovered_amount so you can measure revenue saved.

Hands-free cron processing

cron_process_due_campaigns runs run_retry on every active campaign whose next_attempt_date is due, keeping the batch alive past individual errors. cron_expiry_nudges sweeps active campaigns for soon-to-expire cards, so the whole recovery flow runs unattended.

BYOK PSP, no card data stored

_charge posts a real HTTP request to the customer's own PSP (Stripe, Adyen, Braintree, GoCardless or a custom HTTP gateway) using the campaign's own psp_api_key/psp_api_secret and the stored psp_token_ref; no PAN is ever held in Odoo, only last-4 and expiry for display. Without an API key the campaign simply runs in simulation/preview mode instead of failing. An account.move action_open_dunning button and start_dunning_for_overdue helper launch campaigns from invoices.

Use Cases

A SaaS finance team recovers failed monthly renewals automatically with a 4-step back-off plan instead of manual chasing.
A subscription business nudges customers whose cards expire next month so the renewal does not fail in the first place.
An accounts-receivable clerk launches a dunning campaign straight from an overdue invoice with one button.
A revenue operations lead reviews recovered_amount across campaigns to quantify revenue saved from involuntary churn.
A billing admin routes hard declines (lost/stolen card) straight to customer outreach rather than wasting retry attempts.
A controller sets the final action to manual review so a person checks high-value accounts before any suspension.

Screenshots

Subscription Dunning & Fa — Retry Attempts in Odoo

Retry Attempts

Subscription Dunning & Fa — Dunning Campaigns in Odoo

Dunning Campaigns

Subscription Dunning & Fa — Dunning Plans in Odoo

Dunning Plans

Subscription Dunning & Fa — Run Dunning Retries in Odoo

Run Dunning Retries

Why Choose This Module

Failed card renewals are silent revenue leaks. This module adds a full dunning engine on top of Odoo invoicing and subscriptions: smart retry schedules, card-expiry reminders before the next charge, and escalating recovery campaigns that suspend or cancel only when every attempt is exhausted. It runs on your own payment-provider keys (BYOK) — we never store or proxy card data.

Specifications

  • Compatible: Odoo 18.0 / 19.0
  • License: OPL-1
  • Languages: English
  • Author: Pokutsoft
  • Dependencies: account, mail
  • Support: support@pokutsoft.com

Update date: 2026-07-16