⚠️ PENDING UPDATE — Payments section is under active development
These payment test cases are KNOWN STALE (staleness audit 2026-06-10) and are being rewritten against current code. Do not execute as written. Known drift: TraxionPay removed; channel codes changed (no BDO/BPI/CASH); Credits admin UI & most of its API not built; approve/reject set 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: Credits System

Module: Payments - Credits Management

Priority: P2

Phase: 5

Backend Endpoints:

Frontend Page: mmp/frontend/pwa-app/src/pages/admin/AdminCreditsPage.tsx

Member Page: mmp/frontend/pwa-app/src/pages/member/MemberCreditsPage.tsx

Prerequisites

Test Data

Credit IDMemberAmountReasonSource PaymentStatusExpires
CRD-2024-0001Antonio Dela CruzPHP 500Overpayment on INV-2024-0001PAY-2024-0001UNUSED2025-12-31
CRD-2024-0002Maria CruzPHP 1,000Promotional credit-UNUSED2024-06-30
CRD-2024-0003Antonio Dela CruzPHP 250Partial refundPAY-2024-0002USED-

Data Model Reference

Based on BILLING.md (lines 287-301):

model Credit {

id String @id @default(cuid())

tenantId String

memberId String

amountCents Int

reason String?

sourcePaymentId String?

usedAt DateTime?

usedOnInvoiceId String?

expiresAt DateTime?

}


Test Cases

TC-PAY-070: Credit Created from Overpayment

StepActionExpected Result
1Login as Ana Reyes (FINANCE_MANAGER).Dashboard displayed.
2Navigate to Admin > Payments.Payment list displayed.
3Approve payment PAY-2024-XXXX for PHP 15,500 on invoice of PHP 15,000.Payment approved.
4Verify overpayment handling.System creates credit of PHP 500 for excess amount.
5Navigate to Admin > Credits.Credit list displayed.
6Verify new credit exists.Credit CRD-XXXX with amount PHP 500, reason "Overpayment on INV-XXXX".
7Verify credit linked to source payment.sourcePaymentId references the approved payment.
8Verify member notification.Member receives email about credit added to account.

TC-PAY-071: Manually Create Credit (Admin)

StepActionExpected Result
1Login as ADMIN.Dashboard displayed.
2Navigate to Admin > Credits.Credit list displayed.
3Click "Create Credit" button.Credit creation form opens.
4Select member: Antonio Dela Cruz.Member selected.
5Enter amount: PHP 1,000.Amount entered.
6Enter reason: "Loyalty reward".Reason entered.
7Set expiration date: 2025-12-31.Expiration set.
8Submit form.API POST /api/billing/admin/credits called.
9Verify success message."Credit created successfully" displayed.
10Verify credit in list.New credit appears in credit list.

TC-PAY-072: List All Credits (Admin)

StepActionExpected Result
1Login as Ana Reyes (FINANCE_MANAGER).Dashboard displayed.
2Navigate to Admin > Credits.Credit list displayed.
3Verify list columns.Credit ID, Member, Amount, Reason, Source, Status, Expiry Date, Actions.
4Verify CRD-2024-0001 visible.Antonio Dela Cruz's credit of PHP 500 listed.
5Verify CRD-2024-0002 visible.Maria Cruz's promotional credit listed.
6Verify pagination works.Can navigate between pages if more than page size.

TC-PAY-073: Filter Credits by Status (Admin)

StepActionExpected Result
1Navigate to Admin > Credits.Full list displayed.
2Filter by status: UNUSED.Only unused credits shown.
3Filter by status: USED.Only used credits shown (CRD-2024-0003).
4Filter by status: EXPIRED.Only expired credits shown.
5Filter by status: All.All credits displayed.

TC-PAY-074: Filter Credits by Member (Admin)

StepActionExpected Result
1Navigate to Admin > Credits.Credit list displayed.
2Search/filter by member: Antonio Dela Cruz.Only Roberto's credits shown.
3Verify results.CRD-2024-0001 and CRD-2024-0003 visible.
4Clear filter.All credits displayed again.

TC-PAY-075: Apply Credit to Invoice

