diff --git a/CHANGELOG.md b/CHANGELOG.md index 34ee593..a7c61c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ CHANGELOG ========= +3.1.0 +------------------ + +* Updated `MaxMind\MinFraud\ReportTransaction` to make the `ip_address` + parameter optional. Now the `tag` and at least one of the following + parameters must be supplied: `ipAddress`, `maxmindId`, `minfraudId`, + `transactionId`. + 3.0.1 (2024-05-02) ------------------ diff --git a/README.md b/README.md index 9c834a7..fce5f4e 100644 --- a/README.md +++ b/README.md @@ -282,8 +282,9 @@ All externally visible exceptions are in the `\MaxMind\Exception` namespace. The possible exceptions are: * `InvalidInputException` - This will be thrown when the `->report()` method is - called with invalid input data or when the required `ip_address` or `tag` - fields are missing. + called with invalid input data or when the required fields are missing. The + required fields are `tag` and one or more of the following: `ipAddress`, + `maxmindId`, `minfraudId`, or `transactionId`. * `AuthenticationException` - This will be thrown on calling `->report()`, when the server is unable to authenticate the request, e.g., if the license key or account ID is invalid. diff --git a/src/MinFraud/ReportTransaction.php b/src/MinFraud/ReportTransaction.php index d52e6e2..d92e99a 100644 --- a/src/MinFraud/ReportTransaction.php +++ b/src/MinFraud/ReportTransaction.php @@ -46,9 +46,11 @@ public function __construct( * @param array $values An array of transaction parameters. The keys are the same * as the JSON keys. You may use either this or the named * arguments, but not both. - * @param string $ipAddress Required. The IP address of the customer placing the + * @param string $ipAddress Optional. The IP address of the customer placing the * order. This should be passed as a string like - * "44.55.66.77" or "2001:db8::2:1". + * "44.55.66.77" or "2001:db8::2:1". This field is not + * required if you provide at least one of the transaction's + * `maxmindId`, `minfraudId`, or `transactionId`. * @param string $tag Required. A string indicating the likelihood that a * transaction may be fraudulent. Possible values: * not_fraud, suspected_fraud, spam_or_abuse, or @@ -57,24 +59,28 @@ public function __construct( * processor indicating the reason for the chargeback. * @param string $maxmindId Optional. A unique eight character string identifying * a minFraud Standard or Premium request. These IDs are - * returned in the maxmindID field of a response for a + * returned in the `maxmindID` field of a response for a * successful minFraud request. This field is not - * required, but you are encouraged to provide it, if - * possible. + * required if you provide at least one of the transaction's + * `ipAddress`, `minfraudId`, or `transactionId`. You are + * encouraged to provide it, if possible. * @param string $minfraudId Optional. A UUID that identifies a minFraud Score, * minFraud Insights, or minFraud Factors request. This * ID is returned at /id in the response. This field is - * not required, but you are encouraged to provide it if - * the request was made to one of these services. + * not required if you provide at least one of the transaction's + * `ipAddress`, `maxmindId`, or `transactionId`. You are + * encouraged to provide it if the request was made to one of + * these services. * @param string $notes Optional. Your notes on the fraud tag associated with * the transaction. We manually review many reported * transactions to improve our scoring for you so any * additional details to help us understand context are * helpful. * @param string $transactionId Optional. The transaction ID you originally passed to - * minFraud. This field is not required, but you are - * encouraged to provide it or the transaction's - * maxmind_id or minfraud_id. + * minFraud. This field is not required if you provide at + * least one of the transaction's `ipAddress`, `maxmindId`, or + * `minfraudId`. You are encouraged to provide it or the + * transaction's `maxmindId` or `minfraudId`. * * @throws InvalidInputException when the request has missing or invalid * data @@ -120,14 +126,12 @@ public function report( $values['chargeback_code'] = $chargebackCode; } - if ($ipAddress === null) { - // This is required so we always throw an exception if it is not set - throw new InvalidInputException('An IP address is required'); - } - if (!filter_var($ipAddress, \FILTER_VALIDATE_IP)) { - $this->maybeThrowInvalidInputException("$ipAddress is an invalid IP address"); + if ($ipAddress !== null) { + if (!filter_var($ipAddress, \FILTER_VALIDATE_IP)) { + $this->maybeThrowInvalidInputException("$ipAddress is an invalid IP address"); + } + $values['ip_address'] = $ipAddress; } - $values['ip_address'] = $ipAddress; if ($maxmindId !== null) { if (\strlen($maxmindId) !== 8) { @@ -166,6 +170,18 @@ public function report( $values['transaction_id'] = $transactionId; } + // One of these fields is required so we always throw an exception if one is not set + if (($ipAddress === null || $ipAddress === '') + && ($minfraudId === null || $minfraudId === '') + && ($maxmindId === null || $maxmindId === '') + && ($transactionId === null || $transactionId === '') + ) { + throw new InvalidInputException( + 'The user must pass at least one of the following: ' . + 'ipAddress, minfraudId, maxmindId, transactionId.' + ); + } + $url = self::$basePath . 'transactions/report'; $this->client->post('ReportTransaction', $url, $values); } diff --git a/tests/MaxMind/Test/MinFraud/ReportTransaction/ReportTransactionTest.php b/tests/MaxMind/Test/MinFraud/ReportTransaction/ReportTransactionTest.php index 76982c9..6a93247 100644 --- a/tests/MaxMind/Test/MinFraud/ReportTransaction/ReportTransactionTest.php +++ b/tests/MaxMind/Test/MinFraud/ReportTransaction/ReportTransactionTest.php @@ -62,13 +62,42 @@ public function testRequestsWithNulls(): void ); } + public function testRequiredFields(): void + { + $this->expectNotToPerformAssertions(); + + $req = [ + 'ip_address' => '1.1.1.1', + 'tag' => 'not_fraud', + ]; + $this->createReportTransactionRequest($req, 1)->report($req); + + $req = [ + 'maxmind_id' => '12345678', + 'tag' => 'not_fraud', + ]; + $this->createReportTransactionRequest($req, 1)->report($req); + + $req = [ + 'minfraud_id' => '58fa38d8-4b87-458b-a22b-f00eda1aa20d', + 'tag' => 'not_fraud', + ]; + $this->createReportTransactionRequest($req, 1)->report($req); + + $req = [ + 'tag' => 'not_fraud', + 'transaction_id' => 'abc123', + ]; + $this->createReportTransactionRequest($req, 1)->report($req); + } + /** * @dataProvider requestsMissingRequiredFields */ public function testMissingRequiredFields(array $req): void { $this->expectException(InvalidInputException::class); - $this->expectExceptionMessageMatches('/Expected|is required/'); + $this->expectExceptionMessageMatches('/Expected|is required|must pass at least one of the following/'); $this->createReportTransactionRequest( $req, @@ -82,7 +111,7 @@ public function testMissingRequiredFields(array $req): void public function testMissingRequiredFieldsWithoutValidation(array $req): void { $this->expectException(InvalidInputException::class); - $this->expectExceptionMessageMatches('/Expected|is required/'); + $this->expectExceptionMessageMatches('/Expected|is required|must pass at least one of the following/'); $this->createReportTransactionRequest( $req, @@ -94,7 +123,7 @@ public function testMissingRequiredFieldsWithoutValidation(array $req): void public static function requestsMissingRequiredFields(): array { return [ - 'Missing ip_address' => [ + 'Missing one of ip_address, maxmind_id, minfraud_id, or transaction_id' => [ ['tag' => 'not_fraud'], ], 'Missing tag' => [