Charitable Documentation

Learn how to make the most of Charitable with clear, step-by-step instructions.

Charitable Ambassadors: How Invitation Data Is Stored

Requires: Charitable Pro 1.8.16+
Charitable Ambassadors 3.0.0+

The Invitations feature uses a small custom database table to store the unique tokens that power your ambassadors’ invite URLs. This page explains where that table is, when it gets created, what’s inside it, and what happens if it ever goes missing.

If you’ve never thought about your site’s database before, the short version is: it’s a small, well-managed table that the plugin handles automatically. The rest of this page is for when something unusual happens (an upgrade went sideways, a backup didn’t restore cleanly, an admin asks “what data does this feature store?”) and you need to know the details.

The Short Version

QuestionAnswer
What’s stored?One row per invite token. Each row has the token string, the inviter’s user ID, an optional campaign ID, a created date, a revoked date (if revoked), a view count, and a claim count.
Where’s it stored?In a custom table named <wp_prefix>charitable_ambassadors_invite_tokens (e.g. wp_charitable_ambassadors_invite_tokens).
When is the table created?The first time you enable Invitations on the admin page. Until then, the table doesn’t exist.
Is any personal data stored?No – just the inviter’s WordPress user ID. No names, no emails, no IPs.

When the Table Is Created

Until you enable Invitations, the custom table doesn’t exist – the feature is fully opt-in. The first time you toggle Enable Invitations on at Charitable > Ambassadors > Invitations, you’ll see a one-time confirmation modal explaining what’s about to happen:

“Turning on Invitations will create a new database table to store invite tokens. The table is small and only used by the Invitations feature. Continue?”

Confirm, and the table is created via WordPress’s standard dbDelta() helper (the same mechanism every plugin uses to manage custom tables safely). The schema is rebuilt idempotently – if the table already exists, dbDelta() only emits the ALTER statements it actually needs.

A row is also written to wp_options:

charitable_ambassadors_invites_schema_version = '1.0'

This is how the plugin knows what version of the schema your table is on, so future upgrades can migrate cleanly.

What’s Inside the Table

The table has eight columns – no PII, no donation amounts, nothing the inviter doesn’t already see in their own My Campaigns page:

ColumnWhat it stores
idAuto-incrementing primary key.
tokenThe unique string that appears in the URL. 16 characters, alphanumeric.
user_idThe WordPress user ID of the inviter.
campaign_id(Optional) A parent campaign ID, when the token is scoped to a specific cause.
created_atWhen the token was first generated.
revoked_atWhen the token was revoked (null if active).
view_countHow many times someone has clicked this token’s URL.
claim_countHow many recruits have successfully signed up via this token.

That’s it. No emails, no IPs, no browser fingerprints. The inviter and the recipient are both protected.

How the Table Is Used

Three things happen against this table during normal operation:

  1. Token creation – the first time an eligible ambassador visits My Campaigns with Invitations on, a token row is created for them (and an additional row for each parent campaign they own).
  2. Click resolution – when someone clicks an invite URL, the URL handler looks the token up to find the inviter.
  3. Counters – view_count is bumped on every click; claim_count is bumped when a recruit successfully attributes.

That’s the whole lifecycle. There’s no background processing, no scheduled jobs, no syncing to external services.

The Four Self-Check States

The Invitations admin tab has a self-check banner that catches the rare moments when something’s off:

A self-check banner indicating that Invitations are enabled but the database table is missing, with a Recreate Table button
You’ll seeWhat’s wrongWhat to do
Red: “Enabled but database table missing”A plugin update, manual DB cleanup, or backup restore wiped the table while the setting stayed on.Click Recreate Table – the schema is rebuilt in place. No data loss for new clicks; old tokens are gone.
Yellow: “Schema out of date”A future upgrade introduced a newer schema; your install hasn’t migrated yet.Click Run Upgrade. The migration is safe and idempotent.
Blue: “Disabled but data exists”You turned the feature off but the table is still there with token rows in it.Either Re-enable (data resumes use), or Permanently delete and remove table (data is gone for good).
Blue: “Cache compatibility off”A caching plugin may cache your invite landing page, which would break attribution.Turn on Cache Compatibility under Charitable > Settings > Advanced > Misc.

