Getting Started
After you install#
The install seeds everything it is allowed to seed. Seven things are left, and five of them can only be done by a human in Salesforce Setup. This page is the written version of the Get Started panel inside the app — every screenshot below was taken while completing the setup by hand in a brand-new org, in the order you will hit them.
You were probably sent here automatically
Salesforce redirects you to this page as soon as the package finishes installing or upgrading. Nothing is broken — this is the handover.
Watch it first#
What it is. A fifteen-minute narrated walkthrough of the whole setup, from the Get Started panel to a published donation site. It is assembled from the fifty-two screenshots on this page rather than screen-recorded, so nothing moves faster than you can read: every screen holds for exactly as long as its narration takes, and the banner underneath names the action and where in Salesforce you are standing. Captions are in the player’s subtitles menu, and the chapter list above jumps straight to a step. Pause anywhere — the same screenshot appears further down this page with the full written explanation beside it.
The seven steps#
The Get Started panel (App Launcher → Pledgivo → Settings) is the same checklist, checked against your org live. A step there is never a box you tick — it reports what your org actually looks like right now, so if someone later deactivates the last payment account or aborts the scheduled jobs, the step reopens on its own.
| # | Get Started step | Where the work happens | On this page |
|---|---|---|---|
| 1 | Give your team access | Salesforce Setup | 1. Give your team access |
| 2 | Confirm record type mapping | Already done by the install | 2. Confirm record type mapping |
| 3 | Activate your donation site | Setup → Experience Builder → Workspaces | 3, 4 and 10 |
| 4 | Set up your payment account | Salesforce Setup, then the console | 5 and 7 |
| 5 | Let your donation site use the payment credential | Salesforce Setup | 6. Grant the credential |
| 6 | Start the background jobs | The console, once — the install alone is not enough | 8. Background jobs |
| 7 | Set your organization name and logo | Settings console | 9. Organization name and logo |
An eighth item — Trust the content hosts you actually use — is listed but never counts against your seven. See Third-party content.
Two of the seven steps span more than one section here, because the checklist counts outcomes and this page follows work order. Step 3 is created early and activated last, on purpose: you publish a site while you are building it and activate it once everything behind it works. Step 4 splits because its credential pair is built in Setup before the console can grade any of it — that dependency is spelled out in section 5.
The screenshots step themselves
Every run of screens below is one panel showing a single screenshot at a time, with its explanation underneath. Click the screenshot — or the arrows — to move to the next step, or use the numbered row to jump anywhere. Leave it alone and it advances by itself while it is on screen; hovering pauses it, and touching any control hands it back to you for good.



1. Give your team access#
Nobody can see a campaign, a donation, or the Settings console without one of the packaged permission sets. The install cannot assign them for you — Salesforce gives a post-install script no way to know who on your team does what.
| Permission set | Give it to |
|---|---|
Fundraising_Admin |
Whoever runs fundraising. Full CRUD on every object, plus the Settings console. |
Fundraising_User |
The rest of the fundraising team. Day-to-day record access, no setup. |
Fundraising_ReadOnly |
Anyone who needs to see gifts but never change them — finance, leadership. |
Fundraising_GuestDonor |
Not a person. Assign to your Experience Cloud site's guest user only. Least-privilege grants for the public donation flow. See section 4. |
The route that always works is from the user, not from the permission set:
- Setup → Users → Users → click the person's name.
- Scroll to the Permission Set Assignments related list.
- Edit Assignments.
- Move the set from Available Permission Sets to Enabled Permission Sets → Save.


