Skip to content

Getting Started

Settings console reference#

A field-by-field reference for the Settings console: what each setting does, and — the part that actually matters day to day — what happens the moment you save it.

This page is the companion to Setup assistant, which tours the console's four groups and fourteen panels. This page goes one level deeper: every field, in every panel, with two questions answered for each — what it does, and behavior on update (does the change apply immediately, only to new records going forward, only on the next scheduled batch run, or not at all).

How to read "Behavior on update"

  • Immediate — the very next Apex transaction/page load sees the new value. Settings__c is a Hierarchy Custom Setting; saving it commits instantly with no platform-cache delay.
  • Immediate, but browser-cached — the server-side value changes instantly, but the specific screen that displays it uses a cacheable (@AuraEnabled(cacheable=true)) wire, so an already-open browser tab may keep showing the old value until it reloads or its cache is invalidated.
  • New records only — the setting is a default copied onto a record at creation time. Existing Campaigns, designs, or donations are never touched retroactively.
  • Next scheduled run — a nightly/hourly batch reads the setting; nothing changes until that job next executes (or an admin manually triggers it from System → Scheduled Jobs).
  • No effect (known gap) — the field is editable and saves cleanly, but no code anywhere reads it. Flagged explicitly below rather than silently omitted, so you don't waste time troubleshooting a toggle that was never wired to anything.

Watch it first#

What it is. Three minutes across the four panels that are not part of getting online — Events & Ticketing, Page Designs, Public Links and Logging. These are the ones you come back to once gifts are arriving, rather than the ones you set on day one.

General#

Organization & Donations (General → Organization & Donations)#

Setting What it does Behavior on update
Org display name Org name shown on receipts and portal emails Immediate
Tax ID (EIN) Tax ID printed on receipts Immediate
Campaign type for new fundraisers The Campaign Type stamped on fundraisers you create from now on — the field standard Salesforce campaign reports and dashboards group by New fundraisers only; an existing campaign's type is never rewritten by an edit. The dropdown lists your org's Campaign Type picklist, so add a "Fundraising" value in Setup first if you want one. Leave it on "Use the org's own default" to keep whatever default your org already set — but be aware Salesforce's own stock default is Conference, which is why fresh installs are seeded to Other
Default suggested amounts Suggested-amount chips (comma-separated) pre-filled on a brand-new fundraiser New records only — pre-fills the "New fundraiser" wizard; editing this later never changes an already-created fundraiser's amounts
Default fee-on-top percent (No effect — known gap.) Nothing reads this value; "cover the fee" behavior, where implemented, is controlled per-campaign, not by this org default.
Donation page path Path fragment appended to your Experience site's base URL to build public donation links Immediate for the embed widget's REST endpoint and the Fundraisers console's public-links panel; immediate but browser-cached for the Campaign Gallery (its donation links come from a cacheable wire, so an already-open gallery tab may show the old path until it reloads)
Donor options — Allow tribute/honoree gifts Org-wide master switch for tribute/honoree gifts — and the starting value for a brand-new fundraiser's own toggle Immediate and org-wide. Off = no fundraiser shows the tribute section, no tribute data is captured, and no honoree e-cards go out, whatever an individual fundraiser's toggle says. On = each fundraiser's own toggle decides. Per-fundraiser choices are never overwritten, so they come back exactly as they were if you switch this off and on again
Donor options — Allow company-match prompt Default for whether a brand-new fundraiser shows a company-match prompt — not an org-wide master switch New fundraisers only. Unlike tribute gifts above, switching this off does not hide the prompt on fundraisers that already have their own toggle on: the public page reads the campaign's setting directly. To stop the prompt appearing on a live fundraiser, turn it off on that fundraiser
Donor options — Add donors as Campaign Members Adds each donor to the Campaign their gift came in on, so Contacts in Campaign / Responses in Campaign and the standard campaign reports stop reading zero Off by default, and off is a working state — the app's own Fundraising Progress card and rollups are correct either way. On applies to gifts finalized from now on; it never back-fills past donations. Leave it off if your org already adds campaign members with its own automation. Event attendees have their own separate switch under Events. See Campaigns
Donor options — Assign soft credit automatically Credits a gift given in honor of someone to that person, and credits a donor's household alongside them On by default. Never changes who paid or how much — it only adds credit rows so both parties appear in giving history without the gift being double-counted
Min / Max donation amount Floor/ceiling enforced on gift amounts Immediate — enforced server-side before any Stripe callout; also passed to the donation form as a client-side hint
Portal session cap (hours) The absolute ceiling on a donor-portal session, however active the donor is. Defaults to 4 hours; anything above 168 (7 days) is treated as 168 Immediate for sessions started from now on. A session already open keeps the cap it was stamped with at sign-in
Portal code expiry (minutes) How long the emailed 8-character sign-in code stays valid before the donor must ask for a new one. Defaults to 15 minutes; values outside 5–60 are pulled back into that range Immediate for codes issued from now on. The confirmation screen quotes whatever you set here, so a donor is never told a window you have not configured
Portal idle timeout (minutes) How long an open portal session may sit untouched before the donor is signed out. Defaults to 30 minutes; values outside 5–120 are pulled back into that range Immediate — the window is re-read on each portal call, so a change reaches sessions that are already open
Default thank-you CTA URL / label Fallback call-to-action button shown after a gift, when a campaign doesn't set its own Immediate — a campaign's own thank-you fields, where set, take precedence over this org default
NPSP: sync recurring donations / sync GAU allocations Whether recurring gifts / GAU splits sync into NPSP objects Next donation-finalize event only — never retroactively syncs past donations. Only shown once NPSP is detected in your org.
Person Accounts / NPSP detected (read-only) Informational display of what the "Detect capabilities" scan found Informational only — actual donor-resolution logic re-checks your org's schema live at donation time regardless of what this panel shows
Detect capabilities button Re-runs the org-schema scan for Person Accounts / NPSP Immediate, but manual — installing NPSP or enabling Person Accounts won't update this panel until you click it
Logo upload Org logo shown on receipts, emails and the public donation page header Immediate
Public page footer — footer text The copyright/attribution line in the footer band of every public donation page Immediate and live on the next page load. A campaign can override it on its own record; leave a campaign's override blank to use this.
Public page footer — terms / privacy URLs The two policy links in that footer band Immediate and live. Leave one blank and the footer simply omits that link rather than rendering a dead one. Same per-campaign override.
Public page footer — X (Twitter) / Facebook / Instagram URLs The social icons in that footer band Immediate and live. Each is independent — an unset network shows no icon. Same per-campaign override.
Social share image URL The 1200x630 card a social network shows when someone pastes a campaign link Saved and resolved, but not yet rendered into an og:image tag by anything in this package — it is stored ready for a social-preview feature. Blank falls back to the packaged card published at install.
Story media — Play story videos on the page Whether a video block in a campaign story plays inline, or stays a click-out poster card. Off by default, and off is a working state — the card loads nothing from YouTube until a donor clicks it Immediate and live on the next page load. On is only half the job: inline playback also needs a CSP Trusted Site for https://www.youtube-nocookie.com (frame-src, context Experience Builder Sites) that you create yourself in Setup — the package ships none, deliberately, so the install-time third-party access dialog stays payment-processor-only. With the toggle on and no trusted site the browser blocks the frame silently; no Salesforce API can tell the app whether you created it, so the panel states the requirement rather than grading it. See Write a campaign story
Reset to defaults button Resets settings to their packaged defaults Immediate, but narrower than the label suggests — it resets exactly 13 fields (the four retry/grace/dunning/retry-count values, suggested amounts, auto-receipt toggle, debug logging, the four donor-option toggles, and the two company-match follow-up fields). It does not touch org name, Tax ID, email colors/copy, min/max amounts, the three donor-portal sign-in windows, thank-you CTA, or NPSP sync toggles.

