Pharmacy stock and sales need to agree: what arrived, which batch is available, what was sold and whether payment was actually received. I built PharmaStock POS to connect these records in one application, with a React frontend, a FastAPI backend and a PostgreSQL database.
The operational problem
A product-level quantity alone does not explain batch expiry, receipt costs or the stock movements behind a sale. Digital payment also needs evidence beyond a staff confirmation. The project brings batch records, sales and payment status into an accountable workflow that pharmacy staff can review.
Connecting stock to each sale
Stock receiving records batch numbers, expiry dates, quantities and costs. Checkout allocates eligible stock using first-expiry-first-out (FEFO), blocks expired stock and preserves item and pharmacy details for receipts. Stock writes lock product records in a consistent order to reduce the risk of concurrent sales overselling the same stock.
Administrators, pharmacists and cashiers have different permissions. The application includes product and supplier records, customers, stock movements, audit records, reports and receipt printing. Prescription-related access requires appropriate staff authorization; an application role does not establish professional qualification.
From payment recording to verified checkout
The initial implementation recorded Mobile Money and card payments confirmed by staff. The updated integration uses Paystack hosted checkout and independently verifies the transaction reference, amount, currency and test or live environment on the server. Card details are collected by the payment provider.
- Checkout creates a pending sale and reserves eligible stock.
- The customer opens hosted Card or Mobile Money checkout.
- A signed webhook or staff verification request checks the provider transaction.
- Verified success completes the sale once. Verified failure releases its reservation once.
Closing checkout is not proof of failure. Unknown or abandoned payments remain reserved for reconciliation. A late success after a failed reservation, or a payment involving stock that has since expired, requires administrator review before dispensing.
Deployment and validation
The frontend and API are deployed separately on Render, with migrations applied to Neon PostgreSQL. Initial administrator setup uses a one-time bootstrap token; no default account or public staff registration is provided. The live application is a staff workspace, rather than an anonymous interactive demo.
All 28 backend tests passed locally, and GitHub's PostgreSQL backend checks and frontend build passed. Payment tests use mocked provider responses to check signatures, duplicate verification, mismatched amounts and currencies, failure release and late-success review. These checks do not establish that live merchant transactions or a pharmacy rollout have been validated.
What this project demonstrates
PharmaStock demonstrates a connection between operational records, database consistency, staff permissions and payment evidence. It remains a single-branch pilot: offline transactions, partial returns and automated gateway refunds are outside the current scope. Pharmacy review, merchant testing and an operational pilot are the next steps; no adoption, revenue or clinical outcomes are claimed.
← Back to Insights