// CLIENT STORY
FishPal
FishPal is the membership system for South African angling federations, giving every angler one number for life and a member card that can be verified with a scan.
What FishPal is
FishPal is the online membership system for recreational and competitive angling in South Africa, used by SASACC and its federations. It holds the record of every member, from the national body down to the individual club, and handles everything that depends on that record: joining a club or transferring to another, paying season fees, holding a valid member card, registering boats on a licence, entering events, and committee administration at every level.
It serves four groups of people. Anglers use it to join or move clubs, pay their fees, show their card and manage their profile, mostly from a phone. Guardians use it to manage memberships for family members who do not have their own login. Committee members at club, regional, federation and national level use it to approve members, review proofs of payment, set season fees and dates, and run events. Marshals and officials at events, who need no login at all, scan a member's card to confirm that the membership is valid.
The aim is a single, reliable register for the whole sport, in which each angler has one SA number for life and their standing is the same wherever it is checked. Success is measured by two outcomes: a member can always see whether they are paid up and whether their card is valid, and a committee member can see and act on everything waiting for them without having to ask anyone. To get there, FishPal replaces the separate paper registers and spreadsheets that clubs kept, and applies the sport's season and fee rules in the same way at every level.
Background
Angling in South Africa is organised in several layers. SASACC sits at the top, followed by the federations, the angling regions and, finally, the clubs that anglers join. Each layer has its own committee and its own role in deciding who is a member and on what terms.
Before FishPal, most of these records were kept on paper and in spreadsheets, with each club following its own conventions. Treasurers reconciled EFT payments by hand, moving between clubs meant starting a new record, and marshals at competitions had no reliable way to confirm that an angler was paid up.
Member accounts and the digital card
Each angler receives one SA number for life, which stays with them from club to club. When a member signs in, FishPal shows their standing first: whether they are paid up, what they owe and what they need to do next. Committees continue to use their internal membership codes, but members only ever see plain descriptions.
Every member card carries a QR code that a marshal can scan with any phone. The scan opens a public verification page showing the angler's name, SA number, club and season, together with a short reason when a membership is not valid. The page deliberately excludes amounts owed and the reasons a membership ended, because that information is not needed at the gate. Validity is checked on the server for the season encoded in the card, rather than against the date on the scanning phone, so an old card or a screenshot of one does not pass. Because one person can hold several memberships after moving clubs, the check considers the person as a whole rather than a single record. Members can also save the card as a PDF at standard bank-card size (85.6 by 54 mm) for use where there is no signal.
Guardians manage accounts on behalf of people who do not have their own login, such as a child or an elderly parent. Because this means one person acting as another, we treated it as a security feature from the start. During design we identified three sign-in routes that could have allowed a linked account to log in directly, and we closed them by placing the check at the single point where every session is issued. A guardian who switches into a dependant's account receives a session scoped to that person, and ending the link ends both sessions at once.
Seasons, fees and payments
Almost every rule in FishPal depends on the season, including what a member pays and whether their card is valid. The first version worked out the season from the current date in about 108 separate places. Because South African time and the server's clock differ by two hours, those calculations could disagree around midnight. We replaced them with a single stored season record with a defined state (pending, active or expired), advanced by one scheduled job that cannot change a season twice and that catches up after any downtime. The database enforces a single active season, and an automated test prevents new code from reading the date directly.
The financial rules are built on that foundation. Paying the deposit makes a card valid, which allows members to pay in instalments. Fees remain owed from one season to the next, and a member with an outstanding balance cannot transfer to another club to avoid it. A debt can only be written off through a request that moves from the club up to SASACC, with every step recorded. Whenever FishPal declines an action, it states the club, season and amount involved, and offers a direct way to pay.
In August 2026 we carried out our own review of the payment flow. It showed that a member could declare the amount being paid, that a missing fee could be treated as zero, and that confirmations from the payment gateway were not compared with the amount actually settled. We rebuilt the flow so that the server sets every amount, capped at what is owed less anything awaiting review, and so that repeated clicks return the same payment reference. Card payments run through PayFast, and every notification is now verified by signature, origin, amount and a direct confirmation with PayFast. We validated our signature handling against PayFast's own tools after finding errors in several widely used guides. Any payment whose amount does not match is held for review rather than approved. Each club has its own merchant account, and its credentials are encrypted and never displayed again once saved.
Importing federation records
Federations submit their member rolls every season, each in its own spreadsheet format, so the import had to be repeatable rather than a one-off migration. Our first importer matched club names approximately, and in testing it placed anglers in the wrong clubs. We replaced it with an import that never guesses. Columns are read by their heading rather than their position, and any row that cannot be matched with certainty is set aside with a reason and a note identifying the cell to correct. A run that cannot account for every row it receives fails outright.
Before an import is accepted, around a hundred read-only checks must pass, including a dry run confirming that a repeat import would create no new people. The reasons we returned gave federations specific corrections to make, and after one round of corrected rolls the share of rows set aside fell from 20.3% to 17.9%. In total, the import processed 27,286 rows and brought 21,504 anglers and 595 clubs into the register.
Engineering quality, hosting and support
As the system grew, we found that about 75 parts of the code were each calculating their own answers to the same questions, such as whether a member was active or which age group they belonged to. Each passed its own tests, but the answers did not always agree, and in one case a filter applied at the wrong level meant a national message intended for club presidents reached none of the 591 recipients. We gave every such value a single owner in the code and added tests that fail the build if the calculation appears anywhere else. Age groups, for example, are now calculated from each angler's age on 1 January of the season, so the same report always returns the same result. This matters in practice: 697 members move into a new age group during 2026.
FishPal has more than 4,700 integration tests that run against a real database and about 4,000 tests on the front end. For the most important rules, we deliberately break the code to confirm that the tests detect the fault. Load testing and reviews have found and fixed real issues, including live messaging that had not been connecting in production and a gap that allowed a burst of 70 requests past the login rate limit, now reduced to 11. On a test environment holding about 194,000 profiles, member search time fell from 2.3 seconds to 0.2.
We have built the current version of FishPal since July 2025 and are responsible for all of it, including design, development, testing, releases and support. We also run its DevOps and hosting on AWS, covering the containers it runs in, the database, the release pipeline and the monitoring dashboards. FishPal is live, and development continues, most recently with identity verification and the acceptance of updated policies.
Timeline
Jul 2025
We start the current build of FishPal, using the first version's payments and committee reports as the starting point.
Oct 2025
The web app is rebuilt from the ground up, with payments and club registration.
Jan 2026
FishPal moves onto AWS and gets its brand colours across the app.
Feb 2026
A new API replaces the old one, and the import tool arrives.
Jun 2026
QR verification for marshals, and the big push on speed.
Jul 2026
The organisation structure is redesigned, with a stricter import.
Aug 2026
Card payments through PayFast, each club on its own merchant account.
Sep to Oct 2026
One home for the season, rules for money owed, and the move to 16 angling regions.
Nov 2026
ID verification, and members accepting updated policies.
Today
FishPal is live.