The self-check runs on every visit to the Invitations tab and on Charitable Tools > Site Info. It’s how you find out about table problems before they hit your customers.

Turning the Feature off (Soft Disable)

If you decide Invitations isn’t right for your program, Disable Invitations at the top of the admin tab:

  • The toggle flips to off.
  • The shortcode stops rendering on the landing page (or shows the admin preview when an admin views it).
  • The recruit card stops appearing on My Campaigns.
  • The URL handler stops fielding ?charitable-invite=... clicks.
  • The table stays. Token history is preserved so you can re-enable later without losing it.

This is reversible – re-enable any time and the existing tokens resume working.

Permanently Deleting the Data (Hard Uninstall)

If you want the data gone – say, for GDPR compliance or because you’ve decided you definitely won’t use Invitations again – use Permanently delete and remove table at the bottom of the Invitations tab:

The destructive uninstall confirmation modal, asking the admin to type the table name to confirm

The destructive flow is intentionally a few steps:

  1. Click Permanently delete and remove table.
  2. A confirmation modal asks you to type the table name (e.g. wp_charitable_ambassadors_invite_tokens) to confirm.
  3. Submit. The table is dropped, the _schema_version option is removed, the invites_enabled setting is set to off.
  4. The action is logged to Charitable Tools > Log with the moderator’s user ID.

This is a one-way door. The next time you enable Invitations, a fresh table is created with zero rows.

What Happens During an Export / Backup

The table is a regular MySQL table inside your WordPress database. Any tool that backs up WordPress databases (UpdraftPlus, BackupBuddy, mysqldump, your host’s automated backups) includes it automatically. Restores work the same way – bring the database back, the table comes with it.

What Happens During an Export of Personal Data

The WordPress Personal Data Export tool exports the user’s WordPress account data. The Invitations table stores user_id references, so a user’s invite tokens are included in their personal data export (token strings + view/claim counts). No PII beyond the user ID is in the table.

Tips

  • Don’t manually edit the table. The plugin’s admin UI exposes everything you’d need – revoke a token, regenerate a token, see counts. Hand-editing rows breaks claim_count integrity.
  • If you restore a backup that doesn’t include this table, the self-check will catch it on the next admin visit and offer Recreate Table.
  • The schema is versioned. Future plugin updates may add columns; the upgrade is safe and idempotent.
  • No SQL in this doc by design. Schemas drift; the docs shouldn’t carry them. Always read the plugin’s Charitable_Ambassadors_Invites_Schema class for the canonical column list.

Developer Reference

The rest of this page is for developers and DBAs.

Schema class

Charitable_Ambassadors_Invites_Schema::table_name();        // string - prefixed name
Charitable_Ambassadors_Invites_Schema::exists();            // bool   - does the table exist
Charitable_Ambassadors_Invites_Schema::is_current();        // bool   - exists + columns match + version current
Charitable_Ambassadors_Invites_Schema::schema_version();    // string - stored version (empty if no record)
Charitable_Ambassadors_Invites_Schema::create();            // creates via dbDelta + stamps version
Charitable_Ambassadors_Invites_Schema::upgrade();           // idempotent migration to current schema
Charitable_Ambassadors_Invites_Schema::drop();              // drops table + deletes schema-version option

All methods are static and safe to call from any context (the file is loaded unconditionally so the self-check and Site Info can interrogate state even when Invitations is disabled).

Option keys

charitable_ambassadors_invites_schema_version       # current installed schema version
charitable_settings > ambassadors > invites_enabled # feature master switch

Tokens class

For working with rows in the table programmatically:

Charitable_Ambassadors_Invites_Tokens::get_or_create( $user_id, $campaign_id = 0 );
Charitable_Ambassadors_Invites_Tokens::lookup_by_token_string( $token_string );
Charitable_Ambassadors_Invites_Tokens::lookup_by_id( $token_id );
Charitable_Ambassadors_Invites_Tokens::increment_view( $token_id );
Charitable_Ambassadors_Invites_Tokens::increment_claim( $token_id );
Charitable_Ambassadors_Invites_Tokens::revoke( $token_id );
Charitable_Ambassadors_Invites_Tokens::build_invite_url( $token_string );

Filters

