From 5abee8b510425a316ce90d640cb9dec888692f63 Mon Sep 17 00:00:00 2001 From: roost-io Date: Thu, 30 Apr 2026 16:13:12 +0530 Subject: [PATCH] Functional test generated by RoostGPT Using AI Model gpt-4.1 --- functional_tests/README.md | 17 + .../ZBIO-5213/.roost/roost_metadata.json | 19 + functional_tests/ZBIO-5213/ZBIO-5213.csv | 35 + functional_tests/ZBIO-5213/ZBIO-5213.docx | Bin 0 -> 33819 bytes functional_tests/ZBIO-5213/ZBIO-5213.feature | 483 +++++++++++++ functional_tests/ZBIO-5213/ZBIO-5213.json | 492 ++++++++++++++ functional_tests/ZBIO-5213/ZBIO-5213.xlsx | Bin 0 -> 28191 bytes functional_tests/ZBIO-5213/ZBIO-5213.yaml | 642 ++++++++++++++++++ 8 files changed, 1688 insertions(+) create mode 100644 functional_tests/ZBIO-5213/.roost/roost_metadata.json create mode 100644 functional_tests/ZBIO-5213/ZBIO-5213.csv create mode 100644 functional_tests/ZBIO-5213/ZBIO-5213.docx create mode 100644 functional_tests/ZBIO-5213/ZBIO-5213.feature create mode 100644 functional_tests/ZBIO-5213/ZBIO-5213.json create mode 100644 functional_tests/ZBIO-5213/ZBIO-5213.xlsx create mode 100644 functional_tests/ZBIO-5213/ZBIO-5213.yaml diff --git a/functional_tests/README.md b/functional_tests/README.md index 1c972b2..62cba23 100644 --- a/functional_tests/README.md +++ b/functional_tests/README.md @@ -65,3 +65,20 @@ --- +**Execution Date:** 4/30/2026, 4:13:11 PM + +**Test Unique Identifier:** "ZBIO-5213" + +**Input(s):** + 1. JIRA ID: ZBIO-5213 + +**Test Output Folder:** + 1. [ZBIO-5213.json](ZBIO-5213/ZBIO-5213.json) + 2. [ZBIO-5213.feature](ZBIO-5213/ZBIO-5213.feature) + 3. [ZBIO-5213.csv](ZBIO-5213/ZBIO-5213.csv) + 4. [ZBIO-5213.xlsx](ZBIO-5213/ZBIO-5213.xlsx) + 5. [ZBIO-5213.docx](ZBIO-5213/ZBIO-5213.docx) + 6. [ZBIO-5213.yaml](ZBIO-5213/ZBIO-5213.yaml) + +--- + diff --git a/functional_tests/ZBIO-5213/.roost/roost_metadata.json b/functional_tests/ZBIO-5213/.roost/roost_metadata.json new file mode 100644 index 0000000..9f58f4f --- /dev/null +++ b/functional_tests/ZBIO-5213/.roost/roost_metadata.json @@ -0,0 +1,19 @@ +{ + "project": { + "name": "ZBIO-5213", + "created_at": "2026-04-30T10:43:11.311Z", + "updated_at": "2026-04-30T10:43:11.311Z" + }, + "files": { + "input_files": [ + { + "fileName": "ZBIO-5213.txt", + "fileURI": "/var/tmp/Roost/RoostGPT/demo-functional-test_clone/1777545530/functional_tests/ZBIO-5213/ZBIO-5213.txt", + "fileSha": "0e017aaae1" + } + ] + }, + "api_files": { + "input_files": [] + } +} \ No newline at end of file diff --git a/functional_tests/ZBIO-5213/ZBIO-5213.csv b/functional_tests/ZBIO-5213/ZBIO-5213.csv new file mode 100644 index 0000000..5b1c943 --- /dev/null +++ b/functional_tests/ZBIO-5213/ZBIO-5213.csv @@ -0,0 +1,35 @@ +Send Automated Due Reminder Notification With Masked Card Digits +Validate No Full Card Number is Exposed in Due Reminder Notification Artifacts +Send Overdue Alert Notification After Missed Payment Date +Do Not Send Overdue Alert If Payment Was Made Before Due Date +Collection Notification Sent for Significantly Delinquent Accounts +Collection Notifications Display Only Last 4 Digits in All Channels +Payment Plan Proposal Triggered for Unable-to-Pay Cardholder +Payment Plan Proposal Notification Complies With Card Masking +Payment Plan Proposal Not Sent if Balance Is Paid in Full +Escalate to Collection Agency After Failed Notifications +Transmit Only Last 4 Digits to Collection Agency +Agency Handoff Blocked for Ineligible Accounts +Legal Action Triggered for Defaulted Accounts +Legal Documentation Must Include Only Last 4 Digits of Card Number +Masking Validation for All Lifecycle Communications +No Full Card Number in Internal Audit Logs +Flag and Reject Notification With Incorrect Masking +Block Outbound Communication Containing Full Card Number +Notification Contains Correct Fields and Message Structure +Reject Notification If Required Fields Missing +Notification Sent Only To Authorized Cardholder +Collection Agency Access Limited to Assigned Accounts Only +Log and Retry Failed Notification Transmission With PII Masking +Raise Incident for Undeliverable Collection Notifications +Prevent Escalation If Data Error Detected +Audit Log Integrity for Legal and Collection Events +Valid State Transitions From Due → Overdue → Collections +Failed Payment Plan Acceptance Reverts To Collections +Block Re-entry Into Payment Plan After Legal Action Initiation +Boundary Test - Collection Notification Triggered Exactly At Overdue Days Threshold +Boundary Test - Legal Escalation Triggered Only At Threshold Day +API Sends Only Approved Fields To Collection Agency +No Duplicate Agency Handoffs For Single Account +Outbound Notification Data Must Match Customer and Account +Full Lifecycle: Due Reminder → Overdue → Collections → Payment Plan → Agency → Legal \ No newline at end of file diff --git a/functional_tests/ZBIO-5213/ZBIO-5213.docx b/functional_tests/ZBIO-5213/ZBIO-5213.docx new file mode 100644 index 0000000000000000000000000000000000000000..024c76aab681c7aa32678ba3f64f1048a0df3b67 GIT binary patch literal 33819 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' exists with card ending '' and due date in days + And no previous due reminder sent for this cycle + And notifications are enabled for the account + When I trigger the batch job for due reminder notifications + Then the notification should be sent to the cardholder + And the notification content should include only the last 4 digits '' in masked format '**** **** **** ' + And the payment due date '' is present in the notification + And the full card number is not exposed in any notification, log, or audit entry + And the notification status should be 'sent' + + Examples: + | accountId | last4 | daysToDue | dueDate | + | 8722Acc | 8722 | 3 | 2024-06-07 | + | 4567Acc | 4567 | 5 | 2024-06-09 | + + @api @security + Scenario Outline: Validate No Full Card Number is Exposed in Due Reminder Notification Artifacts + Given cardholder account '' with card number '' and pending payment + And notifications are enabled for the account + When I trigger the batch job for due reminders + Then search all notification payloads, logs, message queues, and database for '' + And assert only masked last 4 digits '' appear in format '**** **** **** ' + And no full or partial card number (other than last 4) appears anywhere + + Examples: + | accountId | cardNumber | last4 | + | 5162Acc | 5162314112348722 | 8722 | + | 4535Acc | 4535123456789001 | 9001 | + + @api @functional + Scenario Outline: Send Overdue Alert Notification After Missed Payment Date + Given a cardholder account '' with card ending '' + And the payment due date has passed by days + And no payment received after due date + When I trigger the batch job for overdue alert notifications + Then the overdue alert notification is sent with overdue amount '' and masked card number '**** **** **** ' + And the full card number is not present anywhere in the message or logs + And notification status is 'sent' + And audit/log entries reflect correct event and message + + Examples: + | accountId | last4 | daysPastDue | overdueAmount | + | 6533Acc | 6533 | 1 | $85 | + | 7800Acc | 7800 | 2 | $142 | + + @api @negative + Scenario Outline: Do Not Send Overdue Alert If Payment Was Made Before Due Date + Given a test account '' with card ending '' and due date '' + And payment in full was posted one day before due date + When I run the overdue alert batch process + Then no overdue alert is sent or visible for the account in logs, notifications, or event tables + And the audit log shows payment posted and no alert event + + Examples: + | accountId | last4 | dueDate | + | 4901Acc | 4901 | 2024-06-08 | + | 2730Acc | 2730 | 2024-06-09 | + + @api @functional + Scenario Outline: Collection Notification Sent for Significantly Delinquent Accounts + Given the account '' is in delinquent status for days with card ending '' + And collection notifications are enabled + When I trigger the collection notification job + Then the collection notification is sent to the cardholder including amount owed '' and only masked card number '**** **** **** ' + And audit and notification logs reflect the event record + And no full or unmasked card number appears in any field + + Examples: + | accountId | last4 | daysDelinquent | amountOwed | + | 6019Acc | 6019 | 32 | $1800 | + | 5200Acc | 5200 | 45 | $3250 | + + @api @security + Scenario Outline: Collection Notifications Display Only Last 4 Digits in All Channels + Given an account '' is overdue and flagged for collection notices with card ending '' + When I launch the collection notification job + Then all communication channels and logs related to collection notification show only masked card number '**** **** **** ', never full PAN + + Examples: + | accountId | last4 | + | 1226Acc | 1226 | + | 3337Acc | 3337 | + + @api @functional + Scenario Outline: Payment Plan Proposal Triggered for Unable-to-Pay Cardholder + Given account '' is overdue, eligible for payment plan, and has card ending '' + When I initiate payment plan proposal via system action or API + Then the payment plan proposal notification includes repayment schedule, reduced fees, and only masked card number '**** **** **** ' + And log/audit entries confirm correct event and no unmasked card data + + Examples: + | accountId | last4 | + | 4105Acc | 4105 | + | 8991Acc | 8991 | + + @api @security + Scenario Outline: Payment Plan Proposal Notification Complies With Card Masking + Given payment plan proposal triggered for account '' with card ending '' + And notification system is enabled + When I retrieve payment plan proposal notification and logs + Then only masked card number '**** **** **** ' should appear in all message channels and logs + And no full or partial unmasked card number appears in any output + + Examples: + | accountId | last4 | + | 5777Acc | 5777 | + | 4105Acc | 4105 | + + @api @negative + Scenario Outline: Payment Plan Proposal Not Sent if Balance Is Paid in Full + Given overdue flag cleared by recent full payment for account '' with card ending '' + And payment plan proposal job is enabled + When I trigger payment plan proposal + Then no payment plan proposal notification is generated, logged, or shown for the account + And audit logs, notification endpoints, and UI lack payment plan proposal events + + Examples: + | accountId | last4 | + | 3278Acc | 3278 | + | 8944Acc | 8944 | + + @api @state-transition + Scenario Outline: Escalate to Collection Agency After Failed Notifications + Given overdue account '' in 'collection escalation' queue with card ending '' + And overdue for >60 days, all prior notifications sent with no payment or user response + And collection agency integration configured + When I trigger agency handoff process + Then account status transitions from 'delinquent' to 'in collection agency' + And agency receives only the last 4 digits '' in outbound payload or records + And no other card details or PII are transmitted + And audit/data export logs reflect transition event and data snapshot + + Examples: + | accountId | last4 | + | 8845Acc | 8845 | + | 7790Acc | 7790 | + + @api @security + Scenario Outline: Transmit Only Last 4 Digits to Collection Agency + Given overdue account '' with card ending '' eligible for agency escalation + When I trigger the collection agency workflow and capture outbound API payload + Then data sent to agency contains only masked card number '**** **** **** ' + And agency system records show only last 4 digits + And audit trail evidences transmission with masking enforcement + + Examples: + | accountId | last4 | + | 4242Acc | 4242 | + | 8788Acc | 8788 | + + @api @negative + Scenario Outline: Agency Handoff Blocked for Ineligible Accounts + Given overdue account '' with partial payment or incomplete notifications, card ending '' + When I attempt escalation to collection agency + Then handoff request is blocked due to ineligibility + And no data is transmitted to agency + And audit log shows handoff prevention with reason code + + Examples: + | accountId | last4 | + | 7900Acc | 7900 | + | 3099Acc | 3099 | + + @api @functional + Scenario Outline: Legal Action Triggered for Defaulted Accounts + Given account '' marked 'default' after full escalation path completed, card ending '' + When legal action initiation is triggered + Then legal documentation is generated per template with only last 4 digits '' masked in all fields + And audit log records legal escalation event + + Examples: + | accountId | last4 | + | 4123Acc | 4123 | + | 2244Acc | 2244 | + + @api @security + Scenario Outline: Legal Documentation Must Include Only Last 4 Digits of Card Number + Given legal escalation path is triggered for account '' with card ending '' + When I retrieve generated legal documents (PDF, e-doc, etc.) + Then every field, section, and attachment displays only masked card '**** **** **** ' + And no unmasked or partial PAN is present anywhere in the documentation + + Examples: + | accountId | last4 | + | 4242Acc | 4242 | + | 5432Acc | 5432 | + + @api @security + Scenario Outline: Masking Validation for All Lifecycle Communications + Given account '' moves through reminder, alert, collection, payment plan, agency, legal stages with card ending '' + When I trigger each lifecycle communication and inspect payloads/messages/logs + Then only masked card number (last 4 digits '') is included + And no full or partial PAN appears in any communication or audit log + + Examples: + | accountId | last4 | + | 9001Acc | 9001 | + | 4242Acc | 4242 | + + @api @security + Scenario Outline: No Full Card Number in Internal Audit Logs + Given audit logging enabled for all collection lifecycle events for account '' with card ending '' + When I perform reminder, overdue, collection, agency, legal actions + Then audit logs contain only masked card number '**** **** **** ' + And no full or partial PAN appears in any log entry + And attempts to inject unmasked PAN are sanitized or blocked + + Examples: + | accountId | last4 | + | 4242Acc | 4242 | + | 9001Acc | 9001 | + + @api @negative + Scenario Outline: Flag and Reject Notification With Incorrect Masking + Given notification engine supports content validation and cardholder account '' exists + And I tamper with notification template to include incorrect masking (e.g., partial mask or >4 digits unmasked) + When I trigger an outbound notification (overdue, collection, legal) + Then the system flags the notification for improper masking + And the message is rejected or quarantined + And error logs record explicit masking violation + And no improperly masked notification is delivered + + Examples: + | accountId | + | 8299Acc | + | 1123Acc | + + @api @security + Scenario Outline: Block Outbound Communication Containing Full Card Number + Given notification processing pipeline supports card number validation + And a message with full PAN ('') is submitted for delivery + When I trigger outbound communication processing + Then the system detects the unmasked PAN and blocks or quarantines the message + And security incident is logged with full details + And no full card number is ever sent to recipient or external system + + Examples: + | fullCardNumber | + | 1234 5678 9012 3456 | + | 4111 1111 1111 4242 | + + @api @functional + Scenario Outline: Notification Contains Correct Fields and Message Structure + Given account '' is eligible for notification with card ending '', due date '', and amount due '' + And notification templates are configured correctly + When system sends notification for stage '' + Then notification content includes cardholder name, last 4 digits '', due date '', and amount due '' + And notification structure is user-readable and contains no missing fields + + Examples: + | accountId | last4 | dueDate | amountDue | stage | + | 4242Acc | 4242 | 2024-06-07 | $250 | Due Reminder | + | 9001Acc | 9001 | 2024-06-10 | $310 | Overdue Alert | + | 4105Acc | 4105 | 2024-05-25 | $1550 | Payment Plan | + + @api @negative + Scenario Outline: Reject Notification If Required Fields Missing + Given notification generator supports faulty templates + And account '' is due for notification + And template is missing '' + When system attempts to send notification + Then notification is rejected and not delivered + And error and audit logs record explicit missing field message + + Examples: + | accountId | missingField | + | 5723Acc | last 4 digits | + | 4105Acc | amount due | + | 9001Acc | due date | + + @api @security + Scenario Outline: Notification Sent Only To Authorized Cardholder + Given cardholder account '' with primary email '' and phone '', card ending '' + And unauthorized account '' exists + When automated due reminder notification workflow is triggered + Then notification is sent only to '' or '' + And the masked card number '**** **** **** ' appears in the notification + And no notification is sent to any unauthorized user (e.g., '') + And logs/audit confirm strictly authorized delivery and data masking + + Examples: + | accountId | authorizedEmail | authorizedPhone | last4 | unauthEmail | + | 4242Acc | test+cardholder001@example.com | +14557890001 | 4242 | test+intruder021@example.com | + + @api @security + Scenario Outline: Collection Agency Access Limited to Assigned Accounts Only + Given agency user '' is logged in and assigned to accounts '' + And each assigned account has card ending '' + And at least one unassigned account '' with card ending '' exists + When agency requests list and details of assigned accounts + Then only assigned accounts are accessible; all others return access denied + And only masked card numbers '' are displayed or exported + And no full card numbers or unrelated PII appear anywhere in agency-accessible screens/exports + + Examples: + | agencyUser | assignedAccounts | assignedLast4 | unassignedAccount | unassignedLast4 | + | AlphaAgent | 100234 | 5678 | 100235 | 3210 | + + @api @functional + Scenario Outline: Log and Retry Failed Notification Transmission With PII Masking + Given delinquent account '' with card ending '' is set to notify + And notification transmission is configured to fail (e.g., simulate SMTP 500) + When notification workflow is triggered and transmission fails + Then system logs the failed event with only masked card number '' present + And initiates exactly one retry as per policy; retry attempt is logged and audited + And no full card number appears in any failed/success logs or error payloads + + Examples: + | accountId | last4 | + | 9876Acc | 9876 | + | 4444Acc | 4444 | + + @api @functional + Scenario Outline: Raise Incident for Undeliverable Collection Notifications + Given overdue account '' eligible for collection notification, card ending '' + And notification endpoints are invalid to simulate delivery failure + And incident management system is enabled + When all allowed notification retries fail + Then notification status is marked 'undeliverable' + And an incident/ticket is raised containing only masked card number '' + And no further collection/legal process is allowed until resolution + + Examples: + | accountId | last4 | + | 9201Acc | 9201 | + | 6543Acc | 6543 | + + @api @negative + Scenario Outline: Prevent Escalation If Data Error Detected + Given delinquent account '' with card number '' and blank email + And escalation workflow is enabled + When escalation to collection notification or legal action is attempted + Then system blocks escalation with clear data error status/message + And no notification is sent until all mandatory data fields are corrected + + Examples: + | accountId | invalidCardNumber | + | 401234Acc | 123X | + | 7835Acc | 872 | + + @api @audit + Scenario Outline: Audit Log Integrity for Legal and Collection Events + Given account '' at legal action initiation or collection escalation stage with card ending '' + And immutable audit subsystem is enabled + When legal or collection event is triggered + Then audit log entry is written with masked card '**** **** **** ', event timestamp, and user ID + And attempts to alter or delete audit log fail or generate alert + And no log entry exposes full card number + + Examples: + | accountId | last4 | + | 4123Acc | 4123 | + | 772910Acc | 4123 | + + # API/State Transition & Boundary Condition Scenarios + @api @state-transition + Scenario Outline: Valid State Transitions From Due → Overdue → Collections + Given account '' with due date '' and no payment made for days + And collections trigger threshold is days overdue + When due reminder is sent, payment is missed, and overdue alert is triggered + Then account automatically transitions from Due to Overdue and, at threshold, to Collections + And all state transitions and notifications contain only masked card number '**** **** **** ' + And manual attempts to skip states are rejected + + Examples: + | accountId | dueDate | daysOverdue | collectionsThreshold | last4 | + | 143160Acc | 2024-06-01 | 8 | 7 | 1600 | + + @api @state-transition + Scenario Outline: Failed Payment Plan Acceptance Reverts To Collections + Given account '' in Collections with payment plan proposal generated, response window is days + When cardholder fails to respond or explicitly rejects within window + Then account remains or reverts to Collections + And collection notification is sent in masked form + And audit log reflects proposal status and state transitions + + Examples: + | accountId | windowDays | + | 604499Acc | 5 | + + @api @negative + Scenario Outline: Block Re-entry Into Payment Plan After Legal Action Initiation + Given account '' is already in Legal Action status with card ending '' + When user or system attempts to initiate or accept a payment plan offer (via API, UI, or manual entry) + Then request is denied with 'INELIGIBLE_STATE' status + And no payment plan record is created for account + And audit logs reflect blocked attempt with masked card info only + + Examples: + | accountId | last4 | + | 980123Acc | 5432 | + | 310088Acc | 9001 | + + @api @boundary + Scenario Outline: Boundary Test - Collection Notification Triggered Exactly At Overdue Days Threshold + Given account '' is overdue by days and collection threshold is days + When overdue check batch job is triggered + Then at (threshold-1) days, no collection notification is sent + And at threshold days, collection notification is sent with masked card number '**** **** **** ' and correct amount owed + And full card number is absent in all notifications and logs + + Examples: + | accountId | overdueDays | threshold | last4 | amountOwed | + | testuserA | 29 | 30 | 4242 | $500 | + | testuserA | 30 | 30 | 4242 | $510 | + + @api @boundary + Scenario Outline: Boundary Test - Legal Escalation Triggered Only At Threshold Day + Given account '' overdue by days, legal escalation threshold is days + When I trigger legal escalation batch process + Then no legal action is triggered at (threshold-1) days + And legal action is triggered at threshold + And legal notification contains only masked card number '**** **** **** ' + And legal event is audit-logged + + Examples: + | accountId | overdueDays | legalThreshold | last4 | + | testuserB | 89 | 90 | 2244 | + | testuserB | 90 | 90 | 2244 | + + @api @security + Scenario Outline: API Sends Only Approved Fields To Collection Agency + Given account '' overdue and met agency escalation criteria, card ending '' + When collection agency handoff is triggered via API + Then API payload contains only 'accountId', 'customerName', and 'last4' (masked card number) + And no other sensitive data is present in the payload + And audit logs reference only masked card data + And attempts to inject unmasked card number are blocked/masked + + Examples: + | accountId | last4 | + | testuserC | 8788 | + + @api @negative + Scenario Outline: No Duplicate Agency Handoffs For Single Account + Given account '' is overdue and eligible for agency escalation + When escalation procedure is triggered multiple times in rapid succession + Then only a single agency handoff event and notification is created + And subsequent triggers are suppressed or ignored as per idempotency logic + And audit logs contain only one escalation event per account + + Examples: + | accountId | + | testuserD | + + @api @functional + Scenario Outline: Outbound Notification Data Must Match Customer and Account + Given accounts '' and '' exist with unique cards '' and '' + And both are at distinct collection lifecycle stages + When system sends notifications for each account + Then each notification includes the correct due date, amount owed, and only the last 4 digits for respective card + And any attempt to send cross-customer data is blocked and logged + + Examples: + | accountIdE | last4E | accountIdF | last4F | stageE | stageF | + | testuserE | 1122 | testuserF | 2211 | Overdue Alert | Payment Plan | + + # End-to-End Lifecycle Scenario + @api @e2e + Scenario: Full Lifecycle: Due Reminder → Overdue → Collections → Payment Plan → Agency → Legal + Given customer account 'testuserG' with unique card number '**** **** **** 9001' is created + And notification, overdue batch, collections, agency, and legal modules are enabled + When system triggers due reminder notification prior to payment due date + And payment due date passes with no payment + And overdue alert notification is generated + And after 30 days, collections notification is triggered + And payment plan proposal is generated after collection stage + And continued non-response leads to collection agency handoff + And subsequent default triggers legal action and notification + Then at each step, notification is generated with correct, masked card data (last 4 digits only) + And system audit logs present all transition and escalation events with compliant data masking + diff --git a/functional_tests/ZBIO-5213/ZBIO-5213.json b/functional_tests/ZBIO-5213/ZBIO-5213.json new file mode 100644 index 0000000..99497c3 --- /dev/null +++ b/functional_tests/ZBIO-5213/ZBIO-5213.json @@ -0,0 +1,492 @@ +[ + { + "type": "functional", + "title": "Send Automated Due Reminder with Last 4 Digits", + "description": "Verifies that an automated credit card payment due reminder is sent to the cardholder before the due date and that the notification includes only the last 4 digits of the credit card number for identification, thus preventing exposure of full card data. Automation: HIGH — applicable for both backend notification services and outbound email/SMS verification.", + "testId": "TC-REM-01", + "testDescription": "A cardholder with an active credit card and an upcoming payment due should receive a due reminder notification that helps them avoid late payment fees. This notification must reference only the last four digits of their card number to ensure identification and privacy.", + "prerequisites": "Cardholder account with active credit card ending in 8722, upcoming payment due date set to 3 days from now, no previous due reminder sent for this cycle, notifications enabled for account.", + "stepsToPerform": "1. Login as test system admin.\n2. Trigger batch job that generates daily due reminders.\n3. Confirm job executes for target cardholder (ending in 8722).\n4. Retrieve generated notification payload (email/SMS/push) for this cardholder.\n5. Inspect message content for presence of payment due date.\n6. Inspect message content for presence of card identifier.\n7. Confirm card number is masked except last four digits (e.g. \"**** **** **** 8722\").\n8. Verify message does NOT contain full or partial (other than last four) card number.\n9. Check notification status as 'sent' in system logs and audit table.\n10. Optionally open mailbox or test SMS endpoint to view actual notification.", + "expectedResult": "Due reminder notification is sent to the cardholder including only the last 4 digits (e.g. 8722) of the credit card number. No unmasked or full card number is present anywhere in the message, logs, or audit entries. Message content includes correct due date, cardholder, and due amount fields.", + "sourceCitation": { + "location": "Lines 6-7, Description", + "excerpt": "Credit Card Due Reminder: An automated notification is sent to the cardholder...should include the last 4 digits of the credit card number" + } + }, + { + "type": "security", + "title": "No Full Card Number Exposed in Due Reminder Notification", + "description": "Ensures that no part of the due reminder notification, including payload, transmission, logs, or user interface, contains the full or partially unmasked credit card number, per data privacy requirements. Automation: HIGH — covers both notification payload and backend/application logs.", + "testId": "TC-REM-02", + "testDescription": "A cardholder receives a due reminder notification. For security and compliance, the message must never include the full credit card number or unmasked segments beyond the last 4 digits. Verification covers outbound message, database, logs, and queues.", + "prerequisites": "Cardholder account enrolled for notifications, credit card number in system (e.g. 5162 3141 1234 8722), pending payment due, test environment log/queue export access.", + "stepsToPerform": "1. Trigger automated due reminder batch job for eligible accounts.\n2. Intercept the generated notification payload (email, SMS, app push, or backend API).\n3. Search message content for occurrence of the full or partial unmasked card number (other than last 4 digits).\n4. Inspect backend message log for message payload.\n5. Review audit log entry for this notification event.\n6. Scan outbound message queue or delivery log.\n7. Probe database 'sent_notifications' (or equivalent) table for message body fields.\n8. Validate UI portal (if applicable) for masked representation.\n9. Attempt 'grep' or pattern search in all notification artifacts for card numbers beyond last 4 digits.\n10. Raise alert in test report if any unmasked portion or full number found.", + "expectedResult": "No instance of the full credit card number or more than the last 4 digits (e.g., only '8722') is present in any notification payload, logs, queues, or database entries. All fields displaying a card number use format '**** **** **** 8722'. Exposure is zero except for the last 4 digits.", + "sourceCitation": { + "location": "Lines 19-20, Description - Note", + "excerpt": "only the last 4 digits of the credit card number should be included... The full credit card number should never be shared or displayed in plain text." + } + }, + { + "type": "functional", + "title": "Send Overdue Alert After Missed Payment Date", + "description": "Validates that the system sends an overdue balance alert after the payment due date is missed, including the last 4 digits of the credit card for correct identification. This helps ensure timely communication and accurate account information. Automation: HIGH — purely system driven with testable outcomes.", + "testId": "TC-OVERDUE-01", + "testDescription": "When a cardholder fails to make payment by the due date, the system must send an overdue alert containing the overdue balance, warning about potential late fees, and showing only the last four digits of the credit card.", + "prerequisites": "Credit card account (number ending in 6533) past due date by 1 day, no payment received after due date, overdue amount > 0, overdue alerting enabled.", + "stepsToPerform": "1. Advance test system clock to one day past payment due date.\n2. Ensure no payment registered for this statement cycle on test card.\n3. Trigger batch process for overdue alert notifications.\n4. Fetch notification payload for cardholder (ending in 6533).\n5. Inspect message body for overdue flag and overdue amount field.\n6. Confirm inclusion of last 4 digits only for card number in message.\n7. Verify absence of full or partial (other than last 4) card number in any part of notification.\n8. Review audit/log entries for alert dispatch event.\n9. Confirm delivery status of notification is 'sent'.\n10. Optionally, check user portal alert section for reflected alert.", + "expectedResult": "Overdue alert notification is sent with overdue balance and only last four digits (e.g. 6533) indicated. Message and system contain no unmasked or full card number beyond last 4 digits. Audit and delivery logs reflect correct event and message.", + "sourceCitation": { + "location": "Lines 11-12, Description", + "excerpt": "Overdue Balance Alert: If a cardholder misses their payment due date, an alert is sent... This alert should include the last 4 digits of the credit card number." + } + }, + { + "type": "negative", + "title": "Alert Not Sent When Payment Received Before Due Date", + "description": "Checks that the system does not send an overdue alert to a cardholder who pays their balance before the due date, ensuring notifications reflect the accurate account state. Automation: HIGH — outcome is deterministically testable via absence of alert and logs.", + "testId": "TC-OVERDUE-02", + "testDescription": "If the cardholder makes a payment in full before or on the due date, the system must not send an overdue balance alert under any circumstance.", + "prerequisites": "Test credit card account (ending in 4901), payment due date set, payment in full posted one day before due date, overdue process scheduled to run.", + "stepsToPerform": "1. Confirm the scheduled payment due date for the cardholder.\n2. Make a full payment on the account one day before the due date using test payment service.\n3. Run or trigger the overdue alert batch process.\n4. Query notification log for account ending in 4901.\n5. Inspect outbound messages for presence of any overdue alert.\n6. Check database 'notifications' or event tables for overdue or late payment alerts.\n7. Navigate to user portal and verify that no overdue alert is shown.\n8. Confirm that audit log shows payment posted and no alert-triggered entry.\n9. Review error or event log for any unexpected alert generation to test account.", + "expectedResult": "No overdue balance alert is sent, logged, or visible for the test account. Notification tables, user UI, logs, and audit trails lack any reference to unnecessary overdue alerts when the full payment is made before due date.", + "sourceCitation": { + "location": "Lines 11-12, Description", + "excerpt": "If a cardholder misses their payment due date, an alert is sent" + } + }, + { + "type": "functional", + "title": "Collection Notification Sent for Significantly Delinquent Accounts", + "description": "Verifies the system escalates by sending a formal collection notification when the account is sufficiently delinquent, including details about the amount owed. Ensures proper escalation per lifecycle rules. Automation: HIGH — can be driven by state manipulation and queued events.", + "testId": "TC-COLL-01", + "testDescription": "For a cardholder account with a payment overdue past the defined threshold (e.g., 30+ days overdue), the system must send a collection notification indicating total due and any penalties, with proper masking of card number.", + "prerequisites": "Account in delinquent status (overdue >30 days), delinquent status flag set, card ending in 6019, outstanding balance not cleared, collection notifications enabled.", + "stepsToPerform": "1. Set test account overdue date to 32 days in the past.\n2. Confirm no payments recorded since due date.\n3. Trigger collection notification job/process.\n4. Retrieve generated notification for cardholder (ending in 6019).\n5. Check notification details for amount owed and additional charges/penalties.\n6. Confirm message includes only last 4 digits of card number.\n7. Inspect audit log and notification dispatch table for event record.\n8. Review logs and DB for absence of unmasked card number.\n9. Verify 'collection notification sent' status updated on account.", + "expectedResult": "Formal collection notification is sent to the cardholder with amount owed, additional charges detailed, and only last 4 digits (6019) of the card included. No full or partially unmasked card number present in message, audit log, or DB.", + "sourceCitation": { + "location": "Lines 13-14, Description", + "excerpt": "Collection Notification: When an account becomes significantly delinquent... by sending formal collection notifications...detailing the amount owed and any additional charges." + } + }, + { + "type": "security", + "title": "Collection Notification Includes Last 4 Digits Only", + "description": "Confirms that collection notifications display only the last four digits of the card in all communication channels and logs, preventing PII and PCI data leakage. Automation: HIGH — message and log inspection is deterministic.", + "testId": "TC-COLL-02", + "testDescription": "A delinquent cardholder receives a formal collection notification. For security, the message and system should display only masked card numbers with visible last four digits, and never the full card number. Test validates all user-facing and system-stored content.", + "prerequisites": "Delinquent account (ending in 1226), overdue status set, notification batch job ready, access to logs and collected message artifacts.", + "stepsToPerform": "1. Simulate account overdue status beyond collection threshold.\n2. Launch system process for sending collection notifications.\n3. Extract delivered notification content.\n4. Examine notification body for card identifier formatting.\n5. Search for full/unmasked card number patterns.\n6. Check backend system logs for dispatched notification and audit entry.\n7. Inspect 'notification_history' DB table for masking correctness.\n8. Scan user portal (if used) for message rendering.\n9. Confirm all occurrences of card number are masked except last 4 digits (e.g. '**** **** **** 1226').", + "expectedResult": "All communication channels, logs, and system records related to collection notification show the card number masked except for the last four digits. No other portions of the card number are visible or retrievable in any output.", + "sourceCitation": { + "location": "Lines 13-14, Description", + "excerpt": "These notifications should include the last 4 digits of the credit card number." + } + }, + { + "type": "functional", + "title": "Trigger Payment Plan Proposal When Cardholder Unable to Pay Full Balance", + "description": "Verifies that when a cardholder cannot pay their full overdue balance, the system generates and sends a payment plan proposal, including only the last 4 digits of the card, outlining a structured repayment schedule. Automation: HIGH — can be achieved via backend simulation and notification verification.", + "testId": "TC-PLAN-01", + "testDescription": "A cardholder's overdue account is eligible for a payment plan due to non-payment. The system initiates a payment plan proposal, explaining reduced interest/fees and including masked card information.", + "prerequisites": "Overdue balance exists and remains unpaid, cardholder (ending in 4105) contacted with prior overdue and collection notices, payment plan proposal logic enabled, account not in payment plan yet.", + "stepsToPerform": "1. Create test account with overdue balance (e.g. $1500, 45 days overdue).\n2. Confirm no full repayment received during overdue cycle.\n3. Review escalation tracking status (prior overdue and collection notifications sent).\n4. Attempt to initiate payment plan proposal via system action (API or batch job).\n5. Retrieve generated payment plan proposal notification.\n6. Inspect proposal for schedule, interest, and reduced fees details.\n7. Confirm only last 4 digits of card number (4105) included.\n8. Validate absence of unprotected card number in message/logs.\n9. Review audit entry for payment plan proposal generation.", + "expectedResult": "Payment plan proposal notification sent with repayment schedule, reduced interest/fees, and only last four digits (4105) included. No unmasked/full card number in message, logs, or database.", + "sourceCitation": { + "location": "Lines 15-16, Description", + "excerpt": "Payment Plan Proposal: In cases where a cardholder is unable to pay the full overdue balance...the card issuer may offer a payment plan proposal... The proposal should include the last 4 digits of the credit card number." + } + }, + { + "type": "security", + "title": "Payment Plan Proposal Notification Complies with Card Number Masking", + "description": "Checks that payment plan proposals include masked credit card details with only the last four digits, thereby meeting PCI and internal masking rules. Automation: HIGH — complete via notification sniper and log scan.", + "testId": "TC-PLAN-02", + "testDescription": "When a payment plan proposal is sent to an eligible cardholder, the message must include only the masked credit card number with the last four digits visible and no other identifying number sequence.", + "prerequisites": "Cardholder account (ending in 5777), payment plan proposal triggered, notification system enabled, test access to notification archives and logs.", + "stepsToPerform": "1. Create or select account with overdue and payment plan eligibility.\n2. Start workflow to generate payment plan proposal.\n3. Retrieve outbound payment plan message from system.\n4. Inspect message content for presence and format of card number.\n5. Confirm that card number is masked except for last 4 digits (e.g., '**** **** **** 5777').\n6. Search message and system logs for full/unmasked card number.\n7. Validate notification must not show more than last 4 digits in any field.\n8. Probe notification database and/or API response for correct masking.\n9. Issue test report/pass-fail status if any violation present.", + "expectedResult": "Payment plan proposal notification (all channels/screens/logs) contains only masked credit card number, with last four digits being the only visible card identifier. No leakage or partial/full card exposure exists in any output.", + "sourceCitation": { + "location": "Lines 15-16, Description", + "excerpt": "The proposal should include the last 4 digits of the credit card number." + } + }, + { + "type": "negative", + "title": "No Proposal Sent if Balance Paid in Full", + "description": "Ensures that payment plan proposals are not generated or sent if the cardholder's overdue balance has already been paid in full, preventing unnecessary or confusing communication. Automation: HIGH — pass/fail based on absence of proposal event/log.", + "testId": "TC-PLAN-03", + "testDescription": "If the cardholder pays their overdue balance in full, the system must not send a payment plan proposal, maintaining accurate and relevant notifications.", + "prerequisites": "Cardholder account (ending in 3278), overdue flag cleared by recent full payment, payment plan proposal job enabled, historical eligibility for payment plan present prior to payment.", + "stepsToPerform": "1. Advance account to overdue status.\n2. Process a full payment on the account before payment plan proposal trigger.\n3. Run or trigger payment plan proposal automation.\n4. Search for payment plan proposal notifications sent to account (3278).\n5. Check notification dispatch and audit logs for proposal creation events.\n6. Inspect 'payment_plan_proposals' DB table for new entries.\n7. Verify user-facing portal does not show any new payment plan proposals.\n8. Review error/event logs for improper trigger or edge-case exceptions.", + "expectedResult": "No payment plan proposal notification is generated, logged, or shown for the account once the balance is paid in full. All system logs and user notification endpoints lack payment plan proposal events.", + "sourceCitation": { + "location": "Lines 15-16, Description", + "excerpt": "In cases where a cardholder is unable to pay the full overdue balance at once...payment plan proposal..." + } + }, + { + "type": "state-transition", + "title": "Escalate to Collection Agency after Failed Notifications", + "description": "Verifies that, when previous reminder and collection notifications do not yield payment activity or response from the cardholder, the system transitions the account to 'collection agency' status and shares only the last 4 digits of card number with the agency. Ensures escalation path proceeds per lifecycle rules and data masking is enforced. Automation: HIGH — all transitions, events, and artifacts are traceable.", + "testId": "TC-AGCY-01", + "testDescription": "If a cardholder fails to act on overdue and collection notifications, the system escalates by handing over the account to a collection agency. Only the last four digits of the credit card number are shared to respect privacy requirements.", + "prerequisites": "Test account (ending in 8845) in 'collection escalation' queue, overdue for >60 days, all prior notifications sent with no payment or user response, collection agency integration configured.", + "stepsToPerform": "1. Create or set account overdue by >60 days.\n2. Confirm overdue and collection notifications sent with no logged payment or response.\n3. Trigger end-of-cycle or scheduled agency hand-off process.\n4. Check account status transition from 'delinquent' to 'in collection agency'.\n5. Intercept data package sent to collection agency.\n6. Inspect transferred data for presence of only last 4 digits of card (8845) — no other card details.\n7. Search agency-outbound message or log artifacts for unmasked card data.\n8. Review audit/data export logs for transition event and transferred data snapshot.\n9. Ensure no other PII or sensitive payment data outside scope is included.", + "expectedResult": "Account is escalated to collection agency after failed notification attempts. Agency receives only the last 4 digits (8845) of the credit card number, with no full or partial unmasked cards. All state-transition events and data exports are correctly logged.", + "sourceCitation": { + "location": "Lines 17-18, Description", + "excerpt": "If the cardholder fails to respond to previous notifications and reminders, the card issuer may involve a collection agency to recover the overdue balance…" + } + }, + { + "type": "security", + "title": "Transmitting Only Last 4 Digits to Collection Agency", + "description": "This test verifies that only the last 4 digits of the credit card number are transmitted to the collection agency when an overdue account is escalated. This is crucial to enforce PCI DSS compliance and minimize the risk of sensitive data leakage to third parties. Automation: HIGH—can be verified at API and payload inspection layers.", + "testId": "TC-AGCY-02", + "testDescription": "When an account is escalated to a collection agency after prior notifications have failed, the system must send only the last 4 digits of the credit card number for identification. At no point should the full card number or any additional digits appear in the data payload sent externally.", + "prerequisites": "1. Test customer account with overdue balance in system. 2. Prior reminders and collection notifications marked as 'no response'. 3. Collection agency integration enabled and addressable. 4. Credit card on file with masked PAN '**** **** **** 4242'.", + "stepsToPerform": "1. Mark account as overdue and ensure required days have passed for escalation. 2. Verify reminders and collection notifications have been sent and not acknowledged. 3. Trigger collection agency involvement workflow for overdue account. 4. Capture outbound API payload or message sent to agency. 5. Inspect transmitted data for cardholder identification fields. 6. Confirm only the last 4 digits ('4242') are present, remaining digits masked or omitted. 7. Attempt to search payload or message log for unmasked PAN—must return nothing. 8. Validate agency system records show '**** **** **** 4242' only. 9. Review system audit trail for evidence of transmission with masking enforced.", + "expectedResult": "1. Only last 4 digits of the card ('4242') are transmitted in all outbound fields; all other digits redacted. 2. Full PAN never appears in payload or logs. 3. Agency system cannot retrieve unmasked card number. 4. Audit log records correct masking enforcement.", + "sourceCitation": { + "location": "Lines 17-18, Description", + "excerpt": "The collection agency should be provided with the last 4 digits of the credit card number for identification purposes." + } + }, + { + "type": "negative", + "title": "Agency Handoff Blocked for Ineligible Accounts", + "description": "This test ensures that the system does not escalate accounts to a collection agency if they are ineligible—e.g., if payment is partially made or reminders have not yet been fully exhausted. This prevents wrongful data sharing and regulatory breaches. Automation: MEDIUM—eligibility paths should be covered via APIs.", + "testId": "TC-AGCY-03", + "testDescription": "When attempting to escalate an account to a collection agency, the system must first verify escalation eligibility (i.e., all notifications and reminders were attempted and payment has not resumed). Ineligible accounts must not be handed off or have data shared with the agency.", + "prerequisites": "1. Test account with overdue balance, but record of partial payment made. 2. Not all collection notifications/reminders sent. 3. Collection agency interface enabled but currently untriggered for this account.", + "stepsToPerform": "1. Identify test account in overdue but partially repaid status. 2. Trigger system workflow to attempt agency escalation. 3. Monitor internal trigger or status update request to agency API. 4. Capture agency handoff attempt and response. 5. Verify system eligibility logic is invoked, referencing notification history and payment status. 6. Observe system decision outcome (should be block/deny). 7. Search outbound logs/messages to agency—should be absent for this account. 8. Attempt to query agency for receipt of this account—should be negative. 9. Review audit trail for explicit 'handoff blocked' event and reason.", + "expectedResult": "1. Agency handoff request is blocked due to ineligibility. 2. No data transmitted to collection agency. 3. Audit log shows handoff prevention with reason code.", + "sourceCitation": { + "location": "Lines 17-18, Description", + "excerpt": "If the cardholder fails to respond to previous notifications and reminders, the card issuer may involve a collection agency..." + } + }, + { + "type": "functional", + "title": "Trigger Legal Action for Defaulted Accounts", + "description": "This test validates that in cases of persistent default, the system can trigger legal action against a cardholder, creating required legal documentation as prescribed. This ensures regulatory and process completeness. Automation: HIGH—core workflow and document generation are API-testable.", + "testId": "TC-LGL-01", + "testDescription": "When a cardholder has defaulted with no response after all collection measures, the legal action initiation process is triggered, automatically generating legal documents for further action.", + "prerequisites": "1. Test account marked 'default' after full escalation path completed. 2. All reminders, alerts, collection notices sent without user response. 3. Legal templates preloaded with placeholders for last 4 digits.", + "stepsToPerform": "1. Set test account to 'default' state in collections system. 2. Confirm all prior communication steps are complete and documented. 3. Trigger legal action initiation for the target account. 4. Capture system-generated legal documentation. 5. Validate fields prepared for cardholder identification; should contain only masked card and last 4 digits. 6. Check legal action status in account workflow log. 7. Review system for any unsent prior notification or missed workflow step. 8. Verify event logs for legal escalation with correct action sequence. 9. Attempt to retrieve legal doc via staff portal, ensuring access control.", + "expectedResult": "1. Legal action is initiated and recorded in account status. 2. Legal documentation is generated per template. 3. Only last 4 digits of card are used for identification in all documents. 4. Audit log shows legal escalation event.", + "sourceCitation": { + "location": "Lines 18-19, Description", + "excerpt": "Legal Action Initiation: In extreme cases of non-payment or default, the card issuer may have to take legal action against the cardholder." + } + }, + { + "type": "security", + "title": "Legal Documentation Includes Only Last 4 Digits", + "description": "This test confirms that any legal documentation generated during escalation includes only the last 4 digits of the card number, never full or partially-unmasked PAN data. This enforces compliance with PCI DSS and privacy laws. Automation: HIGH—text extraction and string inspection can be automated on doc generation.", + "testId": "TC-LGL-02", + "testDescription": "All outbound legal documents generated for collection purposes must redact the card number, displaying only the last 4 digits ('4242'). No additional digits or unmasked data may appear anywhere in the document (header, body, footer, attachments).", + "prerequisites": "1. Legal escalation path triggered on a test defaulted account. 2. Legal document templates active with card identification field. 3. Case management staff enabled to retrieve generated documents.", + "stepsToPerform": "1. Initiate legal action for a defaulted account ('**** **** **** 4242'). 2. Let system generate legal documentation. 3. Retrieve raw generated document (PDF, letter, e-document). 4. Inspect every field/section for card number display. 5. Search the entire doc for any digit sequence longer than 4 matching the PAN—must not be present. 6. Validate the last 4 digits '4242' are present at required location. 7. Check attachments and digital signature metadata for possible leaks. 8. Attempt doc generation with malformed or partial PAN—assert only 'last 4' logic is enforced. 9. Review for evidence of tampering, unintended storage, or full PAN retention.", + "expectedResult": "1. Only the last 4 digits are visible in every field of legal document. 2. No unmasked or partial PAN present. 3. Automated scan of doc yields no >4 digit contiguous numerics matching PAN prefix. 4. Templates cannot be subverted to expose more digits.", + "sourceCitation": { + "location": "Lines 18-19, Description", + "excerpt": "Any legal documentation should include the last 4 digits of the credit card number for identification purposes." + } + }, + { + "type": "security", + "title": "Validate Masking in All Communications Throughout Lifecycle", + "description": "This test ensures all system communications (reminders, alerts, collection letters, legal docs, agency handoff messages) carry only last 4 digits, never the full card number, at any stage of the credit card due collection process. This is an essential control for PCI compliance and to avoid regulatory fines. Automation: HIGH—batch validation of all comms templates and payloads is tractable.", + "testId": "TC-MASK-01", + "testDescription": "Every communication or document sent by the system at any collection lifecycle stage must use only the last four digits of the credit card number for identification. No otherwise-masked, tokenized, or unmasked digits should ever be used.", + "prerequisites": "1. End-to-end collection workflow operational (reminder, alert, collection, payment plan, agency, legal). 2. Test cardholder with eligible account moving through each state. 3. Communication templates active for all process steps.", + "stepsToPerform": "1. Advance test account through payment reminder stage. 2. Capture reminder message and inspect card number presence. 3. Move account to overdue state and trigger alert; inspect alert. 4. Initiate collection notification; validate its card masking. 5. Offer payment plan proposal and capture outbound message. 6. Simulate agency escalation and inspect handoff payload. 7. Trigger legal documentation; capture and review output. 8. Attempt to find full or partially-unmasked PAN in any message, doc, audit log, or notification. 9. Review system audit log for masking enforcement outcome at each step.", + "expectedResult": "1. Every communication instance includes only last 4 digits of card, no exceptions. 2. No full or partial PAN segments (other than last 4) observed. 3. Audit trail confirms masking integrity at all stages.", + "sourceCitation": { + "location": "Lines 19-20, Description - Note", + "excerpt": "only the last 4 digits of the credit card number should be included in any communication or documentation related to the collection process. The full credit card number should never be shared or displayed in plain text." + } + }, + { + "type": "security", + "title": "No Full Card Number in Internal Audit Logs", + "description": "This test ensures full credit card numbers are never written to internal audit logs at any step of the collection or notification lifecycle. Only the last 4 digits may appear, per masking requirement. This controls insider risk and audit scope. Automation: HIGH—string search in logs is feasible.", + "testId": "TC-MASK-02", + "testDescription": "When the system logs events relating to overdue, collections, agency handoff, or legal action, audit records must strictly limit card number exposure to the last 4 digits. No field, context, or payload-capture should retain full or partially-masked (other than last 4) data.", + "prerequisites": "1. Audit logging enabled and writable for all collection events. 2. Test account with known PAN '**** **** **** 4242'. 3. End-to-end lifecycle events (reminder, overdue, collection, agency, legal) initiated.", + "stepsToPerform": "1. Perform due reminder workflow for test account. 2. Move account through overdue, collection, agency, and legal stages, ensuring event logging is triggered. 3. Retrieve audit log entries for each event. 4. Scan all log fields for presence of card number data. 5. Assert only last 4 digits ('4242') appear in any log, if applicable. 6. Search for 16-digit or prefix-matched segments anywhere in records. 7. Verify logs retain all other required fields (account, timestamp, action, status). 8. Attempt injection of corrupted or unmasked PAN into logging system; verify sanitization. 9. Confirm audit log immutability and retrievability for compliance purposes.", + "expectedResult": "1. No full or partial (other than last 4) card number present in audit logs. 2. Only acceptable format is '**** **** **** 4242'. 3. Other log fields unaffected and persistent; logs cannot be tampered with to reveal more.", + "sourceCitation": { + "location": "Lines 19-20, Description - Note", + "excerpt": "The full credit card number should never be shared or displayed in plain text." + } + }, + { + "type": "negative", + "title": "Detect Incorrect Masking in Any Outbound Notification", + "description": "This test validates that any outbound notification containing improperly masked card numbers (e.g., more than last 4 digits, partially masked, format errors) is flagged, rejected, and not delivered. This catch is essential for breach prevention and regulatory adherence. Automation: HIGH—injectable negative case.", + "testId": "TC-MASK-03", + "testDescription": "If a system bug or template error leads to sending an outbound notification (email, SMS, letter) with a card number segment longer than 4 digits or with incomplete masking, the system must block delivery and log a security event.", + "prerequisites": "1. Notification engine with content filtering/validation enabled. 2. Cardholder account with test PAN. 3. Ability to simulate or inject erroneous masking in template or notification generator.", + "stepsToPerform": "1. Configure or tamper with a notification template to include a 6-digit unmasked card segment (e.g., '**** **** **1234'). 2. Trigger overdue, collection, or legal notification for test account. 3. Intercept notification at delivery queue. 4. Validate notification is flagged as containing improper masking. 5. Observe system rejecting or quarantining outbound message. 6. Review error logs or alert system for record of masking violation. 7. Attempt delivery replay; ensure error persists until masking is corrected. 8. Restore correct masking and verify delivery succeeds. 9. Examine audit log for evidence of blocked notification and underlying error.", + "expectedResult": "1. Outbound notification is rejected due to masking error. 2. Security log contains explicit record of violation and message block. 3. No improperly masked notification is delivered to recipient. 4. Recovery is possible and logged after template fixed.", + "sourceCitation": { + "location": "Lines 19-20, Description - Note", + "excerpt": "only the last 4 digits of the credit card number should be included in any communication..." + } + }, + { + "type": "security", + "title": "Block Communications Containing Full Card Number", + "description": "This test confirms the system blocks any outbound or internal communication (notification, doc, message, handoff) that includes the full credit card number, aligning with the explicit prohibition in the requirements. This protects customer data from exposure. Automation: HIGH—inject and filter check.", + "testId": "TC-MASK-04", + "testDescription": "If any message, notification, or internal communication is composed or queued with the full PAN (16 digits), the system must detect this and prevent its transmission by blocking or quarantining the communication and raising an alert.", + "prerequisites": "1. Notification processing with validation filters enabled. 2. Ability to simulate creation of message with unmasked PAN. 3. Access to notification and message delivery audit logs.", + "stepsToPerform": "1. Prepare a notification or internal message intentionally containing a field with value '1234 5678 9012 3456'. 2. Submit message to notification engine for processing. 3. Monitor system validation output for PAN detection. 4. Observe delivery pipeline for message block or quarantine event. 5. Inspect error handling log for details of violation. 6. Attempt to override or force delivery; assert system continues block. 7. Review notification audit logs for evidence of block. 8. Attempt to resend with last 4 digits only; verify allowed. 9. Simulate delivery to all types (email, SMS, agency payload, legal doc).", + "expectedResult": "1. All outbound/inbound communications containing a full PAN are blocked. 2. Security incident is logged with full details. 3. No full card number ever reaches an external system or recipient.", + "sourceCitation": { + "location": "Lines 19-20, Description - Note", + "excerpt": "The full credit card number should never be shared or displayed in plain text." + } + }, + { + "type": "functional", + "title": "Notification Contains Correct Fields and Message Structure", + "description": "This test ensures all user-facing notifications (reminders, alerts, collection notices, payment plans) contain the required fields in proper structure, with last 4 digits of the credit card number for identification. This assures regulatory completeness and clear user communication. Automation: HIGH—message structure is testable.", + "testId": "TC-NOTIFY-01", + "testDescription": "Every notification sent at any stage (reminder, alert, collection notice, payment plan) must include cardholder name, minimum amount due, due date (if relevant), and the last 4 digits of the credit card number as identification.", + "prerequisites": "1. User account with active card '**** **** **** 4242'. 2. Notification templates configured per process requirement. 3. Outbound notification generation and capture enabled.", + "stepsToPerform": "1. Advance account through regular due reminder step. 2. Capture reminder notification as sent to user channel. 3. Inspect notification for required fields: 'Dear [Name]', last 4 digits, amount due, due date. 4. Move account to overdue, trigger overdue alert; retrieve and inspect. 5. Push simulated account into collection state; trigger collection notice, verify field content. 6. Initiate payment plan proposal; capture and validate notification content. 7. For each notification, validate correct structure, no missing fields, correct placement of last 4 digits. 8. Attempt to parse notification as user would (simulate readability and clarity). 9. Review all system logs for evidence of notification delivery and structure validation.", + "expectedResult": "1. Every notification includes the last 4 digits, correct fields, and proper message structure. 2. No notification omits mandatory information. 3. Formatting is user-readable.", + "sourceCitation": { + "location": "Lines 6-16, Description (Multiple bullet points)", + "excerpt": "This notification should include the last 4 digits of the credit card number for identification purposes." + } + }, + { + "type": "negative", + "title": "Reject Notification if Required Fields Missing", + "description": "This test checks if notifications missing mandatory fields (e.g., last 4 digits, amount due, due date) are automatically rejected and not delivered. This upholds communication quality, regulatory requirement, and prevents ambiguous user messaging. Automation: HIGH—template error and filter pipeline.", + "testId": "TC-NOTIFY-02", + "testDescription": "When a notification (reminder, alert, collection, payment plan) is generated with required fields missing—especially the last 4 digits of the card number—the system must reject, quarantine, and log the error without delivery.", + "prerequisites": "1. Notification generator supports field-level template changes. 2. Simulate removal of last 4 digits or other required field from template. 3. Outbound notification auditing enabled.", + "stepsToPerform": "1. Configure a faulty notification template missing the last 4 digits or amount due. 2. Trigger sending of reminder notification for overdue account. 3. Observe system validation pipeline for missing field detection. 4. Attempt delivery; expect notification generation to be halted. 5. Inspect error queue or quarantine for undelivered message. 6. Confirm error log records rejection with field-missing reason. 7. Audit logs to verify notification ID, recipient, missing field, and system action. 8. Fix template and repeat; confirm successful delivery when fields present. 9. Simulate this process for all notification types.", + "expectedResult": "1. Notifications missing mandatory fields are not delivered. 2. Error and audit logs contain explicit missing field messages. 3. Only notifications with all required fields are sent.", + "sourceCitation": { + "location": "Lines 6-16, Description (Multiple bullet points)", + "excerpt": "This notification should include the last 4 digits of the credit card number for identification purposes." + } + }, + { + "type": "security", + "title": "Notification Sent Only to Authorized Cardholder", + "description": "Verifies that automated notifications about an upcoming credit card due date are sent exclusively to the authorized cardholder, never to unauthorized recipients, and that only the last 4 digits of the card number appear in the notification content. This guards against PII/data leaks and enforces notification access control. Automation: HIGH—API and message interception.", + "testId": "TC-ROLE-01", + "testDescription": "When a credit card due reminder notification is triggered for an eligible account, the system must ensure delivery only to the email, SMS, or notification endpoint assigned to the authorized cardholder. No notification must be sent to any other user, and content must always mask the credit card number except the last 4 digits.", + "prerequisites": "1. Cardholder account exists with primary email test+cardholder001@example.com and phone +14557890001.\n2. Due date flag set to 5 days from today.\n3. Secondary (unauthorized) account present for same product, test+intruder021@example.com.\n4. Test card number on file is 4111 1111 1111 4242.", + "stepsToPerform": "1. Trigger the automated due reminder notification workflow for the eligible account.\n2. Intercept outbound notification message from the system (email/SMS/API).\n3. Verify recipient email/phone equals only test+cardholder001@example.com / +14557890001.\n4. Ensure no notifications are sent to test+intruder021@example.com or any other user.\n5. Examine notification content and confirm it contains only masked card ('**** **** **** 4242').\n6. Confirm full card number, partial (>4 digits), or any PII is NOT present in notification headers/payload or delivery logs.\n7. Attempt to subscribe/unsubscribe as the unauthorized user; trigger resend and verify no delivery occurs.\n8. Check system logs for any notification activity to unauthorized recipients—assert absence.\n9. Cross-validate notification audit records for correct recipient and content fields.", + "expectedResult": "1. Notification is sent only to authorized cardholder's registered endpoints.\n2. Notification content contains only the masked card number ('**** **** **** 4242').\n3. No notifications are sent or visible to unauthorized users (manual or automated attack is blocked).\n4. System logs and audits confirm delivery only to authorized recipient and no data leak.\n5. No evidence of full card number exposure in notification or logs.", + "sourceCitation": { + "location": "Lines 6-16, Description", + "excerpt": "an automated notification is sent to the cardholder... notification should include the last 4 digits of the credit card number for identification purposes." + } + }, + { + "type": "security", + "title": "Collection Agency Access Limited to Assigned Accounts Only", + "description": "Validates that collection agency integration provides agency staff access solely to assigned delinquent accounts, with only the last 4 digits of the card number for identification. Ensures no cross-account or PII data leak to unauthorized agencies. Automation: HIGH—API/DB role checks.", + "testId": "TC-ROLE-02", + "testDescription": "When a collection agency is assigned to recover a delinquent credit card balance, the system must restrict agency portal/API access to only those accounts explicitly assigned, and must only share the last 4 digits of each credit card number—never the full number or any unrelated account data.", + "prerequisites": "1. Account 100234 becomes delinquent, assigned to Agency Alpha.\n2. Test card number is 5100 0000 0000 5678 for 100234.\n3. At least one unassigned delinquent account exists (e.g., Account 100235, card 4321 1234 8765 3210).\n4. Agency user has valid API/session credentials.", + "stepsToPerform": "1. Log in as the Agency Alpha user via API or portal.\n2. Request account list assigned to Agency Alpha.\n3. Confirm presence of Account 100234; confirm absence of 100235.\n4. View collection details for 100234 and verify card number field is '**** **** **** 5678' only.\n5. Attempt direct look-up by random or sequential account/card numbers (e.g., 100235).\n6. Confirm all queries for unassigned accounts fail with access denied.\n7. Scan UI/data payloads for presence of full card number/other PII—in all views/downloads.\n8. Submit export/download request for all assigned accounts and verify PII masking.\n9. Examine back-end logs for unauthorized access attempt records.", + "expectedResult": "1. Agency Alpha can view only account(s) assigned; all others are inaccessible.\n2. Only the last four digits ('5678') of the card number are displayed or returned in all screens/data exports.\n3. Access to unassigned accounts is strictly denied, with 403/401 errors as appropriate.\n4. No full card numbers or unrelated PII appear anywhere in agency-accessible interfaces or exports.", + "sourceCitation": { + "location": "Lines 17-18, Description", + "excerpt": "The collection agency should be provided with the last 4 digits of the credit card number for identification purposes." + } + }, + { + "type": "functional", + "title": "Log and Retry Failed Notification Transmission", + "description": "Ensures that when a notification transmission (e.g., email/SMS reminder or alert) fails, the system logs the failed event (without exposing the full card number), initiates an automated retry as per policy, and never leaks PII in logs or error payloads. Automation: HIGH—event injection and log inspection.", + "testId": "TC-ERR-01", + "testDescription": "If a due or collection notification transmission fails due to a transient error (e.g., mail server 500), the system must log the attempt (with correct PII masking), trigger exactly one retry as per business rules, and not expose the full credit card number in any error/artifact.", + "prerequisites": "1. Delinquent credit card account 200896 set to notify, card: 4444 3333 2222 9876.\n2. Notification outbox/queue configured.\n3. Failure injection tool available (e.g., simulate SMTP 500 response).\n4. Log access for notification subsystem.", + "stepsToPerform": "1. Trigger notification workflow for account 200896.\n2. Intercept the outbound notification and inject a transmission failure (force SMTP/API response 500).\n3. Wait for the system to record the transmission failure.\n4. Inspect the notification error log for entry referencing this event.\n5. Confirm that only the last 4 digits ('9876') are present; full card number is not present in any log/message/error.\n6. Verify the retry job is created and scheduled per system configuration.\n7. Trigger the retry transmission; simulate success on the second attempt.\n8. Confirm successful delivery message appears in the outbox/audit for retry attempt.\n9. Validate no unmasked card PII appears in any failed/success log entries or payloads.", + "expectedResult": "1. The failure is logged with only masked card number ('**** **** **** 9876').\n2. Retry is initiated exactly once per policy.\n3. Retry succeeds and the notification is delivered to the recipient.\n4. No full card numbers appear in logs or error traces.\n5. Audit system links both attempts, with proper status entries.", + "sourceCitation": { + "location": "Lines 19-20, Description - Note", + "excerpt": "Note: For security reasons, only the last 4 digits... and the full credit card number should never be shared..." + } + }, + { + "type": "functional", + "title": "Raise Incident for Undeliverable Collection Notifications", + "description": "Verifies that the system raises an incident (e.g., creates a ticket or notifies admin) when repeated notification delivery attempts (reminder, overdue alert, or collection notice) fail, and that no additional communication attempts are made without intervention—ensuring proper escalation and compliance. Automation: HIGH.", + "testId": "TC-ERR-02", + "testDescription": "When all allowed notification retries for a collection notification fail (e.g., mailbox rejected, SMS undeliverable), the system must log the failure, mark notification as undeliverable, and raise a formal incident for human follow-up. No legal/collection process must proceed without resolution.", + "prerequisites": "1. Overdue account 320045 eligible for collection notification, card: 6543 8521 4444 9201.\n2. Notification endpoints deliberately invalid (bounce all email/SMS transmissions).\n3. Incident management integration is enabled.", + "stepsToPerform": "1. Trigger collection notification workflow for 320045.\n2. Observe the system attempt notification transmission (primary endpoint fails: hard bounce).\n3. Exhaust the allowed retry attempts (simulate full delivery failure each round).\n4. Check notification subsystem for final status: undeliverable.\n5. Inspect logs for incident creation request/event.\n6. Validate incident contains account identity, event timeline, and only last 4 digits of card.\n7. Attempt further legal/collection progression for this account—verify block/hold is applied.\n8. Review internal/external notification logs for no further communication attempts until incident resolved.\n9. Confirm audit entry for undeliverable notification and incident event.", + "expectedResult": "1. Incident/ticket is raised in the incident system linked to account 320045, reason: undeliverable notification.\n2. Further collection/legal process is on hold pending resolution.\n3. All logged evidence contains only masked card info ('**** **** **** 9201').\n4. Audit record shows notification undeliverable and incident creation.", + "sourceCitation": { + "location": "Lines 6-16, Description", + "excerpt": "an alert is sent to notify ... consequences of not making the payment promptly" + } + }, + { + "type": "negative", + "title": "Prevent Escalation if Data Error Detected", + "description": "Checks that the system halts escalation to collection or legal processes if a data error (missing/invalid cardholder contact info, card number corruption) is detected, preventing erroneous or non-compliant communication. Automation: HIGH—API and data validation triggers.", + "testId": "TC-ERR-03", + "testDescription": "If mandatory data (contact email, masked card number) is missing or corrupted in a delinquent account, escalation to collection notification, collection agency, or legal event must be stopped/blocked until data is remediated. System must show clear data error status.", + "prerequisites": "1. Delinquent account 401234 prepared for collection escalation.\n2. Card number field contains non-numeric or too short value (e.g., '123X').\n3. Primary contact detail missing/null.\n4. System escalation workflow enabled.", + "stepsToPerform": "1. Load account 401234 with invalid card number and blank email.\n2. Attempt to trigger escalation to collection notification.\n3. Inspect system for immediate validation error/block.\n4. Attempt manual escalation to agency and/or legal status.\n5. Confirm each attempt is denied with a specific data error message.\n6. Validate that system logs the blocked escalation, account status = DATA_ERROR.\n7. Attempt to correct only one field and retry escalate; verify block persists until all mandatory fields are valid.\n8. Repair both fields, trigger escalation again; validate escalation proceeds as normal.\n9. Confirm all error logs contain only appropriately masked data.", + "expectedResult": "1. Escalation is prevented with clear data error status/message (e.g., 'MANDATORY_FIELD_MISSING').\n2. No collection/agency/legal notifications are sent while account data is invalid.\n3. Data error event is logged/audited.\n4. System enforces remediation before further steps.", + "sourceCitation": { + "location": "Lines 13-18, collection workflow logic", + "excerpt": "When an account becomes significantly delinquent, the card issuer may escalate the collection process..." + } + }, + { + "type": "audit", + "title": "Audit Log Integrity for Legal and Collection Events", + "description": "Verifies that every legal action initiation or collection escalation event is logged immutably, with no option for deletion or modification, and includes only the last 4 digits of the card number. Any audit tampering or exposure of full numbers is detected and flagged. Automation: HIGH.", + "testId": "TC-AUDIT-02", + "testDescription": "Whenever legal action is initiated on a delinquent account, the system writes a permanent, immutable audit log entry. Log entry must have only the last 4 digits of the card ('****'), event timestamp, user ID, and initiating action, and may not be altered or deleted post-write.", + "prerequisites": "1. Account 772910 at 'Legal Action Initiation' stage, card: 6011 1243 1902 4123.\n2. Write-access to logs blocked after entry creation.\n3. Immutable audit subsystem enabled.", + "stepsToPerform": "1. Trigger legal action workflow for 772910.\n2. Confirm delivery of legal docs to mailbox (with last 4 digits only).\n3. View audit log shortly after event; confirm log entry contains legal action event, user, masked card '**** **** **** 4123'.\n4. Attempt to delete or modify the audit log entry (through supported or direct DB interface).\n5. Attempt to force-insert a log with full card number.\n6. Query audit log for extraneous/malicious entry; confirm immutability.\n7. Verify all legal and collection escalations appear in audit timeline chronologically.\n8. Check for audit-tampering alerts if log is edited/removed.", + "expectedResult": "1. Initiation of legal or collection event writes immutable, verifiable audit log entry with correct event data and card masking.\n2. Attempts to delete/alter log fail or generate alerts.\n3. No log entry exposes the full card number.", + "sourceCitation": { + "location": "Lines 18-19, Description", + "excerpt": "Legal Action Initiation: In extreme cases of non-payment or default, the card issuer may have to take legal action against the cardholder." + } + }, + { + "type": "state-transition", + "title": "Valid State Transitions: Due → Overdue → Collections", + "description": "Ensures the system enforces correct state transitions for credit card accounts, moving from Due to Overdue upon missed payment, and to Collections upon sustained non-payment, with precise triggers and no skipped states. Automation: HIGH—state engine and event verification.", + "testId": "TC-STATE-01", + "testDescription": "A credit card account must transition through the following states in order: Due, Overdue, Collections, with each state change triggered by clear business events (missed due date, days overdue threshold exceeded). Skipped or out-of-order transitions must not occur.", + "prerequisites": "1. Account 143160 with due date set to today-3 days.\n2. No payment made; payment window expired for > 3 days.\n3. Collections trigger configured to 7 days overdue.", + "stepsToPerform": "1. Initialize account 143160 at Due state; trigger due reminder.\n2. Wait for payment due date to pass with no payment.\n3. Verify account automatically transitions to Overdue.\n4. Trigger overdue balance alert.\n5. Wait until system threshold for collections reached (7 days overdue).\n6. Confirm automatic transition to Collections state.\n7. Trigger formal collection notification.\n8. Attempt to forcibly jump account from Due directly to Collections; verify rejection.\n9. Verify audit trail of each state change (with masked card info).", + "expectedResult": "1. Account moves sequentially from Due → Overdue → Collections as per business event triggers; no steps skipped.\n2. Manual or system attempts to skip states are blocked.\n3. Audit records show only masked card number for all state transitions.", + "sourceCitation": { + "location": "Lines 6-18, Description", + "excerpt": "Credit Card Due Reminder... Overdue Balance Alert... Collection Notification..." + } + }, + { + "type": "state-transition", + "title": "Failed Payment Plan Acceptance Reverts to Collections", + "description": "Validates that if a cardholder declines, ignores, or otherwise fails to accept a payment plan proposal, their account reverts to/continues in Collections state, with correct notifications and audit evidence. Automation: HIGH—stateful and messaging assertions.", + "testId": "TC-STATE-02", + "testDescription": "When offered a payment plan proposal, a cardholder must accept within a defined response window. If they fail to respond or explicitly reject, the system must return or keep their account in Collections, send the proper collection notifications, and update audit logs accordingly.", + "prerequisites": "1. Account 604499 in Collections state, payment plan proposal generated.\n2. Proposal response window = 5 days active.\n3. Cardholder has not responded at all or has declined via UI/API.", + "stepsToPerform": "1. Ensure payment plan proposal is sent to account 604499 (delivery confirmed).\n2. Wait for 5 days (simulate time advance) without response.\n3. System marks proposal as expired or declined.\n4. Observe state transition engine—account remains/reverts to Collections.\n5. Verify that collection notification is re-sent as per policy.\n6. Review audit log for proposal outcome, transition notes, masked card number present.\n7. If decline is via explicit action (button/API), trigger and verify state behavior as above.\n8. Validate no legal action is taken unless next proper triggers are achieved.\n9. Confirm no duplicate proposals are generated for this ineligible state.", + "expectedResult": "1. Account is retained in or returned to Collections after payment plan non-acceptance.\n2. Correct notifications/retry messages are issued to cardholder, with only masked card info ('****').\n3. Complete audit log chain reflects proposal status and state transitions.", + "sourceCitation": { + "location": "Lines 15-18, Description", + "excerpt": "payment plan proposal outlining a structured repayment schedule... If the cardholder fails to respond... the card issuer may involve a collection agency..." + } + }, + { + "type": "negative", + "title": "Block Re-entry into Payment Plan After Legal Action", + "description": "Ensures system enforcement that once an account escalates to Legal Action status, user cannot retroactively re-enter or accept a payment plan. All attempts (UI/API/manual) are denied and logged. Automation: HIGH—end-state and privilege testing.", + "testId": "TC-STATE-03", + "testDescription": "After legal action has begun for a delinquent cardholder, the account is locked from payment plan offers—subsequent user attempts to enter/accept a plan must be blocked systemically and operationally. All unauthorized attempts must be properly logged.", + "prerequisites": "1. Account 980123 in Legal Action status, card: 5200 9999 8888 5432.\n2. User credentials and payment plan request forms enabled.\n3. No active or pending payment plan records.", + "stepsToPerform": "1. At Legal Action status, attempt to access payment plan offer UI as cardholder.\n2. Attempt to submit API request to join/accept payment plan.\n3. Try to trigger plan offer via customer service/manual workaround.\n4. Review system response for each attempt (expect clear rejection message/state code).\n5. Verify no payment plan record is created in DB for last 30 days.\n6. Examine system and audit logs for denied attempt, with masked card info only ('**** **** **** 5432').\n7. Attempt to send escalation appeal—verify same result.\n8. Inspect all legal communication and notification content to confirm no payment plan links/offers shown.\n9. Attempt to revert account to Collections in back-end; verify override is not permitted under policy.", + "expectedResult": "1. No payment plan can be initiated, offered, or accepted once Legal Action status is set.\n2. All attempts are denied with 'INELIGIBLE_STATE' message or equivalent.\n3. Audit and system logs reflect all blocked attempts with only last 4 digits masked.\n4. All associated payment plan UI/API/notification features are deactivated for the account.", + "sourceCitation": { + "location": "Lines 18-19, Description", + "excerpt": "In extreme cases of non-payment or default... legal action..." + } + }, + { + "type": "boundary", + "title": "Boundary Test: Overdue Days Trigger Collection Notification", + "description": "This test verifies that the system correctly triggers the collection notification precisely at the documented threshold of significant delinquency (boundary conditions), and not before, ensuring the escalation logic adheres to policy. Automation: HIGH — pure logic and notification payload inspection. Critical for regulatory compliance as improper escalation can cause user and legal issues.", + "testId": "TC-BVAL-01", + "testDescription": "A cardholder account passes through the overdue balance stage and approaches the system-defined threshold for 'significantly delinquent'. This test enters data for an account at the maximum overdue days that do NOT trigger collection notification and then at the minimum overdue days that MUST trigger collection notification. The system must only initiate escalation when the threshold is precisely met, and must send the notification including amount owed, any charges, and only the last 4 digits of the credit card number.", + "prerequisites": "1. Account 'testuserA' is active and has an outstanding credit card balance. 2. The customer's payment due date has passed. 3. Overdue days parameter for collection notification set (e.g., threshold=30 days for significant delinquency). 4. Outbound notification system is enabled.", + "stepsToPerform": "1. Set account 'testuserA' overdue by (threshold-1) days (e.g., 29 days if threshold is 30). 2. Trigger overdue check batch job. 3. Verify no collection notification is sent—confirm in notification log. 4. Advance account overdue to threshold days (e.g., 30 days). 5. Trigger overdue batch job again. 6. Check notification system log for newly created collection notification event. 7. Retrieve notification content for 'testuserA'. 8. Verify notification contains amount owed, any additional charges, and only the last 4 digits of the card ('**** **** **** 4242'). 9. Verify full credit card number does NOT appear in the message or log. 10. Ensure audit log records notification event with appropriate timestamp and user reference.", + "expectedResult": "1. No collection notification is sent at (threshold-1) days overdue. 2. Collection notification is sent at threshold days overdue. 3. Notification includes only amount owed, additional charges, and last 4 digits of the card. 4. Full card number is never exposed in notification or system logs.", + "sourceCitation": { + "location": "Lines 13-14, Description", + "excerpt": "When an account becomes significantly delinquent, the card issuer may escalate the collection process by sending formal collection notifications to the cardholder, detailing the amount owed and any additional charges." + } + }, + { + "type": "boundary", + "title": "Boundary Test: Legal Escalation Day Threshold", + "description": "This test verifies that legal escalation, including legal communications, is triggered only when an account is overdue the required number of days to qualify as 'extreme case of non-payment or default', and not before. This protects customers from premature legal threats and the bank from legal risk. Automation: HIGH, as date calculations and message payload can be fully validated with test harness.", + "testId": "TC-BVAL-02", + "testDescription": "An account lapses payment beyond the collections phase and is approaching the legal escalation threshold. This test exercises the exact transition point: the last day that does NOT qualify for legal action, and the first day that DOES. It also validates that the legal notification contains only the last 4 digits of the credit card number, never the full number.", + "prerequisites": "1. Account 'testuserB' was already passed to collections, and payment remains unmade. 2. System legal escalation threshold days-overdue is established (e.g., 90 days post due date). 3. Notification engines for collection and legal events are operational.", + "stepsToPerform": "1. Set the overdue days for 'testuserB' account to (legal_threshold-1) days (e.g., 89 days if threshold is 90). 2. Run legal escalation batch process. 3. Verify no legal escalation event or notification is generated (review event logs). 4. Advance account to threshold overdue days (e.g., 90 days). 5. Trigger legal escalation batch job. 6. Confirm legal action notification is generated in communication logs. 7. Retrieve legal notification content sent to customer. 8. Ensure it includes only the last 4 digits of the credit card number ('**** **** **** 2244'). 9. Attempt to find full card data in notification payload (it must NOT be present). 10. Verify legal escalation event is recorded in audit log with user reference and exact overdue day count.", + "expectedResult": "1. No legal action is triggered at (threshold-1) overdue days. 2. Legal action is triggered exactly at threshold. 3. Legal notice contains only the last 4 digits of the card; never the full card number. 4. Legal event is correctly audit-logged.", + "sourceCitation": { + "location": "Lines 18-19, Description", + "excerpt": "In extreme cases of non-payment or default, the card issuer may have to take legal action against the cardholder." + } + }, + { + "type": "security", + "title": "API Sends Only Approved Fields to Collection Agency", + "description": "This test validates that the outbound integration to the collection agency contains only the explicitly approved fields and masks sensitive data as per policy—specifically, only the last 4 digits of the credit card number are ever included. Prevents data leakage and regulatory violations. Automation: HIGH — can be fully validated at API payload and integration log levels.", + "testId": "TC-INTG-01", + "testDescription": "When the system's collection phase escalates to third-party agency handoff, it must assemble a data payload. Only the account holder's reference data and last 4 digits of the credit card number must be provided to the external agency. No other sensitive information (e.g., full card number) may be transmitted. The test also checks that API logs and payload samples do not contain prohibited fields.", + "prerequisites": "1. Account 'testuserC' is overdue and has met agency escalation criteria. 2. Collection agency integration is configured and available in test environment. 3. Data masking and field selection logic for outbound payload is present. 4. API event logging is enabled.", + "stepsToPerform": "1. Mark 'testuserC' as overdue past the agency threshold (e.g., 60 days). 2. Trigger agency handoff function or workflow. 3. Intercept the API payload sent to the collection agency. 4. Review payload structure: validate 'accountId', 'customerName', 'last4' are present. 5. Search payload for any occurrence of a full credit card number; validate only 'last4' appears, e.g., '**** **** **** 8788'. 6. Review outbound API log for possible unmasked sensitive data. 7. Check that masking logic (last 4 only) is consistently applied to all outbound fields. 8. Attempt (negative test) to forcibly enter unmasked card number for this user. 9. Rerun handoff and validate system blocks or masks this field. 10. Confirm an audit log entry exists for the escalation, referencing ONLY masked card data.", + "expectedResult": "1. Outbound payload to agency contains account ref and last 4 digits only; no unmasked card numbers. 2. API and audit logs contain no sensitive data beyond last 4. 3. Attempts to bypass masking are blocked or corrected.", + "sourceCitation": { + "location": "Lines 17-18, Description", + "excerpt": "The collection agency should be provided with the last 4 digits of the credit card number for identification purposes." + } + }, + { + "type": "negative", + "title": "No Duplicate Agency Handoffs for Single Account", + "description": "This negative test ensures that multiple triggers for escalation to collections agency do not create duplicate handoff events for the same overdue account, preventing double-agency pursuit and regulatory violations. It verifies idempotency and deduplication logic. Automation: HIGH — relies on system event, idempotency, and integration event logs.", + "testId": "TC-INTG-02", + "testDescription": "An account overdue and eligible for collection agency handoff is processed repeatedly by the escalation procedure. The system must create only a single agency handoff; subsequent triggers must be suppressed, ignored, or safely idempotent, and only one agency notification is sent. All subsequent attempts must leave system/log in correct, non-duplicated state.", + "prerequisites": "1. Account 'testuserD' is in status overdue and eligible for agency escalation. 2. No prior handoff to agency for this delinquency event on this account. 3. System tracks prior escalations via event IDs or similar mechanism.", + "stepsToPerform": "1. Simulate overdue status reaching agency handoff threshold for 'testuserD'. 2. Trigger agency handoff API call/workflow for the account. 3. Check that a handoff payload is sent and handoff event is logged. 4. Immediately (within millisec) retrigger the agency handoff API workflow for the same account (simulate retry, race, batch rerun). 5. Review outbound logs and the agency’s endpoint for duplicate payloads. 6. Simulate a third call (manual trigger, timer, or batch duplicate). 7. Confirm deduplication logic causes no second or third payload to be sent for the same account/event. 8. Review audit log and deduplication status; verify only one event is finalized. 9. Inspect agency dashboard or test interface for only one entry per account. 10. System error handling and notifications show success for first handoff, 'already handed off' (or similar) for subsequent retries.", + "expectedResult": "1. Only one agency handoff event and notification occurs for a single qualifying overdue event per account. 2. Audit logs contain a single escalation event. 3. Agency receives no duplicate instructions.", + "sourceCitation": { + "location": "Lines 17-18, Description", + "excerpt": "If the cardholder fails to respond… may involve a collection agency..." + } + }, + { + "type": "functional", + "title": "Outbound Notification Data Match Customer and Account", + "description": "This test confirms that all outbound notifications (reminder, overdue alert, collection notice, payment plan, legal) always display data matching the correct customer and account, including: due date, amount owed, and ONLY the last 4 digits of the correct credit card number. Prevents data misrouting, a critical privacy and regulatory concern. Automation: HIGH — pure notification content and log inspection.", + "testId": "TC-DATA-01", + "testDescription": "Every time the system sends a notification at any stage, it must include: the correct due date, amount owed, and match the last 4 digits of the registered card number. No data from one user may appear in another's notifications. This scenario simulates sending a notification, including a negative step introducing deliberate cross-account data error, expecting that system blocks or corrects such issues before delivery.", + "prerequisites": "1. Accounts 'testuserE' and 'testuserF' both exist with unique card numbers. 2. Both users are at distinct stages (e.g., one at overdue, one at payment plan proposal). 3. Notification system is enabled and records all outgoing messages.", + "stepsToPerform": "1. Generate overdue notification for 'testuserE'; intercept message before delivery. 2. Verify notification includes correct due date and amount owed for 'testuserE'. 3. Confirm card identifier displayed is only the last 4 digits of 'testuserE' card (e.g., '**** **** **** 1122'). 4. Generate payment plan proposal notification for 'testuserF'. 5. Confirm that notification contains 'testuserF' card's last 4 digits and their specific account data (due date, amount). 6. Attempt a forced data injection (negative path): assign 'testuserE' card digits to a notification for 'testuserF'. 7. Trigger notification delivery; system should detect and block/prevent mismatched data. 8. Query notification logs for delivered messages to both users. 9. Randomly sample logs/messages to validate no cross-user data exposure. 10. Check for system or audit log warning in case of detected cross-data attempt.", + "expectedResult": "1. Each notification contains the correct due date, amount, and correct card's last 4 digits only. 2. No notification contains data belonging to another customer. 3. Any attempt to send cross-customer data is blocked and logged.", + "sourceCitation": { + "location": "Lines 6-16, Description", + "excerpt": "credit card payment due date... amount owed... last 4 digits of the credit card number..." + } + }, + { + "type": "e2e", + "title": "Full Lifecycle: Due Reminder → Overdue → Collections → Payment Plan → Agency → Legal", + "description": "This end-to-end test runs a synthetic customer through the entire overdue and escalation lifecycle, validating notification triggering, data content, masking, and state transitions from due reminder to overdue, collection notification, payment plan offer, agency handoff, and finally legal escalation. Critical for verifying overall process flow, regulatory compliance, and cross-stage data handoff. Automation: MEDIUM — multiple system/batch triggers, message review.", + "testId": "TC-E2E-01", + "testDescription": "A customer account is created and allowed to progress naturally, without payment, through all escalation points: receives due reminder, misses payment, receives overdue alert, reaches collection notification threshold, receives payment plan proposal, is handed off to collection agency, and on ongoing default, escalates to legal action. At each stage, notification is generated with correct, masked card data. Includes audit log and masking validation at every step.", + "prerequisites": "1. Customer testuserG with unique card number ('**** **** **** 9001') created in test system. 2. Notification, overdue batch, collections, agency, legal modules enabled. 3. System clock/mocks can simulate passage of time for overdue progression.", + "stepsToPerform": "1. Customer receives due reminder notification prior to payment due date. 2. Allow due date to pass without payment (simulate no transaction). 3. System generates overdue alert; verify notification and log. 4. After prescribed overdue period (e.g., 30 days), trigger collections notification; verify contents. 5. Let payment remain unmade and reach payment plan proposal threshold; generate and verify proposal. 6. Simulate continued non-response; system triggers collection agency handoff. 7. Review handoff payload: confirm last 4 digits only, other data masked. 8. Still no payment: exceed legal escalation threshold; generate legal action notice. 9. At each step, capture notification contents and verify ONLY last 4 digits appear, amounts/dates match status, no full card info exposed. 10. Inspect system's audit logs for all transition events, notification sends, and escalations.", + "expectedResult": "1. Each escalation triggers in correct order, at appropriate timing/state. 2. Every notification contains only last 4 digits; full card number never exposed. 3. All notification and escalation events are present in system audit log. 4. Data and state remain consistent and compliant throughout lifecycle.", + "sourceCitation": { + "location": "Lines 6-19, Description (all bullet points)", + "excerpt": "Credit Card Due Reminder... Overdue Balance Alert... Collection Notification... Payment Plan Proposal... Collection Agency Involvement... Legal Action Initiation..." + } + } +] \ No newline at end of file diff --git a/functional_tests/ZBIO-5213/ZBIO-5213.xlsx b/functional_tests/ZBIO-5213/ZBIO-5213.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e2db0a76cc4bfffbdf4cb3384d8fb0cbbb59213a GIT binary patch literal 28191 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 M`;HVc`(yfl0bX*bfB*mh literal 0 HcmV?d00001 diff --git a/functional_tests/ZBIO-5213/ZBIO-5213.yaml b/functional_tests/ZBIO-5213/ZBIO-5213.yaml new file mode 100644 index 0000000..2e5a271 --- /dev/null +++ b/functional_tests/ZBIO-5213/ZBIO-5213.yaml @@ -0,0 +1,642 @@ +openapi: 3.0.3 +info: + title: Credit Card Collection Lifecycle Communication and Data Masking API + description: > + API for managing credit card collection lifecycle events, notifications, escalations, audit, and ensuring data masking compliance. + version: '1.0.0' +servers: + - url: https://testcardsystem.example.com +security: + - bearerAuth: [] + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + parameters: + AccountId: + name: accountId + in: path + required: true + schema: + type: string + description: Unique account identifier + Stage: + name: stage + in: query + required: false + schema: + type: string + enum: [DueReminder, OverdueAlert, Collection, PaymentPlan, Agency, Legal] + description: The notification/collection lifecycle stage + NotificationId: + name: notificationId + in: path + required: true + schema: + type: string + description: The notification or event identifier + AgencyUser: + name: agencyUser + in: path + required: true + schema: + type: string + description: The collection agency user identifier + IncidentId: + name: incidentId + in: path + required: true + schema: + type: string + description: Unique id for an incident/ticket + + schemas: + MaskedCard: + type: object + properties: + maskedNumber: + type: string + pattern: '^\\*\\*\\*\\* \\*\\*\\*\\* \\*\\*\\*\\* \\d{4}$' + example: '**** **** **** 4242' + last4: + type: string + pattern: '^\\d{4}$' + example: '4242' + NotificationRequest: + type: object + properties: + accountId: + type: string + stage: + type: string + enum: [DueReminder, OverdueAlert, Collection, PaymentPlan, Agency, Legal] + dueDate: + type: string + format: date + amountDue: + type: string + example: '$250' + required: [accountId, stage] + NotificationResponse: + type: object + properties: + notificationId: + type: string + status: + type: string + enum: [sent, undeliverable, rejected] + deliveredAt: + type: string + format: date-time + recipient: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + dueDate: + type: string + format: date + amountDue: + type: string + message: + type: string + required: [status, maskedCard] + ErrorResponse: + type: object + properties: + errorCode: + type: string + example: INVALID_MASKING + message: + type: string + EscalationRequest: + type: object + properties: + accountId: + type: string + required: [accountId] + EscalationResponse: + type: object + properties: + status: + type: string + previousState: + type: string + newState: + type: string + agencyPayload: + type: object + properties: + accountId: + type: string + customerName: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + auditReference: + type: string + required: [status, newState] + PaymentPlanProposalRequest: + type: object + properties: + accountId: + type: string + required: [accountId] + PaymentPlanProposalResponse: + type: object + properties: + status: + type: string + repaymentSchedule: + type: string + reducedFees: + type: string + notificationId: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + auditReference: + type: string + required: [status, notificationId, maskedCard] + AuditLogEntry: + type: object + properties: + eventId: + type: string + accountId: + type: string + eventType: + type: string + timestamp: + type: string + format: date-time + userId: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + status: + type: string + details: + type: object + required: [eventId, accountId, eventType, timestamp, userId, maskedCard] + IncidentReport: + type: object + properties: + incidentId: + type: string + status: + type: string + enum: [open, resolved] + reason: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + openedAt: + type: string + format: date-time + required: [incidentId, status, reason, maskedCard] + AgencyHandoffRequest: + type: object + properties: + accountId: + type: string + required: [accountId] + AgencyHandoffResponse: + type: object + properties: + handoffId: + type: string + status: + type: string + enum: [success, duplicate, ineligible, rejected] + agencyPayload: + type: object + properties: + accountId: + type: string + customerName: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + auditReference: + type: string + required: [status, agencyPayload] + +paths: + # Notification generation endpoint + /notifications/send: + post: + summary: Send notification for a collection lifecycle event + description: Send a lifecycle notification (due, overdue, collection, payment plan, legal, etc.) ensuring PAN masking and mandatory fields. + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationRequest' + responses: + '200': + description: Notification sent successfully + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationResponse' + '400': + description: Bad Request (e.g., improper masking, missing fields) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Unauthorized or forbidden recipient + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + # Notification retrieval by accountId or notificationId (for logs/audit/PII masking validation) + /accounts/{accountId}/notifications: + get: + summary: Get all notifications for an account + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/AccountId' + responses: + '200': + description: List of notifications for the account + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/NotificationResponse' + + /notifications/{notificationId}: + get: + summary: Retrieve a specific notification + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/NotificationId' + responses: + '200': + description: Notification details, always showing masked card number only + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationResponse' + '404': + description: Notification not found + + # Batch job trigger for notifications, overdue, collection, and legal + /batch/jobs/{stage}: + post: + summary: Trigger batch job for lifecycle stage (due reminder, overdue, collection, legal, etc.) + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/Stage' + responses: + '200': + description: Batch job execution status with list of notification results + content: + application/json: + schema: + type: object + properties: + executed: + type: boolean + stage: + type: string + results: + type: array + items: + $ref: '#/components/schemas/NotificationResponse' + '403': + description: Stage not enabled or unauthorized + '500': + description: Batch job failure + + # Initiate payment plan proposal + /accounts/{accountId}/payment-plan-proposal: + post: + summary: Initiate payment plan proposal for an eligible account + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/AccountId' + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentPlanProposalRequest' + responses: + '200': + description: Payment plan proposal initiated and notification sent + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentPlanProposalResponse' + '400': + description: Not eligible for payment plan or already in legal status + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + # Trigger escalation/handoff to collection agency + /agency/handoff: + post: + summary: Handoff eligible accounts to collection agency (API payload always masked) + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AgencyHandoffRequest' + responses: + '200': + description: Handoff successful, only approved fields transmitted + content: + application/json: + schema: + $ref: '#/components/schemas/AgencyHandoffResponse' + '409': + description: Duplicate escalation suppressed by idempotency logic + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '400': + description: Ineligible for handoff, or rejected masking/integrity + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + # Get collection agency user assigned accounts + /agencies/{agencyUser}/accounts: + get: + summary: List assigned accounts for a collection agency user (access controlled, masked data only) + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/AgencyUser' + responses: + '200': + description: List of assigned accounts with masked card data + content: + application/json: + schema: + type: array + items: + type: object + properties: + accountId: + type: string + customerName: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + required: [accountId, maskedCard] + '403': + description: Access denied for unassigned accounts + + # Incident/Ticket endpoint for undeliverable notifications + /incidents: + post: + summary: Raise an incident due to failed or undeliverable notifications + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + accountId: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + reason: + type: string + responses: + '201': + description: Incident created for undeliverable notification + content: + application/json: + schema: + $ref: '#/components/schemas/IncidentReport' + + # Fetch audit logs for given account or event + /accounts/{accountId}/audit: + get: + summary: Get immutable audit logs for account events (always masked) + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/AccountId' + responses: + '200': + description: Audit log entries (masked) + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/AuditLogEntry' + + # Simulated endpoint for notification template/content validation + /notifications/validate: + post: + summary: Validate notification content for correct field presence and masking (template QA) + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + content: + type: string + fieldsPresent: + type: array + items: + type: string + maskedCard: + type: string + responses: + '200': + description: Notification content ok (compliant) + content: + application/json: + schema: + type: object + properties: + valid: + type: boolean + '400': + description: Masking or required field violation + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + # Legal documents retrieval endpoint + /accounts/{accountId}/legal-documents: + get: + summary: Retrieve all legal documents generated for an account (masked card data only) + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/AccountId' + responses: + '200': + description: List of legal documents in PDF or e-doc format pointers, content is masked + content: + application/json: + schema: + type: array + items: + type: object + properties: + documentId: + type: string + documentType: + type: string + enum: [PDF, E-Doc] + url: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + required: [documentId, url, maskedCard] + # Outbound message validation endpoint for anti-PAN-leak + /outbound/validate: + post: + summary: Check outbound communication for full card number leaks (block/quarantine API) + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + content: + type: string + responses: + '200': + description: No PAN found, safe to deliver + content: + application/json: + schema: + type: object + properties: + compliant: + type: boolean + example: true + '400': + description: PAN found, message blocked/quarantined + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + # Endpoint for retry and logging of notification transmission failures + /notifications/{notificationId}/retry: + post: + summary: Retry failed notification transmission, ensuring only masked card is present in logs + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/NotificationId' + responses: + '200': + description: Retry executed, status and audit updated + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationResponse' + + # Outbound notification event consistency across accounts/cross-customer protection + /notifications/batch/send: + post: + summary: Send notification batch for multiple accounts (cross-customer data prevention) + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/NotificationRequest' + responses: + '200': + description: Notifications sent for each account, each with correct/masked data + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/NotificationResponse' + '409': + description: Attempt to send cross-customer data detected and prevented + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + + # State transition endpoint (Due → Overdue → Collection, etc.) + /accounts/{accountId}/state-transition: + post: + summary: Explicitly advance or query account state transitions, enforcing masking and business rules + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/AccountId' + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + requestedTransition: + type: string + enum: [Due, Overdue, Collection, PaymentPlan, Agency, Legal] + responses: + '200': + description: State transition completed + content: + application/json: + schema: + type: object + properties: + previousState: + type: string + newState: + type: string + maskedCard: + $ref: '#/components/schemas/MaskedCard' + result: + type: string + '400': + description: Invalid or ineligible transition (e.g., cannot bypass states) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse'