Donation Recovery automatically captures donor intent on your fundraising forms and sends a personalized reminder email when a donation is left incomplete. When a donor returns via the recovery link, their form is pre-filled so they can complete their gift in seconds.
Available in Charitable Pro 1.8.13.5+.
Key Features
- Silently tracks donor activity (email, name, amount) as donors fill out donation forms
- Automatically detects abandoned sessions using a background cron job
- Sends a branded HTML recovery email with a one-click “Complete My Gift” link
- Pre-fills the donation form with the donor’s previously entered details when they return
- Built-in unsubscribe mechanism on every recovery email
- Per-campaign scope control: choose exactly which campaigns participate
- Dedicated Reports tab with date-filtered stats, a sessions table, and CSV export
- Recovery stats surface directly in the Reports Overview tile
Why Use Donation Recovery?
Even motivated donors abandon donation forms – a distraction, a slow page load, or an interruption can end a session before it converts. Donation Recovery catches those moments automatically and gives donors a frictionless path back to completing their gift, without any manual follow-up from your team.
See It In Action
Requirements
- Charitable Pro 1.8.13.1 or later
- WordPress 6.2 or later
- PHP 7.2 or later
- WP-Cron enabled (or an external cron trigger)
Getting Started
Activation
- In your WordPress admin, go to Charitable > Settings > General.
- Click the Donation Recovery sub-tab.
- Check Enable Donation Recovery.
- Under Campaign Recovery Scope, select the campaigns you want to track. No campaigns are included by default.
- Click Save Settings.
Recovery is now active for the selected campaigns. Sessions will be detected and emails scheduled automatically.
Configuration Options
All settings live at Charitable > Settings > General > Donation Recovery.
Core Settings
| Setting | Type | Default | Description |
|---|---|---|---|
| Enable Donation Recovery | Checkbox | Enabled | Master on/off switch for the entire feature. |
| Abandonment Cutoff | Number (minutes) | 60 | Minutes of inactivity before a session is marked abandoned. Min: 15. Max: 1440 (24 hours). |
| Session Retention | Number (days) | 90 | How many days session records are kept before automatic cleanup. Min: 30. Max: 365. |
Campaign Recovery Scope
Select which campaigns participate in recovery. The list shows all published, non-expired campaigns along with each campaign’s all-time session count, recovered count, and recovery rate. A search box and Select All / Deselect All buttons help manage large campaign lists.
| Option | Description |
|---|---|
| Campaign checkboxes | Select individual campaigns to enable recovery tracking. |
| Include new campaigns automatically | When checked, any newly published campaign is automatically added to the recovery scope. |
Note: Charitable Ambassadors peer-to-peer campaigns are not supported and are excluded from this list.
Recovery Email Sender
| Setting | Type | Default | Description |
|---|---|---|---|
| Recovery Email: From Name | Text | Your site name | The name displayed in the “From” field of recovery emails. |
| Recovery Email: From Address | WordPress admin email | The email address used as the sender for recovery emails. |
How Tracking Works
When a donor visits a donation form page for an active recovery campaign, a lightweight JavaScript tracker loads in the background. It listens for changes to the email, first name, last name, and amount fields.
When the donor enters a valid email address (on blur), the tracker sends the captured data to a REST API endpoint at /charitable-recovery/v1/capture. The endpoint is nonce-authenticated and rate-limited to 20 requests per minute per IP address. No data is stored until a valid email address is present.
The tracker captures:
- Email address
- First name and last name (if entered)
- Donation amount
- Donation period (one-time or recurring, if applicable)
- Source URL (the page the donor was on when they filled out the form)
The tracker runs on both legacy donation forms and Visual Form Builder (VFB) forms.
Note: The tracker is a JavaScript file that loads on donation form pages. If another plugin or your theme produces a JavaScript error on the same page, it may prevent the tracker from initializing. This would cause no sessions to be captured, even when donors fill out the form. See the Troubleshooting section for steps to diagnose JavaScript conflicts.
Abandonment Detection
A WP-Cron job runs every 5 minutes (charitable_recovery_detect_abandoned). On each run, it identifies sessions that have been in “tracking” status for longer than the configured Abandonment Cutoff period and marks them as abandoned.
Sessions are automatically cleaned up after the configured Session Retention period.
About WP-Cron
WordPress uses a virtual cron system called WP-Cron. Unlike a traditional server cron job, WP-Cron only fires when someone visits your site – it piggybacks on regular page loads. Under normal traffic conditions this works well, but there are situations where it can be unreliable:
- Low-traffic sites: If your site receives very few visitors, scheduled tasks may fire significantly later than expected. A recovery email scheduled for 1 hour after abandonment might not actually send until the next visitor loads a page.
DISABLE_WP_CRONset totrue: Some hosts and performance plugins setdefine( 'DISABLE_WP_CRON', true );inwp-config.phpto reduce page load overhead. If this is set without a real server cron to replace it, abandonment detection and email sending will stop entirely.- Plugin conflicts: Some plugins incorrectly clear all scheduled events on activation or deactivation, or they may prevent new events from being registered. If this happens, the
charitable_recovery_detect_abandonedevent may disappear from the schedule without warning. Recovery emails will stop sending until the plugin is deactivated and the site is re-saved. - Shared hosting resource limits: On heavily loaded shared hosting, PHP execution may be killed before cron jobs finish processing a large batch of sessions.
If recovery emails are delayed or not sending at all, WP-Cron is the first thing to investigate. See the Troubleshooting section below for steps and recommended tools.
Recovery Emails
After a session is marked abandoned, a recovery email is scheduled to send approximately 1 hour later via WP-Cron.
Email Content
The recovery email includes:
- A personalized greeting using the donor’s first name (or “Hi there,” if no name was captured)
- The campaign name the donor was donating to
- A green “Complete My Gift” call-to-action button
- A plain-text fallback URL
- An unsubscribe link in the footer
Email Security
Recovery links use signed HMAC tokens (SHA-256) that expire after 7 days. Tokens are bound to the session key, email ID, and expiry timestamp – they cannot be reused across different sessions. If a token is expired or invalid, the donor is redirected to the site homepage.
Skipped Emails
An email is not sent if:
- The donor’s email address is on the unsubscribe list
- The campaign has ended before the email is sent
- A recovery email has already been sent for this session
- The session has already been marked as recovered, unsubscribed, or expired
Donor Return and Form Pre-Fill
When a donor clicks the recovery link, they are redirected back to the page where they originally started their donation (using the captured source_url). Their form is automatically pre-filled with:
- Email address
- First name and last name
- Donation amount (matched to a preset radio button, or entered in the custom amount field)
Pre-fill runs on DOM-ready and again after 400 ms to support dynamically rendered forms. Pre-fill never overwrites a field the donor has already typed in.
Unsubscribing
Every recovery email includes an unsubscribe link. When a donor clicks it, their email address is added to a suppression list and no further recovery emails are sent to that address from your site.
Reports and Analytics
Donation Recovery has a dedicated tab in Charitable > Reports > Donation Recovery.
Stats Tiles
| Tile | Description |
|---|---|
| Total Tracked | Sessions where an email address was captured. |
| Abandoned | Sessions that passed the abandonment cutoff. |
| Recovered | Sessions where the donor completed their donation after receiving a recovery email. |
| Recovery Rate | Recovered donations as a percentage of abandoned sessions. |
| Recovered Revenue | Total donation value from recovered sessions. |
All tiles respond to the date range filter at the top of the page.
Date Range Filter
Use the date pickers to filter all stats and the sessions table to a custom range. Quick-select presets are available for Last 7 days, Last 30 days, and Last 90 days.
Sessions Table
Shows up to 50 sessions for the selected date range, ordered by most recently modified. Each row displays donor name, email, campaign, amount, status badge, email count, and timestamps.
Session statuses:
– Tracking – active session, donor is still on the form
– Abandoned – session passed the cutoff without completion
– Recovered – donor completed their donation
– Unsubscribed – donor clicked the unsubscribe link
– Expired – session was cleaned up by the retention policy
CSV Export
Click Download CSV on the Sessions table to export all sessions (no row limit) for the active date range. The CSV includes first name, last name, email, campaign, amount, currency, status, emails sent, donation ID, date created, and date modified.
Recovery Overview Hint
The Reports Overview tab shows a recovery hint directly beneath the Total Donations tile. The hint shows how many donations were recovered and the recovered revenue for the current Overview date range. It updates automatically when you change the Overview date filter.
Recovery by Campaign
Below the sessions table, a per-campaign breakdown shows total sessions, abandoned, recovered, and revenue for each campaign within the date range.
Template Customization
The recovery email HTML template can be overridden in your theme:
your-theme/charitable/emails/recovery-immediate.php
Copy the original from wp-content/plugins/charitable-recovery/templates/emails/recovery-immediate.php to your theme folder and modify as needed. The following variables are available in the template:
| Variable | Description |
|---|---|
$session | The session object (email, firstname, lastname, amount, campaign_id, etc.) |
$recovery_url | The signed recovery URL for the CTA button |
$unsub_url | The one-click unsubscribe URL |
Developer Resources
Hooks and Filters
charitable_recovery_detect_abandoned— WP-Cron action hook; fires every 5 minutes to detect abandoned sessions. You can hook into this to run additional logic after abandonment detection.charitable_recovery_send_email— WP-Cron action hook; fires once per scheduled recovery email. Receives the$email_row_idas its first argument.
REST Endpoint
The tracker submits data to:
POST /wp-json/charitable-recovery/v1/capture
Requires a valid X-WP-Nonce header. Rate-limited to 20 requests per minute per IP address. Accepts application/json.
Settings API
Recovery settings are stored under the charitable_settings option in the general__recovery group. Access them via:
charitable_get_option( array( 'general__recovery', 'recovery_enabled' ), 1 );
charitable_get_option( array( 'general__recovery', 'abandonment_cutoff' ), 60 );
charitable_get_option( array( 'general__recovery', 'session_retention_days' ), 90 );
charitable_get_option( array( 'general__recovery', 'recovery_sender_name' ), get_bloginfo('name') );
charitable_get_option( array( 'general__recovery', 'recovery_sender_email' ), get_option('admin_email') );
charitable_get_option( array( 'general__recovery', 'recovery_campaign_ids' ), array() );
charitable_get_option( array( 'general__recovery', 'recovery_include_new_campaigns' ), 0 );
Troubleshooting
Recovery emails are not being sent
The most common cause is a WP-Cron problem. Work through these checks in order:
- Confirm WP-Cron is not disabled. Open
wp-config.phpand check whetherDISABLE_WP_CRONis defined. If it is set totrue, WP-Cron will not fire at all unless you have a real server cron job set up to trigger it manually. Contact your host if you are unsure how to configure a server cron for WordPress. - Check for a conflicting plugin. Some caching, performance, and security plugins interact with WP-Cron in ways that clear or block scheduled events. If you recently activated or deactivated another plugin and emails stopped, that plugin is a likely suspect. Try deactivating it temporarily and checking whether recovery events reappear.
- Inspect the scheduled events directly. Install a free plugin such as WP Crontrol (available on WordPress.org) to view all scheduled events. Once installed, go to Tools > Cron Events and look for
charitable_recovery_detect_abandoned. If it is missing, save the Donation Recovery settings page once to re-register it. If it keeps disappearing after re-registration, a conflicting plugin is likely removing it. - Confirm campaign scope and unsubscribe status. Verify that the affected campaign is selected under Campaign Recovery Scope and that the donor’s email address is not on the suppression list.
- Contact your host. If WP-Cron appears to be running but emails still do not arrive, your host may be blocking outbound email from PHP’s
mail()function. Ask them whether they require an SMTP plugin for reliable email delivery.
If you have worked through all of the above and emails are still not sending, contact Charitable support with a description of what you found in WP Crontrol.
The donation form is not being pre-filled on return
The source_url recorded when the donor originally filled out the form is used for the redirect. If the form was embedded on a page that has since changed URL, the redirect target may no longer match. Check that the campaign is using the correct permalink and that the recovery plugin’s JavaScript tracker loaded on the original form page.
A donor keeps receiving emails after unsubscribing
The suppression list is stored in the WordPress options table as charitable_recovery_unsubscribed_emails. Confirm the entry is present with correct capitalization. The comparison is case-insensitive, but the email must be stored without leading or trailing spaces.
No sessions are being tracked (the Reports tab shows zero activity)
If the Reports tab shows no tracked sessions despite donors visiting donation form pages, the JavaScript tracker may not be running correctly.
The most common causes are:
- A JavaScript error from another plugin or your theme. If a script that loads before the Donation Recovery tracker throws an uncaught error, it can block all subsequent JavaScript on the page, including the tracker. Open your browser’s developer console (F12 in most browsers, then click the Console tab) while on a donation form page and look for any red error messages. If you see errors that reference another plugin or your theme, deactivate them one at a time to identify the source.
- A JavaScript minification or concatenation plugin. Some caching and optimization plugins (such as Autoptimize, W3 Total Cache, or WP Rocket) combine and minify JavaScript files. This can occasionally introduce syntax errors or load-order problems that break the tracker. Try disabling JavaScript optimization temporarily and testing again.
- A Content Security Policy (CSP) header blocking the REST API call. Some security plugins add strict CSP headers that prevent JavaScript from making
fetchorXMLHttpRequestcalls to your own site. Check the browser console for CSP-related errors.
To isolate the issue, temporarily switch to a default WordPress theme (such as Twenty Twenty-Four) and deactivate all plugins except Charitable and Donation Recovery. If sessions start appearing, re-activate your other plugins one at a time to identify the conflict.
If you cannot resolve the conflict on your own, contact Charitable support with the name of the conflicting plugin and any console error messages you found.
Stats show zero recovered revenue
Recovered revenue is summed from the amount column on sessions where the donor’s entered amount was captured before they abandoned. If a donor selected an amount after clicking the recovery link (without the amount being in the pre-fill URL), the amount on the session record may be empty or zero. This reflects the intent captured before abandonment, not the final donation amount.
Frequently Asked Questions
Will this slow down my donation forms?
No. The tracker script is lightweight and runs asynchronously. It never blocks form rendering or submission. If the REST API call fails for any reason (network error, rate limit), it fails silently so the donor’s experience is not affected.
What happens if WP-Cron stops working on my site?
New sessions will continue to be captured (that part does not use cron), but abandonment detection and email sending will stop until cron is restored. Sessions that were pending will be processed in the next successful cron run. Install WP Crontrol from WordPress.org to monitor your scheduled events and confirm cron is running. If issues persist, contact your hosting provider — they can advise on whether WP-Cron is being blocked and help you set up a real server-level cron job as a replacement.
Can a plugin conflict break Donation Recovery?
Yes, in two ways. First, a plugin that interferes with WP-Cron can prevent abandonment detection and email sending (see the WP-Cron troubleshooting section above). Second, a plugin or theme that produces a JavaScript error on your donation form page may prevent the tracker from initializing, which means no sessions are captured at all. If you suspect a conflict, use your browser’s developer console to look for JavaScript errors, and try deactivating other plugins one at a time to isolate the cause.
Does Donation Recovery work with Charitable Ambassadors (peer-to-peer)?
Not at this time. Peer-to-peer campaigns managed through Charitable Ambassadors are excluded from the Campaign Recovery Scope list and are not supported.
Do donors need to be logged in for recovery to work?
No. Recovery is entirely email-based. As long as the donor enters a valid email address in the donation form before abandoning, a session is captured and a recovery email can be sent.
Can I customize the recovery email?
Yes. Copy the template from wp-content/plugins/charitable-recovery/templates/emails/recovery-immediate.php into your theme at charitable/emails/recovery-immediate.php and modify it. You can change the layout, colors, copy, and any element of the email while keeping the required PHP variables ($recovery_url, $unsub_url, $session) intact.
How long are recovery links valid?
Recovery links expire after 7 days. After expiry, clicking the link redirects the donor to your site’s homepage. Expired tokens are logged for auditing purposes.
Additional Resources
- [PLACEHOLDER: Link to Charitable Reports documentation]
- [PLACEHOLDER: Link to Charitable Email Settings documentation]
- WP Crontrol – free cron inspection plugin on WordPress.org
- [PLACEHOLDER: Link to Charitable Pro upgrade page]
- [PLACEHOLDER: Link to Charitable support]