StepActionExpected Result
1Login as FINANCE_MANAGER.Dashboard displayed.
2Navigate to Admin > Invoices.Invoice list displayed.
3Open pending invoice INV-2024-XXXX for Antonio Dela Cruz (PHP 15,000).Invoice details displayed.
4Click "Apply Credit" button.Available credits modal opens.
5Verify Roberto's available credits listed.CRD-2024-0001 (PHP 500) shown.
6Select CRD-2024-0001 to apply.Credit selected.
7Confirm application.API POST /api/billing/credits/:id/apply called.
8Verify success message."Credit applied successfully" displayed.
9Verify invoice balance reduced.Invoice balance now PHP 14,500.
10Verify credit status.CRD-2024-0001 now marked as USED.
11Verify credit usedAt timestamp.Current timestamp recorded.
12Verify credit usedOnInvoiceId.Links to INV-2024-XXXX.

TC-PAY-076: Apply Credit During Payment Submission

StepActionExpected Result
1Login as Antonio Dela Cruz (MEMBER).Member dashboard displayed.
2Navigate to My Invoices.Invoice list displayed.
3Select pending invoice of PHP 15,000.Invoice details displayed.
4Click "Pay Now".Payment form opens.
5Verify credit option displayed."Available Credit: PHP 500" shown.
6Check "Apply available credit".Credit checkbox selected.
7Verify amount adjustment.Amount to pay shows PHP 14,500.
8Complete payment for PHP 14,500.Payment submitted.
9Verify credit applied.Credit marked as used.
10Verify invoice marked paid.Invoice status changes to PAID.

TC-PAY-077: Partial Credit Usage

StepActionExpected Result
1Login as FINANCE_MANAGER.Dashboard displayed.
2Member has credit of PHP 1,000.Credit CRD-2024-0002 for Maria Cruz.
3Apply credit to invoice of PHP 600.Credit application form opens.
4Enter amount to apply: PHP 600.Partial amount entered.
5Confirm application.Credit partially applied.
6Verify original credit updated.CRD-2024-0002 amount reduced to PHP 400 OR new credit created for remainder.
7Verify invoice fully paid.Invoice status PAID.
8Verify remaining credit available.PHP 400 credit still available for Maria Cruz.

TC-PAY-078: Credit Balance Display for Member

StepActionExpected Result
1Login as Antonio Dela Cruz (MEMBER).Member dashboard displayed.
2Check dashboard widgets."Available Credit: PHP 500" displayed.
3Navigate to My Credits page.Credit history displayed.
4Verify credit list columns.Amount, Reason, Date Created, Expiry Date, Status.
5Verify CRD-2024-0001 visible.PHP 500 credit with expiry date shown.
6Verify CRD-2024-0003 visible.PHP 250 shown as USED with usage date.
7Verify total available credit.Summary shows PHP 500 available.

TC-PAY-079: Credit Expiration Warning

StepActionExpected Result
1Login as Maria Cruz (MEMBER) with credit expiring soon.Dashboard displayed.
2Check dashboard notifications."Credit expiring soon" warning displayed.
3Navigate to My Credits.Credit list displayed.
4Verify expiring credit highlighted.CRD-2024-0002 shows warning indicator.
5Verify days until expiry shown."Expires in X days" displayed.

TC-PAY-080: Credit Expiration Handling

StepActionExpected Result
1Scheduled job runs for credit expiration.System checks credit expiry dates.
2Credit CRD-2024-0002 past expiry date.Credit identified as expired.
3Verify credit status changed.Status set to EXPIRED.
4Verify credit no longer usable.Cannot apply expired credit to invoices.
5Verify member notification sent.Member receives "Credit expired" notification.

TC-PAY-081: Attempt to Apply Expired Credit

StepActionExpected Result
1Login as FINANCE_MANAGER.Dashboard displayed.
2Navigate to member's invoice.Invoice displayed.
3Attempt to apply expired credit.Credit selection shown.
4Select expired credit CRD-2024-0002.-
5Attempt to apply.Error: "Credit has expired and cannot be applied".
6Verify invoice unchanged.Invoice balance unchanged.

TC-PAY-082: Attempt to Apply Already Used Credit