FilterDefaultPurpose
charitable_ambassadors_invites_table_namewp_charitable_ambassadors_invite_tokensOverride the table name (e.g. multisite scoped tables). Not recommended in production.
charitable_ambassadors_invitations_storage_docs_urlthis pageOverride the docs URL the self-check banners link to.

Actions

ActionArgsFires when
charitable_ambassadors_invites_schema_created$table_nameSchema::create() actually created (not just updated) the table.
charitable_ambassadors_invites_schema_upgraded$from_version, $to_versionSchema::create() ran dbDelta and applied ALTERs.
charitable_ambassadors_invites_schema_dropped$table_nameSchema::drop() removed the table.

Site Info integration

Charitable Tools » Site Info has an Ambassadors block that shows:

  • Whether the table exists.
  • The current schema version.
  • The total row count.
  • Whether the schema is current.

See Site Info for the full layout.

Multisite

Each subsite gets its own table because the table name is prefixed via $wpdb->prefix. Network-active doesn’t change this – the feature still opts in per subsite.

Personal data export

The Invitations feature registers a personal-data exporter with the WordPress Privacy Tools. When a user requests their personal data export, the exporter walks their token rows and includes the token strings, dates, view counts, and claim counts in their export.

Capabilities

All admin operations (recreate, upgrade, drop) require manage_charitable_settings. The destructive uninstall additionally requires typing the table name to confirm.

Customization Examples

Hide the destructive uninstall option from a specific user role:

add_filter( 'user_has_cap', function ( $allcaps, $caps, $args ) {
    if ( ! empty( $caps ) && in_array( 'manage_charitable_settings', $caps, true ) ) {
        $user = get_userdata( $args[1] );
        if ( $user && in_array( 'finance_admin', (array) $user->roles, true ) ) {
            unset( $allcaps['manage_charitable_settings'] );
        }
    }
    return $allcaps;
}, 10, 3 );

Webhook your audit system when the destructive uninstall fires:

add_action( 'charitable_ambassadors_invites_schema_dropped', function ( $table_name ) {
    wp_remote_post( 'https://audit.example.com/hook', [
        'body' => [
            'event'      => 'invites_table_dropped',
            'table_name' => $table_name,
            'user_id'    => get_current_user_id(),
            'site_url'   => site_url(),
            'timestamp'  => time(),
        ],
    ] );
} );

Re-point the self-check banners to your internal docs:

add_filter( 'charitable_ambassadors_invitations_storage_docs_url', function () {
    return home_url( '/internal/charitable-invitations-runbook/' );
} );

Related

Helpful Links

🤝 Get help when you need it

Connect with Customer Support →

📑 Find the guide you need

Browse the Documentation Hub →

⬇️ Download proven strategies, campaign ideas, and expert tools

Get the Fundraising Kit →

🔗 Let your AI Assistant do the fundraising work for you.

Connect Charitable to your AI assistant →

💸 Get Free Fundraising Resources
Head to the Charitable Fundraising Hub →

🤔 Got questions about Charitable?
Charitable FAQs →

Need help understanding non-profit terms and jargon?
See our Non-Profit Glossary →


Still have questions? We’re here to help!

Last Modified:

What's New In Charitable

View The Latest Updates
🔔 Subscribe to get our latest updates
📧 Subscribe to Emails

Email Subscription

Join our Newsletter

We won’t spam you. We only send an email when we think it will genuinely help you. Unsubscribe at any time!

Improvement Payments

💸 Introducing Tiered Rates for Fee Relief: Match the Ask to the Gift!

Fee Relief asks your donors one short question at checkout: would you like to cover the processing fee on this gift? Until now that question used a single rate for every donation on a gateway, so a $10 gift and a $500 gift were asked for the same percentage. Fee Relief 1.3.0 lets you set as many donation bands as you like, each carrying its own rate. Why this is important:

  • 🪙 Gentler on small gifts: A fixed transaction cost is a far bigger share of a $10 donation than a $500 one, so bands let you ask for less at the bottom.
  • 🎚️ As many bands as you need: Each band carries its own percentage and its own fixed amount, and the top band runs on with no upper limit.
  • 🛑 An optional ceiling: A Maximum fee field stops any donor being asked for more than a number you choose, however large the gift.
  • 🔌 Set per payment gateway: Stripe can run on four bands while Windcave and Payfast stay on a single rate, because bands belong to a gateway and not to your whole site.
  • 🛡️ Nothing changes until you say so: Your current rates stay exactly as they are until you switch Use Tiered Rates on under Charitable » Settings » Advanced » Fee Relief.

