Skip to content

Commit 09fc96d

Browse files
committed
Update model classes
This mostly syncs them to the 3.2.0 classes, dropping any breaking change.
1 parent 46c37f7 commit 09fc96d

30 files changed

Lines changed: 259 additions & 191 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ CHANGELOG
44
1.19.0 (2023-11-21)
55
-------------------
66

7+
* Updated model classes with non-breaking changes from the 3.2.0
8+
release.
79
* Updated Jackson and `geoip2` dependencies.
810

911
1.18.0 (2021-08-31)

src/main/java/com/maxmind/minfraud/AbstractModel.java

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
11
package com.maxmind.minfraud;
22

3-
import com.fasterxml.jackson.annotation.JsonInclude;
4-
import com.fasterxml.jackson.databind.MapperFeature;
5-
import com.fasterxml.jackson.databind.ObjectMapper;
6-
import com.fasterxml.jackson.databind.SerializationFeature;
7-
import com.fasterxml.jackson.databind.util.StdDateFormat;
8-
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
9-
103
import java.io.IOException;
114

125
public abstract class AbstractModel {
13-
146
/**
157
* @return JSON representation of this object.
168
* @throws IOException if there is an error serializing the object to JSON.
179
*/
1810
public final String toJson() throws IOException {
19-
ObjectMapper mapper = new ObjectMapper();
20-
mapper.registerModule(new JavaTimeModule());
21-
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
22-
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
23-
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
24-
mapper.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS);
25-
mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true));
26-
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
27-
28-
return mapper.writeValueAsString(this);
11+
return Mapper.get().writeValueAsString(this);
2912
}
3013

3114
@Override
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.maxmind.minfraud;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import com.fasterxml.jackson.databind.DeserializationFeature;
5+
import com.fasterxml.jackson.databind.MapperFeature;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.SerializationFeature;
8+
import com.fasterxml.jackson.databind.json.JsonMapper;
9+
import com.fasterxml.jackson.databind.util.StdDateFormat;
10+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
11+
12+
class Mapper {
13+
private static final ObjectMapper mapper = JsonMapper.builder()
14+
.addModule(new JavaTimeModule())
15+
.defaultDateFormat(new StdDateFormat().withColonInTimeZone(true))
16+
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
17+
.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)
18+
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
19+
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
20+
.serializationInclusion(JsonInclude.Include.NON_NULL)
21+
.serializationInclusion(JsonInclude.Include.NON_EMPTY)
22+
.build();
23+
24+
public static ObjectMapper get() {
25+
return mapper;
26+
}
27+
}

src/main/java/com/maxmind/minfraud/request/AbstractLocation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import com.maxmind.minfraud.AbstractModel;
5-
65
import java.util.regex.Pattern;
76

