-
Notifications
You must be signed in to change notification settings - Fork 72
feat: implement evidence matrix for dispute document recommendations #11181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
feat: implement evidence matrix for dispute document recommendations #11181
Conversation
Test the buildOption 1. Jetpack Beta
Option 2. Jurassic Ninja - available for logged-in A12s🚀 Launch a JN site with this branch 🚀 ℹ️ Install this Tampermonkey script to get more options. Build info:
Note: the build is updated when a new commit is pushed to this PR. |
|
Size Change: +50.6 kB (+6%) 🔍 Total Size: 927 kB
ℹ️ View Unchanged
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR refactors the dispute evidence recommendation system by extracting constants and introducing a feature-flagged evidence matrix for more granular control over recommended document fields based on dispute reason and product type combinations.
- Extracts
DOCUMENT_FIELD_KEYSconstants into a separate module for better code organization - Introduces an evidence matrix system that maps dispute reasons and product types to specific recommended document fields
- Adds comprehensive test coverage for the new feature-flagged evidence matrix functionality
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
client/disputes/new-evidence/document-field-keys.ts |
New file extracting document field key constants previously defined inline |
client/disputes/new-evidence/recommended-document-fields.ts |
Refactored to import constants from separate module and integrate feature-flagged evidence matrix lookup |
client/disputes/new-evidence/evidence-matrix.ts |
New file implementing evidence matrix mapping dispute reasons and product types to recommended document fields |
client/disputes/new-evidence/__tests__/recommended-document-fields.test.ts |
Added test setup for feature flag mocking and comprehensive test coverage for evidence matrix scenarios |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'woocommerce-payments' | ||
| ), | ||
| description: __( | ||
| 'Proof of past undisputed transactions from the same customer, with matching billing and device details', |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing period at the end of the description. For consistency with other descriptions in this file and throughout the codebase, this description should end with a period.
| 'Proof of past undisputed transactions from the same customer, with matching billing and device details', | |
| 'Proof of past undisputed transactions from the same customer, with matching billing and device details.', |
…subscription_canceled and duplicate reasons
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ? [ | ||
| // For is_duplicate: Order receipt, Refund receipt, Refund policy | ||
| { | ||
| key: DOCUMENT_FIELD_KEYS.RECEIPT, | ||
| label: __( | ||
| 'Order receipt', | ||
| 'woocommerce-payments' | ||
| ), | ||
| description: __( | ||
| "A copy of the customer's receipt, which can be found in the receipt history for this transaction.", | ||
| 'woocommerce-payments' | ||
| ), | ||
| order: 10, | ||
| }, | ||
| { | ||
| key: | ||
| DOCUMENT_FIELD_KEYS.REFUND_RECEIPT_DOCUMENTATION, | ||
| key: DOCUMENT_FIELD_KEYS.ACCESS_ACTIVITY_LOG, | ||
| label: __( | ||
| 'Refund receipt', | ||
| 'Proof of active subscription', | ||
| 'woocommerce-payments' | ||
| ), | ||
| description: __( | ||
| 'A confirmation that the refund was processed.', | ||
| 'Any documents showing the billing history, subscription status, or cancellation logs, for example.', | ||
| 'woocommerce-payments' | ||
| ), | ||
| order: 15, | ||
| order: 30, | ||
| }, | ||
| { | ||
| key: DOCUMENT_FIELD_KEYS.REFUND_POLICY, | ||
| label: __( | ||
| 'Refund policy', | ||
| 'Store refund policy', | ||
| 'woocommerce-payments' | ||
| ), | ||
| description: __( | ||
| "A screenshot of your store's refund policy.", | ||
| 'woocommerce-payments' | ||
| ), | ||
| order: 20, | ||
| order: 40, | ||
| }, | ||
| ] | ||
| : [ | ||
| // For is_not_duplicate: Order receipt, Any additional receipts, Customer communication, Refund policy, Other documents | ||
| { | ||
| key: | ||
| DOCUMENT_FIELD_KEYS.DUPLICATE_CHARGE_DOCUMENTATION, | ||
| key: DOCUMENT_FIELD_KEYS.CANCELLATION_POLICY, | ||
| label: __( | ||
| 'Any additional receipts', | ||
| 'Terms of service', | ||
| 'woocommerce-payments' | ||
| ), | ||
| description: __( | ||
| 'Receipt(s) for any other order(s) from this customer.', | ||
| "A screenshot of your store's terms of service.", | ||
| 'woocommerce-payments' | ||
| ), | ||
| order: 12, | ||
| order: 50, | ||
| }, |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback logic for duplicate disputes with is_duplicate status appears incorrect. When the feature flag is OFF and duplicateStatus === 'is_duplicate', this returns fields for subscription-related disputes (ACCESS_ACTIVITY_LOG with "Proof of active subscription" label, cancellation_policy), which don't make sense for duplicate charge disputes.
According to the PR description and test cases, when the feature flag is enabled, the is_duplicate scenario should show: "Order receipt, Refund receipt, Refund policy". The fallback should mirror this behavior or provide appropriate duplicate-specific fields, not subscription-related fields.
| 'woocommerce-payments' | ||
| ), | ||
| description: __( | ||
| 'Proof of past undisputed transactions from the same customer, with matching billing and device details', |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing period at the end of the sentence. The description should end with a period for consistency with other field descriptions.
| 'Proof of past undisputed transactions from the same customer, with matching billing and device details', | |
| 'Proof of past undisputed transactions from the same customer, with matching billing and device details.', |
The duplicate dispute entries from develop (eb1b9ca, 95b3cc1) were specifically for booking_reservation product type, not defaults for all product types. Changes: - Rename default__is_duplicate to booking_reservation__is_duplicate - Rename default__is_not_duplicate to booking_reservation__is_not_duplicate - Remove fallback to default entries in getMatrixFields - Update tests to pass booking_reservation as productType - Fix physical_product test to expect trunk fallback behavior (6 fields) This ensures unimplemented productTypes (like physical_product) fall back to trunk behavior, maintaining consistency with the incremental implementation approach. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| if ( isFeatureFlagEnabled ) { | ||
| // For duplicate disputes, use duplicateStatus for composite key lookup | ||
| // and fall back to 'default' productType if not provided |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "fall back to 'default' productType if not provided" is misleading. The value 'default' doesn't actually exist in the evidence matrix - it's just used as a placeholder to trigger the matrix lookup, which will return undefined and cause the function to fall back to trunk behavior. Consider updating the comment to clarify this, e.g., "use 'default' as placeholder to attempt matrix lookup (will fall back if no entry exists)"
| // and fall back to 'default' productType if not provided | |
| // use 'default' as placeholder to attempt matrix lookup (will fall back if no entry exists) |
Fixes WOOPMNT-5430
Changes proposed in this Pull Request
This PR introduces a matrix-based architecture for managing dispute evidence document recommendations based on dispute reason and product type combinations.
Why this change is needed:
The dispute challenge form needs to show different recommended evidence documents depending on the combination of dispute reason (fraudulent, duplicate, subscription_canceled, etc.) and product type (booking_reservation, physical_product, etc.). Previously, this logic was spread across multiple conditionals. This matrix approach provides:
What this change does:
evidence-matrix.ts) that maps[reason][productType]to recommended document fieldsDOCUMENT_FIELD_KEYSto a separate file to avoid circular dependenciesgetRecommendedDocumentFields()to use the matrix when availablefraudulent+booking_reservation(WOOPMNT-5430):subscription_canceled+multiple(no subscription logs)subscription_canceled+other(simplified fields)duplicate+booking_reservationentries for bothis_duplicateandis_not_duplicatescenariosFallback behavior:
This allows incremental implementation - each
[reason][productType]combination can be added to the matrix task by task, while unimplemented combinations safely fall back to trunk behavior.Trade-offs:
productType__status) are used for status-dependent lookups (duplicate disputes) rather than a nested structure, keeping the lookup simple while supporting the additional dimensionHow can this code break?
What are we doing to make sure this code doesn't break?
isDisputeAdditionalEvidenceTypesEnabledTesting instructions
Prerequisites:
Enable the feature flag:
Test cases:
Fraudulent + Booking/Reservation (new feature - WOOPMNT-5430):
fraudulentfor a booking/reservation productSubscription Canceled + Multiple:
subscription_canceledfor an order with multiple productsSubscription Canceled + Other:
subscription_canceledfor an "other" product typeDuplicate + Booking/Reservation + Is Duplicate:
Duplicate + Booking/Reservation + Is Not Duplicate:
Feature flag OFF (backward compatibility):
wp option delete _wcpay_feature_dispute_additional_evidence_typesUnimplemented combinations fall back to trunk:
subscription_canceled+physical_productduplicate+physical_productnpm run changelogto add a changelog file, choosepatchto leave it empty if the change is not significant.Post merge