Check out our announcement here.

Donations Improvement

📊 Your Pro Dashboard Can Now Compare, Export, and Score!

Most fundraising dashboards only tell you how much you have raised. Charitable Pro 1.8.19 rebuilds the dashboard and the Reports Overview around the harder questions: whether anything is broken, whether this period beat the last one, and which single change would make the most difference today. Why this is important:

  • 📈 Every figure has a trend: Pick a period and the tiles and the chart move together, with each total shown against the previous period.
  • 🗓️ Charts that stay readable: Short ranges group donations day by day, while longer ranges group by week or month, so a full year reads as a curve instead of a flat line.
  • 🔀 Compare any 2 periods: Not just consecutive ones, so you can ask how this December did against last December. That matters because fundraising is seasonal.
  • 📤 Export the whole summary: Send the full overview out as CSV or PDF, ready for a board pack or a funder report.
  • 🎯 Score your setup for free: Have your fundraising setup scored, so the one change worth making next is the one you can see.

Check out our announcement here.

Feature New

🎟️ Introducing Charitable Events: Sell Tickets Inside Your Campaigns!

Most nonprofits sell event tickets in one tool and collect donations in another, which leaves two sets of reports and a manual match at the end of the year. Charitable Events brings both together, selling tickets through the same donation forms and payment gateways you already run in Charitable. Why this is important:

  • 🎟️ Every ticket is a donation: Ticket sales run through the gateway you already use and count toward the campaign goal, with everything managed under Charitable » Events.
  • 📱 QR check-in from any phone: Each attendee gets their own QR code on the receipt, and volunteers scan at the door through a check-in link that needs no WordPress account.
  • 🧾 Receipts ready for tax time: Give each ticket type a fair market value, and Charitable puts the correct tax-deductible amount on every donor receipt.
  • 📋 Attendee details at checkout: Ask every guest for a meal choice, shirt size, or access needs, with a separate attendee record created for each ticket.
  • 🗓️ Blocks and calendars included: Three editor blocks plus Sugar Calendar and The Events Calendar support put your events where supporters already look.

Check out our announcement here.

ai New

🚀 Unleash AI Power in Charitable!

Your AI assistant can now build, edit, and manage your Charitable fundraising campaigns directly — just by asking. With Charitable Pro adding write support for the WordPress Abilities API, tools like ChatGPT, Claude, and Cursor can handle full administrative actions safely through MCP. Why this is important:

  • 🤖 Campaign creation in plain language: Prompt your assistant with a goal like “Set up a fundraiser for the shelter with a $5,000 goal”, and it builds a real draft campaign complete with suggested donation tiers.
  • 🎨 Instant donation form tweaks: Add custom fields, change button colors, or reorder elements without diving into form settings.
  • 📝 Offline gift logging: Tell your assistant about cash or check gifts, and it will match donor emails and record transactions into your history.
  • 🛡️ Safety and control by default: Write access stays strictly off until turned on in Charitable » Tools » AI MCP, keeping read-only reporting safe by default.
  • 📜 Full audit logging: Every change made by an AI assistant is tracked under Charitable » Tools » Logs, so you always know who (or what) updated your site.

Check out our announcement here.

Improvement Payments

💰 Accept Recurring Donations with Windcave and Charitable

A donor sets their gift up once on Windcave’s secure payment page, and Charitable bills every renewal after that on schedule. Why this is important:

🏦 Organizations banked in New Zealand or Australia: monthly giving on the gateway your bank already set you up with, with no second processor to onboard.
⛪ Churches taking regular tithes and offerings: congregants set their own schedule once, which is the simplest way to launch recurring church giving without a separate platform.
🌏 Groups with donors in several currencies: Windcave handles more than 20, so a supporter can give in the currency they actually hold.
📅 Operating funds rather than one-time campaigns: switch on Recurring Only mode and the one-off option disappears, so every gift to that campaign is a subscription.
🧾 Teams with no developer on staff: 3 sets of credentials pasted into a settings page, and no code anywhere.

Check out our announcement here.