minfraud 1.4.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +7 -0
  3. data/.github/workflows/rubocop.yml +1 -1
  4. data/.github/workflows/test.yml +1 -4
  5. data/.rubocop.yml +4 -25
  6. data/CHANGELOG.md +82 -1
  7. data/Gemfile +0 -9
  8. data/LICENSE.txt +1 -1
  9. data/README.dev.md +1 -1
  10. data/README.md +13 -12
  11. data/lib/minfraud/assessments.rb +21 -16
  12. data/lib/minfraud/components/account.rb +1 -1
  13. data/lib/minfraud/components/billing.rb +1 -1
  14. data/lib/minfraud/components/credit_card.rb +21 -9
  15. data/lib/minfraud/components/custom_inputs.rb +1 -1
  16. data/lib/minfraud/components/device.rb +1 -1
  17. data/lib/minfraud/components/email.rb +93 -4
  18. data/lib/minfraud/components/event.rb +11 -11
  19. data/lib/minfraud/components/order.rb +1 -1
  20. data/lib/minfraud/components/payment.rb +152 -133
  21. data/lib/minfraud/components/report/transaction.rb +2 -2
  22. data/lib/minfraud/components/shipping.rb +2 -2
  23. data/lib/minfraud/components/shopping_cart.rb +2 -2
  24. data/lib/minfraud/components/shopping_cart_item.rb +3 -3
  25. data/lib/minfraud/http_service/response.rb +28 -21
  26. data/lib/minfraud/model/device.rb +1 -1
  27. data/lib/minfraud/model/disposition.rb +13 -6
  28. data/lib/minfraud/model/ip_address.rb +20 -44
  29. data/lib/minfraud/model/ip_risk_reason.rb +48 -0
  30. data/lib/minfraud/model/score.rb +1 -1
  31. data/lib/minfraud/model/subscores.rb +0 -22
  32. data/lib/minfraud/report.rb +19 -11
  33. data/lib/minfraud/validates.rb +2 -2
  34. data/lib/minfraud/version.rb +1 -1
  35. data/lib/minfraud.rb +18 -24
  36. data/minfraud.gemspec +10 -6
  37. metadata +40 -51
  38. data/lib/maxmind/geoip2/model/city.rb +0 -99
  39. data/lib/maxmind/geoip2/model/country.rb +0 -94
  40. data/lib/maxmind/geoip2/model/insights.rb +0 -38
  41. data/lib/maxmind/geoip2/record/abstract.rb +0 -46
  42. data/lib/maxmind/geoip2/record/city.rb +0 -62
  43. data/lib/maxmind/geoip2/record/continent.rb +0 -61
  44. data/lib/maxmind/geoip2/record/country.rb +0 -78
  45. data/lib/maxmind/geoip2/record/location.rb +0 -97
  46. data/lib/maxmind/geoip2/record/maxmind.rb +0 -41
  47. data/lib/maxmind/geoip2/record/place.rb +0 -52
  48. data/lib/maxmind/geoip2/record/postal.rb +0 -54
  49. data/lib/maxmind/geoip2/record/represented_country.rb +0 -47
  50. data/lib/maxmind/geoip2/record/subdivision.rb +0 -72
  51. data/lib/maxmind/geoip2/record/traits.rb +0 -233
  52. data/lib/minfraud/http_service/request.rb +0 -38
  53. data/lib/minfraud/http_service.rb +0 -45
@@ -4,7 +4,7 @@ module Minfraud
4
4
  module Components
5
5
  # Payment corresponds to the payment object of a minFraud request.
6
6
  #
7
- # @see https://dev.maxmind.com/minfraud/#Payment_(/payment)
7
+ # @see https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--payment
8
8
  class Payment < Base
9
9
  include ::Minfraud::Enum
10
10
  include Minfraud::Validates
@@ -15,138 +15,157 @@ module Minfraud
15
15
  # @!attribute processor
16
16
  #
17
17
  # @return [Symbol, nil]
