Skip to content

Commit a66cc4d

Browse files
authored
Merge pull request #227 from maxmind/wstorey/eng-2872-eventparty-and-paymentmethod-minfraud-inputs-are-supported
Add /event/party, /payment/method, and new /event/type values
2 parents c4e0908 + 9c960d9 commit a66cc4d

5 files changed

Lines changed: 136 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ CHANGELOG
55
------------------
66

77
* Added `securepay` to the payment processor validation.
8+
* Added `credit_application` and `fund_transfer` to event type validation.
9+
* Added the input `/event/party`. This is the party submitting the
10+
transaction.
11+
* Added the input `/payment/method`. This is the payment method associated
12+
with the transaction.
813

914
3.3.0 (2025-05-23)
1015
------------------

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ $request = $mf->withDevice(
154154
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36',
155155
acceptLanguage: 'en-US,en;q=0.8'
156156
)->withEvent(
157+
party: 'customer',
157158
transactionId: 'txn3134133',
158159
shopId: 's2123',
159160
time: '2012-04-12T23:20:50+00:00',
@@ -190,6 +191,7 @@ $request = $mf->withDevice(
190191
phoneCountryCode: '1',
191192
deliverySpeed: 'same_day'
192193
)->withPayment(
194+
method: 'card',
193195
processor: 'stripe',
194196
wasAuthorized: false,
195197
declineCode: 'invalid number'

src/MinFraud.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,19 @@ public function withDevice(
297297
* are:
298298
* - `account_creation`
299299
* - `account_login`
300+
* - `credit_application`
300301
* - `email_change`
302+
* - `fund_transfer`
301303
* - `password_reset`
302304
* - `payout_change`
303305
* - `purchase`
304306
* - `recurring_purchase`
305307
* - `referral`
306308
* - `survey`
309+
* @param string|null $party The party submitting the transaction. The valid values
310+
* are:
311+
* - `agent`
312+
* - `customer`
307313
*
308314
* @return MinFraud A new immutable MinFraud object. This object is a clone of
309315
* the original with additional data.
@@ -317,13 +323,15 @@ public function withEvent(
317323
?string $time = null,
318324
?string $transactionId = null,
319325
?string $type = null,
326+
?string $party = null,
320327
): self {
321328
if (\count($values) !== 0) {
322329
if (\func_num_args() !== 1) {
323330
throw new \InvalidArgumentException(
324331
'You may only provide the $values array or named arguments, not both.',
325332
);
326333
}
334+
$party = $this->remove($values, 'party');
327335
$shopId = $this->remove($values, 'shop_id');
328336
$time = $this->remove($values, 'time');
329337
$transactionId = $this->remove($values, 'transaction_id');
@@ -332,6 +340,13 @@ public function withEvent(
332340
$this->verifyEmpty($values);
333341
}
334342

343+
if ($party !== null) {
344+
if (!\in_array($party, ['agent', 'customer'], true)) {
345+
$this->maybeThrowInvalidInputException("$party is not a valid party");
346+
}
347+
$values['party'] = $party;
348+
}
349+
335350
if ($shopId !== null) {
336351
$values['shop_id'] = $shopId;
337352
}
@@ -354,7 +369,9 @@ public function withEvent(
354369
if (!\in_array($type, [
355370
'account_creation',
356371
'account_login',
372+
'credit_application',
357373
'email_change',
374+
'fund_transfer',
358375
'password_reset',
359376
'payout_change',
360377
'purchase',
@@ -753,6 +770,18 @@ public function withShipping(
753770
* @param bool|null $wasAuthorized The authorization outcome from the payment
754771
* processor. If the transaction has not yet been
755772
* approved or denied, do not include this field.
773+
* @param string|null $method The payment method associated with the transaction.
774+
* The valid values are:
775+
* - `bank_debit`
776+
* - `bank_redirect`
777+
* - `bank_transfer`
778+
* - `buy_now_pay_later`
779+
* - `card`
780+
* - `crypto`
781+
* - `digital_wallet`
782+
* - `gift_card`
783+
* - `real_time_payment`
784+
* - `rewards`
756785
*
757786
* @return MinFraud A new immutable MinFraud object. This object is
758787
* a clone of the original with additional data.
@@ -762,6 +791,7 @@ public function withPayment(
762791
?string $declineCode = null,
763792
?string $processor = null,
764793
?bool $wasAuthorized = null,
794+
?string $method = null,
765795
): self {
766796
if (\count($values) !== 0) {
767797
if (\func_num_args() !== 1) {
@@ -771,6 +801,7 @@ public function withPayment(
771801
}
772802

773803
$declineCode = $this->remove($values, 'decline_code');
804+
$method = $this->remove($values, 'method');
774805
$processor = $this->remove($values, 'processor');
775806
$wasAuthorized = $this->remove($values, 'was_authorized', ['boolean']);
776807

@@ -781,6 +812,24 @@ public function withPayment(
781812
$values['decline_code'] = $declineCode;
782813
}
783814

815+
if ($method !== null) {
816+
if (!\in_array($method, [
817+
'bank_debit',
818+
'bank_redirect',
819+
'bank_transfer',
820+
'buy_now_pay_later',
821+
'card',
822+
'crypto',
823+
'digital_wallet',
824+
'gift_card',
825+
'real_time_payment',
826+
'rewards',
827+
], true)) {
828+
$this->maybeThrowInvalidInputException("$method is not a valid payment method");
829+
}
830+
$values['method'] = $method;
831+
}
832+
784833
if ($processor !== null) {
785834
if (!\in_array($processor, [
786835
'adyen',

tests/MaxMind/Test/MinFraudTest.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public function testFullInsightsRequestUsingNamedArgs(string $class, string $ser
136136
domain: 'maxmind.com'
137137
)
138138
->withEvent(
139+
party: 'customer',
139140
transactionId: 'txn3134133',
140141
shopId: 's2123',
141142
time: '2014-04-12T23:20:50+00:00',
@@ -152,6 +153,7 @@ public function testFullInsightsRequestUsingNamedArgs(string $class, string $ser
152153
referrerUri: 'http://www.amazon.com/'
153154
)
154155
->withPayment(
156+
method: 'card',
155157
processor: 'stripe',
156158
wasAuthorized: false,
157159
declineCode: 'invalid number'
@@ -1102,7 +1104,9 @@ public static function goodEventTypes(): array
11021104
return [
11031105
['account_creation'],
11041106
['account_login'],
1107+
['credit_application'],
11051108
['email_change'],
1109+
['fund_transfer'],
11061110
['password_reset'],
11071111
['payout_change'],
11081112
['purchase'],
@@ -1123,6 +1127,39 @@ public function testBadEventType(): void
11231127
)->withEvent(['type' => 'unknown']);
11241128
}
11251129

1130+
/**
1131+
* @dataProvider goodEventParties
1132+
*/
1133+
public function testGoodEventParty(string $good): void
1134+
{
1135+
$this->createMinFraudRequestWithFullResponse(
1136+
'insights',
1137+
0
1138+
)->withEvent(['party' => $good]);
1139+
}
1140+
1141+
/**
1142+
* @return array<list<string>>
1143+
*/
1144+
public static function goodEventParties(): array
1145+
{
1146+
return [
1147+
['agent'],
1148+
['customer'],
1149+
];
1150+
}
1151+
1152+
public function testBadEventParty(): void
1153+
{
1154+
$this->expectException(InvalidInputException::class);
1155+
$this->expectExceptionMessage('valid party');
1156+
1157+
$this->createMinFraudRequestWithFullResponse(
1158+
'insights',
1159+
0
1160+
)->withEvent(['party' => 'unknown']);
1161+
}
1162+
11261163
/**
11271164
* @dataProvider badCurrency
11281165
*/
@@ -1186,6 +1223,47 @@ public function testBadPaymentProcessor(): void
11861223
)->withPayment(['processor' => 'unknown']);
11871224
}
11881225

1226+
/**
1227+
* @dataProvider goodPaymentMethods
1228+
*/
1229+
public function testGoodPaymentMethod(string $good): void
1230+
{
1231+
$this->createMinFraudRequestWithFullResponse(
1232+
'insights',
1233+
0
1234+
)->withPayment(['method' => $good]);
1235+
}
1236+
1237+
/**
1238+
* @return array<list<string>>
1239+
*/
1240+
public static function goodPaymentMethods(): array
1241+
{
1242+
return [
1243+
['bank_debit'],
1244+
['bank_redirect'],
1245+
['bank_transfer'],
1246+
['buy_now_pay_later'],
1247+
['card'],
1248+
['crypto'],
1249+
['digital_wallet'],
1250+
['gift_card'],
1251+
['real_time_payment'],
1252+
['rewards'],
1253+
];
1254+
}
1255+
1256+
public function testBadPaymentMethod(): void
1257+
{
1258+
$this->expectException(InvalidInputException::class);
1259+
$this->expectExceptionMessage('valid payment method');
1260+
1261+
$this->createMinFraudRequestWithFullResponse(
1262+
'insights',
1263+
0
1264+
)->withPayment(['method' => 'unknown']);
1265+
}
1266+
11891267
/**
11901268
* @dataProvider validAmounts
11911269
*/

tests/data/minfraud/full-request.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"event": {
3+
"party": "customer",
34
"transaction_id": "txn3134133",
45
"shop_id": "s2123",
56
"time": "2014-04-12T23:20:50+00:00",
@@ -41,6 +42,7 @@
4142
"delivery_speed": "same_day"
4243
},
4344
"payment": {
45+
"method": "card",
4446
"processor": "stripe",
4547
"was_authorized": false,
4648
"decline_code": "invalid number"

0 commit comments

Comments
 (0)