From b84b91e73cd450e443d9dc0d70735cbcb46f1e36 Mon Sep 17 00:00:00 2001 From: William Storey Date: Tue, 16 Sep 2025 21:56:10 +0000 Subject: [PATCH 1/4] Add CREDIT_APPLICATION and FUND_TRANSFER to Event.Type enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added two new event types to support credit application submissions and fund transfer transactions in the minFraud API. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- CHANGELOG.md | 1 + src/main/java/com/maxmind/minfraud/request/Event.java | 8 ++++++++ src/test/java/com/maxmind/minfraud/request/EventTest.java | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69bb5701..cc5badf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ CHANGELOG `FactorsResponse.getSubscores()` method. Use `getRiskScoreReasons()` instead. * BREAKING: Java 17 is now required (previously Java 11). +* Added `CREDIT_APPLICATION` and `FUND_TRANSFER` to the `Event.Type` enum. 3.9.0 ------------------ diff --git a/src/main/java/com/maxmind/minfraud/request/Event.java b/src/main/java/com/maxmind/minfraud/request/Event.java index d49d8304..6784d9a0 100644 --- a/src/main/java/com/maxmind/minfraud/request/Event.java +++ b/src/main/java/com/maxmind/minfraud/request/Event.java @@ -142,10 +142,18 @@ public enum Type { * The account was logged into */ ACCOUNT_LOGIN, + /** + * A credit application was submitted + */ + CREDIT_APPLICATION, /** * The account email was changed */ EMAIL_CHANGE, + /** + * A fund transfer was initiated + */ + FUND_TRANSFER, /** * The account password was reset */ diff --git a/src/test/java/com/maxmind/minfraud/request/EventTest.java b/src/test/java/com/maxmind/minfraud/request/EventTest.java index c91b1b5d..1199ab26 100644 --- a/src/test/java/com/maxmind/minfraud/request/EventTest.java +++ b/src/test/java/com/maxmind/minfraud/request/EventTest.java @@ -43,5 +43,11 @@ public void testType() { event = new Builder().type(Type.PAYOUT_CHANGE).build(); assertEquals(Type.PAYOUT_CHANGE, event.getType()); + + event = new Builder().type(Type.CREDIT_APPLICATION).build(); + assertEquals(Type.CREDIT_APPLICATION, event.getType()); + + event = new Builder().type(Type.FUND_TRANSFER).build(); + assertEquals(Type.FUND_TRANSFER, event.getType()); } } From 08571ff15e8cdac8280b6fc252bffe04bac89615 Mon Sep 17 00:00:00 2001 From: William Storey Date: Tue, 16 Sep 2025 22:02:04 +0000 Subject: [PATCH 2/4] Add /event/party input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added new party field to indicate whether an agent or customer is submitting the transaction. The party field accepts AGENT and CUSTOMER enum values and is serialized as lowercase in JSON requests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- CHANGELOG.md | 3 ++ README.md | 1 + .../com/maxmind/minfraud/request/Event.java | 41 +++++++++++++++++++ .../maxmind/minfraud/request/EventTest.java | 10 +++++ 4 files changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc5badf4..90415b29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ CHANGELOG instead. * BREAKING: Java 17 is now required (previously Java 11). * Added `CREDIT_APPLICATION` and `FUND_TRANSFER` to the `Event.Type` enum. +* Added the input `/event/party`. This is the party submitting the + transaction. You may provide this using the `party` method on + `Event.Builder`. 3.9.0 ------------------ diff --git a/README.md b/README.md index cf298208..2be004fa 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ Transaction request = new Transaction.Builder( .build() ).event( new Event.Builder() + .party(Event.Party.CUSTOMER) .shopId("2432") .time(new Date()) .transactionId("tr1242") diff --git a/src/main/java/com/maxmind/minfraud/request/Event.java b/src/main/java/com/maxmind/minfraud/request/Event.java index 6784d9a0..1ca0da1a 100644 --- a/src/main/java/com/maxmind/minfraud/request/Event.java +++ b/src/main/java/com/maxmind/minfraud/request/Event.java @@ -12,12 +12,14 @@ */ public final class Event extends AbstractModel { + private final Party party; private final String transactionId; private final String shopId; private final ZonedDateTime time; private final Type type; private Event(Event.Builder builder) { + party = builder.party; transactionId = builder.transactionId; shopId = builder.shopId; time = builder.time; @@ -28,11 +30,21 @@ private Event(Event.Builder builder) { * {@code Builder} creates instances of {@code Event} from values set by the builder's methods. */ public static final class Builder { + Party party; String transactionId; String shopId; ZonedDateTime time; Type type; + /** + * @param party The party submitting the transaction. + * @return The builder object. + */ + public Event.Builder party(Party party) { + this.party = party; + return this; + } + /** * @param id Your internal ID for the transaction. We can use this to locate a specific * transaction in our logs, and it will also show up in email alerts and @@ -90,6 +102,14 @@ public Event build() { } } + /** + * @return The party submitting the transaction. + */ + @JsonProperty("party") + public Party getParty() { + return party; + } + /** * @return The transaction ID. */ @@ -186,4 +206,25 @@ public String toString() { return this.name().toLowerCase(); } } + + /** + * The enumerated event party types. + */ + public enum Party { + /** + * An agent is submitting the transaction + */ + AGENT, + /** + * A customer is submitting the transaction + */ + CUSTOMER; + + /** + * @return a string representation of the object. + */ + public String toString() { + return this.name().toLowerCase(); + } + } } \ No newline at end of file diff --git a/src/test/java/com/maxmind/minfraud/request/EventTest.java b/src/test/java/com/maxmind/minfraud/request/EventTest.java index 1199ab26..bbcdf77b 100644 --- a/src/test/java/com/maxmind/minfraud/request/EventTest.java +++ b/src/test/java/com/maxmind/minfraud/request/EventTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.maxmind.minfraud.request.Event.Builder; +import com.maxmind.minfraud.request.Event.Party; import com.maxmind.minfraud.request.Event.Type; import java.time.ZonedDateTime; import java.util.Date; @@ -10,6 +11,15 @@ public class EventTest { + @Test + public void testParty() { + Event event = new Builder().party(Party.AGENT).build(); + assertEquals(Party.AGENT, event.getParty()); + + event = new Builder().party(Party.CUSTOMER).build(); + assertEquals(Party.CUSTOMER, event.getParty()); + } + @Test public void testTransactionId() { Event event = new Builder().transactionId("t12").build(); From 253d5d15852a268bc6fd84b20ad03da5bae879c0 Mon Sep 17 00:00:00 2001 From: William Storey Date: Tue, 16 Sep 2025 22:06:11 +0000 Subject: [PATCH 3/4] Add /payment/method input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added new method field to specify the payment method associated with the transaction. The method field accepts values like CARD, DIGITAL_WALLET, BUY_NOW_PAY_LATER, CRYPTO, and others, serialized as lowercase with underscores in JSON requests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- CHANGELOG.md | 3 + README.md | 1 + .../com/maxmind/minfraud/request/Payment.java | 73 +++++++++++++++++++ .../maxmind/minfraud/request/PaymentTest.java | 13 ++++ 4 files changed, 90 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90415b29..0bace614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ CHANGELOG * Added the input `/event/party`. This is the party submitting the transaction. You may provide this using the `party` method on `Event.Builder`. +* Added the input `/payment/method`. This is the payment method associated + with the transaction. You may provide this using the `method` method on + `Payment.Builder`. 3.9.0 ------------------ diff --git a/README.md b/README.md index 2be004fa..7684ec97 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ Transaction request = new Transaction.Builder( ).payment( new Payment.Builder() .declineCode("invalid") + .method(Payment.Method.CARD) .processor(Payment.Processor.ADYEN) .wasAuthorized(false) .build() diff --git a/src/main/java/com/maxmind/minfraud/request/Payment.java b/src/main/java/com/maxmind/minfraud/request/Payment.java index 40d0937b..47ac7f26 100644 --- a/src/main/java/com/maxmind/minfraud/request/Payment.java +++ b/src/main/java/com/maxmind/minfraud/request/Payment.java @@ -7,11 +7,13 @@ * The payment information for the transaction. */ public final class Payment extends AbstractModel { + private final Method method; private final Processor processor; private final Boolean wasAuthorized; private final String declineCode; private Payment(Payment.Builder builder) { + method = builder.method; processor = builder.processor; wasAuthorized = builder.wasAuthorized; declineCode = builder.declineCode; @@ -22,10 +24,20 @@ private Payment(Payment.Builder builder) { * methods. */ public static final class Builder { + Method method; Processor processor; Boolean wasAuthorized; String declineCode; + /** + * @param method The payment method used for the transaction. + * @return The builder object. + */ + public Payment.Builder method(Method method) { + this.method = method; + return this; + } + /** * @param processor The payment processor used for the transaction. * @return The builder object. @@ -64,6 +76,14 @@ public Payment build() { } } + /** + * @return The payment method. + */ + @JsonProperty("method") + public Method getMethod() { + return method; + } + /** * @return The payment processor. */ @@ -262,4 +282,57 @@ public String toString() { return this.name().toLowerCase(); } } + + /** + * Enumeration of payment methods + */ + public enum Method { + /** + * Bank debit payment + */ + BANK_DEBIT, + /** + * Bank redirect payment + */ + BANK_REDIRECT, + /** + * Bank transfer payment + */ + BANK_TRANSFER, + /** + * Buy now, pay later payment + */ + BUY_NOW_PAY_LATER, + /** + * Card payment + */ + CARD, + /** + * Cryptocurrency payment + */ + CRYPTO, + /** + * Digital wallet payment + */ + DIGITAL_WALLET, + /** + * Gift card payment + */ + GIFT_CARD, + /** + * Real time payment + */ + REAL_TIME_PAYMENT, + /** + * Rewards payment + */ + REWARDS; + + /** + * @return a string representation of the object. + */ + public String toString() { + return this.name().toLowerCase(); + } + } } diff --git a/src/test/java/com/maxmind/minfraud/request/PaymentTest.java b/src/test/java/com/maxmind/minfraud/request/PaymentTest.java index 171fc1f6..d2367972 100644 --- a/src/test/java/com/maxmind/minfraud/request/PaymentTest.java +++ b/src/test/java/com/maxmind/minfraud/request/PaymentTest.java @@ -4,11 +4,24 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.maxmind.minfraud.request.Payment.Builder; +import com.maxmind.minfraud.request.Payment.Method; import com.maxmind.minfraud.request.Payment.Processor; import org.junit.jupiter.api.Test; public class PaymentTest { + @Test + public void testMethod() { + Payment payment = new Builder().method(Method.CARD).build(); + assertEquals(Method.CARD, payment.getMethod()); + + payment = new Builder().method(Method.DIGITAL_WALLET).build(); + assertEquals(Method.DIGITAL_WALLET, payment.getMethod()); + + payment = new Builder().method(Method.BUY_NOW_PAY_LATER).build(); + assertEquals(Method.BUY_NOW_PAY_LATER, payment.getMethod()); + } + @Test public void testProcessor() { Payment payment = new Builder().processor(Processor.ADYEN).build(); From d9d98867df76baafe940fbe88857da6597a29627 Mon Sep 17 00:00:00 2001 From: William Storey Date: Tue, 16 Sep 2025 22:28:02 +0000 Subject: [PATCH 4/4] Update test data to include new party and method fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated JSON test files and RequestTestHelper to include the new party field (customer) in event objects and method field (card) in payment objects, ensuring complete test coverage. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../java/com/maxmind/minfraud/request/RequestTestHelper.java | 2 ++ src/test/resources/test-data/full-request-email-md5.json | 2 ++ src/test/resources/test-data/full-request.json | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/test/java/com/maxmind/minfraud/request/RequestTestHelper.java b/src/test/java/com/maxmind/minfraud/request/RequestTestHelper.java index 6ee72e6f..6319ec8e 100644 --- a/src/test/java/com/maxmind/minfraud/request/RequestTestHelper.java +++ b/src/test/java/com/maxmind/minfraud/request/RequestTestHelper.java @@ -58,6 +58,7 @@ private static Transaction makeTransaction(Email e) throws Exception { .event( new Event .Builder() + .party(Event.Party.CUSTOMER) .transactionId("txn3134133") .shopId("s2123") .time(ZonedDateTime.parse("2012-04-12T23:20:50.52Z")) @@ -102,6 +103,7 @@ private static Transaction makeTransaction(Email e) throws Exception { .build() ).payment( new Payment.Builder() + .method(Payment.Method.CARD) .processor(Payment.Processor.STRIPE) .wasAuthorized(false) .declineCode("invalid number") diff --git a/src/test/resources/test-data/full-request-email-md5.json b/src/test/resources/test-data/full-request-email-md5.json index 670fd607..eaa7b5d8 100644 --- a/src/test/resources/test-data/full-request-email-md5.json +++ b/src/test/resources/test-data/full-request-email-md5.json @@ -1,5 +1,6 @@ { "event": { + "party": "customer", "transaction_id": "txn3134133", "shop_id": "s2123", "time": "2012-04-12T23:20:50.52Z", @@ -41,6 +42,7 @@ "delivery_speed": "same_day" }, "payment": { + "method": "card", "processor": "stripe", "was_authorized": false, "decline_code": "invalid number" diff --git a/src/test/resources/test-data/full-request.json b/src/test/resources/test-data/full-request.json index 98085be6..a2a70cce 100644 --- a/src/test/resources/test-data/full-request.json +++ b/src/test/resources/test-data/full-request.json @@ -1,5 +1,6 @@ { "event": { + "party": "customer", "transaction_id": "txn3134133", "shop_id": "s2123", "time": "2012-04-12T23:20:50.52Z", @@ -41,6 +42,7 @@ "delivery_speed": "same_day" }, "payment": { + "method": "card", "processor": "stripe", "was_authorized": false, "decline_code": "invalid number"