18
- enum_accessor :processor, [
19
- :adyen,
20
- :affirm,
21
- :afterpay,
22
- :altapay,
23
- :amazon_payments,
24
- :american_express_payment_gateway,
25
- :authorizenet,
26
- :balanced,
27
- :beanstream,
28
- :bluepay,
29
- :bluesnap,
30
- :bpoint,
31
- :braintree,
32
- :cardpay,
33
- :cashfree,
34
- :ccavenue,
35
- :ccnow,
36
- :cetelem,
37
- :chase_paymentech,
38
- :checkout_com,
39
- :cielo,
40
- :collector,
41
- :commdoo,
42
- :compropago,
43
- :concept_payments,
44
- :conekta,
45
- :ct_payments,
46
- :cuentadigital,
47
- :curopayments,
48
- :cybersource,
49
- :dalenys,
50
- :dalpay,
51
- :datacash,
52
- :dibs,
53
- :digital_river,
54
- :dotpay,
55
- :ebs,
56
- :ecomm365,
57
- :ecommpay,
58
- :elavon,
59
- :emerchantpay,
60
- :epay,
61
- :eprocessing_network,
62
- :epx,
63
- :eway,
64
- :exact,
65
- :first_atlantic_commerce,
66
- :first_data,
67
- :g2a_pay,
68
- :global_payments,
69
- :gocardless,
70
- :heartland,
71
- :hipay,
72
- :ingenico,
73
- :interac,
74
- :internetsecure,
75
- :intuit_quickbooks_payments,
76
- :iugu,
77
- :klarna,
78
- :komoju,
79
- :lemon_way,
80
- :mastercard_payment_gateway,
81
- :mercadopago,
82
- :mercanet,
83
- :merchant_esolutions,
84
- :mirjeh,
85
- :mollie,
86
- :moneris_solutions,
87
- :nmi,
88
- :oceanpayment,
89
- :oney,
90
- :openpaymx,
91
- :optimal_payments,
92
- :orangepay,
93
- :other,
94
- :pacnet_services,
95
- :payeezy,
96
- :payfast,
97
- :paygate,
98
- :paylike,
99
- :payment_express,
100
- :paymentwall,
101
- :payone,
102
- :paypal,
103
- :payplus,
104
- :paysafecard,
105
- :paystation,
106
- :paytm,
107
- :paytrace,
108
- :paytrail,
109
- :payture,
110
- :payu,
111
- :payulatam,
112
- :payway,
113
- :payza,
114
- :pinpayments,
115
- :posconnect,
116
- :princeton_payment_solutions,
117
- :psigate,
118
- :qiwi,
119
- :quickpay,
120
- :raberil,
121
- :razorpay,
122
- :rede,
123
- :redpagos,
124
- :rewardspay,
125
- :sagepay,
126
- :securetrading,
127
- :simplify_commerce,
128
- :skrill,
129
- :smartcoin,
130
- :smartdebit,
131
- :solidtrust_pay,
132
- :sps_decidir,
133
- :stripe,
134
- :synapsefi,
135
- :systempay,
136
- :telerecargas,
137
- :towah,
138
- :transact_pro,
139
- :tsys,
140
- :usa_epay,
141
- :vantiv,
142
- :verepay,
143
- :vericheck,
144
- :vindicia,
145
- :virtual_card_services,
146
- :vme,
147
- :vpos,
148
- :wirecard,
149
- :worldpay
18
+ enum_accessor :processor, %i[
19
+ adyen
20
+ affirm
21
+ afterpay
22
+ altapay
23
+ amazon_payments
24
+ american_express_payment_gateway
25
+ apple_pay
26
+ aps_payments
27
+ authorizenet
28
+ balanced
29
+ beanstream
30
+ bluepay
31
+ bluesnap
32
+ boacompra
33
+ boku
34
+ bpoint
35
+ braintree
36
+ cardknox
37
+ cardpay
38
+ cashfree
39
+ ccavenue
40
+ ccnow
41
+ cetelem
42
+ chase_paymentech
43
+ checkout_com
44
+ cielo
45
+ collector
46
+ commdoo
47
+ compropago
48
+ concept_payments
49
+ conekta
50
+ coregateway
51
+ creditguard
52
+ credorax
53
+ ct_payments
54
+ cuentadigital
55
+ curopayments
56
+ cybersource
57
+ dalenys
58
+ dalpay
59
+ datacap
60
+ datacash
61
+ dibs
62
+ digital_river
63
+ dlocal
64
+ dotpay
65
+ ebs
66
+ ecomm365
67
+ ecommpay
68
+ elavon
69
+ emerchantpay
70
+ epay
71
+ eprocessing_network
72
+ epx
73
+ eway
74
+ exact
75
+ first_atlantic_commerce
76
+ first_data
77
+ fiserv
78
+ g2a_pay
79
+ global_payments
80
+ gocardless
81
+ heartland
82
+ hipay
83
+ ingenico
84
+ interac
85
+ internetsecure
86
+ intuit_quickbooks_payments
87
+ iugu
88
+ klarna
89
+ komoju
90
+ lemon_way
91
+ mastercard_payment_gateway
92
+ mercadopago
93
+ mercanet
94
+ merchant_esolutions
95
+ mirjeh
96
+ mollie
97
+ moneris_solutions
98
+ neopay
99
+ neosurf
100
+ nmi
101
+ oceanpayment
102
+ oney
103
+ onpay
104
+ openbucks
105
+ openpaymx
106
+ optimal_payments
107
+ orangepay
108
+ other
109
+ pacnet_services
110
+ payeezy
111
+ payfast
112
+ paygate
113
+ paylike
114
+ payment_express
115
+ paymentwall
116
+ payone
117
+ paypal
118
+ payplus
119
+ paysafecard
120
+ paysera
121
+ paystation
122
+ paytm
123
+ paytrace
124
+ paytrail
125
+ payture
126
+ payu
127
+ payulatam
128
+ payvision
129
+ payway
130
+ payza
131
+ pinpayments
132
+ posconnect
133
+ princeton_payment_solutions
134
+ psigate
135
+ qiwi
136
+ quickpay
137
+ raberil
138
+ razorpay
139
+ rede
140
+ redpagos
141
+ rewardspay
142
+ safecharge
143
+ sagepay
144
+ securetrading
145
+ simplify_commerce
146
+ skrill
147
+ smartcoin
148
+ smartdebit
149
+ solidtrust_pay
150
+ sps_decidir
151
+ stripe
152
+ synapsefi
153
+ systempay
154
+ telerecargas
155
+ towah
156
+ transact_pro
157
+ trustly
158
+ tsys
159
+ usa_epay
160
+ vantiv
161
+ verepay
162
+ vericheck
163
+ vindicia
164
+ virtual_card_services
165
+ vme
166
+ vpos
167
+ wirecard
168
+ worldpay
150
169
  ]
151
170
 
152
171
  # The authorization outcome from the payment processor. If the
@@ -5,7 +5,7 @@ module Minfraud
5
5
  module Report
6
6
  # Contains the fields used in the Report Transaction API.
7
7
  #
8
- # @see https://dev.maxmind.com/minfraud/report-transaction/
8
+ # @see https://dev.maxmind.com/minfraud/report-a-transaction?lang=en
9
9
  class Transaction < Base
10
10
  include ::Minfraud::Enum
11
11
 
@@ -24,7 +24,7 @@ module Minfraud
24
24
  # @!attribute tag
25
25
  #
26
26
  # @return [Symbol, nil]
27
- enum_accessor :tag, [:chargeback, :not_fraud, :spam_or_abuse, :suspected_fraud]
27
+ enum_accessor :tag, %i[chargeback not_fraud spam_or_abuse suspected_fraud]
28
28
 
29
29
  # A string which is provided by your payment processor indicating the
30
30
  # reason for the chargeback.
@@ -4,7 +4,7 @@ module Minfraud
4
4
  module Components
5
5
  # Shipping corresponds to the shipping object of a minFraud request.
6
6
  #
7
- # @see https://dev.maxmind.com/minfraud/#Shipping_(/shipping)
7
+ # @see https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--shipping
8
8
  class Shipping < Addressable
9
9
  include ::Minfraud::Enum
10
10
 
@@ -14,7 +14,7 @@ module Minfraud
14
14
  # @!attribute delivery_speed
15
15
  #
16
16
  # @return [Symbol, nil]
17
- enum_accessor :delivery_speed, [:same_day, :overnight, :expedited, :standard]
17
+ enum_accessor :delivery_speed, %i[same_day overnight expedited standard]
18
18
 
19
19
  # @param params [Hash] Hash of parameters. Each key/value should
20
20
  # correspond to one of the available attributes.
@@ -5,7 +5,7 @@ module Minfraud
5
5
  # ShoppingCart corresponds to the shopping_cart object of a minFraud
6
6
  # request.
7
7
  #
8
- # @see https://dev.maxmind.com/minfraud/#Shopping_Cart_(/shoppingcart)
8
+ # @see https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--shopping-cart
9
9
  class ShoppingCart < Base
10
10
  # An array of Minfraud::Components::ShoppingCartItem instances.
11
11
  #
@@ -13,7 +13,7 @@ module Minfraud
13
13
  attr_accessor :items
14
14
 
15
15
  # @param params [Array] Array of shopping cart items. You may provide
16
- # each item as either as Hash where each key is a symbol corresponding
16
+ # each item as either a Hash where each key is a symbol corresponding
17
17
  # to an item's field, or as a Minfraud:::Components::ShoppingCartItem
18
18
  # object.
19
19
  def initialize(params = [])
@@ -5,20 +5,20 @@ module Minfraud
5
5
  # ShoppingCartItem corresponds to objects in the shopping_cart object
6
6
  # of a minFraud request.
7
7
  #
8
- # @see https://dev.maxmind.com/minfraud/#Shopping_Cart_Item
8
+ # @see https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--shopping-cart--item
9
9
  class ShoppingCartItem < Base
10
10
  include Minfraud::Validates
11
11
 
12
12
  # The category of the item. This can also be a hashed value; see link.
13
13
  #
14
- # @see https://dev.maxmind.com/minfraud/#cart-hashing
14
+ # @see https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--shopping-cart--item__category
15
15
  #
16
16
  # @return [String, nil]
17
17
  attr_accessor :category
18
18
 
19
19
  # The internal ID of the item. This can also be a hashed value; see link.
20
20
  #
21
- # @see https://dev.maxmind.com/minfraud/#cart-hashing
21
+ # @see https://dev.maxmind.com/minfraud/api-documentation/requests?lang=en#schema--request--shopping-cart--item__item_id
22
22
  #
23
23
  # @return [String, nil]
24
24
  attr_accessor :item_id
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
3
4
  require 'minfraud/model/error'
4
5
  require 'minfraud/model/factors'
5
6
  require 'minfraud/model/insights'
@@ -9,32 +10,35 @@ module Minfraud
9
10
  module HTTPService
10
11
  # Response class for HTTP requests.
11
12
  class Response
12
- # HTTP response status.
13
+ # Response HTTP status code.
13
14
  #
14
- # @return [Integer, nil]
15
+ # @return [Fixnum, nil]
15
16
  attr_reader :status
16
17
 
17
- # HTTP response model.
18
+ # Response model.
18
19
  #
19
20
  # @return [Minfraud::Model::Score, Minfraud::Model::Insights,
20
21
  # Minfraud::Model::Factors, nil]
21
22
  attr_reader :body
22
23
 
23
- # HTTP response headers.
24
+ # @param endpoint [Symbol, nil] endpoint name, like :score.
24
25
  #
25
- # @return [Hash, nil]
26
- attr_reader :headers
26
+ # @param locales [Array<String>, nil] locales, like ["en"].
27
+ #
28
+ # @param response [HTTP::Response] the response object.
29
+ #
30
+ # @param body [String] the response body.
31
+ #
32
+ # @raise [JSON::ParserError] if there was invalid JSON in the response.
33
+ def initialize(endpoint, locales, response, body)
34
+ @status = response.code
27
35
 
28
- # @param params [Hash] Hash of parameters. +:status+, +:endpoint+,
29
- # +:body+, +:locales+, and +:headers+ are used.
30
- def initialize(params = {})
31
- @status = params[:status]
32
- @body = make_body(
33
- params[:endpoint],
34
- params[:body],
35
- params[:locales]
36
+ @body = make_body(
37
+ endpoint,
38
+ locales,
39
+ response,
40
+ body,
36
41
  )
37
- @headers = params[:headers]
38
42
  end
39
43
 
40
44
  # Return the minFraud-specific response code.
@@ -48,15 +52,18 @@ module Minfraud
48
52
 
49
53
  private
50
54
 
51
- def make_body(endpoint, body, locales)
52
- if @status != 200
53
- # Won't be a Hash when the body is not JSON.
54
- return nil unless body.is_a?(Hash)
55
+ def make_body(endpoint, locales, response, body)
56
+ if !response.mime_type || !response.mime_type.match(/json/i)
57
+ return nil
58
+ end
59
+
60
+ h = JSON.parse(body)
55
61
 
56
- return Minfraud::Model::Error.new(body)
62
+ if @status != 200
63
+ return Minfraud::Model::Error.new(h)
57
64
  end
58
65
 
59
- ENDPOINT_TO_CLASS[endpoint].new(body, locales)
66
+ ENDPOINT_TO_CLASS[endpoint].new(h, locales)
60
67
  end
61
68
 
62
69
  ENDPOINT_TO_CLASS = {
@@ -8,7 +8,7 @@ module Minfraud
8
8
  #
9
9
  # In order to receive device output from minFraud Insights or minFraud
10
10
  # Factors, you must be using the Device Tracking Add-on
11
- # (https://dev.maxmind.com/minfraud/device/).
11
+ # (https://dev.maxmind.com/minfraud/track-devices?lang=en).
12
12
  class Device < Abstract
13
13
  # This number represents our confidence that the device_id refers to a
14
14
  # unique device as opposed to a cluster of similar devices. A confidence
@@ -10,25 +10,32 @@ module Minfraud
10
10
  # rules.
11
11
  class Disposition < Abstract
12
12
  # The action to take on the transaction as defined by your custom rules.
13
- # The current set of values are "accept", "manual_review", and "reject".
14
- # If you do not have custom rules set up, this will be nil.
13
+ # The current set of values are "accept", "manual_review", "reject", and
14
+ # "test". If you do not have custom rules set up, this will be nil.
15
15
  #
16
16
  # @return [String, nil]
17
17
  attr_reader :action
18
18
 
19
19
  # The reason for the action. The current possible values are
20
- # "custom_rule", "block_list", and "default". If you do not have custom
21
- # rules set up, this will be nil.
20
+ # "custom_rule" and "default". If you do not have custom rules set up,
21
+ # this will be nil.
22
22
  #
23
23
  # @return [String, nil]
24
24
  attr_reader :reason
25
25
 
26
+ # The label of the custom rule that was triggered. If you do not have
27
+ # custom rules set up, the triggered custom rule does not have a label,
28
+ # or no custom rule was triggered, this will be nil.
29
+ # @return [String, nil]
30
+ attr_reader :rule_label
31
+
26
32
  # @!visibility private
27
33
  def initialize(record)
28
34
  super(record)
29
35
 
30
- @action = get('action')
31
- @reason = get('reason')
36
+ @action = get('action')
37
+ @reason = get('reason')
38
+ @rule_label = get('rule_label')
32
39
  end
33
40
  end
34
41
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'maxmind/geoip2/model/insights'
4
4
  require 'minfraud/model/geoip2_location'
5
+ require 'minfraud/model/ip_risk_reason'
5
6
 
6
7
  module Minfraud
7
8
  module Model
@@ -13,9 +14,20 @@ module Minfraud
13
14
  # @return [Float]
14
15
  attr_reader :risk
15
16
 
17
+ # This field contains IPRiskReason objects identifying the reasons why
18
+ # the IP address received the associated risk. This will be an empty
19
+ # array if there are no reasons.
20
+ #
21
+ # @return [Array<Minfraud::Model::IPRiskReason>]
22
+ attr_reader :risk_reasons
23
+
16
24
  # @!visibility private
17
25
  def initialize(record, locales)
18
- super(record, locales)
26
+ if record
27
+ super(record, locales)
28
+ else
29
+ super({}, locales)
30
+ end
19
31
 
20
32
  if record
21
33
  @location = Minfraud::Model::GeoIP2Location.new(record.fetch('location', nil))
@@ -28,55 +40,19 @@ module Minfraud
28
40
  @risk = nil
29
41
  end
30
42
 
31
- # Decorate objects with deprecated attributes and names for backwards
32
- # compatibility. Do this here rather than with the overhead of
33
- # subclasses/modules for them in the hope that one day we can delete
34
- # them.
35
-
36
- # These are named differently in maxmind-geoip2.
37
- @country.define_singleton_method(:is_in_european_union) { in_european_union? }
38
- @registered_country.define_singleton_method(:is_in_european_union) { in_european_union? }
39
- @represented_country.define_singleton_method(:is_in_european_union) { in_european_union? }
40
- @traits.define_singleton_method(:is_anonymous) { anonymous? }
41
- @traits.define_singleton_method(:is_anonymous_vpn) { anonymous_vpn? }
42
- @traits.define_singleton_method(:is_hosting_provider) { hosting_provider? }
43
- @traits.define_singleton_method(:is_public_proxy) { public_proxy? }
44
- @traits.define_singleton_method(:is_tor_exit_node) { tor_exit_node? }
45
-
46
- # Mashify turned each language code into an attribute, but
47
- # maxmind-geoip2 exposes the names as a hash.
48
- LANGUAGE_CODES.each do |c|
49
- if @city.names
50
- @city.names.define_singleton_method(c) { fetch(c.to_s, nil) }
51
- end
52
- if @continent.names
53
- @continent.names.define_singleton_method(c) { fetch(c.to_s, nil) }
54
- end
55
- if @country.names
56
- @country.names.define_singleton_method(c) { fetch(c.to_s, nil) }
57
- end
58
- if @registered_country.names
59
- @registered_country.names.define_singleton_method(c) { fetch(c.to_s, nil) }
60
- end
61
- if @represented_country.names
62
- @represented_country.names.define_singleton_method(c) { fetch(c.to_s, nil) }
63
- end
64
- @subdivisions.each do |s|
65
- if s.names
66
- s.names.define_singleton_method(c) { fetch(c.to_s, nil) }
67
- end
43
+ @risk_reasons = []
44
+ if record&.key?('risk_reasons')
45
+ record['risk_reasons'].each do |r|
46
+ @risk_reasons << Minfraud::Model::IPRiskReason.new(r)
68
47
  end
69
48
  end
70
49
 
71
- # This attribute is deprecated.
72
- @country.define_singleton_method(:is_high_risk) { get('is_high_risk') }
73
-
74
- # These attributes are deprecated and aren't in maxmind-geoip2.
50
+ # These attributes are deprecated and aren't in maxmind-geoip2. The
51
+ # webservice still sends them as of writing, so we'd like to keep them
52
+ # for now as they could still be providing value.
75
53
  @traits.define_singleton_method(:is_anonymous_proxy) { get('is_anonymous_proxy') }
76
54
  @traits.define_singleton_method(:is_satellite_provider) { get('is_satellite_provider') }
77
55
  end
78
-
79
- LANGUAGE_CODES = [:de, :en, :es, :fr, :ja, :'pt-BR', :ru, :'zh-CN'].freeze
80
56
  end
81
57
  end
82
58
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Reason for the IP risk.
8
+ #
9
+ # This class provides both a machine-readable code and a human-readable
10
+ # explanation of the reason for the IP risk score.
11
+ #
12
+ # Although more codes may be added in the future, the current codes are:
13
+ #
14
+ # * ANONYMOUS_IP - The IP address belongs to an anonymous network. See the
15
+ # object at ip_address.traits for more details.
16
+ # * BILLING_POSTAL_VELOCITY - Many different billing postal codes have been
17
+ # seen on this IP address.
18
+ # * EMAIL_VELOCITY - Many different email addresses have been seen on this
19
+ # IP address.
20
+ # * HIGH_RISK_DEVICE - A high risk device was seen on this IP address.
21
+ # * HIGH_RISK_EMAIL - A high risk email address was seen on this IP address
22
+ # in your past transactions.
23
+ # * ISSUER_ID_NUMBER_VELOCITY - Many different issuer ID numbers have been
24
+ # seen on this IP address.
25
+ # * MINFRAUD_NETWORK_ACTIVITY - Suspicious activity has been seen on this
26
+ # IP address across minFraud customers.
27
+ class IPRiskReason < Abstract
28
+ # This value is a machine-readable code identifying the reason.
29
+ #
30
+ # @return [String, nil]
31
+ attr_reader :code
32
+
33
+ # This field provides a human-readable explanation of the reason. The
34
+ # text may change at any time and should not be matched against.
35
+ #
36
+ # @return [String, nil]
37
+ attr_reader :reason
38
+
39
+ # @!visibility private
40
+ def initialize(record)
41
+ super(record)
42
+
43
+ @code = get('code')
44
+ @reason = get('reason')
45
+ end
46
+ end
47
+ end
48
+ end
@@ -65,7 +65,7 @@ module Minfraud
65
65
  @queries_remaining = get('queries_remaining')
66
66
  @risk_score = get('risk_score')
67
67
  @warnings = []
68
- if record && record.key?('warnings')
68
+ if record&.key?('warnings')
69
69
  record['warnings'].each do |w|
70
70
  @warnings << Minfraud::Model::Warning.new(w)
71
71
  end