The Settings console is Fundraising_Admin only. A Fundraising_User cannot open it, and
cannot change what it configures by another route either: payment accounts, page designs, and
every app setting are read-only for that set. They still see those records — picking a design
or a payment account for a campaign keeps working — they just cannot edit them from a record page,
the API, or Data Loader. If someone on your team needs to configure payments, designs, or org
settings, give them Fundraising_Admin; there is no middle tier.
2. Confirm record type mapping#
The app writes donations, events, and tributes onto Opportunity and Campaign record types. The install seeds a default mapping of seven records pointing at the record types it ships, so this step arrives green — the evidence line on Get Started reads "7/7 mapping records present".
Open Settings → System → Record Types only if your org already uses its own record types for gifts and you want the app to write to those instead.
Change this before you take gifts, not after
Remapping later does not move donations that were already written under the old record type. Decide now if you are going to.
3. Create the donation site#
Get Started step 3, part one
Donors give on an Experience Cloud site, not inside Salesforce. Internal-only use — staff recording gifts taken over the phone — does not need one; anything public does.
The console's Experience Cloud → Site & Domain panel is the checklist for this whole section. It grades each step against your org where Salesforce exposes an API and says so plainly where it does not: a step marked Can't verify is not a warning, it is the honest state, and it is yours to confirm.
If Setup has no Digital Experiences menu, switch the feature on first: Setup → Digital Experiences → Settings → Enable Digital Experiences. It is org-wide, asks you to pick an Enhanced Domain subdomain, and cannot be undone.


sf community create command for anyone who works from a terminal; the UI route below is the same outcome.

fundraising, not fundraising-2026-test.



4. The site's guest user#
Get Started step 3, part two
Every public visitor to your site is one Salesforce user: the site's guest user. What that user can reach is what the public can reach, so this section is the security boundary of the entire public experience — and it is where a first setup most often stalls, because the guest user is not where you would look for it.
How to actually reach the guest user
It is not in Setup → Users (no list view contains it), and Experience Workspaces → Administration → Members cannot assign to it — that page defines which profiles and permission sets count as site members, which is a different thing entirely.
The route that works: Workspaces → Administration → Pages → Go to Force.com → Public Access Settings → View Users → the user named "<your site> Site Guest User".
From there, Permission Set Assignments → Edit Assignments behaves like any other user.
Two permission sets have to reach that user, and only one of them ships with the package.
| Set | Where it comes from | Why |
|---|---|---|
Fundraising_GuestDonor |
Packaged | Every custom object and field a public donation, event or ticket page reads |
| A Campaign read set you create | You, by hand | Campaign is a standard object, and Salesforce strips standard-object permissions out of a packaged permission set at build time |
A fundraiser is a Campaign record, so without that second grant every public campaign, donation and ticket page fails to load. Granting Read on Campaign directly on the guest user's profile works just as well — Site & Domain counts either route.
Read, and nothing else
A guest user must never hold Create, Edit or Delete on Campaign. When you create the
permission set, leave the License field as --None--: the picklist offers no "Guest User
License" option, and a set created under the org's Salesforce licence cannot be assigned to a
guest user at all — the assignment fails three clicks later with a licence mismatch.


Fundraising Guest Donor set assigned. This is per site, not org-wide: repointing the package at a different site later means assigning it there too. A site whose guest user never got this fails quietly — pages load, forms render, and every donation breaks on submit.




5. Build the Stripe credential pair#
Get Started step 4, stages 1 and 2
This package never ships, stores, or creates a payment credential of its own. You build the External Credential and Named Credential yourself in Setup — that is where your Stripe secret key lives, encrypted, and it never touches a custom field or an Apex method.
You build two pairs, not one. This is deliberate, and it is the security boundary of the whole integration:
| Pair | Key to use | Who is allowed to reach it |
|---|---|---|
Public — Stripe_Auth_Public + Stripe_Public |
A restricted key (rk_live_… / rk_test_…) that can create charges and nothing else |
Staff and the site's guest user |
Admin — Stripe_Auth_Admin + Stripe_Admin |
A back-office key — best a second restricted key scoped to refunds and reads, or your full secret key (sk_live_… / sk_test_…) |
Staff only. Never the guest user |
New to Stripe, or not sure which key is which and what to switch on when you create the restricted one? The two Stripe keys, and what each one may do covers it from the start, with the exact permissions to grant.
Why the panel cannot grade this stage yet
The eleven steps are graded per payment account — the checks read the credential a payment account names. Until section 7 creates that account, the six build steps report Action needed no matter how correctly you have built them in Setup. That is why the panel leads with a Do this next card instead of the step list, and why Add account stays disabled until at least one named credential exists in the org. Build the pair first, and let the grading catch up afterwards.





Build it in Setup#
The external credential holds the secret; the named credential holds the URL and the callout options. Neither is usable without the other.

