Build a parking payment app by creating sessions on entry (with time-in recorded), calculating fees based on duration at exit, and collecting payment via Paystack before releasing the vehicle. Use a QR code or number plate lookup at entry to create the session. At exit, calculate the fee, initialize a Paystack transaction, and update the session to paid when the webhook fires.
A parking payment app manages sessions between vehicle entry and exit. The core data is simple: when did the vehicle enter, when did it exit, how much does it owe, and has it paid?
The flow:
Database tables: parking_lots (location, rate per hour, max daily rate), sessions (plate, lot_id, entry_at, exit_at, fee_amount, status, paystack_reference), rates (lot_id, period, rate — for peak/off-peak pricing).
function calculateParkingFee(entryAt, exitAt, ratePerHour, maxDailyRate) {
var minutes = Math.ceil((exitAt - entryAt) / 60000); // ms to minutes
var hours = Math.ceil(minutes / 60); // round up to nearest hour
var fee = hours * ratePerHour;
return Math.min(fee, maxDailyRate); // cap at daily max
}
async function initiateExitPayment(sessionId, driverEmail) {
var session = await db.sessions.findById(sessionId);
var lot = await db.parkingLots.findById(session.lot_id);
var now = Date.now();
var fee = calculateParkingFee(session.entry_at, now, lot.rate_per_hour, lot.max_daily_rate);
var reference = 'PARK-' + sessionId + '-' + Date.now();
await db.sessions.update(sessionId, { fee_amount: fee, paystack_reference: reference });
var response = await fetch('https://api.paystack.co/transaction/initialize', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
email: driverEmail,
amount: fee, // in kobo/cents
currency: 'KES',
reference: reference,
metadata: { session_id: sessionId, plate: session.plate, lot_name: lot.name },
}),
});
var data = await response.json();
return data.data.authorization_url; // send to driver's phone
}
The webhook handler verifies the signature, finds the session by reference, marks it paid, and signals the barrier controller (via GPIO, serial port, or REST API depending on your hardware).
if (event.event === 'charge.success') {
var sessionId = event.data.metadata.session_id;
await db.sessions.update(sessionId, { status: 'paid', exit_at: new Date(), paystack_txn: event.data.id });
await barrierController.open(sessionId); // trigger exit barrier
}
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
See build a vehicle inspection booking and payment app for another government/transport sector Paystack integration.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course