SUCCEEDED/FAILED (not "APPROVED"/"REJECTED"); live Paynamics flows are untestable now (no prod credentials, events currently free).
URLs in this section were NOT migrated to the staging-subdomain form (
stg-rcme.membervu.com) in the 2026-06-10 env pass — they will be corrected during the rewrite.
Reference:
_bmad-output/test-artifacts/test-reviews/test-guide-html-staleness-audit-2026-06-10.md
Test Cases: Payment Approval Workflow
Module: Payments - Payment Approval
Backend Endpoints:
GET /api/billing/admin/paymentsPOST /api/billing/admin/payments/:paymentId/approvePOST /api/billing/admin/payments/:paymentId/rejectPOST /api/billing/admin/payments/manual
Frontend Page: mmp/frontend/pwa-app/src/pages/admin/AdminPaymentsPage.tsx
Prerequisites
- User logged in with ADMIN or FINANCE_MANAGER role.
- Pending payments exist awaiting approval.
- Test data from
00_MASTER_TEST_DATA.mdis seeded.
Test Data
| Payment | Invoice | Member | Amount | Status |
|---|---|---|---|---|
| PAY-2024-0002 | INV-2024-0002 | Antonio Dela Cruz | PHP 15,000 | PENDING |
| PAY-2024-0003 | INV-2024-0003 | Antonio Dela Cruz | PHP 2,500 | REJECTED |
Test Cases
TC-PAY-025: View All Pending Payments
| Step | Action | Expected Result |
|---|---|---|
| 1 | Login as Ana Reyes (FINANCE_MANAGER). | Dashboard displayed. |
| 2 | Navigate to Admin > Payments. | Payment list displayed. |
| 3 | Filter by status: PENDING. | Only pending payments shown. |
| 4 | Verify PAY-2024-0002 visible. | Antonio Dela Cruz's pending payment listed. |
| 5 | Verify columns. | Payment ID, Member, Invoice, Amount, Method, Date, Status, Proof. |
TC-PAY-026: View Payment Details
| Step | Action | Expected Result |
|---|---|---|
| 1 | Click on PAY-2024-0002 in payment list. | Payment detail modal/page opens. |
| 2 | Verify payment info. | Amount: PHP 15,000, Method: GCash, Reference: 9171234567-001. |
| 3 | Verify linked invoice. | Invoice INV-2024-0002 displayed with link. |
| 4 | Verify member info. | Antonio Dela Cruz's details shown. |
| 5 | Verify payment proof. | Proof image displayed (if uploaded). |
TC-PAY-027: Approve Payment
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open pending payment PAY-2024-0002. | Payment details displayed. |
| 2 | Review payment proof. | Proof image visible and verifiable. |
| 3 | Click "Approve" button. | Confirmation dialog may appear. |
| 4 | Confirm approval. | API POST /api/billing/admin/payments/:id/approve called. |
| 5 | Verify success message. | "Payment approved" displayed. |
| 6 | Verify payment status. | Status changed to "APPROVED". |
| 7 | Verify invoice status. | Linked invoice status updated to "PAID". |
| 8 | Verify notification sent. | Member receives payment confirmation email. |
TC-PAY-028: Approve Payment with Notes
| Step | Action | Expected Result |
|---|---|---|
| 1 | Click "Approve" on pending payment. | Approval form opens. |
| 2 | Enter approval notes: "Verified with bank statement". | Notes entered. |
| 3 | Confirm approval. | Payment approved with notes recorded. |
| 4 | Verify audit trail. | Notes visible in payment history/audit. |
TC-PAY-029: Reject Payment
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open pending payment. | Payment details displayed. |
| 2 | Click "Reject" button. | Rejection form opens. |
| 3 | Enter rejection reason: "Reference number not found in bank records". | Reason entered (required). |
| 4 | Confirm rejection. | API POST /api/billing/admin/payments/:id/reject called. |
| 5 | Verify success message. | "Payment rejected" displayed. |
| 6 | Verify payment status. | Status changed to "REJECTED". |
| 7 | Verify invoice unchanged. | Invoice remains PENDING (not paid). |
| 8 | Verify member notified. | Member receives rejection email with reason. |
TC-PAY-030: Reject Payment Without Reason
| Step | Action | Expected Result |
|---|---|---|
| 1 | Click "Reject" on pending payment. | Rejection form opens. |
| 2 | Leave reason field empty. | - |
| 3 | Attempt to confirm. | Validation error: "Rejection reason is required". |
TC-PAY-031: Approve Already Approved Payment
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open payment PAY-2024-0001 (APPROVED). | Payment displayed. |
| 2 | Look for "Approve" button. | Button not visible or disabled. |
| 3 | Attempt via API. | Status 400 Bad Request - "Payment already approved". |
TC-PAY-032: Reject Already Rejected Payment
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open payment PAY-2024-0003 (REJECTED). | Payment displayed. |
| 2 | Look for "Reject" button. | Button not visible or disabled. |
TC-PAY-033: Re-approve Rejected Payment
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open rejected payment. | - |
| 2 | Check if "Approve" is available. | May be available for re-review. |
| 3 | If available, approve. | Payment status changed to APPROVED. |
| 4 | Verify audit trail. | Both rejection and approval recorded. |
TC-PAY-034: Manual Payment Entry by Admin
| Step | Action | Expected Result |
|---|---|---|
| 1 | Login as FINANCE_MANAGER. | - |
| 2 | Navigate to Admin > Payments. | Payment list displayed. |
| 3 | Click "Record Manual Payment". | Manual payment form opens. |
| 4 | Select invoice: INV-2024-0002. | Invoice selected. |
| 5 | Select member: Antonio Dela Cruz. | Member auto-selected from invoice. |
| 6 | Enter amount: PHP 15,000. | Amount entered. |
| 7 | Select method: Cash. | Cash selected. |
| 8 | Enter reference: CASH-20240127-001. | Reference entered. |
| 9 | Enter notes: "Cash received at office". | Notes entered. |
| 10 | Submit. | API POST /api/billing/admin/payments/manual called. |
| 11 | Verify payment created. | Payment created with status "APPROVED" (admin-entered). |
| 12 | Verify invoice updated. | Invoice marked as PAID. |
TC-PAY-035: Filter Payments by Status
| Step | Action | Expected Result |
|---|---|---|
| 1 | Navigate to Admin > Payments. | Full list displayed. |
| 2 | Filter: PENDING. | Only pending payments shown. |
| 3 | Filter: APPROVED. | Only approved payments shown. |
| 4 | Filter: REJECTED. | Only rejected payments shown. |
| 5 | Filter: All. | All payments shown. |
TC-PAY-036: Filter Payments by Date Range
| Step | Action | Expected Result |
|---|---|---|
| 1 | Set date range: This week. | Payments from this week displayed. |
| 2 | Set date range: This month. | Payments from this month displayed. |
| 3 | Set custom date range. | Payments within range displayed. |
TC-PAY-037: Filter Payments by Member
| Step | Action | Expected Result |
|---|---|---|
| 1 | Search/filter by member: Antonio Dela Cruz. | Only Roberto's payments shown. |
| 2 | Verify all his payments listed. | PAY-2024-0002, PAY-2024-0003 visible. |
TC-PAY-038: Bulk Approve Payments
| Step | Action | Expected Result |
|---|---|---|
| 1 | Select multiple pending payments (checkboxes). | Multiple rows selected. |
| 2 | Click "Bulk Approve". | Confirmation dialog. |
| 3 | Confirm. | All selected payments approved. |
| 4 | Verify status changes. | All selected now "APPROVED". |
| 5 | Verify invoices updated. | All linked invoices updated. |
TC-PAY-039: Permission Check - Member Cannot Approve
| Step | Action | Expected Result |
|---|---|---|
| 1 | Login as Maria Cruz (MEMBER). | Member dashboard. |
| 2 | Attempt to access Admin > Payments. | Access denied. |
| 3 | Attempt direct API call to approve. | Status 403 Forbidden. |
TC-PAY-040: View Payment Proof
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open payment with proof attached. | Payment details displayed. |
| 2 | Click on proof thumbnail. | Full-size image opens in modal/new tab. |
| 3 | Verify image quality. | Clear enough to verify payment details. |
| 4 | Download proof if option available. | File downloads. |
API Test Cases
TC-PAY-API-009: GET /api/billing/admin/payments
Request: GET /api/billing/admin/payments?status=PENDING
Expected Response: 200 OK
{
"payments": [
{
"id": "PAY-2024-0002",
"invoiceId": "INV-2024-0002",
"invoiceNumber": "INV-2024-0002",
"member": { "id": "...", "name": "Antonio Dela Cruz" },
"amount": 15000,
"method": "GCASH",
"referenceNumber": "9171234567-001",
"status": "PENDING",
"proofUrl": "https://...",
"createdAt": "timestamp"
}
],
"pagination": { "page": 1, "total": 5 }
}
TC-PAY-API-010: POST /api/billing/admin/payments/:id/approve
Request: POST /api/billing/admin/payments/PAY-2024-0002/approve
{
"notes": "Verified with GCash transaction history"
}
Expected Response: 200 OK
{
"payment": {
"id": "PAY-2024-0002",
"status": "APPROVED",
"approvedAt": "timestamp",
"approvedBy": "treasurer@demo.membervu.com"
},
"invoice": {
"id": "INV-2024-0002",
"status": "PAID"
}
}
TC-PAY-API-011: POST /api/billing/admin/payments/:id/reject
Request: POST /api/billing/admin/payments/PAY-2024-0002/reject
{
"reason": "Reference number not found in bank records"
}
Expected Response: 200 OK
{
"payment": {
"id": "PAY-2024-0002",
"status": "REJECTED",
"rejectedAt": "timestamp",
"rejectedBy": "treasurer@demo.membervu.com",
"rejectionReason": "Reference number not found in bank records"
}
}
TC-PAY-API-012: POST /api/billing/admin/payments/manual
Request:
{
"invoiceId": "INV-2024-0002",
"amount": 15000,
"paymentMethod": "CASH",
"referenceNumber": "CASH-20240127-001",
"paymentDate": "2024-01-27",
"notes": "Cash received at office"
}
Expected Response: 201 Created
{
"payment": {
"id": "PAY-2024-XXXX",
"status": "APPROVED",
"isManualEntry": true
}
}