minfraud 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +20 -3
  4. data/CHANGELOG.md +31 -3
  5. data/CODE_OF_CONDUCT.md +4 -4
  6. data/Gemfile +9 -2
  7. data/LICENSE.txt +2 -1
  8. data/README.dev.md +4 -0
  9. data/README.md +106 -35
  10. data/lib/maxmind/geoip2/model/city.rb +99 -0
  11. data/lib/maxmind/geoip2/model/country.rb +94 -0
  12. data/lib/maxmind/geoip2/model/insights.rb +38 -0
  13. data/lib/maxmind/geoip2/record/abstract.rb +46 -0
  14. data/lib/maxmind/geoip2/record/city.rb +62 -0
  15. data/lib/maxmind/geoip2/record/continent.rb +61 -0
  16. data/lib/maxmind/geoip2/record/country.rb +78 -0
  17. data/lib/maxmind/geoip2/record/location.rb +97 -0
  18. data/lib/maxmind/geoip2/record/maxmind.rb +41 -0
  19. data/lib/maxmind/geoip2/record/place.rb +52 -0
  20. data/lib/maxmind/geoip2/record/postal.rb +54 -0
  21. data/lib/maxmind/geoip2/record/represented_country.rb +47 -0
  22. data/lib/maxmind/geoip2/record/subdivision.rb +72 -0
  23. data/lib/maxmind/geoip2/record/traits.rb +224 -0
  24. data/lib/minfraud.rb +5 -3
  25. data/lib/minfraud/assessments.rb +14 -5
  26. data/lib/minfraud/components/account.rb +1 -1
  27. data/lib/minfraud/components/addressable.rb +1 -1
  28. data/lib/minfraud/components/custom_inputs.rb +14 -0
  29. data/lib/minfraud/components/device.rb +11 -0
  30. data/lib/minfraud/components/event.rb +12 -1
  31. data/lib/minfraud/components/payment.rb +124 -12
  32. data/lib/minfraud/components/report/transaction.rb +69 -0
  33. data/lib/minfraud/error_handler.rb +36 -16
  34. data/lib/minfraud/http_service.rb +0 -1
  35. data/lib/minfraud/http_service/response.rb +36 -4
  36. data/lib/minfraud/model/abstract.rb +20 -0
  37. data/lib/minfraud/model/address.rb +52 -0
  38. data/lib/minfraud/model/billing_address.rb +11 -0
  39. data/lib/minfraud/model/credit_card.rb +75 -0
  40. data/lib/minfraud/model/device.rb +54 -0
  41. data/lib/minfraud/model/disposition.rb +35 -0
  42. data/lib/minfraud/model/email.rb +54 -0
  43. data/lib/minfraud/model/email_domain.rb +24 -0
  44. data/lib/minfraud/model/error.rb +28 -0
  45. data/lib/minfraud/model/factors.rb +24 -0
  46. data/lib/minfraud/model/geoip2_location.rb +25 -0
  47. data/lib/minfraud/model/insights.rb +68 -0
  48. data/lib/minfraud/model/ip_address.rb +82 -0
  49. data/lib/minfraud/model/issuer.rb +49 -0
  50. data/lib/minfraud/model/score.rb +76 -0
  51. data/lib/minfraud/model/score_ip_address.rb +23 -0
  52. data/lib/minfraud/model/shipping_address.rb +30 -0
  53. data/lib/minfraud/model/subscores.rb +156 -0
  54. data/lib/minfraud/model/warning.rb +63 -0
  55. data/lib/minfraud/report.rb +38 -0
  56. data/lib/minfraud/resolver.rb +2 -1
  57. data/lib/minfraud/version.rb +1 -1
  58. data/minfraud.gemspec +16 -16
  59. metadata +61 -39
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/record/location'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model of the GeoIP2 location information, including the local time.
8
+ class GeoIP2Location < MaxMind::GeoIP2::Record::Location
9
+ # The date and time of the transaction in the time zone associated with
10
+ # the IP address. The value is formatted according to RFC 3339. For
11
+ # instance, the local time in Boston might be returned as
12
+ # 2015-04-27T19:17:24-04:00.
13
+ #
14
+ # @return [String]
15
+ attr_reader :local_time
16
+
17
+ # @!visibility private
18
+ def initialize(record)
19
+ super(record)
20
+
21
+ @local_time = get('local_time')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/billing_address'
4
+ require 'minfraud/model/credit_card'
5
+ require 'minfraud/model/device'
6
+ require 'minfraud/model/email'
7
+ require 'minfraud/model/ip_address'
8
+ require 'minfraud/model/score'
9
+ require 'minfraud/model/shipping_address'
10
+
11
+ module Minfraud
12
+ module Model
13
+ # Model of the Insights response.
14
+ class Insights < Score
15
+ # An object containing minFraud data related to the billing address used
16
+ # in the transaction.
17
+ #
18
+ # @return [Minfraud::Model::BillingAddress]
19
+ attr_reader :billing_address
20
+
21
+ # An object containing minFraud data about the credit card used in the
22
+ # transaction.
23
+ #
24
+ # @return [Minfraud::Model::CreditCard]
25
+ attr_reader :credit_card
26
+
27
+ # This object contains information about the device that MaxMind believes
28
+ # is associated with the IP address passed in the request.
29
+ #
30
+ # @return [Minfraud::Model::Device]
31
+ attr_reader :device
32
+
33
+ # This object contains information about the email address passed in the
34
+ # request.
35
+ #
36
+ # @return [Minfraud::Model::Email]
37
+ attr_reader :email
38
+
39
+ # An object containing GeoIP2 and minFraud Insights information about the
40
+ # geolocated IP address.
41
+ #
42
+ # @return [Minfraud::Model::IPAddress]
43
+ attr_reader :ip_address
44
+
45
+ # An object containing minFraud data related to the shipping address used
46
+ # in the transaction.
47
+ #
48
+ # @return [Minfraud::Model::ShippingAddress]
49
+ attr_reader :shipping_address
50
+
51
+ # @!visibility private
52
+ def initialize(record, locales)
53
+ super(record, locales)
54
+
55
+ @billing_address = Minfraud::Model::BillingAddress.new(
56
+ get('billing_address')
57
+ )
58
+ @credit_card = Minfraud::Model::CreditCard.new(get('credit_card'))
59
+ @device = Minfraud::Model::Device.new(get('device'))
60
+ @email = Minfraud::Model::Email.new(get('email'))
61
+ @ip_address = Minfraud::Model::IPAddress.new(get('ip_address'), locales)
62
+ @shipping_address = Minfraud::Model::ShippingAddress.new(
63
+ get('shipping_address')
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/model/insights'
4
+ require 'minfraud/model/geoip2_location'
5
+
6
+ module Minfraud
7
+ module Model
8
+ # Model containing GeoIP2 data and the risk for the IP address.
9
+ class IPAddress < MaxMind::GeoIP2::Model::Insights
10
+ # This field contains the risk associated with the IP address. The value
11
+ # ranges from 0.01 to 99. A higher score indicates a higher risk.
12
+ #
13
+ # @return [Float]
14
+ attr_reader :risk
15
+
16
+ # @!visibility private
17
+ def initialize(record, locales)
18
+ super(record, locales)
19
+
20
+ if record
21
+ @location = Minfraud::Model::GeoIP2Location.new(record.fetch('location', nil))
22
+ else
23
+ @location = Minfraud::Model::GeoIP2Location.new(nil)
24
+ end
25
+ if record
26
+ @risk = record.fetch('risk', nil)
27
+ else
28
+ @risk = nil
29
+ end
30
+
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
68
+ end
69
+ end
70
+
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.
75
+ @traits.define_singleton_method(:is_anonymous_proxy) { get('is_anonymous_proxy') }
76
+ @traits.define_singleton_method(:is_satellite_provider) { get('is_satellite_provider') }
77
+ end
78
+
79
+ LANGUAGE_CODES = [:de, :en, :es, :fr, :ja, :'pt-BR', :ru, :'zh-CN'].freeze
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model containing information about the card issuer.
8
+ class Issuer < Abstract
9
+ # The name of the bank which issued the credit card.
10
+ #
11
+ # @return [String, nil]
12
+ attr_reader :name
13
+
14
+ # This property is true if the name matches the name provided in the
15
+ # request for the card issuer. It is false if the name does not match.
16
+ # The property is nil if either no name or issuer ID number (IIN) was
17
+ # provided in the request or if MaxMind does not have a name associated
18
+ # with the IIN.
19
+ #
20
+ # @return [Boolean, nil]
21
+ attr_reader :matches_provided_name
22
+
23
+ # This property is true if the phone number matches the number provided
24
+ # in the request for the card issuer. It is false if the number does not
25
+ # match. It is nil if either no phone number was provided or issuer ID
26
+ # number (IIN) was provided in the request or if MaxMind does not have a
27
+ # phone number associated with the IIN.
28
+ #
29
+ # @return [Boolean, nil]
30
+ attr_reader :matches_provided_phone_number
31
+
32
+ # The phone number of the bank which issued the credit card. In some
33
+ # cases the phone number we return may be out of date.
34
+ #
35
+ # @return [String, nil]
36
+ attr_reader :phone_number
37
+
38
+ # @!visibility private
39
+ def initialize(record)
40
+ super(record)
41
+
42
+ @name = get('name')
43
+ @phone_number = get('phone_number')
44
+ @matches_provided_name = get('matches_provided_name')
45
+ @matches_provided_phone_number = get('matches_provided_phone_number')
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+ require 'minfraud/model/disposition'
5
+ require 'minfraud/model/score_ip_address'
6
+ require 'minfraud/model/warning'
7
+
8
+ module Minfraud
9
+ module Model
10
+ # Model of the Score response.
11
+ class Score < Abstract
12
+ # An object containing the disposition set by custom rules.
13
+ #
14
+ # @return [Minfraud::Model::Disposition]
15
+ attr_reader :disposition
16
+
17
+ # The approximate US dollar value of the funds remaining on your MaxMind
18
+ # account.
19
+ #
20
+ # @return [Float]
21
+ attr_reader :funds_remaining
22
+
23
+ # This is a UUID that identifies the minFraud request. Please use this ID
24
+ # in bug reports or support requests to MaxMind so that we can easily
25
+ # identify a particular request.
26
+ #
27
+ # @return [String]
28
+ attr_reader :id
29
+
30
+ # An object containing the IP risk for the transaction.
31
+ #
32
+ # @return [Minfraud::Model::ScoreIPAddress]
33
+ attr_reader :ip_address
34
+
35
+ # The approximate number of queries remaining for this service before
36
+ # your account runs out of funds.
37
+ #
38
+ # @return [Integer]
39
+ attr_reader :queries_remaining
40
+
41
+ # This property contains the risk score, from 0.01 to 99. A higher score
42
+ # indicates a higher risk of fraud. For example, a score of 20 indicates
43
+ # a 20% chance that a transaction is fraudulent. We never return a risk
44
+ # score of 0, since all transactions have the possibility of being
45
+ # fraudulent. Likewise we never return a risk score of 100.
46
+ #
47
+ # @return [Float]
48
+ attr_reader :risk_score
49
+
50
+ # This array contains objects detailing issues with the request that was
51
+ # sent, such as invalid or unknown inputs. It is highly recommended that
52
+ # you check this array for issues when integrating the web service.
53
+ #
54
+ # @return [Array<Minfraud::Model::Warning>]
55
+ attr_reader :warnings
56
+
57
+ # @!visibility private
58
+ def initialize(record, _locales)
59
+ super(record)
60
+
61
+ @disposition = Minfraud::Model::Disposition.new(get('disposition'))
62
+ @funds_remaining = get('funds_remaining')
63
+ @id = get('id')
64
+ @ip_address = Minfraud::Model::ScoreIPAddress.new(get('ip_address'))
65
+ @queries_remaining = get('queries_remaining')
66
+ @risk_score = get('risk_score')
67
+ @warnings = []
68
+ if record && record.key?('warnings')
69
+ record['warnings'].each do |w|
70
+ @warnings << Minfraud::Model::Warning.new(w)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model containing the IP address's risk for the Score response.
8
+ class ScoreIPAddress < Abstract
9
+ # This field contains the risk associated with the IP address. The value
10
+ # ranges from 0.01 to 99. A higher score indicates a higher risk.
11
+ #
12
+ # @return [Float]
13
+ attr_reader :risk
14
+
15
+ # @!visibility private
16
+ def initialize(record)
17
+ super(record)
18
+
19
+ @risk = get('risk')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/address'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model containing information about the shipping address.
8
+ class ShippingAddress < Address
9
+ # The distance in kilometers from the shipping address to billing
10
+ # address.
11
+ #
12
+ # @return [Integer, nil]
13
+ attr_reader :distance_to_billing_address
14
+
15
+ # This field is true if the shipping address is an address associated
16
+ # with fraudulent transactions. The field is false when the address is
17
+ # not associated with increased risk. The key will only be present when a
18
+ # shipping address is provided.
19
+ attr_reader :is_high_risk
20
+
21
+ # @!visibility private
22
+ def initialize(record)
23
+ super(record)
24
+
25
+ @distance_to_billing_address = get('distance_to_billing_address')
26
+ @is_high_risk = get('is_high_risk')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Subscores for components that are used in calculating the riskScore.
8
+ class Subscores < Abstract
9
+ # The risk associated with the AVS result. If present, this is a value in
10
+ # the range 0.01 to 99.
11
+ #
12
+ # @return [Float, nil]
13
+ attr_reader :avs_result
14
+
15
+ # The risk associated with the billing address. If present, this is a
16
+ # value in the range 0.01 to 99.
17
+ #
18
+ # @return [Float, nil]
19
+ attr_reader :billing_address
20
+
21
+ # The risk associated with the distance between the billing address and
22
+ # the location for the given IP address. If present, this is a value in
23
+ # the range 0.01 to 99.
24
+ #
25
+ # @return [Float, nil]
26
+ attr_reader :billing_address_distance_to_ip_location
27
+
28
+ # The risk associated with the browser attributes such as the User-Agent
29
+ # and Accept-Language. If present, this is a value in the range 0.01 to
30
+ # 99.
31
+ #
32
+ # @return [Float, nil]
33
+ attr_reader :browser
34
+
35
+ # Individualized risk of chargeback for the given IP address given for
36
+ # your account and any shop ID passed. This is only available to users
37
+ # sending chargeback data to MaxMind. If present, this is a value in the
38
+ # range 0.01 to 99.
39
+ #
40
+ # @return [Float, nil]
41
+ attr_reader :chargeback
42
+
43
+ # The risk associated with the country the transaction originated from.
44
+ # If present, this is a value in the range 0.01 to 99.
45
+ #
46
+ # @return [Float, nil]
47
+ attr_reader :country
48
+
49
+ # The risk associated with the combination of IP country, card issuer
50
+ # country, billing country, and shipping country. If present, this is a
51
+ # value in the range 0.01 to 99.
52
+ #
53
+ # @return [Float, nil]
54
+ attr_reader :country_mismatch
55
+
56
+ # The risk associated with the CVV result. If present, this is a value in
57
+ # the range 0.01 to 99.
58
+ #
59
+ # @return [Float, nil]
60
+ attr_reader :cvv_result
61
+
62
+ # The risk associated with the particular email address. If present, this
63
+ # is a value in the range 0.01 to 99.
64
+ #
65
+ # @return [Float, nil]
66
+ attr_reader :email_address
67
+
68
+ # The general risk associated with the email domain. If present, this is
69
+ # a value in the range 0.01 to 99.
70
+ #
71
+ # @return [Float, nil]
72
+ attr_reader :email_domain
73
+
74
+ # The risk associated with the issuer ID number on the email domain. If
75
+ # present, this is a value in the range 0.01 to 99.
76
+ #
77
+ # Deprecated effective August 29, 2019. This subscore will default to 1
78
+ # and will be removed in a future release. The user tenure on email is
79
+ # reflected in the /subscores/email_address output.
80
+ #
81
+ # @return [Float, nil]
82
+ attr_reader :email_tenure
83
+
84
+ # The risk associated with the issuer ID number on the IP address. If
85
+ # present, this is a value in the range 0.01 to 99.
86
+ #
87
+ # Deprecated effective August 29, 2019. This subscore will default to 1
88
+ # and will be removed in a future release. The IP tenure is reflected in
89
+ # the overall risk score.
90
+ #
91
+ # @return [Float, nil]
92
+ attr_reader :ip_tenure
93
+
94
+ # The risk associated with the particular issuer ID number (IIN) given
95
+ # the billing location and the history of usage of the IIN on your
96
+ # account and shop ID. If present, this is a value in the range 0.01 to
97
+ # 99.
98
+ #
99
+ # @return [Float, nil]
100
+ attr_reader :issuer_id_number
101
+
102
+ # The risk associated with the particular order amount for your account
103
+ # and shop ID. If present, this is a value in the range 0.01 to 99.
104
+ #
105
+ # @return [Float, nil]
106
+ attr_reader :order_amount
107
+
108
+ # The risk associated with the particular phone number. If present, this
109
+ # is a value in the range 0.01 to 99.
110
+ #
111
+ # @return [Float, nil]
112
+ attr_reader :phone_number
113
+
114
+ # The risk associated with the distance between the shipping address and
115
+ # the IP location for the given IP address. If present, this is a value
116
+ # in the range 0.01 to 99.
117
+ #
118
+ # @return [Float, nil]
119
+ attr_reader :shipping_address_distance_to_ip_location
120
+
121
+ # The risk associated with the local time of day of the transaction in
122
+ # the IP address location. If present, this is a value in the range 0.01
123
+ # to 99.
124
+ #
125
+ # @return [Float, nil]
126
+ attr_reader :time_of_day
127
+
128
+ # @!visibility private
129
+ def initialize(record)
130
+ super(record)
131
+
132
+ @avs_result = get('avs_result')
133
+ @billing_address = get('billing_address')
134
+ @billing_address_distance_to_ip_location = get(
135
+ 'billing_address_distance_to_ip_location'
136
+ )
137
+ @browser = get('browser')
138
+ @chargeback = get('chargeback')
139
+ @country = get('country')
140
+ @country_mismatch = get('country_mismatch')
141
+ @cvv_result = get('cvv_result')
142
+ @email_address = get('email_address')
143
+ @email_domain = get('email_domain')
144
+ @email_tenure = get('email_tenure')
145
+ @ip_tenure = get('ip_tenure')
146
+ @issuer_id_number = get('issuer_id_number')
147
+ @order_amount = get('order_amount')
148
+ @phone_number = get('phone_number')
149
+ @shipping_address_distance_to_ip_location = get(
150
+ 'shipping_address_distance_to_ip_location'
151
+ )
152
+ @time_of_day = get('time_of_day')
153
+ end
154
+ end
155
+ end
156
+ end