87
/**
@@ -129,7 +128,8 @@ public final T region(String code) {
129128
*/
130129
public final T country(String code) {
131130
if (!COUNTRY_CODE_PATTERN.matcher(code).matches()) {
132-
throw new IllegalArgumentException("Expected two-letter country code in the ISO 3166-1 alpha-2 format");
131+
throw new IllegalArgumentException(
132+
"Expected two-letter country code in the ISO 3166-1 alpha-2 format");
133133
}
134134
country = code;
135135
return (T) this;

src/main/java/com/maxmind/minfraud/request/Account.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import com.maxmind.minfraud.AbstractModel;
5-
import org.apache.commons.codec.digest.DigestUtils;
5+
import java.math.BigInteger;
6+
import java.nio.charset.StandardCharsets;
7+
import java.security.MessageDigest;
8+
import java.security.NoSuchAlgorithmException;
69

710
/**
811
* Account related data for the minFraud request
@@ -46,8 +49,15 @@ public Account.Builder userId(String id) {
4649
* @return The builder object.
4750
*/
4851
public Account.Builder username(String username) {
49-
this.usernameMd5 = DigestUtils.md5Hex(username);
50-
return this;
52+
try {
53+
MessageDigest d = MessageDigest.getInstance("MD5");
54+
d.update(username.getBytes(StandardCharsets.UTF_8));
55+
BigInteger i = new BigInteger(1, d.digest());
56+
this.usernameMd5 = String.format("%032x", i);
57+
return this;
58+
} catch (NoSuchAlgorithmException e) {
59+
throw new RuntimeException("No MD5 algorithm for MessageDigest!", e);
60+
}
5161
}
5262

5363
/**

src/main/java/com/maxmind/minfraud/request/CreditCard.java

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,30 @@
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import com.maxmind.minfraud.AbstractModel;
5-
65
import java.util.regex.Pattern;
76

87
/**
98
* The credit card information for the transaction.
109
*/
1110
public final class CreditCard extends AbstractModel {
1211
private final String issuerIdNumber;
13-
private final String last4Digits;
12+
private final String lastDigits;
1413
private final String bankName;
1514
private final String bankPhoneCountryCode;
1615
private final String bankPhoneNumber;
16+
private final String country;
1717
private final Character avsResult;
1818
private final Character cvvResult;
1919
private final String token;
2020
private final Boolean was3dSecureSuccessful;
2121

2222
private CreditCard(CreditCard.Builder builder) {
2323
issuerIdNumber = builder.issuerIdNumber;
24-
last4Digits = builder.last4Digits;
24+
lastDigits = builder.lastDigits;
2525
bankName = builder.bankName;
2626
bankPhoneCountryCode = builder.bankPhoneCountryCode;
2727
bankPhoneNumber = builder.bankPhoneNumber;
28+
country = builder.country;
2829
avsResult = builder.avsResult;
2930
cvvResult = builder.cvvResult;
3031
token = builder.token;
@@ -36,47 +37,53 @@ private CreditCard(CreditCard.Builder builder) {
3637
* from values set by the builder's methods.
3738
*/
3839
public static final class Builder {
39-
private static final Pattern IIN_PATTERN = Pattern.compile("^[0-9]{6}$");
40-
private static final Pattern LAST_4_PATTERN = Pattern.compile("^[0-9]{4}$");
41-
private static final Pattern TOKEN_PATTERN = Pattern.compile("^(?![0-9]{1,19}$)[\\x21-\\x7E]{1,255}$");
40+
private static final Pattern COUNTRY_CODE_PATTERN = Pattern.compile("^[A-Z]{2}$");
41+
private static final Pattern IIN_PATTERN = Pattern.compile("^(?:[0-9]{6}|[0-9]{8})$");
42+
private static final Pattern LAST_DIGITS_PATTERN =
43+
Pattern.compile("^(?:[0-9]{2}|[0-9]{4})$");
44+
private static final Pattern TOKEN_PATTERN =
45+
Pattern.compile("^(?![0-9]{1,19}$)[\\x21-\\x7E]{1,255}$");
4246

4347
String issuerIdNumber;
44-
String last4Digits;
48+
String lastDigits;
4549
String bankName;
4650
String bankPhoneCountryCode;
4751
String bankPhoneNumber;
52+
String country;
4853
String token;
4954
Character avsResult;
5055
Character cvvResult;
5156
Boolean was3dSecureSuccessful;
5257

5358
/**
5459
* @param number The issuer ID number for the credit card. This is the
55-
* first 6 digits of the credit card number. It
60+
* first 6 or 8 digits of the credit card number. It
5661
* identifies the issuing bank.
5762
* @return The builder object.
5863
* @throws IllegalArgumentException when number is not a six digit
5964
* string.
6065
*/
6166
public CreditCard.Builder issuerIdNumber(String number) {
6267
if (!IIN_PATTERN.matcher(number).matches()) {
63-
throw new IllegalArgumentException("The issuer ID number " + number + " is of the wrong format.");
68+
throw new IllegalArgumentException(
69+
"The issuer ID number " + number + " is of the wrong format.");
6470
}
6571
issuerIdNumber = number;
6672
return this;
6773
}
6874

6975
/**
70-
* @param digits The last four digits of the credit card number.
76+
* @param digits The last two or four digits of the credit card number.
7177
* @return The builder object.
72-
* @throws IllegalArgumentException when number is not a four digit
78+
* @throws IllegalArgumentException when number is not a two or four digit
7379
* string.
7480
*/
7581
public CreditCard.Builder last4Digits(String digits) {
76-
if (!LAST_4_PATTERN.matcher(digits).matches()) {
77-
throw new IllegalArgumentException("The last 4 credit card digits " + digits + " are of the wrong format.");
82+
if (!LAST_DIGITS_PATTERN.matcher(digits).matches()) {
83+
throw new IllegalArgumentException(
84+
"The last credit card digits " + digits + " are of the wrong format.");
7885
}
79-
last4Digits = digits;
86+
lastDigits = digits;
8087
return this;
8188
}
8289

@@ -109,6 +116,25 @@ public CreditCard.Builder bankPhoneNumber(String number) {
109116
return this;
110117
}
111118

119+
/**
120+
* @param code The two character ISO 3166-1 alpha-2 country code where
121+
* the issuer of the card is located. This may be passed
122+
* instead of issuerIdNumber if you do not wish to pass
123+
* partial account numbers, or if your payment processor
124+
* does not provide them.
125+
* @return The builder object.
126+
* @throws IllegalArgumentException when code is not a two-letter
127+
* country code.
128+
*/
129+
public CreditCard.Builder country(String code) {
130+
if (!COUNTRY_CODE_PATTERN.matcher(code).matches()) {
131+
throw new IllegalArgumentException(
132+
"Expected two-letter country code in the ISO 3166-1 alpha-2 format");
133+
}
134+
country = code;
135+
return this;
136+
}
137+
112138
/**
113139
* @param code The address verification system (AVS) check result, as
114140
* returned to you by the credit card processor. The
@@ -145,8 +171,8 @@ public CreditCard.Builder cvvResult(Character code) {
145171
public CreditCard.Builder token(String token) {
146172
if (!TOKEN_PATTERN.matcher(token).matches()) {
147173
throw new IllegalArgumentException("The credit card token was invalid. "
148-
+ "Tokens must be non-space ASCII printable characters. If the "
149-
+ "token consists of all digits, it must be more than 19 digits.");
174+
+ "Tokens must be non-space ASCII printable characters. If the "
175+
+ "token consists of all digits, it must be more than 19 digits.");
150176
}
151177
this.token = token;
152178
return this;
@@ -188,11 +214,11 @@ public String getIssuerIdNumber() {
188214
}
189215

190216
/**
191-
* @return The last 4 digits of the credit card number.
217+
* @return The last two or four digits of the credit card number.
192218
*/
193219
@JsonProperty("last_4_digits")
194220
public String getLast4Digits() {
195-
return last4Digits;
221+
return lastDigits;
196222
}
197223

198224
/**
@@ -221,6 +247,15 @@ public String getBankPhoneNumber() {
221247
return bankPhoneNumber;
222248
}
223249

250+
/**
251+
* @return The two character ISO 3166-1 alpha-2 country code where the
252+
* issuer of the card is located.
253+
*/
254+
@JsonProperty("country")
255+
public String getCountry() {
256+
return country;
257+
}
258+
224259
/**
225260
* @return The address verification system (AVS) check result, as
226261
* returned to you by the credit card processor. The minFraud service
@@ -250,12 +285,12 @@ public String getToken() {
250285

251286
/**
252287
* @return An indication of whether or not the outcome of 3D-Secure
253-
* verification (e.g. Safekey, SecureCode, Verified by Visa) was
254-
* successful, as provided by the end user. {@code true} if customer
255-
* verification was successful, or {@code false} if the customer
256-
* failed verification. {@code null} if 3-D Secure verification was
257-
* not used, was unavailable, or resulted in another outcome other
258-
* than success or failure.
288+
* verification (e.g. Safekey, SecureCode, Verified by Visa) was
289+
* successful, as provided by the end user. {@code true} if customer
290+
* verification was successful, or {@code false} if the customer
291+
* failed verification. {@code null} if 3-D Secure verification was
292+
* not used, was unavailable, or resulted in another outcome other
293+
* than success or failure.
259294
*/
260295
@JsonProperty("was_3d_secure_successful")
261296
public Boolean getWas3dSecureSuccessful() {

src/main/java/com/maxmind/minfraud/request/CustomInputs.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.annotation.JsonAnyGetter;
44
import com.maxmind.minfraud.AbstractModel;
5-
65
import java.util.Collections;
76
import java.util.HashMap;
87
import java.util.Map;
@@ -42,10 +41,11 @@ public static class Builder {
4241
*/
4342
public Builder put(String key, String value) {
4443
validateKey(key);
45-
if (value.length() > 255 || value.contains("\n"))
46-
throw new IllegalArgumentException("The custom input string " +
47-
value + " is invalid. The string be less than" +
48-
"256 characters and the string must not contain a newline.");
44+
if (value.length() > 255 || value.contains("\n")) {
45+
throw new IllegalArgumentException("The custom input string "
46+
+ value + " is invalid. The string be less than"
47+
+ "256 characters and the string must not contain a newline.");
48+
}
4949
inputs.put(key, value);
5050
return this;
5151
}
@@ -63,11 +63,12 @@ public Builder put(String key, String value) {
6363
public Builder put(String key, Number value) {
6464
validateKey(key);
6565
double doubleValue = value.doubleValue();
66-
if (doubleValue <= -NUM_MAX || doubleValue >= NUM_MAX)
66+
if (doubleValue <= -NUM_MAX || doubleValue >= NUM_MAX) {
6767
throw new IllegalArgumentException(
68-
"The custom input number " + value + "is invalid. " +
69-
"The number must be between -" + NUM_MAX +
70-
" and " + NUM_MAX + ", exclusive.");
68+
"The custom input number " + value + "is invalid. "
69+
+ "The number must be between -" + NUM_MAX
70+
+ " and " + NUM_MAX + ", exclusive.");
71+
}
7172
inputs.put(key, value);
7273
return this;
7374
}
@@ -99,7 +100,7 @@ public CustomInputs build() {
99100
private void validateKey(String key) {
100101
if (!KEY_PATTERN.matcher(key).matches()) {
101102
throw new IllegalArgumentException("The custom input key "
102-
+ key + " is invalid.");
103+
+ key + " is invalid.");
103104
}
104105
}
105106
}

src/main/java/com/maxmind/minfraud/request/Device.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import com.maxmind.minfraud.AbstractModel;
5-
65
import java.net.InetAddress;
76

87
/**
@@ -90,7 +89,7 @@ public Device.Builder ipAddress(InetAddress ipAddress) {
9089
*/
9190
public Device.Builder sessionAge(Double sessionAge) {
9291
this.sessionAge =
93-
sessionAge;
92+
sessionAge;
9493
return this;
9594
}
9695

0 commit comments

Comments
 (0)