Stripe_Auth_Public, and set Authentication Protocol to Custom — Stripe authenticates with a bearer token, not OAuth.
pledgivo_test__ prefix; in your org it is exactly what you typed.)
Bearer rk_… — the word Bearer and a space must precede the key, because the header is passed through verbatim. Once saved the value is write-only: Salesforce will never show it again, to you or to any Apex.
{!$Credential.YourCredentialName.SecretKey}. The middle of that formula is the credential's saved API name — copy it from the record rather than retyping it. A formula pointing at a name that does not exist saves without complaint and fails silently at the first live donation.
Stripe_Auth_Admin — identical in shape, different key, its own OrgPrincipal. The two share no state, which is the point: a leak of one does not expose the other.
https://api.stripe.com, no trailing path, and the external credential you just built. Everything else you need is on this same form — you do not have to save and re-edit.



https://api.stripe.com. This is the finished state of stage 2 — and the state that unlocks the Add account button back in the console.6. Grant the credential#
Get Started step 5 · Payments stage 3
This is the step that catches people out. A credential nobody is granted is a credential nobody can use — including the staff who issue refunds from a donation record. And granting it to your site's guest user widens what an anonymous visitor can reach, so it stays your decision. The package never makes it for you.
Public donations fail at the payment step until you do this. Everything else on the page works, which is exactly what makes it easy to miss.
Why the permission set can't be part of the package
Salesforce does not allow a managed permission set to grant access to an external credential
principal — the API rejects it outright. That is why these sets have to be ones you create in
your own org, and why Fundraising_Admin can never ship with the grant on it.
Build one permission set per credential, so that "who can charge" and "who can refund" are two different answers:
- Setup → Permission Sets → New. Leave License as
--None--. - On the set: Apps → External Credential Principal Access → Edit.
- Enable the entry for your credential's principal — it reads like
Stripe_Auth_Public - OrgPrincipal→ Save. - On the same set: Object Settings → User External Credentials → Edit, tick Read and Create → Save.
- Manage Assignments → add the people who take payments (public set) or issue refunds (admin set).
- Assign the public set — and only the public set — to the site guest user, via the Public Access Settings route.
Step 4 is not optional, and it is a different page from step 3
A credential callout needs two grants: the principal (step 3) and Read + Create on the standard User External Credential object (step 4). Miss the second and the donation fails at exactly the same point as missing the first — the donor sees a generic apology and the real error only appears in Diagnostic Logs:
You don't have read permissions on the User External Credential object.
The package ships this grant in its own permission set, and Salesforce strips it during packaging: a managed permission set cannot carry standard-object permissions, and the build reports success anyway. That is why it has to be yours. All three places in the Settings console that grade this step check for it — Get Started step 5, the Payments panel's Let your public site use the credential, and the Site & domain panel — and each names the object by name when it is missing, so none of them can show green on an org where donations still fail.



Don't forget the guest user — and don't give it the admin credential
Assigning to staff but not to the site guest user is the failure mode that looks healthiest: internal testing works and every public donation fails at payment.
The opposite mistake is worse and just as quiet. Putting the guest user on the set that grants the admin credential lets an anonymous visitor's session reach a full secret key, refunds included.
7. Add the payment account and prove it works#
Payments stage 4 — this is what closes Get Started step 4
A named credential is plumbing. The Payment Account record is what a campaign actually charges through, and it is the record every one of the eleven checks is graded against. Until an active one exists, the donation form cannot take money and the guide cannot grade itself.





rk_test_…PUBLIC, {!$Credential.…SecretKey}, https://api.stripe.com — never a real key. The console has no way to display a secret, by design.



