33import com .fasterxml .jackson .annotation .JsonProperty ;
44import com .maxmind .minfraud .AbstractModel ;
55
6+ import java .util .regex .Pattern ;
7+
68/**
79 * The credit card information for the transaction.
810 */
@@ -14,6 +16,7 @@ public final class CreditCard extends AbstractModel {
1416 private final String bankPhoneNumber ;
1517 private final Character avsResult ;
1618 private final Character cvvResult ;
19+ private final String token ;
1720
1821 private CreditCard (CreditCard .Builder builder ) {
1922 issuerIdNumber = builder .issuerIdNumber ;
@@ -23,18 +26,24 @@ private CreditCard(CreditCard.Builder builder) {
2326 bankPhoneNumber = builder .bankPhoneNumber ;
2427 avsResult = builder .avsResult ;
2528 cvvResult = builder .cvvResult ;
29+ token = builder .token ;
2630 }
2731
2832 /**
2933 * {@code Builder} creates instances of the parent {@code CreditCard}
3034 * from values set by the builder's methods.
3135 */
3236 public static final class Builder {
37+ private static final Pattern IIN_PATTERN = Pattern .compile ("^[0-9]{6}$" );
38+ private static final Pattern LAST_4_PATTERN = Pattern .compile ("^[0-9]{4}$" );
39+ private static final Pattern TOKEN_PATTERN = Pattern .compile ("^(?![0-9]{1,19}$)[\\ x21-\\ x7E]{1,255}$" );
40+
3341 String issuerIdNumber ;
3442 String last4Digits ;
3543 String bankName ;
3644 String bankPhoneCountryCode ;
3745 String bankPhoneNumber ;
46+ String token ;
3847 Character avsResult ;
3948 Character cvvResult ;
4049
@@ -47,7 +56,7 @@ public static final class Builder {
4756 * string.
4857 */
4958 public CreditCard .Builder issuerIdNumber (String number ) {
50- if (!number .matches ("[0-9]{6}" )) {
59+ if (!IIN_PATTERN . matcher ( number ) .matches ()) {
5160 throw new IllegalArgumentException ("The issuer ID number " + number + " is of the wrong format." );
5261 }
5362 issuerIdNumber = number ;
@@ -61,7 +70,7 @@ public CreditCard.Builder issuerIdNumber(String number) {
6170 * string.
6271 */
6372 public CreditCard .Builder last4Digits (String digits ) {
64- if (!digits .matches ("[0-9]{4}" )) {
73+ if (!LAST_4_PATTERN . matcher ( digits ) .matches ()) {
6574 throw new IllegalArgumentException ("The last 4 credit card digits " + digits + " are of the wrong format." );
6675 }
6776 last4Digits = digits ;
@@ -117,6 +126,23 @@ public CreditCard.Builder cvvResult(Character code) {
117126 return this ;
118127 }
119128
129+ /**
130+ * @param token A token uniquely identifying the card. This should not be
131+ * the actual credit card number.
132+ * @return The builder object.
133+ * @throws IllegalArgumentException when the token is invalid.
134+ *
135+ */
136+ public CreditCard .Builder token (String token ) {
137+ if (!TOKEN_PATTERN .matcher (token ).matches ()) {
138+ throw new IllegalArgumentException ("The credit card token was invalid. "
139+ + "Tokens must be non-space ASCII printable characters. If the "
140+ + "token consists of all digits, it must be more than 19 digits." );
141+ }
142+ this .token = token ;
143+ return this ;
144+ }
145+
120146 /**
121147 * @return An instance of {@code CreditCard} created from the
122148 * fields set on this builder.
@@ -186,4 +212,12 @@ public Character getAvsResult() {
186212 public Character getCvvResult () {
187213 return cvvResult ;
188214 }
215+
216+ /**
217+ * @return A credit card token uniquely identifying the card.
218+ */
219+ @ JsonProperty ("token" )
220+ public String getToken () {
221+ return token ;
222+ }
189223}
0 commit comments