Work/Education
Fikadis
Pocket money, tuck shop and store records in one system that keeps selling offline.
Live · paying customersLive, with active paying customers. Schools can sign up today.
WebInstallable web app
The problem
“Pocket money vanishes, the tuck shop is hard to reconcile, and parents cannot see anything.”
Nigerian private schools handle many small cash transactions with little control. Students carry cash and lose it. Attendants take cash at the tuck shop, and end-of-day reconciliation is guesswork. Textbooks and uniforms leave the store with no record. Parents have no quick way to see what a child spent. Many school systems charge per student per term, so the bill grows with the school, and most assume reliable internet, which many schools do not have. Holding parents' money would also need a banking-type licence.
Who had it
- Bursars and ownersReconciled daily figures and an audit trail they can stand behind.
- Tuck-shop and store staffA fast till, and records that protect them when figures are questioned.
- ParentsFund a child's wallet from a phone and see what was spent.
- StudentsPay at break without carrying cash.
What the answer had to survive
- School WiFi drops, and the till must keep selling.
- The vendor must never hold parents' money.
- One school's records must never reach another school.
- Every money movement needs an approval and an audit trail.
- Onboarding real schools means importing untidy spreadsheets.
What we built
One accountable system for wallets, sales, stock and books, with no money held.
Each student has a wallet, and every sale is stamped to a student, a cashier and a time. Sales queue on the cashier's device when WiFi drops and sync when it returns. Parents top up through Paystack, which pays the school directly, so Fikadis only records the entitlement. Restricted store items wait for an accountant's approval. Every school's data is filtered by school on every query, and a double-entry ledger and audit log back each action. The school pays one flat fee, not a charge per student.
What it does
Tuck-shop till
- Barcode student lookupFind a student by name, class or barcode scan, build a cart and debit the wallet in one step.
- Offline sellingSales and wallet changes queue on the cashier's device and sync on their own when the network returns.
- Stock trackingItem catalogue with prices, low-stock thresholds, and stock movements for receiving and write-offs.
- Branded receiptsPrintable and PDF receipts carrying the school's logo.
Wallets and parents
- Student walletsCredit, debit, transfer and reversal for each student, with opening balances on import.
- Parent top-upsParents fund wallets by card on Paystack checkout, and the credit lands in seconds.
- Installable parent portalA per-school branded web app on the phone, with one login for all of a parent's children.
- Spending insightsAverage daily spend, wallet runway, weekly trend and top categories for each child.
Store and fees
- Materials storeTextbooks, uniforms and sports kit issued directly, or only after an accountant approves.
- Bulk disbursementIssue materials to a whole class and keep a dispatch history with statements.
- Fee billingFee templates, class rosters, student bills, receipts and statements.
Expenses and books
- Expense vouchersVouchers move from draft to approved to paid, with policy warnings and attached receipts.
- Vendor payoutsApproved vendor payments go out by Paystack transfer, with failed transfers retried or marked paid offline.
- Double-entry accountingTrial balance, income statement, balance sheet, cash flow and aging reports.
- Audit trailEvery meaningful action is logged with who, when and from where.
Access and safety
- Roles and permissionsBursar, cashier, material officer, approver, parent and custom roles built from about 29 permissions.
- Two-factor sign-inOptional authenticator-app codes with single-use backup codes, plus login lockouts.
- Data export and deletionA school can export its data, or delete its account after a 30-day grace window.
A day with it
- 1
School signs up
The school registers, accepts the terms, verifies its email and starts guided onboarding with students.
- 2
Students are loaded
The admin imports a spreadsheet of students and opening balances, then sets classes and fee templates.
- 3
Parents top up
Parents open a link, install the portal on their phone and fund their child's wallet by card.
- 4
Break-time sale
The cashier scans the student's ID card and rings the purchase. The wallet debits at once, even offline.
- 5
Store issue
The storekeeper issues a textbook or uniform. Restricted items wait for the accountant's approval.
- 6
Bursar reviews
The bursar checks daily reports, approves vouchers, pays vendors and prints statements and the audit trail.
How it works inside
Staff and parents use a browser app on their phone or PC. A service worker keeps the till working offline and replays queued sales later. One web application and one database serve every school, with each school's rows kept apart. Paystack handles payments and nightly backups go offsite.
Cut the network to see what this system does without it.Internet links are down. Everything on the device and inside the building carries on, and queues its changes.
On the device
- Browser app with offline queueTill, admin pages and parent portal; queues sales when offline.
- Barcode scannerReads the student ID card at the till.
Our cloud
- Web applicationAdmin pages, public pages and the JSON API behind Cloudflare.
- School databaseWallets, ledger entries and audit log, filtered by school.
- Scheduled jobsReconcile payments, send reminders, clean up, back up.
Outside services
- PaystackCard checkout, transfers and payment webhooks.
- Email serviceVerification, receipts and reminders.
- SMS providerParent alerts through prepaid credits.
- Offsite backup storageNightly verified database dumps.
Every part and every link, as text
- Browser app with offline queue — Till, admin pages and parent portal; queues sales when offline. (on the device)
- Barcode scanner — Reads the student ID card at the till. (on the device)
- Web application — Admin pages, public pages and the JSON API behind Cloudflare. (our cloud)
- School database — Wallets, ledger entries and audit log, filtered by school. (our cloud)
- Scheduled jobs — Reconcile payments, send reminders, clean up, back up. (our cloud)
- Paystack — Card checkout, transfers and payment webhooks. (outside services)
- Email service — Verification, receipts and reminders. (outside services)
- SMS provider — Parent alerts through prepaid credits. (outside services)
- Offsite backup storage — Nightly verified database dumps. (outside services)
- Barcode scanner → Browser app with offline queue: Student ID barcode (works offline)
- Browser app with offline queue → Browser app with offline queue: Queues sales, replays later (works offline)
- Browser app with offline queue → Web application: Sales, top-ups, reports (needs internet)
- Web application → School database: Wallets, ledger, audit log (works offline)
- Browser app with offline queue → Paystack: Parent pays on checkout (needs internet)
- Paystack → Web application: Verify and transfer webhooks (needs internet)
- Web application → Paystack: Vendor and refund transfers (needs internet)
- Web application → Email service: Receipts and reminders (needs internet)
- Web application → SMS provider: Low-balance alerts (needs internet)
- Scheduled jobs → Web application: Reconcile and remind (works offline)
- Scheduled jobs → Offsite backup storage: Nightly verified dump (needs internet)
The hard parts
A payment that could be taken but never recorded
- The situation
- Payment is confirmed when the paying browser returns to the site. If a payer closes the tab first, money could be taken without a record.
- What we did
- We added a job that re-verifies pending subscription payments every 15 minutes. We also wrote a check that proves each payment key authenticates with the provider, and guards that catch mistyped email addresses at signup.
- The lesson
- Money flows are checked end to end, not assumed.
Backups that would have failed silently
- The situation
- The backup script shipped with the wrong database defaults, and its failure alerts used a mail command that was not installed. A failing backup would have said nothing.
- What we did
- We fixed the script, verified each upload by byte comparison, and broke the upload key on purpose to prove the alert fires. Then we drilled a full restore from the offsite copy.
- The lesson
- A school's money records can be recovered, and someone is told if they cannot.
Making the audit trail show the real visitor
- The situation
- Behind a content delivery network, the application would have logged the network's address instead of the person's address.
- What we did
- We set the web server to trust the network's published address ranges and pass through the real client address and protocol. We proved it with a marked request.
- The lesson
- An audit log is only evidence if it records who actually did the thing.
A school spreadsheet where every field shifted
- The situation
- A school's student file failed to import. Every row reported a missing class and an invalid email, because blank columns had pushed each field out of place.
- What we did
- We wrote down the exact seven-column format and cleaned the file, dropping separator rows and fixing stray spaces from an Excel paste. We loaded it through the application's own code, so each student also got a parent record and an opening balance.
- The lesson
- Onboarding messy school data works under the same rules the app enforces daily.
The stack
- Apps
- Vanilla JavaScriptService workerIndexedDBInstallable web app
- Backend
- PHP 8.3nginxPaystack API
- Data
- MySQL 8Double-entry ledger
- Infrastructure
- CloudflareCloud server in FrankfurtOffsite object storage
- Services
- PaystackAmazon SESTermii SMS
How it came together
- 1It runs offlineVersion 5.2.0 brought the offline till, performance indexes and ID card printing.
- 2Parents love itVersion 5.3.0 brought top-ups, insights, a multi-child portal and an installable app.
- 3Hardened for productionTwo-factor sign-in, account deletion, error capture, backups and a restore drill were added.
- 4Its own serverThe code was audited and a dedicated server built, secured and brought live.
- 5Ready to be relied onNightly offsite backups, monitoring and a status dashboard followed a readiness audit.
- 6Live paymentsLive payment keys were installed and verified, with a reconciliation job and guards against mistyped emails.