Full walkthrough: Connecting Stripe.
8. Background jobs#
Donations are finalized, payments swept, refunds reconciled, and campaign totals repaired by scheduled Apex — 24 cron entries in total. The install creates all 24, and the step still reports "24 of 24 background jobs are scheduled". Press the button anyway.
This is the one step a fresh install does not finish for you
A post-install script runs as a Salesforce system user your org cannot reach, and a scheduled job belongs to whoever scheduled it. So the 24 jobs the install creates are real cron entries owned by a user that no longer resolves — they are scheduled, and they do not run. The count is honest and reassuring and tells you nothing about the thing that matters.
On a fresh install the step therefore reads amber, not green: "The background jobs have not completed a pass yet, and no gift is waiting on them." Amber rather than red because nothing is at risk yet — you have taken no gift — but the work is real. Press Restart the background jobs. It aborts each orphaned job and reschedules it under your own login, and the step turns green within a few minutes, once the finalizer has completed its first pass and stamped the marker the console reads.
Do it before you share a donation link, not after.
Restart them as a user who can reach Stripe — order matters
Re-owning the jobs fixes who runs them. It does not, on its own, make them able to
authenticate. A named-principal callout runs as the owner of the job, so a job owned by
someone holding no permission set that grants the external credential's principal fails every
single time it fires — refunds and chargebacks never come back, recurring gifts never charge,
and a payment taken but not recorded is never swept up. Every cron row still reads WAITING,
on time, and the job count still reads 24 of 24.
So do step 6 before this one, and press Restart the background jobs while logged in as a user who holds that grant — the jobs are rescheduled under whoever presses it. The Scheduled Jobs health row checks this from that point on: it names the owner when the owner holds no such grant, and offers its own Fix button only when you hold one, because the repair is to take the jobs over.
One limit, stated plainly: a package cannot see which credential a given grant belongs to
(SetupEntityAccess names the permission set but its target is not queryable). So the row can
prove an owner holds no grant, and it can never prove the grant they hold is the right
one. When every owner is granted, the row keeps its colour and adds a sentence asking you to
confirm the grant is on the credential your payment account names.
Confirm this step is green before you share a donation link
The Finalizer-<m> family is what turns a confirmed card payment into an Opportunity, a
donor record and a receipt. With the finalizer stopped, a donor's card is still charged and
they still land on the thank-you page reading "your receipt is on its way" — but nothing is
created in Salesforce. The gift waits as a Donation Staging record and finalizes on the
next pass once the jobs are running again, so nothing is lost permanently. The danger is
the gap in between, when your reports show fewer gifts than your Stripe dashboard does.
The donation form deliberately does not refuse the gift when the finalizer is down —
blocking a donation to protect against a delay would be the larger outage. It does raise the
alarm: every gift taken while the pipeline is stopped writes a PIPELINE_STALE error to the
Transaction Log, and both this step and the Gifts Being Recorded health check turn
red and name the number — "3 gifts are charged but NOT recorded." That count is what
separates red from the amber above: amber means the jobs are not running and nothing is
waiting on them; red means gifts are.
A green job count is not proof the jobs are running
"24 of 24 background jobs are scheduled" says the cron entries exist — a job that is scheduled but fails on every fire still counts. The console therefore reads a second signal: the finalizer stamps the time each time it completes a pass, and if that stamp is more than 30 minutes old (six missed passes) this step goes red regardless of the job count. That is the number to trust.
You need this step after a fresh install, if some jobs were aborted (a deployment that touched a scheduled class will do it), or if the post-install script did not complete. Settings console → Get Started, where the button reads Restart the background jobs when the jobs exist but are not running and Schedule the missing jobs when some are genuinely absent — the same button either way. Scheduled Jobs has the per-job breakdown and on-demand runs. Pressing it on a healthy org changes nothing: a job that exists and is running keeps its schedule, including a cadence you customized. A job whose owner no longer resolves is aborted and recreated under you.
To confirm a gift really landed, open Donation Monitor: it lists every staging record still
waiting, and warns at the top when the Finalizer family is not scheduled.
| Family | Count | Cadence |
|---|---|---|
Finalizer-<m> |
12 | Every 5 minutes |
ReconciliationHeartbeat-<m> |
4 | Every 15 minutes |
Fundraising — Guest Request Sweep-<m> |
3 | Every 20 minutes |
| Recurring donations, retention purge | 2 | Daily |
StripePaymentSweep, RefundReconcile |
2 | Hourly |
CampaignRollup |
1 | Nightly |
9. Organization name and logo#
Your organization name and logo appear on the donation form, the receipt email, and the donor portal. The install seeds a placeholder logo so nothing renders broken on day one — it is not your logo.
The display name has no placeholder. Leave it blank and the public pages do not quietly borrow your Salesforce org name — the donation form's trust bar, the thank-you page, the event-ticket page and the donor portal simply head with no name at all, and the campaign gallery falls back to the literal word "Fundraising". The one page that does substitute your Salesforce org name is the internal receipt print view, because a tax receipt with an empty letterhead is not a receipt. So set this before you share a link, not after.
Settings → General → Organization & Donations holds the rest of your public-facing identity too: the footer line, terms and privacy links, and the social handles that render in the footer band of every public donation page. They live here rather than on a page design because they describe your organization, not a visual style — so changing a campaign's style never changes which privacy policy its donors are pointed at. Leave any of them blank and the footer omits it.
The same panel holds your gift rules: minimum and maximum amount, suggested amounts, processing-fee percentage and fixed portion, the donation page path, donor portal link expiry, and the default thank-you button. There is no mailing address field — receipts take their address from your Salesforce company information.
The Get Started step reads back what a donor will see: 'Public pages show "Acme Nonprofit"'. Set the display name before you send anyone a link.
Set the address donor email comes from#
Not a Get Started step — but do it before you take a real donation
Out of the box, every receipt, ticket confirmation and payment-failure notice is sent from whichever user or background job triggered it. On a live org that means a donor's tax receipt arrives from a scheduled-job address nobody monitors. Apex cannot invent a sender, so fixing this is a two-part job and the Salesforce half comes first.
- Setup → Organization-Wide Addresses → Add. Enter the address donors should see (e.g.
donations@your-org.org) and a display name. - Tick Allow All Profiles to Use this From Address. This is not optional: receipts are sent by the Experience Cloud guest user and by scheduled jobs, and an address restricted to selected profiles simply won't be used by either.
- Open the confirmation email Salesforce sends to that address and click through, so the record shows Verified.
- Back in Settings → General → Email & Receipts, put the same address in From email and save.
- Settings → System → Health Check → the Donor Email Sender row confirms it. That row is the only place the difference shows: a From email that matches no verified, all-profiles Org-Wide Email Address costs no donor a receipt — it just silently keeps sending from the triggering user, with no error anywhere.
Once a From email is in effect, the From name field stops being applied — Salesforce takes the display name from the Org-Wide Email Address record instead. Set the name you want on that record.
Full walkthrough: Brand your receipt and notification emails.
10. Publish and activate the site#
This is what finally closes Get Started step 3
Back to the one step the earlier sections left open. Two operations remain, they are different things, and they live on different screens.
Published is not the same as Live
Publish pushes your page changes to the site. Activate makes the site reachable by the public. A published site that has never been activated serves nothing to anyone. The Activate button is not in Experience Builder — it is in Workspaces → Administration → Settings, next to the status.
Get Started shows step 3 as Partly done until then, and quotes the status by its API name:
the Preview you see in Workspaces reads as UnderConstruction in the console. Same state,
two names.



