Skip to content

Commit 8eb7464

Browse files
committed
Include fee_acknowledged flag to the evidence data for Visa Compliance disputes
1 parent a0f0fe7 commit 8eb7464

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

includes/wc-payment-api/class-wc-payments-api-client.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,12 +677,29 @@ public function update_dispute( $dispute_id, $evidence, $submit, $metadata ) {
677677
);
678678
}
679679

680+
// Fetch the dispute to check if it's a Visa compliance (noncompliant) dispute.
681+
$dispute_details = $this->get_dispute( $dispute_id );
682+
if ( is_wp_error( $dispute_details ) ) {
683+
return $dispute_details;
684+
}
685+
680686
$request = [
681687
'evidence' => $evidence,
682688
'submit' => $submit,
683689
'metadata' => $metadata,
684690
];
685691

692+
// Add Visa compliance flag for noncompliant disputes.
693+
if ( isset( $dispute_details['reason'] ) && 'noncompliant' === $dispute_details['reason'] ) {
694+
$request['evidence_details'] = [
695+
'enhanced_eligibility' => [
696+
'visa_compliance' => [
697+
'status' => 'fee_acknowledged',
698+
],
699+
],
700+
];
701+
}
702+
686703
$dispute = $this->request( $request, self::DISPUTES_API . '/' . $dispute_id, self::POST );
687704
// Invalidate the dispute caches.
688705
\WC_Payments::get_database_cache()->delete_dispute_caches();

tests/unit/wc-payment-api/test-class-wc-payments-api-client.php

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,152 @@ public function test_determine_suggested_product_type( $order_items, $expected_p
13231323
$this->assertEquals( $expected_product_type, $result );
13241324
}
13251325