StepActionExpected Result
1Login as FINANCE_MANAGER.Dashboard displayed.
2Attempt to apply CRD-2024-0003 (already used).-
3Verify credit not in available list.Used credits not shown in selection.
4Attempt via direct API call.Status 400 Bad Request - "Credit already used".

TC-PAY-083: Credit Cannot Exceed Invoice Balance

StepActionExpected Result
1Member has credit of PHP 1,000.Credit available.
2Apply credit to invoice of PHP 500.Credit application form opens.
3Verify maximum applicable amount.System limits to PHP 500 (invoice balance).
4Apply PHP 500 from credit.Credit partially used.
5Verify invoice fully paid.Invoice status PAID.
6Verify remaining credit.PHP 500 credit remains available.

TC-PAY-084: Delete/Void Credit (Admin)

StepActionExpected Result
1Login as ADMIN.Dashboard displayed.
2Navigate to Admin > Credits.Credit list displayed.
3Find unused credit CRD-2024-0001.Credit displayed.
4Click "Delete" or "Void" action.Confirmation dialog appears.
5Enter reason: "Issued in error".Reason entered (required).
6Confirm deletion.API DELETE /api/billing/admin/credits/:id called.
7Verify success message."Credit voided successfully" displayed.
8Verify credit removed from available list.Credit no longer available for use.
9Verify audit trail.Deletion recorded with reason and admin who voided.

TC-PAY-085: Cannot Delete Used Credit

StepActionExpected Result
1Login as ADMIN.Dashboard displayed.
2Find used credit CRD-2024-0003.Credit displayed with USED status.
3Look for delete action.Delete button disabled or hidden.
4Attempt via direct API call.Status 400 Bad Request - "Cannot delete used credit".

TC-PAY-086: Member Cannot Create Credits

StepActionExpected Result
1Login as Maria Cruz (MEMBER).Member dashboard displayed.
2Attempt to access Admin > Credits.Access denied - no menu option visible.
3Attempt direct navigation to admin credits URL.Redirect to member dashboard or 403 error.
4Attempt API POST /api/billing/admin/credits.Status 403 Forbidden.

TC-PAY-087: Credit with No Expiration

StepActionExpected Result
1Login as ADMIN.Dashboard displayed.
2Create credit without expiration date.Leave expiration field empty.
3Submit form.Credit created successfully.
4Verify credit in list.Expiry shows "Never" or "-".
5Verify credit remains valid indefinitely.No expiration processing applies.

TC-PAY-088: Multiple Credits Applied to Single Invoice

StepActionExpected Result
1Member has two credits: PHP 300 and PHP 200.Both credits available.
2Open invoice of PHP 1,000.Invoice displayed.
3Apply first credit (PHP 300).Balance reduced to PHP 700.
4Apply second credit (PHP 200).Balance reduced to PHP 500.
5Both credits marked as used.Both credits show USED status.
6Invoice balance now PHP 500.Remaining balance displayed.
7Member pays remaining PHP 500.Invoice marked as PAID.

API Test Cases

TC-PAY-API-020: GET /api/billing/admin/credits

Request: GET /api/billing/admin/credits?status=UNUSED

Expected Response: 200 OK

{

"credits": [

{

"id": "CRD-2024-0001",

"memberId": "member-roberto",

"member": { "id": "member-roberto", "name": "Antonio Dela Cruz" },

"amountCents": 50000,

"amount": 500,

"reason": "Overpayment on INV-2024-0001",

"sourcePaymentId": "PAY-2024-0001",

"status": "UNUSED",

"usedAt": null,

"usedOnInvoiceId": null,

"expiresAt": "2025-12-31T23:59:59Z",

"createdAt": "2024-01-15T10:30:00Z"

}

],

"pagination": { "page": 1, "total": 5 }

}

TC-PAY-API-021: POST /api/billing/admin/credits

Request:

{

"memberId": "member-roberto",

"amountCents": 100000,

"reason": "Loyalty reward",

"expiresAt": "2025-12-31T23:59:59Z"

}

Expected Response: 201 Created

{

"credit": {

"id": "CRD-2024-XXXX",

"memberId": "member-roberto",

"amountCents": 100000,

"reason": "Loyalty reward",

"sourcePaymentId": null,

"status": "UNUSED",

"usedAt": null,

"usedOnInvoiceId": null,

"expiresAt": "2025-12-31T23:59:59Z",

"createdAt": "timestamp"

}

}