Anonymous giving has been removed

Earlier releases carried an "Allow anonymous giving" toggle here and an Anonymous__c checkbox on donations and recurring donations. Nothing ever wrote them — no donation form asked donors the question — so they have been removed rather than left as settings that appear to work. Anonymous giving may return as a real, end-to-end feature in a later release.

Email & Receipts (General → Email & Receipts)#

Setting What it does Behavior on update
From name The sender display name on donor email — but only while From email below is empty. Once a From address resolves to an Org-Wide Email Address, Salesforce takes the display name from that record and this field stops being applied (the two are mutually exclusive in the platform API) Immediate, for the next email sent
From email Two independent jobs. (1) It is the lookup key for the address donor email is sent from: the package matches it against your org's Org-Wide Email Addresses and, if it finds one that is both verified and has Allow All Profiles to Use this From Address ticked, stamps every donor message with it. (2) It is printed as your contact address on seven emails — failed payment, re-authorization, dunning, refund confirmation, employer-match instructions, and the two tribute notices Immediate. A value that matches no such Org-Wide Email Address fails silently at send time: the email still goes out, just from whichever user or background job triggered it. Both boxes matter — receipts are sent by the site's guest user and by scheduled jobs, which is why Allow All Profiles is not optional. Run Health Check → the Donor Email Sender line to see which half is missing
Reply-to email Sets the Reply-To header on every transactional email the package sends. It doubles as the fallback staff recipient — a refund request or card-dispute alert with no gift owner to notify is sent here Immediate. Blank means replies go to the sending address itself
Support phone Shown on Dunning, Failed-Payment, and Re-Auth emails Immediate where shown. Not shown on the donation receipt or recurring-confirmation emails — a donor never sees it unless something goes wrong with a payment.
Brand colors (primary / accent / heading / background) Hex colors used on the receipt email Immediate. Server-side validated as a 6-digit hex (#rrggbb) — an invalid value is rejected with an error, not silently accepted.
Auto-send receipt Whether a receipt email fires automatically when a donation finalizes Immediate, for the next finalized donation
Receipt email template Which classic Email Template to render for receipts Immediate — but if the name you enter doesn't resolve to a real template, it silently falls back to the packaged default rather than erroring. A typo won't break receipts; it'll just quietly ignore your custom template.
Receipt intro message / signature / footer text Copy blocks on the receipt email Immediate
Receipt legal text — no goods received The legal sentence at the foot of a receipt for a plain gift, where the donor received nothing in return. Applies to every receipt surface, not just the email — the donor-portal receipt, the printed receipt, and the annual giving statement use it too Immediate. When set it is used verbatim for this case and the packaged wording is suppressed. Leave blank for the packaged US 501(c)(3) default. It is never used for an event order — that has its own field.
Receipt legal text — goods received The sentence used instead when the donor got something back (an event or ticket order), including one whose tier carried no fair market value Immediate, same surfaces. Must not say "no goods or services were provided" — that is false for these gifts and regulated in the US. Leave blank for the packaged default.
Receipt legal text — goods received, partly refunded The sentence for the rare receipt covering a partly refunded event order, where no deductible figure can be stated Immediate, same surfaces. Should tell the donor to contact you for the deductible amount. Leave blank for the packaged default.
Receipt number prefix The leading segment of every receipt number — RCPT produces RCPT-2026-000142. Blank uses RCPT. Immediate, for the next receipt issued. Letters, digits and underscores only; anything else (including hyphens, which are the separator) is dropped, and the value is upper-cased when the number is built. Changing it never renumbers receipts already issued — the two formats simply coexist, which is fine because the numbers only have to be unique, not uniform.
Recurring thank-you message Copy on the recurring-donation confirmation email Immediate
Org mailing address Compliance address printed on receipts Immediate
Donor portal path Path fragment for the donor-portal link included in the sign-in-code and dunning emails (the link opens the sign-in screen; it carries no credential of its own) Immediate, but inconsistently normalized: most consumers of this value auto-fix a missing leading slash, but the Dunning email template concatenates it raw. If you omit the leading slash here, the link in dunning emails specifically can come out malformed even though everywhere else treats it the same either way. Enter it with a leading slash (e.g. /donor) to avoid the discrepancy.

Events & Ticketing (General → Events & Ticketing)#

Setting What it does Behavior on update
Deductible calculation mode Whether the non-deductible portion of a ticket price is computed from each ticket type's Fair Market Value, or as a flat percentage. The two fields are not interchangeable — each mode reads only its own, and ignores the other New tickets only — only affects orders finalized after the change; already-issued receipts keep the split that was computed at the time. Switching to Percentage makes the ticket type's Deductible % required from then on; ticket types created earlier keep what they had, and any still missing a percentage records its sales as 0% deductible (whole price non-deductible) and logs a warning, rather than reading a fair-market value a percentage org never fills. Set the percentage on each existing tier — 0 is a valid answer — before selling under the new mode.
Sync attendees as Campaign Members Whether finalizing a ticket order also creates a Campaign Member for each attendee who resolved to a known donor — a Contact, or the person contact behind a Person Account New tickets only. Guest attendees captured as name/email only (no donor match) are skipped — Campaign Member requires a person record. A sync failure never blocks or reverses the underlying paid order.

Logging (General → Logging)#

Setting What it does Behavior on update
Log level Minimum severity the package's internal logger persists to a queryable log record (Off / Error / Warn / Info / Debug) Immediate — takes effect on the very next log call anywhere in the org, not just from this console
Debug echo to Apex debug log Also mirrors log calls into System.debug for live viewing in Developer Console Immediate. Does not change what's persisted as a queryable log record — that's Log level's job exclusively. Turning this on will not make more log history appear on the Diagnostic Logs tab.
Purge after (days) Age threshold at which the nightly retention job permanently deletes old log records, transaction logs, and completed donation-staging bookkeeping rows Next scheduled run only (nightly, 3am) — changing this has zero immediate effect. Deleted rows are not restorable by raising the value back up afterward.

This panel sets the level — the Diagnostic Logs tab is where you read the result

The entries these settings produce are on their own tab in the app navigation, filterable by severity, context and date and searchable across messages and stack traces. It reads both settings back: if Log level is Off the tab says so outright, and it names the purge window, so an empty list can never be misread as "nothing went wrong" when the real answer is "nothing was written" or "it was already deleted." See Monitor donations and read the logs.

Purge after (days) feeds a real delete, on demand

The nightly purge is scheduled, but an admin can also trigger it immediately from System → Scheduled Jobs ("Retention purge → Run now"). That action deletes using whatever value is saved here at the moment you click it — lowering this number and then running the purge manually will remove more history at once than the nightly job typically would.

Licence & Seats (General → Licence & Seats)#

Read-only. Nothing on this panel is a setting; it is the one place inside the app that shows the package licence the way Salesforce records it, so an admin does not have to find Installed Packages to answer "how many seats do we have left?"

Shown What it means
Status The licence status Salesforce holds for this org (Active, Trial, Expired, Suspended). A user without a seat, or in an org whose licence is Expired or Suspended, sees the licence notice in place of each staff console until the subscription is put right. A live Trial is a normal, fully working licence: every console shows a Trial · N days left badge with a Complete checkout button until the trial converts or ends
Seats Used of allowed, with a meter that turns amber at one seat left and red when every seat is taken. A site licence shows Site licence instead of a count — every user in the org is covered and there is nothing to assign
Expires The renewal date, or Never for a licence with no end date. Inside 30 days the panel says so in amber
Assign seats The Setup path — Setup → Installed Packages → Manage Licenses — because a package cannot assign its own seats; only a Salesforce admin can
Manage subscription Opens the subscription portal in a new tab, carrying your org Id so the portal can find the right account. This is where seats are added or a lapsed subscription renewed

The panel reads the same PackageLicense record the platform uses to block unlicensed users, so what it shows is what Salesforce will enforce. In an org where the package is not installed as a managed package — a developer scratch org — it says so and shows nothing else, which is correct: there is no licence to read.

The Health Check board carries the same facts as one row

Package Licence under System → Health Check goes amber inside 30 days of expiry or with one seat or fewer left, and red once the licence has expired, so an approaching problem shows up on the board an admin already looks at rather than only on a panel they have to remember.


Payments#

Payment Accounts (Payments → Payment Accounts)#

Backed by Payment_Account__c records, not Settings__c — this panel creates and edits the payment-gateway connections your campaigns charge through. It has no delete: a payment account can be deactivated but never deleted (see the callout below).

Field / action What it does Behavior on update
Display label, Payment processor Required fields identifying the account Immediate. The processor list is built from what the package actually implements — Stripe today. There are no reserved "coming soon" options to pick and then be blocked on.
Donor Restricted Key The credential donor-facing charges authenticate with — a restricted, charge-only key, and the one your site guest user is granted Immediate. Despite the name, this field holds a credential name, never a key: there is no secret-key field anywhere in this panel. You build the External Credential and Named Credential yourself in Setup — named whatever suits you, since nothing in the app looks them up by name — and the record stores the name you chose. That is what lets one org run several gateway accounts and tell them apart here. The guided checklist above the account list walks that build and then reads your org back to grade it.
Admin Restricted Key The credential back-office work authenticates with — a second restricted key, scoped to refunds and the reads the reconcilers, orphan sweep, off-session recurring renewals and Test connection need Immediate, and again a credential name of your choosing, not a key. A full secret key is not an accepted value on either credential: steps 10 and 11 of the checklist each make one live call the scoped key should refuse, and an unrestricted key answers instead — grading the step Failed and keeping the account off Ready to take payments until the key is scoped. Never grant this credential to a site guest user; step 9 names the permission sets your guest holds and asks you to confirm this isn't among them. Naming the same credential in both fields is accepted and warns rather than blocks — but one key cannot be scoped two ways, so at least one of the two probes then grades Failed.
Publishable key Stripe's non-secret publishable key, exposed to the donor's browser Immediate. It also determines the Mode badge: a pk_test_… key marks the account Test, pk_live_… marks it Live. There is no mode field to set — and therefore none to set wrongly.
Active Whether the account can be charged through — and the only way to retire one Immediate and load-bearing: deactivating an account instantly blocks any campaign linked to it from taking a charge — the next donation attempt is rejected until an active account is linked. An inactive account keeps its full donation history, and the cards and schedules it created stay intact.
Test connection button Verifies the account can reach the gateway on its admin credential Runs a real, live connectivity check against the gateway every time you click it — not cached or simulated. It says nothing about scope: step 10's and step 11's Run the check buttons are what settle whether each key is genuinely restricted.

Payment accounts cannot be deleted — deactivate instead

There is no Delete button on this panel, and attempting to delete a Payment_Account__c record any other way (record page, Data Loader, API) is refused outright. This is deliberate, not a permissions gap.

A saved card (pm_…) and customer (cus_…) are minted by one Stripe account and are chargeable only by that account. The payment-account record is the only thing naming which Named Credential identifies it. Delete the record and every saved card and recurring schedule created through it becomes permanently unchargeable — the tokens cannot be re-pointed at a different Stripe account, re-minted, or recovered. Renewals would silently fall through to the campaign's current account, Stripe would answer resource_missing, and the dunning cadence would read that as a declined card and start chasing donors whose cards are perfectly fine.

Uncheck Active to retire an account. It stops taking new gifts immediately and keeps every record it ever created.

Don't edit a payment account that's already working — create a new one

Re-pointing a live account's Named Credential or publishable key at a different Stripe account has the same effect as deleting it, without the guard: existing tokens keep referencing the old Stripe account while new charges go to the new one. If you're switching Stripe accounts, create a second payment account record, link the campaigns you want moved to it, and deactivate the old one once its recurring schedules have run out or been re-collected.

Refunds (Payments → Refunds)#

Setting What it does Behavior on update
Enable refunds Master switch for the entire refund subsystem Immediate for new refund attempts, and for the hourly reconciliation job's next run. Immediate but browser-cached on the record-page refund button itself — an already-open donation record may show the old enabled/disabled state until refreshed.
Refund window (days) How many days past a gift's close date it can still be refunded from Salesforce Immediate for the next refund attempt / reconciliation run

Turning off refunds also stops dispute/chargeback syncing

"Enable refunds" isn't just the refund button's on/off switch — the same flag gates the hourly reconciler that pulls both refund status and dispute/chargeback updates from Stripe. Disabling it silently stops chargeback-lifecycle updates from reaching Salesforce too, not only new refund attempts — a materially larger blast radius than the label implies.

A refund window of 0 quietly disables refunds without touching the switch

Setting the refund window to 0 days makes essentially every already-closed gift fall outside its refund window immediately, functionally freezing refunds org-wide — a subtle way to disable refunds without ever touching "Enable refunds."

Recurring & Dunning (Payments → Recurring & Dunning)#

All four fields here are read once a day by the nightly recurring-billing batch chain (donor rollups → renewal charges → auto-cancel) — none of them take effect immediately.

Setting What it does Behavior on update
Failed payment retries How many times a declined recurring charge is retried before being marked Failed Next scheduled run (nightly)
Retry interval (days) Spacing between consecutive retry attempts Next scheduled run (nightly)
Grace period (days) How long a Failed recurring schedule is kept before being auto-canceled Next scheduled run (nightly) — specifically, the following night's sweep, since auto-cancel runs last in the nightly chain
Dunning email frequency (days) How often a decline/dunning email is re-sent to a donor with a failing payment method Next scheduled run (nightly)

Checkout Protection (Payments → Checkout Protection)#

Public donation and ticket pages are, by design, reachable by anyone with the link — which means they are also reachable by an automated script. Two kinds of abuse land on a fundraising page: card testing (someone runs stolen card numbers through your form to find which ones still work, using your Stripe account to do it) and volumetric flooding (a script starting thousands of checkouts to bury the org in staging rows). This panel sets the limits that stop both before a payment intent is ever created.

Setting What it does Behavior on update
Attempts per email address How many checkout attempts one email address may start on one campaign inside its window Immediate — the next attempt is measured against the new number
Email window (minutes) The period that per-address count is measured over Immediate
Attempts per campaign Total attempts allowed against one campaign inside its window, from all visitors combined Immediate
Campaign window (minutes) The period that campaign-wide count is measured over Immediate

The packaged defaults are 5 attempts per address per 10 minutes and 500 attempts per campaign per hour. Leave a box empty to go back to its default. A donor who trips either limit sees a short "please wait a moment and try again" message on the form, not an error.

The per-address limit counts per campaign, not per donor

Someone giving to two of your appeals in the same sitting is normal behaviour, and the limit is deliberately keyed on the address and the campaign so that never trips it. The campaign-wide ceiling is the one that catches an attacker rotating through addresses to stay under the per-address number.

Zero switches a limit off — it does not mean 'allow nothing'

Setting either Attempts per email address or Attempts per campaign to 0 turns that limit off entirely. That is the intended escape hatch if a limit is misfiring during a live campaign, but it does mean a 0 typed in the hope of locking the page down has exactly the opposite effect. To pause a campaign, close it or unpublish the page instead.

Raise the campaign ceiling before a giving day

The campaign-wide number is a safety ceiling, not a day-to-day rate limit, and tripping it rejects genuine donors along with the flood. Before a matching-gift hour or a giving-day push, check the ceiling is comfortably above the peak you actually expect.

This is the fundraising app's own control and sits in front of the gateway's. Stripe Radar sees signals no Salesforce-side count can — card fingerprints across every merchant on Stripe, device, network reputation — and blocks individual charges. These limits stop the flood reaching your org at all. Run both: see Turn on Stripe Radar for the gateway side.


Experience Cloud#

Site & Domain (Experience Cloud → Site & Domain)#

Not a settings form — a seven-step guided checklist (Enable Digital Experiences → Create or choose your site → Turn on guest access → Assign the guest permission set → Give the guest user read access to Campaign → Build each public page → Publish the site, then activate it) with a running progress tally at the top, followed by one un-numbered row for the guest Stripe credential that sits outside the tally. Every step carries exactly one status chip: Done (confirmed against your org this load), Pending (confirmed not done — the action is yours), or Can't verify (Salesforce exposes no API to check that step, so the panel says so rather than guessing at guest access or your page list — two things that remain permanently unreadable from Apex, not broken).

Two grants the package cannot ship — and both are machine-checked

A managed package may grant neither a standard object permission (Give the guest user read access to Campaign) nor an external-credential principal (the guest Stripe credential row at the foot of the panel). Salesforce strips the first out of a packaged permission set when the version is built and rejects the second outright, so Fundraising_GuestDonor carries every custom-object and custom-field grant your public pages need and neither of these two. Both are therefore one-time admin grants — and both are read back here, so you see Done or Pending rather than being asked to confirm your own work. The Campaign step reads the grant itself, not the set that carries it — build it as a permission set of your own (the guide calls it Guest Campaign Read; the name is yours) and assign it to the guest user.

The guest credential grant is machine-checked, not self-confirmed

The credential row reports Done (a permission set granting an external credential is assigned to this site's guest user, and that user can create the credential record a callout needs) or Pending (one of those is missing) — it is not a step you confirm yourself. The package can never ship this grant, because a managed permission set may not carry an external-credential principal, so you build it by hand once; the panel reads it back.

It answers in one of two ways, and the wording tells you which. Naming the credential behind a grant needs ConnectApi.NamedCredentials.getExternalCredential(), and an installed org generally refuses that call to a packaged app. When it does, the panel falls back to a plain SetupEntityAccess query and asks the plainer question: does this site's guest user hold a permission set granting an external credential principal? A no rules out the payment credential along with everything else. A yes is the answer you want, and the row goes green — its sentence just asks you to confirm the grant is on the credential your payment account names, because no app can read that back. A successful test donation settles it. Get Started step 5 grades the same two grants the same way, so the two panels agree.

Step / action What it does Behavior on update
Site picker + Use this site Connects the console to one of your org's Experience Cloud sites Immediate — every other panel/endpoint that resolves "the" site reads the same stored value, so they can never disagree
Build each public page table Lists all six public pages (Home, Donate, Thank you, Receipt, Donor portal, Tickets) against the path your org is actually configured with, plus a live link to open each one Read-only — pages are still built by hand in Experience Builder; this table never writes anything

Embedding (Allow embedding master switch + Allowed embed origins) sits as its own always-open block at the foot of the panel, deliberately outside the seven-step checklist and its tally — it's optional and unrelated to whether the site itself is ready to take donations. Allowed embed origins is not validated — an entry missing https:// or containing a path will simply never match a real request origin, with no error surfaced anywhere; double-check each entry is a bare scheme+host.

Full walkthrough: Set up your Experience Cloud site.

Entirely read-only — nothing on this panel is a setting you change here. It's a live, always-fresh readout of donation/fundraiser/team links built from the Donation page path (set in Organization & Donations) and the site connected in Site & Domain.

Looking for the donation page path?

It isn't edited here — it lives on General → Organization & Donations, under Gift rules.

The Campaign Gallery can lag behind this panel

This panel always shows the current path/links. The public-facing Campaign Gallery page, however, loads its donation links through a browser-cached call — a visitor with the gallery already open may keep seeing the old donation path until their browser reloads it. The embed widget and internal admin links are not cached and reflect changes immediately.

Page Designs (Experience Cloud → Page Designs)#

Backed by Campaign_Design__c records — themes and layout composed in the Page Canvas builder, applied to campaigns by reference.

Your logo, footer and social links are no longer part of a design

Each design record used to carry its own logo URL, footer text, terms/privacy links and social handles. Those describe your organization, not a theme, so a campaign switching from one style to another silently changed which privacy policy its donors were pointed at. They now live once, in General → Organization & Donations, and every design renders the same set. A campaign that genuinely needs its own — a joint appeal, say — overrides them on its own record.

Setting / action What it does Behavior on update
Active toggle Whether the design can be used Immediate and live for every campaign already using it — not just new ones. Turning a design's Active flag off instantly falls back any campaign pointing at it to your default design, the next time a guest loads that campaign's page.
Set as default Which design campaigns with no design chosen fall back to — and the theme every public page that is not a donation page paints itself from (the campaign gallery, the donor portal, the thank-you page, receipts and the ticket wallet) Immediate and live — same instant-fallback behavior as above. Exactly one design can hold the flag: marking a design default clears it from whichever design held it before, wherever the change was made — this console, the Salesforce record page, a data load or an import.
Colors, fonts, hero image, spacing/shadow/radius style Visual theme tokens Immediate and live for every campaign on that design, on their next page load — no Experience Cloud site republish needed, since this is a data change, not a component/metadata change
Column ratio How the public page splits between the story column and the payment box, and which side the payment box sits on — 60/40, 50/50 or 40/60 Immediate and live. A campaign can override it on its own record.
Form title/description/disclaimer/footer defaults Default form copy for campaigns using this design Immediate and live, but a campaign's own override (where set) always wins over the design's default
Show progress bar Whether the raised-of-goal progress bar renders — on the hero banner, the donation form and the embedded widget alike Immediate and live. Switching it off removes the bar from all three surfaces. It has nothing to remove on a campaign with no goal amount (an Ongoing fundraiser), or on an Event campaign (which shows a tier picker instead), so on those it is a no-op by design, not a bug.
Show donor wall (No effect — known gap.) Saved and passed through to the guest page's data, but no guest-facing component currently reads this flag to gate anything.
Theme tokens (advanced JSON) Raw override of the design's theme-token values Immediate. Any token name not on the packaged, protected allow-list is silently dropped when the design is read back — it is not rejected at save time, so a typo in a token name won't error, it'll just be ignored.

The advanced token list grew a lot

The Add override dropdown on a design's Advanced tab now carries 147 tokens, grouped by what they affect. Five of those groups — Story, Sections, Tabs, Donation box and Footer — cover the two-column public page: the hero crop and its overlay, the story column's line length and paragraph rhythm, the documents/updates/FAQ tab strip, every surface of the donation box down to the progress bar, and the contact band at the foot of the page. Anything you can see on a public donation page that isn't the campaign's own content is a token you can change here, which is what lets two designs look like two different products rather than two colour schemes of the same one.

One design is default, and it dresses more than the fallback

Only a donation page follows its own campaign's design. Every other public page — the campaign gallery, the donor portal, the thank-you page, receipts and the ticket wallet — has no campaign to read, so it paints itself from whichever design is marked default. Changing the default therefore restyles all of them at once: colours, fonts, corner radius and spacing. That includes the donor portal's buttons and its statement and trust panels, which take the default design's primary colour rather than a fixed one.

Warnings follow the theme; errors deliberately do not

Each packaged design also sets its own caution colours — the amber used for a pending refund line, a "few tickets left" chip, or an expiring card notice — so a warning sits in the same temperature as the rest of the page. Marigold is the exception and warns in terracotta, because its own brand colour is already ochre and an amber warning would read as a second heading rather than as a warning.

Error colours are the same on all six designs (#C7362B with its tint and hairline) and intentionally so. An error is a safety signal: a failed card, a closed campaign, a form that won't submit. If it took each design's own palette it could end up looking like the brand — the donate button and the "your payment failed" box in the same red. You can still override the error tokens on a design's Advanced tab, but think twice before pointing them at your primary colour.

The hero is sized by proportion, not by height

A design sets Hero aspect ratio (--pf-hero-ratio, e.g. 21 / 8) rather than a pixel height. A fixed height crops the same photo to a different slice of itself on a phone than on a desktop; a ratio keeps the crop identical at every width. The old --pf-hero-header-height token was retired — a design that still lists it in its advanced JSON will have that entry dropped on the next read, with no error.

| Page Canvas blocks | The Compose → Payment → Thank You block layout | Immediate and live | | Delete button | Removes a design | Blocked with an error if any campaign currently references it — you must reassign or clear those campaigns' design first. (The confirmation dialog's own wording implies a silent fallback to the default design instead; the actual behavior is a hard block, not a fallback — don't rely on the dialog text.) |

Delete is blocked, not a silent reassignment

The delete-confirmation dialog reads as if campaigns using the design will simply fall back to your default. In practice, the delete is refused outright while any campaign still references it — reassign or clear those campaigns' design field first.

Donor Portal (Experience Cloud → Donor Portal)#

All fields below feed the donor-facing self-service portal and take effect immediately server-side; because the portal's own configuration read is a cacheable wire, a donor who already has the portal open may not see a just-changed title, message, or visibility toggle without a page refresh.

Setting What it does Behavior on update
Show summary / recurring / history / wallet panels Which sections of the portal are visible to a donor Immediate, browser-cached (see above)
Request title / subtitle Copy on step 1 of sign-in, where a donor enters their email Immediate, browser-cached
Confirmation title / message Copy on step 2 of sign-in, captioning the box the donor types the emailed code into Immediate, browser-cached
Empty recurring / history / wallet messages Copy shown when a section has nothing to display Immediate, browser-cached

Keep the confirmation message conditional

The code renders this one message whether or not the entered email matched a donor, so customizing it cannot leak who is on your list — the screen does not branch, and there is nothing for a custom string to give away. What a custom string can be is untrue: word it as a flat "we've emailed you a code" and half the people who read it were sent nothing. Keep the "if a matching donor record exists" hedge, or an equivalent, for that reason.


System#

Record Types (System → Record Types)#

This panel is not read-only. Each row can be overridden to point package logic at a different Record Type than the packaged default.

Action What it does Behavior on update
Edit → choose a record type → Save Overrides which Record Type the package stamps on new records for that object New records only — every record this app creates for that object going forward uses your chosen Record Type. Records already created are never modified.
Reset / "Reset to default" Clears an override, reverting to the packaged Record Type New records only, same as above

Health Check (System → Health Check)#

Check What it does Behavior of its "Fix" button (where shown)
Scheduled Jobs Counts the cron entries the package expects — the donation finalizer, the reconciliation heartbeat, recurring billing, retention purge, refund/dispute reconciliation, the Stripe payment sweep, and the nightly campaign-total rebuild. It confirms they are scheduled, which is not the same as running; Gifts Being Recorded below is the row that knows the difference. Once a payment account exists it also answers a second question in the same sentence: can the jobs that call the gateway authenticate? A named-principal callout runs as the job's owner, so it goes red and names that owner when they hold no permission set granting an external credential principal — the state in which every refund, renewal and sweep fails silently while the count stays green. A package cannot see which credential a grant belongs to, so when every owner is granted the row keeps its colour and asks you to confirm the grant is on the credential your payment account names Fix schedules whatever is missing and re-owns any job whose owner no longer resolves. Safe to click at any time — a job that exists and is running is left alone, cadence included. It also appears for a stranded owner, but only if you yourself hold a credential grant — the repair is to reschedule the jobs under your login, which helps nobody if your login cannot authenticate either. If it isn't shown, grant the principal first (see Grant the credential)
Gifts Being Recorded Confirms the finalizer is actually running, not merely scheduled. The Scheduled Jobs row above counts jobs; this row reads a marker the finalizer stamps from inside itself, so it catches the case where all jobs are present but every run is failing. Three states, not two: green when a pass completed recently, amber when no pass has ever completed and no gift is waiting on one — every fresh install, where the work is real but nothing is at risk — and red when gifts are genuinely charged with no donation record, naming the count Fix re-schedules the whole pipeline under your own login, including re-owning any job the install left with an unreachable owner — the same repair as the Scheduled Jobs row. Available on amber as well as red, because the fresh install is the state that most needs it. Re-run the check a few minutes later
Donor Email Sender Confirms the From email on Email & Receipts actually resolves to an Org-Wide Email Address the package can send as — one that is verified and has Allow All Profiles to Use this From Address ticked. This is the only place the difference surfaces: a From address that resolves to nothing costs no donor a receipt, it just sends every one of them from whichever user or background job happened to trigger it No Fix button — the record has to be created and verified in Setup → Organization-Wide Addresses. The row names which of the two boxes is missing
Record Type Mappings Confirms all expected Record Type slots are mapped Fix adds only the missing default slots — it never overwrites an override you've already set
Payment Accounts Confirms at least one active payment account exists No Fix button — go configure one on the Payments panel
SOQL Limit (this request) Reports this request's own SOQL query usage Informational only — a per-transaction number, not an ongoing org-wide usage metric
Experience Cloud Site Confirms a site is connected (Known UI gap.) Its Fix button shows a success message but does not actually create anything — it only returns the same CLI command shown on the Site & Domain panel. The check will still show as failing after you click Fix; you still need to run that command yourself.
Package Licence Reads the org's licence for this package: green while it is active with seats to spare, amber when it expires within 30 days or one seat or fewer is left, red once it has expired. Not installed as a managed package (a developer org) is green — there is no licence to check No Fix button — seats are assigned under Setup → Installed Packages → Manage Licenses, and renewals happen on the subscription portal linked from Licence & Seats

"Fix" on the Experience Cloud Site row doesn't fix it

Clicking Fix shows a "Fixed" toast, but no site is created — it's informational only, same as the "Copy CLI command" action on Site & Domain. Run the CLI command yourself, then reconnect from the Site & Domain panel.

Scheduled Jobs (System → Scheduled Jobs)#

Controls the package's background cron schedule. The two cadences it can change are stored on Settings__c (Finalizer Interval (Minutes) and Heartbeat Interval (Minutes)); everything else on this panel acts on cron entries directly.

Every scheduled job appears as a card showing what it does, when it runs, and whether it is waiting or paused. The two families — Donation Finalizer and Reconciliation Heartbeat — expand to a cadence editor, because they need to run more often than once an hour and Salesforce can only express that as several jobs spaced across the hour (which is why one family shows a dozen rows; they are not duplicates). Every other job runs on a fixed schedule and its card is read-only: to move one, use Salesforce Setup → Scheduled Jobs and search for the job name printed at the bottom of its card.

The cadence is a trade between how fresh your data is and how many job slots you spend#

A Salesforce org can hold 100 scheduled jobs in total — across every package and everything your own admins have scheduled. At the shipped cadences this package occupies 24 of them: 12 for the Donation Finalizer (every 5 minutes), 4 for the Reconciliation Heartbeat (every 15), and 8 fixed single jobs. That is the largest single thing on the panel, and it is adjustable:

Finalizer interval Jobs used What a donor's gift looks like
5 min (default) 12 The donation record appears within about five minutes of the payment
10 min 6 Within about ten minutes
15 min 4 Within about fifteen minutes
20 min 3 Within about twenty minutes
30 min 2 Within about half an hour
60 min 1 Up to an hour

The delay is real but it is not a payment delay: the donor is charged and sees their thank-you page immediately, and the finalizer is what turns that charge into the Contact and Opportunity your staff see in Salesforce. Nothing is lost while it waits. Widen the interval if you are short of job slots; keep it at 5 if your team works from the donation records as gifts arrive.

Widening the finalizer costs one more thing, less obvious than the delay: it is also how quickly the console notices a pipeline that has genuinely stopped. That alarm waits three missed passes and never less than 30 minutes — so at the default cadence it speaks up after 30 minutes, and on an hourly finalizer after three hours. It has to scale that way, or an org finalizing hourly would report itself broken for half of every hour while working perfectly.

The Reconciliation Heartbeat is a safety net rather than a donor-facing path, so it can safely run less often than the Finalizer.

Both intervals must divide the hour evenly (5, 10, 15, 20, 30 or 60). A value typed straight into the Custom Setting that is not on that list is ignored and the packaged default is used instead.

Action What it does Behavior on update
Schedule missing jobs (panel header, and the button on the empty state) Schedules every background job the package expects — the finalizer and heartbeat families, recurring billing, retention purge, refund/dispute reconciliation, the Stripe payment sweep and the nightly campaign-total rebuild Immediate, and safe to click at any time. A job that exists and is running is left exactly as it is, cadence included. A job whose owner no longer resolves — which is every job a fresh install created, since the post-install script runs as a system user the org cannot reach — is aborted and rescheduled under your login. That second behaviour is the whole reason to press this after a fresh install. Same action as Fix on the Health Check row and the Get Started button, which reads "Restart the background jobs" when the jobs exist but are dead. If the panel is empty, this is the only control that can start the schedule — the cadence editor only appears once a family has jobs to edit.
"Run every" cadence + Save (per job family) Reschedules how often the Donation Finalizer / Reconciliation Heartbeat jobs fire, and stores the choice on Settings__c so upgrades, Health Check fixes and settings saves all keep it Immediate. Clearing the old entries and creating the new ones is one action, so a save that fails leaves the family as it was rather than scheduled nowhere. Re-saving the same interval is safe.
Run now — Recurring donations Manually kicks off the same nightly recurring-billing chain used at 2am Runs immediately, and it is the real thing — it charges every recurring gift due today exactly as the nightly job would, regardless of whether that nightly job is currently scheduled. Not a preview or dry run.
Run now — Donor summary rollups Recalculates donor lifetime-giving totals Immediate; does not trigger any charges
Run now — Retention purge Immediately deletes old logs/transaction logs/completed donation-staging rows Immediate, using whatever "Purge after (days)" value is currently saved on the Logging panel — not restorable afterward
Run now — Refunds and disputes Pulls refunds issued directly in the Stripe dashboard, and any chargeback activity, back into Salesforce Immediate; read-only against Stripe — it records what already happened there and never issues a refund itself. Also runs hourly on its own. Does nothing until Stripe is connected.
Run now — Payment sweep Finds Stripe payments that succeeded but never became a donation record, and finishes them Immediate; re-reads existing payments only, so it cannot double-charge. Also runs hourly on its own. Does nothing until Stripe is connected.
Run now — Campaign totals Recalculates every campaign's raised amount and donor count from its donations Immediate; overwrites the stored totals with what the donations actually say. Use it after a bulk import or any time a campaign's total looks wrong. Also runs nightly on its own.

"Run now" for recurring donations places real charges

This is not a test or preview button. Clicking it charges every donor whose recurring gift is due today, the same as if the nightly job had fired. Each charge is protected from being accidentally repeated on the same schedule the same day (an unchanged charge won't be billed twice), but any schedule not yet charged today will be charged the moment you click this.

Donation Monitor (app tab — no longer a Settings panel)#

A live worklist of donations stuck between "paid on Stripe" and "recorded as an Opportunity" — not settings fields. It lives on the Donation Monitor tab in the app navigation, not in this console; it is documented here because its one action changes records. For the filters and a worked troubleshooting sequence see Monitor donations and read the logs.

Action What it does Behavior on update
Retry now (per row) Re-checks the donation's payment status with Stripe and finalizes/expires it accordingly Immediate. This only re-reads the existing payment's current status from Stripe — it never submits a new charge, so retrying cannot cause a double charge. If the payment actually succeeded but finalizing keeps failing (e.g. a validation rule), the record is deliberately never auto-expired, so retrying repeatedly is safe — it just won't self-resolve until whatever is blocking finalization is fixed.

Next#

  • Setup assistant tour


    The four groups and every panel, at a glance.

    Setup assistant →

  • Settings & integrations concept


    How the three-tier settings model (Settings, packaged registry, credentials) fits together.

    Settings & integrations →