The Problem: Referral Incentives That Don't Fit Nonprofits
Referral programs are everywhere. Refer a friend, get $10 off. Get a free month. Earn points.
For a charitable giving platform, none of those work. You can't say "Refer a friend and we'll donate less of your money." The incentive has to be intrinsic — something that makes the referrer more effective at the thing they already care about.
Our answer: vote power multipliers. Refer people, and your vote in the monthly charity election counts for more.
How It Works (The 30-Second Version)
- Every PIFster member gets a unique 6-character referral code (e.g.,
K7NP3W) - They share their link:
pifster.org/join?ref=K7NP3W - When someone signs up through that link, they become the referrer's "child" in the referral graph
- Each month, we rank referrers by new signups — the leader is crowned PIFster of the Month (POM)
- The POM and everyone in their referral tree (up to 3 levels deep) gets a vote multiplier
- That multiplier makes their vote count 2x, 3x, or more in the monthly charity election
The result: referring people doesn't just grow the community — it directly amplifies your influence over where the money goes. Aligned incentives.
The Gamified Referral Graph
This isn't a flat "who referred who" list. It's a directed graph with depth.
If Alice is the POM this month, everyone in this tree — Bob, Carol, Dave, Eve, and Frank — gets the vote multiplier. This creates a cascading incentive: Bob benefits when Alice leads, so Bob is motivated to help Alice maintain the lead.
The Closure Table Pattern
A naive approach would store edges (parent→child) and use recursive queries to find descendants. That's expensive. Instead, we use a closure table — a precomputed table of every ancestor→descendant relationship with the depth between them.
Now answering "who is in Alice's tree up to depth 3?" is a single flat query:
No recursion. No joins. O(1) lookup.
Building the Closure Table
When a new edge is created (Bob refers Carol), we insert the direct edge and compute all ancestor relationships in one SQL statement:
The key insight is the INSERT ... SELECT for closure propagation. When Bob refers Carol, we find every ancestor of Bob (Alice at depth 1, Bob at depth 0) and create new closure rows pointing to Carol at depth + 1. This single query handles the entire transitive closure update.
We cap depth at 3 to prevent unbounded growth. Three levels of network effects is enough to create interesting dynamics without becoming an MLM.
The Referral Journey
1. Token Provisioning
Every user gets a unique 6-character referral token, auto-generated on registration from a reduced charset (no I/O/0/1):
2. The Join Link
When someone visits pifster.org/join?ref=K7NP3W, a handler validates the token format, sets a 30-day pifster_ref cookie, and redirects to the registration page. The cookie survives if the visitor doesn't register immediately — they have a month to come back.
3. Registration + Email Verification
When the new user registers and verifies their email via magic link, the ReferralFinalizationListener fires:
- Read the pending referral parent from user meta (set during registration from the cookie)
- Call
createEdge()to insert the edge + update the closure table - Refresh the POM leaderboard cache
- Clear the cookie and pending state
The edge isn't created until email verification completes — this prevents fake signups from gaming the leaderboard.
4. Gift Card Auto-Referral
Here's where it connects to gift memberships: when someone buys a gift membership and the recipient redeems it, the purchaser is automatically registered as the referrer — no referral link needed. The gift card is the referral.
The Monthly Leaderboard
The “Parent Always Wins” Problem
There's an inherent flaw in tree-based referral systems: ancestors passively accumulate credit for their descendants' work. In our example tree, if Bob refers 10 people and Carol refers 5, Alice gets credit for all 15 — despite doing nothing new herself. Left unchecked, the earliest adopters permanently dominate the leaderboard simply by having been first.
We solve this with two deliberate constraints:
- Rank by direct (depth-1) referrals only. Alice only gets credit for Bob and Frank — the people she personally referred. Bob's and Carol's recruiting efforts earn them ranking points, not Alice.
- Reset the scoreboard every month. Last month's POM starts at zero on the 1st, just like a brand-new member. There are no dynasty advantages — the leaderboard is a sprint, not an inheritance.
The tree still matters for who benefits from the multiplier (the entire downline gets boosted vote power), but who earns the crown is purely a function of individual effort in the current month.
The Query
Each month, we rank all referrers for the active period window. The leaderboard query joins the closure table with edges, filtered to verified referrals within the current month's date range:
Ranking rules:
- Primary sort: direct (depth-1) referrals. You can't game the system by having your referrals refer people — only your personal referrals count for ranking.
- Tiebreaker: total verified across all depths. If two people have 5 direct referrals each, the one whose network is growing faster ranks higher.
- Second tiebreaker: earliest last referral. Rewards consistent effort over last-minute sprints.
The Vote Multiplier
Here's where it pays off. When a user casts a vote, the PomVoteMultiplierService checks if they deserve a boost:
The Profile Dashboard
Users see their referral stats on their profile: current rank, gap to top positions, multiplier status, and proximity messages like "2 personal referrals to take the lead!"
Statuses include:
- Ready to Rise — you have no referrals yet this month
- Ranked — you're on the board but not leading
- Leading — you're the current POM
- Empty Leaderboard — nobody has referred anyone this month (first-mover advantage!)
What We Deliberately Avoided
- Cash rewards. Money incentives corrupt the mission. Influence is the only currency.
- Unlimited depth. We cap at 3 levels. Deeper trees create MLM dynamics where early adopters permanently benefit regardless of ongoing effort.
- Permanent multipliers. The multiplier resets every month. Last month's POM starts at 1x on the first of the new month, just like everyone else.
- Penalizing churn. If someone you referred cancels, your referral still counts. We don't want people pressuring their friends to stay.
Tips If You Build This
- Use a closure table, not recursive queries. The closure table trades write-time computation for constant-time reads. Worth it when you're querying the graph on every vote.
- Verify before counting. Don't create the referral edge until email verification completes. Fake signups are the first thing gamers try.
- Rank by direct referrals, not network size. If you rank by total descendants, early adopters who referred one prolific person get credit for their referral's work.
- Cap your depth. 2-3 levels is the sweet spot. Deep enough for cascading incentives, shallow enough to avoid “passive income” dynamics.
- Make it visible. The leaderboard, the gap-to-first counter, the multiplier badge — these UI elements do more for engagement than the underlying system.
- Cookie the referral early, finalize late. Set the cookie on the join link, but don't create the edge until after email verification. This handles the case where someone clicks the link, browses, leaves, and comes back days later.
PIFster is a community-driven charitable giving platform where donors vote on which charity receives the community's pooled donations each month. We run on WordPress with magic link authentication, pay-what-you-want checkout, and gift memberships for donor acquisition. If you're building something similar, we'd love to hear about it.

