Core Concepts
Settings & integrations#
Configuration is deliberately split across three tiers by how often it changes and how sensitive it is — not thrown into one catch-all object.
The three tiers#
| Tier | Storage | Editable by | Holds |
|---|---|---|---|
| 1 | Settings__c (Hierarchy Custom Setting) |
Admins, at runtime, from the Settings console | Everything an admin should be able to tune without a deploy — retry counts, grace periods, feature toggles, thank-you copy |
| 2 | Packaged code and metadata — PaymentGatewayRegistry (Apex), Theme_Token__mdt (Custom Metadata Type) |
Nobody in the subscriber org; changes only via package upgrade | Facts about what the package itself ships — which class implements which processor, which theme tokens a page design may override |
| 3 | External + Named Credentials, built by hand in Setup — the package ships none and creates none | Admins, in Setup only; never through custom Apex or a custom field | Secrets — API keys, tokens |
This split matters because it maps directly to who can safely change what: a fundraising admin should be able to change the recurring retry count without a code deploy, but should never be able to (or need to) directly edit which Apex class handles Stripe calls, and a secret key should never be readable through a SOQL query or a debug log.
Settings__c in practice#
Settings__c is a Hierarchy Custom Setting, which means it supports org-wide defaults with
optional profile- or user-level overrides, though in practice nearly everything is configured
at the org-default level through the Settings console.
It covers refunds, recurring/dunning behavior, event defaults, logging verbosity, Experience
Cloud/embed toggles, donor portal copy, and organization display defaults — see the
Settings data model reference for the complete field list.
Two of its fields describe your payment processor rather than your fundraising: Fee Coverage Percent and Fee Coverage Fixed hold the rate used to gross up a gift when a donor chooses to cover processing fees. Both are optional — blank falls back to the US card standard (2.9% + $0.30) — and neither has any effect until a campaign opts in. See Donations & payments.
SettingsService is the typed accessor every Apex class reads through — application code
never queries Settings__c directly, so a field rename or a new default only has to change in
one place.
Reading what the logger wrote — the Diagnostic Logs tab#
Logging verbosity is a setting; reading the logs is not. Diagnostic Logs in the app navigation lists the most recent entries the package wrote about its own behaviour — newest first, capped at 200, and the page says so rather than presenting a truncated list as the whole story. The Logging panel in the Settings console still decides what gets recorded. This tab is where you read it, and it deliberately sits outside that console: troubleshooting happens repeatedly, during an incident, and often by someone who has no business changing the org's settings on the way past.
The part worth understanding is what an empty list means, because on its own it means nothing. The page reads both logging settings back and says which case you are in: if Log level is Off nothing is being written at all, and a banner says so; at the Error default the info or debug entry you are hunting for was never recorded; and because the nightly retention job deletes by age, an incident from last quarter can be gone rather than absent. Only once none of those apply does an empty list actually mean the org is clean — and that is the one reading a log viewer must never get wrong.
Who sees it follows from who can already read the underlying records. Log__c is Private, and
AppLogger writes each entry as whoever ran the transaction, so the tab is granted to
Fundraising_Admin and Fundraising_ReadOnly — the two sets holding View All on the object —
and deliberately not to Fundraising_User, which would see only its own sessions and read that
partial list as an all-clear.
See Monitor donations and read the logs for the filters and a worked sequence.
The payment gateway registry#
PaymentGatewayRegistry exists so a second payment processor could be added later without
touching the donation pipeline: it maps a processor to the class implementing IPaymentGateway,
the API version to call, and the shape of credential that processor needs.
PaymentGatewayFactory.getByAccount() is the one place that resolves a Payment_Account__c to
its gateway implementation — nothing else in the codebase branches on the processor. Today,
Stripe (StripeGateway) is the only registered implementation.
The registry is Apex rather than custom metadata, which is why tier 2 above is described as
"packaged code and metadata" rather than "custom metadata". It used to be a CMDT
(Payment_Gateway__mdt, removed August 2026), and that was the wrong tier for it: every value
in it named something the package itself ships, so no subscriber could ever meaningfully change
one — being data bought no flexibility and cost a compile-time check. The rule of thumb it
produced: if an admin may need to change it between upgrades it belongs in tier 1; if every
value names a part of the package, it belongs in code.
NPSP, detected not required#
Pledgivo works in any org, with or without the Nonprofit Success Pack installed. If NPSP is
present, NpspSyncService optionally mirrors recurring donations to
npe03__Recurring_Donation__c and fund designations to NPSP's GAU Allocations — each gated by
its own Settings__c toggle, both off by default. See NPSP →.
Related reference#
-
Setup assistant
A tour of every Settings console panel.
-
Settings console reference
What every setting does, and behavior on update.
-
Settings fields
Complete field-level reference for
Settings__c. -
Stripe integration
How
IPaymentGatewayandPaymentGatewayRegistryfit together.