Then activate:
- Setup → Digital Experiences → All Sites → Workspaces beside your site.
- Administration → Settings.
- Activate, next to the status.
Salesforce warns that activating sends a welcome email to members; you can suppress that beforehand under Administration → Emails. Once the status reads Live, come back to Get Started, press Re-check, and the counter closes at 7 / 7 — your org is ready to take donations.
Third-party content#
Optional — nothing here is required
During the install Salesforce shows you an Approve Third-Party Access dialog listing every external domain the package wants your org to trust. This package lists Stripe and nothing else:
| Domain | Why |
|---|---|
js.stripe.com |
Loads Stripe.js, which collects the card details |
api.stripe.com |
The payment API the browser confirms against |
m.stripe.com, m.stripe.network |
Stripe's fraud-signal endpoints — payments fail without them |
hooks.stripe.com |
3-D Secure / bank authentication screens |
That is deliberate. A fundraising package asking to reach a list of unfamiliar domains reads as a warning rather than as a payment integration, so the optional features that use other hosts ship without their trusted sites. You add those yourself, only if you want the feature.
| Add this domain | Directive | Unlocks |
|---|---|---|
https://images.unsplash.com |
Image | Using an Unsplash photo as a campaign hero or social card |
https://www.youtube.com |
Frame | A YouTube video in a campaign page video block |
https://www.youtube-nocookie.com |
Frame | YouTube privacy-enhanced (no-cookie) embeds |
https://player.vimeo.com |
Frame | A Vimeo video in a campaign page video block |
To add one: Setup → Security → CSP Trusted Sites → New Trusted Site. Enter the URL exactly as written above, name it anything, tick the directive shown, leave Context as All, and save.

