Skip to content

Commit 5993144

Browse files
authored
Merge pull request #522 from maxmind/pcronin/updates
Custom rule label, minFraud "test" action, and 3DS result added
2 parents 2f8e41f + 90f3262 commit 5993144

File tree

11 files changed

+109
-32
lines changed

11 files changed

+109
-32
lines changed

.husky/_/husky.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ if [ -z "$husky_skip_init" ]; then
2323

2424
if [ $exitCode != 0 ]; then
2525
echo "husky - $hook_name hook exited with code $exitCode (error)"
26-
exit $exitCode
2726
fi
2827

29-
exit 0
28+
exit $exitCode
3029
fi

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
CHANGELOG
22
=========
33

4+
4.3.0
5+
6+
* Added support for the new `test` disposition action.
7+
* Added support for the `/disposition/rule_label` output in Score, Insights and
8+
Factors. This is available at `response.disposition.ruleLabel()`, and is the
9+
label of the custom rule that was triggered by the transaction.
10+
* Added support for the `/credit_card/was_3d_secure_successful` input in Score,
11+
Insights and Factors. The input should indicate whether or not the outcome of
12+
3D-Secure verification (e.g. Safekey, SecureCode, Verified by Visa) was
13+
successful. `true` if customer verification was successful, or `false` if the
14+
customer failed verification. If 3-D Secure verification was not used, was
15+
unavailable, or resulted in another outcome other than success or failure, do
16+
not include this field. Use the `was3DSecureSuccessful` property in a call to
17+
`new minFraud.CreditCard()` to set it.
18+
419
4.2.0 (2021-08-18)
520
------------------
621

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ try {
218218
issuerIdNumber: '411111',
219219
last4digits: '1234',
220220
token: 'a_token',
221+
was3DSecureSuccessful: true,
221222
}),
222223
order: new minFraud.Order({
223224
affiliateId: 'robotnet',

fixtures/insights.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@
205205

206206
"disposition": {
207207
"action": "accept",
208-
"reason": "default"
208+
"reason": "default",
209+
"rule_label": "the label"
209210
},
210211

211212
"warnings": [

fixtures/score.json

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919

2020
"disposition": {
2121
"action": "accept",
22-
"reason": "default"
22+
"reason": "default",
23+
"rule_label": "the label"
2324
},
2425

2526
"warnings": [
@@ -42,7 +43,8 @@
4243

4344
"disposition": {
4445
"action": "accept",
45-
"reason": "default"
46+
"reason": "default",
47+
"rule_label": "the label"
4648
}
4749
},
4850
"noDisposition": {
@@ -55,6 +57,29 @@
5557
"risk": 0.01
5658
},
5759

60+
"warnings": [
61+
{
62+
"code": "INPUT_INVALID",
63+
"warning": "Encountered value at /shipping/city that does not meet the required constraints",
64+
"input_pointer": "/shipping/city"
65+
}
66+
]
67+
},
68+
"noDispositionRuleLabel": {
69+
"id": "5bc5d6c2-b2c8-40af-87f4-6d61af86b6ae",
70+
"risk_score": 0.01,
71+
"funds_remaining": 25.0,
72+
"queries_remaining": 5000,
73+
74+
"ip_address": {
75+
"risk": 0.01
76+
},
77+
78+
"disposition": {
79+
"action": "accept",
80+
"reason": "default"
81+
},
82+
5883
"warnings": [
5984
{
6085
"code": "INPUT_INVALID",

src/request/credit-card.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe('CreditCard()', () => {
3232
${'token is not all digits'} | ${{ token: 'a7f6%gf83fhAu' }}
3333
${'token is non-space and printable'} | ${{ token: 'valid_token' }}
3434
${'token is a number with more than 19 characters'} | ${{ token: '12345678901234567890' }}
35-
`('does not thrown an error if $condition', ({ val }) => {
35+
`('does not throw an error if $condition', ({ val }) => {
3636
expect(() => new CreditCard(val)).not.toThrow();
3737
});
3838

@@ -45,6 +45,7 @@ describe('CreditCard()', () => {
4545
issuerIdNumber: '411111',
4646
last4digits: '1234',
4747
token: 'valid_token',
48+
was3DSecureSuccessful: true,
4849
})
4950
).not.toThrow();
5051
});

src/request/credit-card.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ interface CreditCardProps {
3838
* The card verification value (CVV) code as provided by the payment processor.
3939
*/
4040
cvvResult?: string;
41+
/**
42+
* Whether or not the outcome of 3D-Secure verification (e.g. Safekey,
43+
* SecureCode, Verified by Visa) was successful as provided by the end user.
44+
* `true` if customer verification was successful, or `false` if the customer
45+
* failed verification. If 3-D Secure verification was not used, was
46+
* unavailable, or resulted in another outcome other than success or failure,
47+
* do not set this property.
48+
*/
49+
was3DSecureSuccessful?: boolean;
4150
}
4251

4352
const singleChar = /^[A-Za-z0-9]$/;
@@ -65,6 +74,8 @@ export default class CreditCard implements CreditCardProps {
6574
public avsResult?: string;
6675
/** @inheritDoc CreditCardProps.cvvResult */
6776
public cvvResult?: string;
77+
/** @inheritDoc CreditCardProps.was3DSecureSuccessful */
78+
public was3DSecureSuccessful?: boolean;
6879

6980
public constructor(creditCard: CreditCardProps) {
7081
if (

src/response/models/score.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ export default class Score {
4242
public readonly warnings?: records.Warning[];
4343

4444
public constructor(response: webRecords.ScoreResponse) {
45-
this.disposition = response.disposition as records.Disposition;
45+
this.disposition = camelizeResponse(
46+
response.disposition
47+
) as records.Disposition;
4648
this.fundsRemaining = response.funds_remaining;
4749
this.id = response.id;
4850
this.ipAddress = response.ip_address;

src/response/records.ts

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,11 @@ export interface CreditCardIssuer {
9494
*/
9595
readonly name: string;
9696
/**
97-
* This property is `true` if the name matches the name provided in the request
98-
* for the card issuer. It is `false` if the name does not match. The property
99-
* is `null` if either no name or no issuer ID number (IIN) was provided in the
100-
* request or if MaxMind does not have a name associated with the IIN.
97+
* This property is `true` if the name matches the name provided in the
98+
* request for the card issuer. It is `false` if the name does not match. The
99+
* property is `null` if either no name or no issuer ID number (IIN) was
100+
* provided in the request or if MaxMind does not have a name associated with
101+
* the IIN.
101102
*/
102103
readonly matchesProvidedName?: boolean;
103104
/**
@@ -107,9 +108,9 @@ export interface CreditCardIssuer {
107108
readonly phoneNumber: string;
108109
/**
109110
* This property is `true` if the phone number matches the number provided in
110-
* the request for the card issuer. It is `false` if the number does not match.
111-
* It is `null` if either no phone number or no issuer ID number(IIN) was
112-
* provided in the request or if MaxMind does not have a phone number
111+
* the request for the card issuer. It is `false` if the number does not
112+
* match. It is `null` if either no phone number or no issuer ID number (IIN)
113+
* was provided in the request or if MaxMind does not have a phone number
113114
* associated with the IIN.
114115
*/
115116
readonly matchesProvidedPhoneNumber?: boolean;
@@ -194,7 +195,8 @@ export interface Device {
194195
}
195196

196197
/**
197-
* This object contains information about the email address domain passed in the request.
198+
* This object contains information about the email address domain passed in the
199+
* request.
198200
*/
199201
export interface EmailDomain {
200202
/**
@@ -204,7 +206,8 @@ export interface EmailDomain {
204206
}
205207

206208
/**
207-
* This object contains information about the email address passed in the request.
209+
* This object contains information about the email address passed in the
210+
* request.
208211
*/
209212
export interface Email {
210213
/**
@@ -247,9 +250,9 @@ export interface ShippingAddress {
247250
readonly isHighRisk: boolean;
248251
/**
249252
* This property is `true` if the postal code provided with the address is in
250-
* the city for the address.The property is `false` when the postal code is not
251-
* in the city. If the address was not provided or could not be parsed, the
252-
* property will be `null`.
253+
* the city for the address. The property is `false` when the postal code is
254+
* not in the city. If the address was not provided or could not be parsed,
255+
* the property will be `null`.
253256
*/
254257
readonly isPostalInCity?: boolean;
255258
/**
@@ -269,9 +272,9 @@ export interface ShippingAddress {
269272
*/
270273
readonly distanceToBillingAddress: number;
271274
/**
272-
* This property is `true` if the address is in the IP country.The property is
273-
* `false` when the address is not in the IP country. If the address could not
274-
* be parsed or was not provided or if the IP address could not be
275+
* This property is `true` if the address is in the IP country. The property
276+
* is `false` when the address is not in the IP country. If the address could
277+
* not be parsed or was not provided or if the IP address could not be
275278
* geolocated, the property will be `null`.
276279
*/
277280
readonly isInIpCountry?: boolean;
@@ -280,9 +283,9 @@ export interface ShippingAddress {
280283
export interface BillingAddress {
281284
/**
282285
* This property is `true` if the postal code provided with the address is in
283-
* the city for the address.The property is `false` when the postal code is not
284-
* in the city. If the address was not provided or could not be parsed, the
285-
* property will be `null`.
286+
* the city for the address. The property is `false` when the postal code is
287+
* not in the city. If the address was not provided or could not be parsed,
288+
* the property will be `null`.
286289
*/
287290
readonly isPostalInCity?: boolean;
288291
/**
@@ -298,9 +301,9 @@ export interface BillingAddress {
298301
*/
299302
readonly distanceToIpLocation: number;
300303
/**
301-
* This property is `true` if the address is in the IP country.The property is
302-
* `false` when the address is not in the IP country. If the address could not
303-
* be parsed or was not provided or if the IP address could not be
304+
* This property is `true` if the address is in the IP country. The property
305+
* is `false` when the address is not in the IP country. If the address could
306+
* not be parsed or was not provided or if the IP address could not be
304307
* geolocated, the property will be `null`.
305308
*/
306309
readonly isInIpCountry?: boolean;
@@ -312,8 +315,8 @@ export interface BillingAddress {
312315
export interface Disposition {
313316
/**
314317
* The action to take on the transaction as defined by your custom rules. The
315-
* current set of values are "accept", "manual_review", and "reject". If you
316-
* do not have custom rules set up, `null` will be returned.
318+
* current set of values are "accept", "manual_review", "reject", and "test".
319+
* If you do not have custom rules set up, `null` will be returned.
317320
*/
318321
readonly action: DispositionAction;
319322
/**
@@ -322,6 +325,12 @@ export interface Disposition {
322325
* will be returned.
323326
*/
324327
readonly reason: DispositionReason;
328+
/**
329+
* The label of the custom rule that was triggered. If you do not have custom
330+
* rules set up, the triggered custom rule does not have a label, or no custom
331+
* rule was triggered, `null` will be returned.
332+
*/
333+
readonly ruleLabel?: string;
325334
}
326335

327336
/**
@@ -352,7 +361,7 @@ export interface Subscores {
352361
readonly browser?: number;
353362
/**
354363
* Individualized risk of chargeback for the given IP address on your account
355-
* and shop ID.This is only available to users sending chargeback data to
364+
* and shop ID. This is only available to users sending chargeback data to
356365
* MaxMind. If present, this is a value in the range 0.01 to 99.
357366
*/
358367
readonly chargeback?: number;

src/response/web-records.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,14 @@ export interface BillingAddressWebRecord {
104104
readonly is_in_ip_country?: boolean;
105105
}
106106

107-
export type DispositionAction = 'accept' | 'reject' | 'manual_review';
107+
export type DispositionAction = 'accept' | 'reject' | 'manual_review' | 'test';
108108

109109
export type DispositionReason = 'default' | 'custom_rule';
110110

111111
export interface DispositionWebRecord {
112112
readonly action: DispositionAction;
113113
readonly reason: DispositionReason;
114+
readonly rule_label?: string;
114115
}
115116

116117
export interface SubscoresWebRecord {

0 commit comments

Comments
 (0)