1326+
/**
1327+
* Test updating a dispute with or without Visa compliance flag based on dispute reason.
1328+
*
1329+
* @dataProvider data_update_dispute_visa_compliance
1330+
* @throws API_Exception
1331+
*/
1332+
public function test_update_dispute_visa_compliance_flag( $dispute_reason, $should_have_flag ) {
1333+
$dispute_id = 'dp_test123';
1334+
$evidence = [
1335+
'product_description' => 'Product description',
1336+
'customer_name' => 'Customer Name',
1337+
'uncategorized_text' => 'Additional details',
1338+
'customer_email_address' => '[email protected]',
1339+
'customer_purchase_ip' => '1.2.3.4',
1340+
'billing_address' => '123 Main St',
1341+
'receipt' => 'file_123',
1342+
'customer_signature' => 'file_456',
1343+
'shipping_documentation' => 'file_789',
1344+
];
1345+
$submit = true;
1346+
$metadata = [ 'order_id' => '123' ];
1347+
1348+
// Mock the dispute cache to avoid errors.
1349+
$mock_cache = $this->createMock( \WCPay\Database_Cache::class );
1350+
$mock_cache->method( 'delete_dispute_caches' )
1351+
->willReturn( null );
1352+
1353+
// Replace the database cache in the container.
1354+
wcpay_get_test_container()->replace( \WCPay\Database_Cache::class, $mock_cache );
1355+
1356+
// Mock the HTTP client to first return dispute details, then accept the update.
1357+
$this->mock_http_client
1358+
->expects( $this->exactly( 2 ) )
1359+
->method( 'remote_request' )
1360+
->willReturnCallback(
1361+
function ( $data, $body ) use ( $dispute_id, $evidence, $metadata, $dispute_reason, $should_have_flag ) {
1362+
// First call: GET dispute to check the reason.
1363+
if ( strpos( $data['url'], '/disputes/' . $dispute_id ) !== false && 'GET' === $data['method'] ) {
1364+
return [
1365+
'body' => wp_json_encode(
1366+
[
1367+
'id' => $dispute_id,
1368+
'charge' => 'ch_test123',
1369+
'reason' => $dispute_reason,
1370+
'status' => 'needs_response',
1371+
]
1372+
),
1373+
'response' => [
1374+
'code' => 200,
1375+
'message' => 'OK',
1376+
],
1377+
];
1378+
}
1379+
1380+
// Second call: POST to update the dispute.
1381+
if ( strpos( $data['url'], '/disputes/' . $dispute_id ) !== false && 'POST' === $data['method'] ) {
1382+
// Validate the request parameters.
1383+
$this->validate_default_remote_request_params(
1384+
$data,
1385+
'https://public-api.wordpress.com/wpcom/v2/sites/%s/wcpay/disputes/' . $dispute_id,
1386+
'POST'
1387+
);
1388+
1389+
// Validate the body contains or doesn't contain the Visa compliance flag.
1390+
$decoded = json_decode( $body, true );
1391+
1392+
// Verify the standard evidence is present.
1393+
$this->assertArrayHasKey( 'evidence', $decoded );
1394+
$this->assertEquals( $evidence, $decoded['evidence'] );
1395+
1396+
// Verify the submit flag is set.
1397+
$this->assertArrayHasKey( 'submit', $decoded );
1398+
$this->assertTrue( $decoded['submit'] );
1399+
1400+
// Verify the metadata is present.
1401+
$this->assertArrayHasKey( 'metadata', $decoded );
1402+
$this->assertEquals( $metadata, $decoded['metadata'] );
1403+
1404+
// Verify the Visa compliance flag presence based on dispute reason.
1405+
if ( $should_have_flag ) {
1406+
$this->assertArrayHasKey( 'evidence_details', $decoded );
1407+
$this->assertArrayHasKey( 'enhanced_eligibility', $decoded['evidence_details'] );
1408+
$this->assertArrayHasKey( 'visa_compliance', $decoded['evidence_details']['enhanced_eligibility'] );
1409+
$this->assertArrayHasKey( 'status', $decoded['evidence_details']['enhanced_eligibility']['visa_compliance'] );
1410+
$this->assertEquals( 'fee_acknowledged', $decoded['evidence_details']['enhanced_eligibility']['visa_compliance']['status'] );
1411+
} else {
1412+
$this->assertArrayNotHasKey( 'evidence_details', $decoded );
1413+
}
1414+
1415+
return [
1416+
'body' => wp_json_encode(
1417+
[
1418+
'id' => $dispute_id,
1419+
'charge' => 'ch_test123',
1420+
'reason' => $dispute_reason,
1421+
'status' => 'needs_response',
1422+
'evidence' => $evidence,
1423+
]
1424+
),
1425+
'response' => [
1426+
'code' => 200,
1427+
'message' => 'OK',
1428+
],
1429+
];
1430+
}
1431+
1432+
return [
1433+
'body' => wp_json_encode( [] ),
1434+
'response' => [
1435+
'code' => 404,
1436+
'message' => 'Not Found',
1437+
],
1438+
];
1439+
}
1440+
);
1441+
1442+
// Call the method under test.
1443+
$result = $this->payments_api_client->update_dispute( $dispute_id, $evidence, $submit, $metadata );
1444+
1445+
// Assert the response is correct.
1446+
$this->assertEquals( $dispute_id, $result['id'] );
1447+
1448+
// Clean up.
1449+
wcpay_get_test_container()->reset_all_replacements();
1450+
}
1451+
1452+
/**
1453+
* Data provider for test_update_dispute_visa_compliance_flag.
1454+
*/
1455+
public function data_update_dispute_visa_compliance() {
1456+
return [
1457+
'noncompliant_dispute_should_have_flag' => [
1458+
'dispute_reason' => 'noncompliant',
1459+
'should_have_flag' => true,
1460+
],
1461+
'fraudulent_dispute_should_not_have_flag' => [
1462+
'dispute_reason' => 'fraudulent',
1463+
'should_have_flag' => false,
1464+
],
1465+
'product_unacceptable_dispute_should_not_have_flag' => [
1466+
'dispute_reason' => 'product_unacceptable',
1467+
'should_have_flag' => false,
1468+
],
1469+
];
1470+
}
1471+
13261472
/**
13271473
* Data provider for test_determine_suggested_product_type.
13281474
*/

0 commit comments

Comments
 (0)