Guided test plan for feature validation, concurrency/race conditions, and logical flows with examples and expected results.
Suggestion: This category is typically called Concurrency Testing or Race Condition Testing. Use parallel execution, per-wallet locking, and assert no duplicates and correct final balances.
Assumptions aligning with your docs:
IN (credit), OUT (debit)booking, refund, topup, admin_refund, b2e_adjust, change_bookingpending and require admin approvalGiven wallet_id=5001, currency=PKR, starting balance=10,000
{
"payable_id": 5001,
"type": "OUT",
"amount": 1_200,
"currency": "PKR",
"transaction_ref": "PNR-123",
"entry_type": "booking"
}
Expected: 200 OK, booking recorded; New balance = 8,800; Ledger: one OUT:1,200 booking
Reduce fare by 300 (credit back difference)
{
"payable_id": 5001,
"type": "IN",
"amount": 300,
"currency": "PKR",
"transaction_ref": "PNR-123-B2E-REDUCE",
"entry_type": "b2e_adjust"
}
Expected: 200 OK; New balance = 9,100; Ledger: IN:300 b2e_adjust
Increase fare by 200 (additional debit)
{
"payable_id": 5001,
"type": "OUT",
"amount": 200,
"currency": "PKR",
"transaction_ref": "PNR-123-B2E-INCREASE",
"entry_type": "b2e_adjust"
}
Expected: 200 OK; New balance = 8,900; Ledger: OUT:200 b2e_adjust
Old booking 1,200 → new booking 900; refund difference 300
{
"payable_id": 5001,
"type": "IN",
"amount": 300,
"currency": "PKR",
"transaction_ref": "PNR-123-CHANGE-REFUND",
"entry_type": "change_booking"
}
Expected: 200 OK; New balance = 9,200; Ledger: IN:300 change_booking
Replay the same refund
{
"payable_id": 5001,
"type": "IN",
"amount": 300,
"currency": "PKR",
"transaction_ref": "PNR-123-CHANGE-REFUND",
"entry_type": "change_booking"
}
Expected: 409 Conflict (duplicate); Balance remains 9,200
Initiate admin refund of 3,500
{
"payable_id": 5001,
"type": "IN",
"amount": 3_500,
"currency": "PKR",
"transaction_ref": "PNR-123-ADMIN-REFUND",
"entry_type": "admin_refund"
}
Expected (initiate): 202 Accepted; Transaction status=pending; Balance still 9,200
Expected (approve): On admin approval → status=successful; New balance = 12,700
Module-specific refund path with approval gate
{
"payable_id": 5001,
"type": "IN",
"amount": 700,
"currency": "PKR",
"transaction_ref": "BUS-REF-987",
"entry_type": "admin_refund"
}
Expected (initiate): pending if policy requires; Expected (approve): balance increases by 700
Immediate success if amount ≤ threshold
{
"payable_id": 5001,
"type": "IN",
"amount": 1_000,
"currency": "PKR",
"transaction_ref": "TRAIN-REF-555",
"entry_type": "admin_refund"
}
Expected: 200 OK; Balance += 1,000
Behaves same as train unless custom policy
{
"payable_id": 5001,
"type": "IN",
"amount": 800,
"currency": "PKR",
"transaction_ref": "CAR-REF-321",
"entry_type": "admin_refund"
}
Expected: 200 OK; Balance += 800
Start topup of 2,000 (pending), then confirm
// initiate
{
"payable_id": 5001,
"type": "IN",
"amount": 2_000,
"currency": "PKR",
"transaction_ref": "TOPUP-CC-888",
"entry_type": "topup"
}
// confirm (admin)
POST /admin/topups/TOPUP-CC-888/confirm
Expected (initiate): 202 Accepted, status=pending, balance unchanged
Expected (confirm): status=successful, Balance += 2,000
Perform OUT bookings for bus/train/car and verify final balance equals starting balance minus all successful debits.
Start bal=20,000; booking 6,000; change refund 1,000; admin refund 3,500 (pending then approve)
Expected balances by step: 1) After booking: 14,000 2) After change refund: 15,000 3) After admin refund (pending): 15,000 (no change) 4) After approval: 18,500
Balance=500; change requires additional 800 (OUT)
Expected: 422 Unprocessable Entity (insufficient balance); no mutation
transaction_ref per (wallet, type) to avoid duplicate rejections during new attempts.Need more detailed cases per module (bus/train/car)? Let me know and I’ll expand with module-specific amounts and policies.