What it shows. The optional step, reading your org's trusted sites live: here images.unsplash.com and www.youtube-nocookie.com are TRUSTED and the other two are NOT ADDED — "2 of 4 optional content hosts are trusted in this org". It never counts against your seven steps and it never offers a fix button, because Salesforce does not let Apex create a trusted site. This one is yours.
A video in a campaign story is a narrower case
The story field's @[…](youtube:…) block only ever embeds https://www.youtube-nocookie.com,
and only when Play story videos on the page is switched on in Settings → General →
Organization & Donations → Story media. Left off — the default — a story video is a poster card that
links out to YouTube in a new tab and needs no trusted site at all.
If you do switch it on, the Organization panel prints the exact recipe: URL
https://www.youtube-nocookie.com, frame-src only, and Context Experience Builder Sites
(narrower than All, because a story only ever renders on a public site). See
Write a campaign story.
www.youtube.com and player.vimeo.com above are for the Page Canvas video block, which is
a different feature and accepts both hosts.
Your campaigns start with a packaged hero image, not a stock photo
The package ships its own artwork — a hero backdrop and a social share card, both drawn from the brand palette rather than licensed from a stock library — and publishes them into your org at install time. The ten packaged page designs are stamped with the hero automatically and the share card resolves org-wide, so a campaign looks finished on day one. A design you create starts with an empty hero field and stays that way — a blank there is treated as your choice, not as something to fill in for you, and a campaign built on it shows a plain coloured hero unless the campaign supplies its own header image.
They are served from your own org's file domain, which browsers allow without a trusted site, so nothing on the list above is needed to see them. Replace the hero at any time by uploading your own image in Designs, or the share card in Organization & Donations; an image you have chosen is never overwritten by a package upgrade. To paste a URL from an outside host instead — Unsplash, your own CDN — that host needs a CSP trusted site first, per the table above.
When you're done#
The Get Started panel shows 7/7 and "Your org is ready to take donations." Setup is finished — but your org still has nothing to give to.
Everything you raise money with lives in the Fundraisers tab#
Campaigns and ticketed events are not created in Settings. Open the Fundraisers tab (App Launcher → Pledgivo → Fundraisers, or the Open Fundraisers button on the finished Get Started panel). It is the console your fundraising team works in day to day, and it is the only place a public donation page comes from.
| In the Fundraisers tab | What you get |
|---|---|
| New fundraiser wizard | A Campaign, step by step: goal and fund, designations, page design, and its public URL. |
| Ticket types | Turns a campaign into a ticketed event — tiers, prices, capacity, and the registration page. |
| The fundraiser list | Search, filter, publish, or deactivate anything already live. |
| A fundraiser's detail page | Its donations, registrations, attendees, questions, and FAQs in one place. |
The Settings console you just finished is for org-wide configuration — payments, receipts, branding, jobs. You will rarely go back to it. The Fundraisers tab is where the actual work happens.
Full walkthrough: Set up your first campaign, or Set up a ticketed event.
Put a donate button on your own website#
Your donation pages work as links, and they also work embedded. The Embedding block at the bottom of Site & Domain is where that is switched on and locked down.

What it shows. Your site's Base URL — the real public path, the one the publish dialog printed — the Allow embedding master switch, and Allowed embed origins. That last list is an allowlist, not a formality: only the origins named there may host your widget, and it takes full origins (https://example.org), not bare domains. During development a local origin such as http://localhost:8910 belongs here and should come out again before you go live.
Full walkthrough: Embed a donate button on your website.
Then prove it end to end#
Once your first campaign is published, send yourself a real gift for the smallest amount Stripe allows and refund it. It is the only way to prove the whole path — form, payment, receipt, refund — works in your org.