Skip to content

Commit

Permalink
Merge pull request #112 from maxmind/pcronin/updates
Browse files Browse the repository at this point in the history
Custom rule label, minFraud "test" action, and 3DS result added
  • Loading branch information
PatrickCronin authored Aug 24, 2021
2 parents e840c67 + 0115b25 commit a6b3aca
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 15 deletions.
8 changes: 7 additions & 1 deletion MaxMind.MinFraud.UnitTest/Request/CreditCardTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public void TestCvvResult()
Assert.Equal('N', cc.CvvResult);
}


[Theory]
[InlineData("4485921507912924")]
[InlineData("432312")]
Expand All @@ -114,5 +113,12 @@ public void TestValidToken(string token)
var cc = new CreditCard(token: token);
Assert.Equal(token, cc.Token);
}

[Fact]
public void TestWas3DSecureSuccessful()
{
var cc = new CreditCard(was3DSecureSuccessful: true);
Assert.True(cc.Was3DSecureSuccessful);
}
}
}
6 changes: 4 additions & 2 deletions MaxMind.MinFraud.UnitTest/Request/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ public static Transaction CreateFullRequestUsingConstructors()
avsResult: 'Y',
cvvResult: 'N',
last4Digits: "7643",
token: "123456abc1234"
token: "123456abc1234",
was3DSecureSuccessful: false
),
customInputs: new CustomInputs.Builder
{
Expand Down Expand Up @@ -238,7 +239,8 @@ public static Transaction CreateFullRequest()
AvsResult = 'Y',
CvvResult = 'N',
Last4Digits = "7643",
Token = "123456abc1234"
Token = "123456abc1234",
Was3DSecureSuccessful = false,
},
CustomInputs = new CustomInputs.Builder
{
Expand Down
4 changes: 3 additions & 1 deletion MaxMind.MinFraud.UnitTest/Response/DispositionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ public void TestDisposition()
@"
{
""action"": ""manual_review"",
""reason"": ""custom_rule""
""reason"": ""custom_rule"",
""rule_label"": ""the rule's label""
}
")!;

Assert.Equal("manual_review", disposition.Action);
Assert.Equal("custom_rule", disposition.Reason);
Assert.Equal("the rule's label", disposition.RuleLabel);
}
}
}
3 changes: 2 additions & 1 deletion MaxMind.MinFraud.UnitTest/TestData/factors-response.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"queries_remaining": 1000,
"disposition": {
"action": "reject",
"reason": "custom_rule"
"reason": "custom_rule",
"rule_label": "The label"
},
"ip_address": {
"risk": 0.01,
Expand Down
3 changes: 2 additions & 1 deletion MaxMind.MinFraud.UnitTest/TestData/full-request.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
"bank_phone_number": "123-456-1234",
"avs_result": "Y",
"cvv_result": "N",
"token": "123456abc1234"
"token": "123456abc1234",
"was_3d_secure_successful": false
},
"custom_inputs": {
"float_input": 12.1,
Expand Down
3 changes: 2 additions & 1 deletion MaxMind.MinFraud.UnitTest/TestData/insights-response.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"queries_remaining": 1000,
"disposition": {
"action": "reject",
"reason": "custom_rule"
"reason": "custom_rule",
"rule_label": "The label"
},
"ip_address": {
"risk": 0.01,
Expand Down
3 changes: 2 additions & 1 deletion MaxMind.MinFraud.UnitTest/TestData/score-response.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"queries_remaining": 1000,
"disposition": {
"action": "reject",
"reason": "custom_rule"
"reason": "custom_rule",
"rule_label": "The label"
},
"ip_address": {
"risk": 99.0
Expand Down
41 changes: 38 additions & 3 deletions MaxMind.MinFraud/Request/CreditCard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ public sealed class CreditCard
/// as provided by the payment processor.</param>
/// <param name="token">A token uniquely identifying the card. This
/// should not be the actual credit card number.</param>
/// <param name="was3DSecureSuccessful">Whether or not the 3D-Secure
/// verification (e.g. Safekey, SecureCode, Verified by Visa) was
/// successful, as provided by the end user. `true` if customer
/// verification was successful, or `false` if the customer failed
/// verification. If 3-D Secure verification was not used, was
/// unavailable, or resulted in an outcome other than success or
/// failure, do not include this parameter.</param>
public CreditCard(
string? issuerIdNumber = null,
string? last4Digits = null,
Expand All @@ -50,7 +57,8 @@ public CreditCard(
string? bankPhoneNumber = null,
char? avsResult = null,
char? cvvResult = null,
string? token = null
string? token = null,
bool? was3DSecureSuccessful = null
)
{
IssuerIdNumber = issuerIdNumber;
Expand All @@ -61,6 +69,23 @@ public CreditCard(
AvsResult = avsResult;
CvvResult = cvvResult;
Token = token;
Was3DSecureSuccessful = was3DSecureSuccessful;
}

/// <summary>
/// [Obsolete("Legacy constructor for backwards compatibility")]
/// </summary>
public CreditCard(
string? issuerIdNumber,
string? last4Digits,
string? bankName,
string? bankPhoneCountryCode,
string? bankPhoneNumber,
char? avsResult,
char? cvvResult,
string? token
) : this(issuerIdNumber, last4Digits, bankName, bankPhoneCountryCode, bankPhoneNumber, avsResult, cvvResult, token, null)
{
}

/// <summary>
Expand Down Expand Up @@ -133,7 +158,6 @@ public string? Last4Digits
[JsonPropertyName("cvv_result")]
public char? CvvResult { get; init; }


/// <summary>
/// A token uniquely identifying the card. This should not be
/// the actual credit card number.
Expand All @@ -154,14 +178,25 @@ public string? Token
}
}

/// <summary>
/// Whether or not the 3D-Secure verification (e.g. Safekey, SecureCode,
/// Verified by Visa) was successful, as provided by the end user.
/// `true` if customer verification was successful, or `false` if the
/// customer failed verification. If 3-D Secure verification was not
/// used, was unavailable, or resulted in an outcome other than success
/// or failure, do not include this parameter.
/// </summary>
[JsonPropertyName("was_3d_secure_successful")]
public bool? Was3DSecureSuccessful { get; init; }

/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
public override string ToString()
{
return
$"IssuerIdNumber: {IssuerIdNumber}, Last4Digits: {Last4Digits}, BankName: {BankName}, BankPhoneCountryCode: {BankPhoneCountryCode}, BankPhoneNumber: {BankPhoneNumber}, AvsResult: {AvsResult}, CvvResult: {CvvResult}, Token: {Token}";
$"IssuerIdNumber: {IssuerIdNumber}, Last4Digits: {Last4Digits}, BankName: {BankName}, BankPhoneCountryCode: {BankPhoneCountryCode}, BankPhoneNumber: {BankPhoneNumber}, AvsResult: {AvsResult}, CvvResult: {CvvResult}, Token: {Token}, Was3DSecureSuccessful: {Was3DSecureSuccessful}";
}
}
}
15 changes: 12 additions & 3 deletions MaxMind.MinFraud/Response/Disposition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public sealed class Disposition
/// <summary>
/// The action to take on the transaction as defined by your custom
/// rules. The current set of values are "accept", "manual_review",
/// and "reject". If you do not have custom rules set up, <c>null</c>
/// will be returned.
/// "reject" and "test". If you do not have custom rules set up,
/// <c>null</c> will be returned.
/// </summary>
[JsonPropertyName("action")]
public string? Action { get; init; }
Expand All @@ -24,12 +24,21 @@ public sealed class Disposition
[JsonPropertyName("reason")]
public string? Reason { get; init; }

/// <summary>
/// The label of the custom rule that was triggered. If you do not have
/// custom rules set up, the triggered custom rule does not have a
/// label, or no custom rule was triggered, <c>null</c> will be
/// returned.
/// </summary>
[JsonPropertyName("rule_label")]
public string? RuleLabel { get; init; }

/// <summary>
/// Returns a string that represents the current object.
/// </summary>
public override string ToString()
{
return $"Action: {Action}, Reason: {Reason}";
return $"Action: {Action}, Reason: {Reason}, Rule Label: {RuleLabel}";
}
}
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,8 @@ public class MinFraudExample
AvsResult = 'Y',
CvvResult = 'N',
Last4Digits = "7643",
Token = "123456abc1234"
Token = "123456abc1234",
Was3DSecureSuccessful = true
},
CustomInputs = new CustomInputs.Builder
{
Expand Down
12 changes: 12 additions & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ Release Notes
* `Dlocal`
* `Onpay`
* `Safecharge`
* Documented the new "test" disposition.
* Added support for the `/disposition/risk_label` output in Score, Insights and
Factors. This is the available as the `RiskLabel` property of
`MaxMind.MinFraud.Response.Disposition`, and is the label of the custom rule
that was triggered by the transaction.
* Added support for the `/credit_card/was_3d_secure_successful` input in Score,
Insights and Factors. This input should indicate whether or not the outcome
of 3-D Secure verification (e.g. Safekey, SecureCode, Verified by Visa) was
successful. `true` if customer verification was successful, or `false` if
the customer failed verification. If 3-D Secure verification was not used, was
unavailable, or resulted in another outcome other than success or failure, do
not include this field.

3.1.0 (2021-02-02)
------------------
Expand Down

0 comments on commit a6b3aca

Please sign in to comment.