TC-PAY-API-022: GET /api/billing/credits/balance

Request: GET /api/billing/credits/balance (authenticated as member)

Expected Response: 200 OK

{

"totalAvailableCents": 50000,

"totalAvailable": 500,

"credits": [

{

"id": "CRD-2024-0001",

"amountCents": 50000,

"amount": 500,

"reason": "Overpayment on INV-2024-0001",

"expiresAt": "2025-12-31T23:59:59Z",

"expiresInDays": 340

}

]

}

TC-PAY-API-023: POST /api/billing/credits/:creditId/apply

Request: POST /api/billing/credits/CRD-2024-0001/apply

{

"invoiceId": "INV-2024-0005",

"amountCents": 50000

}

Expected Response: 200 OK

{

"credit": {

"id": "CRD-2024-0001",

"status": "USED",

"usedAt": "timestamp",

"usedOnInvoiceId": "INV-2024-0005"

},

"invoice": {

"id": "INV-2024-0005",

"previousBalanceCents": 1500000,

"newBalanceCents": 1450000,

"creditAppliedCents": 50000

}

}

TC-PAY-API-024: POST /api/billing/credits/:creditId/apply - Expired Credit

Request: POST /api/billing/credits/CRD-2024-0002/apply (expired credit)

{

"invoiceId": "INV-2024-0005",

"amountCents": 100000

}

Expected Response: 400 Bad Request

{

"error": "CREDIT_EXPIRED",

"message": "Credit has expired and cannot be applied"

}

TC-PAY-API-025: POST /api/billing/credits/:creditId/apply - Already Used

Request: POST /api/billing/credits/CRD-2024-0003/apply (used credit)

{

"invoiceId": "INV-2024-0005",

"amountCents": 25000

}

Expected Response: 400 Bad Request

{

"error": "CREDIT_ALREADY_USED",

"message": "Credit has already been applied to another invoice"

}

TC-PAY-API-026: DELETE /api/billing/admin/credits/:creditId

Request: DELETE /api/billing/admin/credits/CRD-2024-0001

{

"reason": "Issued in error"

}

Expected Response: 200 OK

{

"success": true,

"message": "Credit voided successfully",

"credit": {

"id": "CRD-2024-0001",

"status": "VOIDED",

"voidedAt": "timestamp",

"voidedBy": "admin@rcme.membervu.com",

"voidReason": "Issued in error"

}

}

TC-PAY-API-027: DELETE /api/billing/admin/credits/:creditId - Used Credit

Request: DELETE /api/billing/admin/credits/CRD-2024-0003 (used credit)

Expected Response: 400 Bad Request

{

"error": "CANNOT_DELETE_USED_CREDIT",

"message": "Cannot delete credit that has already been applied to an invoice"

}

TC-PAY-API-028: POST /api/billing/admin/credits - Unauthorized

Request: POST /api/billing/admin/credits (as MEMBER role)

{

"memberId": "member-self",

"amountCents": 100000,

"reason": "Self-issued credit"

}

Expected Response: 403 Forbidden

{

"error": "FORBIDDEN",

"message": "Insufficient permissions to create credits"

}


Edge Cases

TC-PAY-089: Credit Amount Validation

StepActionExpected Result
1Attempt to create credit with amount 0.Validation error: "Amount must be greater than 0".
2Attempt to create credit with negative amount.Validation error: "Amount must be greater than 0".
3Attempt to create credit with very large amount.System handles or shows max limit warning.

TC-PAY-090: Credit for Inactive Member

StepActionExpected Result
1Attempt to create credit for inactive/suspended member.Warning displayed: "Member is inactive".
2Confirm creation.Credit created (or blocked per business rules).
3Verify credit usability.Define expected behavior for inactive member credits.

TC-PAY-091: Concurrent Credit Application

StepActionExpected Result
1Open two browser tabs with same invoice.Same invoice displayed in both.
2Apply same credit from both tabs simultaneously.One succeeds, one fails with "Credit already used".
3Verify credit applied only once.Invoice balance reduced once, credit marked used once.

Notes