minfraud 1.0.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/rubocop.yml +12 -0
  3. data/.github/workflows/test.yml +32 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop.yml +108 -0
  6. data/CHANGELOG.md +70 -2
  7. data/CODE_OF_CONDUCT.md +4 -4
  8. data/Gemfile +11 -2
  9. data/LICENSE.txt +2 -1
  10. data/README.dev.md +4 -0
  11. data/README.md +245 -59
  12. data/Rakefile +9 -3
  13. data/bin/console +4 -3
  14. data/lib/maxmind/geoip2/model/city.rb +99 -0
  15. data/lib/maxmind/geoip2/model/country.rb +94 -0
  16. data/lib/maxmind/geoip2/model/insights.rb +38 -0
  17. data/lib/maxmind/geoip2/record/abstract.rb +46 -0
  18. data/lib/maxmind/geoip2/record/city.rb +62 -0
  19. data/lib/maxmind/geoip2/record/continent.rb +61 -0
  20. data/lib/maxmind/geoip2/record/country.rb +78 -0
  21. data/lib/maxmind/geoip2/record/location.rb +97 -0
  22. data/lib/maxmind/geoip2/record/maxmind.rb +41 -0
  23. data/lib/maxmind/geoip2/record/place.rb +52 -0
  24. data/lib/maxmind/geoip2/record/postal.rb +54 -0
  25. data/lib/maxmind/geoip2/record/represented_country.rb +47 -0
  26. data/lib/maxmind/geoip2/record/subdivision.rb +72 -0
  27. data/lib/maxmind/geoip2/record/traits.rb +233 -0
  28. data/lib/minfraud.rb +48 -8
  29. data/lib/minfraud/assessments.rb +118 -49
  30. data/lib/minfraud/components/account.rb +31 -9
  31. data/lib/minfraud/components/addressable.rb +73 -26
  32. data/lib/minfraud/components/base.rb +35 -11
  33. data/lib/minfraud/components/billing.rb +5 -0
  34. data/lib/minfraud/components/credit_card.rb +64 -20
  35. data/lib/minfraud/components/custom_inputs.rb +25 -0
  36. data/lib/minfraud/components/device.rb +51 -10
  37. data/lib/minfraud/components/email.rb +29 -7
  38. data/lib/minfraud/components/event.rb +60 -13
  39. data/lib/minfraud/components/order.rb +60 -22
  40. data/lib/minfraud/components/payment.rb +166 -21
  41. data/lib/minfraud/components/report/transaction.rb +80 -0
  42. data/lib/minfraud/components/shipping.rb +14 -5
  43. data/lib/minfraud/components/shopping_cart.rb +19 -12
  44. data/lib/minfraud/components/shopping_cart_item.rb +42 -13
  45. data/lib/minfraud/enum.rb +22 -8
  46. data/lib/minfraud/error_handler.rb +45 -18
  47. data/lib/minfraud/errors.rb +22 -2
  48. data/lib/minfraud/http_service.rb +22 -8
  49. data/lib/minfraud/http_service/request.rb +19 -18
  50. data/lib/minfraud/http_service/response.rb +49 -12
  51. data/lib/minfraud/model/abstract.rb +20 -0
  52. data/lib/minfraud/model/address.rb +52 -0
  53. data/lib/minfraud/model/billing_address.rb +11 -0
  54. data/lib/minfraud/model/credit_card.rb +75 -0
  55. data/lib/minfraud/model/device.rb +54 -0
  56. data/lib/minfraud/model/disposition.rb +35 -0
  57. data/lib/minfraud/model/email.rb +54 -0
  58. data/lib/minfraud/model/email_domain.rb +24 -0
  59. data/lib/minfraud/model/error.rb +28 -0
  60. data/lib/minfraud/model/factors.rb +24 -0
  61. data/lib/minfraud/model/geoip2_location.rb +25 -0
  62. data/lib/minfraud/model/insights.rb +68 -0
  63. data/lib/minfraud/model/ip_address.rb +82 -0
  64. data/lib/minfraud/model/issuer.rb +49 -0
  65. data/lib/minfraud/model/score.rb +76 -0
  66. data/lib/minfraud/model/score_ip_address.rb +23 -0
  67. data/lib/minfraud/model/shipping_address.rb +30 -0
  68. data/lib/minfraud/model/subscores.rb +178 -0
  69. data/lib/minfraud/model/warning.rb +63 -0
  70. data/lib/minfraud/report.rb +58 -0
  71. data/lib/minfraud/resolver.rb +25 -16
  72. data/lib/minfraud/validates.rb +187 -0
  73. data/lib/minfraud/version.rb +4 -1
  74. data/minfraud.gemspec +23 -18
  75. metadata +113 -39
  76. data/.travis.yml +0 -5
@@ -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,178 @@
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 device. If present, this is a value in the
63
+ # range of 0.01 to 99.
64
+ #
65
+ # @return [Float, nil]
66
+ attr_reader :device
67
+
68
+ # The risk associated with the particular email address. If present, this
69
+ # is a value in the range 0.01 to 99.
70
+ #
71
+ # @return [Float, nil]
72
+ attr_reader :email_address
73
+
74
+ # The general risk associated with the email domain. If present, this is
75
+ # a value in the range 0.01 to 99.
76
+ #
77
+ # @return [Float, nil]
78
+ attr_reader :email_domain
79
+
80
+ # The risk associated with the email address local part (the part of
81
+ # the email address before the @ symbol). If present, this is a value
82
+ # in the range 0.01 to 99.
83
+ #
84
+ # @return [Float, nil]
85
+ attr_reader :email_local_part
86
+
87
+ # The risk associated with the issuer ID number on the email domain. If
88
+ # present, this is a value in the range 0.01 to 99.
89
+ #
90
+ # Deprecated effective August 29, 2019. This subscore will default to 1
91
+ # and will be removed in a future release. The user tenure on email is
92
+ # reflected in the /subscores/email_address output.
93
+ #
94
+ # @return [Float, nil]
95
+ attr_reader :email_tenure
96
+
97
+ # The risk associated with the issuer ID number on the IP address. If
98
+ # present, this is a value in the range 0.01 to 99.
99
+ #
100
+ # Deprecated effective August 29, 2019. This subscore will default to 1
101
+ # and will be removed in a future release. The IP tenure is reflected in
102
+ # the overall risk score.
103
+ #
104
+ # @return [Float, nil]
105
+ attr_reader :ip_tenure
106
+
107
+ # The risk associated with the particular issuer ID number (IIN) given
108
+ # the billing location and the history of usage of the IIN on your
109
+ # account and shop ID. If present, this is a value in the range 0.01 to
110
+ # 99.
111
+ #
112
+ # @return [Float, nil]
113
+ attr_reader :issuer_id_number
114
+
115
+ # The risk associated with the particular order amount for your account
116
+ # and shop ID. If present, this is a value in the range 0.01 to 99.
117
+ #
118
+ # @return [Float, nil]
119
+ attr_reader :order_amount
120
+
121
+ # The risk associated with the particular phone number. If present, this
122
+ # is a value in the range 0.01 to 99.
123
+ #
124
+ # @return [Float, nil]
125
+ attr_reader :phone_number
126
+
127
+ # The risk associated with the shipping address. If present, this is a
128
+ # value in the range 0.01 to 99.
129
+ #
130
+ # @return [Float, nil]
131
+ attr_reader :shipping_address
132
+
133
+ # The risk associated with the distance between the shipping address and
134
+ # the IP location for the given IP address. If present, this is a value
135
+ # in the range 0.01 to 99.
136
+ #
137
+ # @return [Float, nil]
138
+ attr_reader :shipping_address_distance_to_ip_location
139
+
140
+ # The risk associated with the local time of day of the transaction in
141
+ # the IP address location. If present, this is a value in the range 0.01
142
+ # to 99.
143
+ #
144
+ # @return [Float, nil]
145
+ attr_reader :time_of_day
146
+
147
+ # @!visibility private
148
+ def initialize(record)
149
+ super(record)
150
+
151
+ @avs_result = get('avs_result')
152
+ @billing_address = get('billing_address')
153
+ @billing_address_distance_to_ip_location = get(
154
+ 'billing_address_distance_to_ip_location'
155
+ )
156
+ @browser = get('browser')
157
+ @chargeback = get('chargeback')
158
+ @country = get('country')
159
+ @country_mismatch = get('country_mismatch')
160
+ @cvv_result = get('cvv_result')
161
+ @device = get('device')
162
+ @email_address = get('email_address')
163
+ @email_domain = get('email_domain')
164
+ @email_local_part = get('email_local_part')
165
+ @email_tenure = get('email_tenure')
166
+ @ip_tenure = get('ip_tenure')
167
+ @issuer_id_number = get('issuer_id_number')
168
+ @order_amount = get('order_amount')
169
+ @phone_number = get('phone_number')
170
+ @shipping_address = get('shipping_address')
171
+ @shipping_address_distance_to_ip_location = get(
172
+ 'shipping_address_distance_to_ip_location'
173
+ )
174
+ @time_of_day = get('time_of_day')
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Warning about the minFraud request.
8
+ #
9
+ # Although more codes may be added in the future, the current warning codes
10
+ # are:
11
+ #
12
+ # * BILLING_CITY_NOT_FOUND - the billing city could not be found in our
13
+ # database.
14
+ # * BILLING_COUNTRY_MISSING - billing address information was provided
15
+ # without providing a billing country.
16
+ # * BILLING_COUNTRY_NOT_FOUND - the billing country could not be found in
17
+ # our database.
18
+ # * BILLING_POSTAL_NOT_FOUND - the billing postal could not be found in our
19
+ # database.
20
+ # * INPUT_INVALID - the value associated with the key does not meet the
21
+ # required constraints, e.g., "United States" in a field that requires a
22
+ # two-letter country code.
23
+ # * INPUT_UNKNOWN - an unknown key was encountered in the request body.
24
+ # * IP_ADDRESS_NOT_FOUND - the IP address could not be geolocated.
25
+ # * SHIPPING_COUNTRY_MISSING - shipping address information was provided
26
+ # without providing a shipping country.
27
+ # * SHIPPING_CITY_NOT_FOUND - the shipping city could not be found in our
28
+ # database.
29
+ # * SHIPPING_COUNTRY_NOT_FOUND - the shipping country could not be found in
30
+ # our database.
31
+ # * SHIPPING_POSTAL_NOT_FOUND - the shipping postal could not be found in
32
+ # our database.
33
+ class Warning < Abstract
34
+ # This value is a machine-readable code identifying the warning.
35
+ #
36
+ # @return [String]
37
+ attr_reader :code
38
+
39
+ # This property provides a human-readable explanation of the warning. The
40
+ # description may change at any time and should not be matched against.
41
+ #
42
+ # @return [String]
43
+ attr_reader :warning
44
+
45
+ # A JSON Pointer to the input field that the warning is associated with.
46
+ # For instance, if the warning was about the billing city, this would be
47
+ # '/billing/city'. If it was for the price in the second shopping cart
48
+ # item, it would be '/shopping_cart/1/price'.
49
+ #
50
+ # @return [String, nil]
51
+ attr_reader :input_pointer
52
+
53
+ # @!visibility private
54
+ def initialize(record)
55
+ super(record)
56
+
57
+ @code = get('code')
58
+ @warning = get('warning')
59
+ @input_pointer = get('input_pointer')
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minfraud
4
+ # Report is used to perform minFraud Report Transaction API requests.
5
+ #
6
+ # @see https://dev.maxmind.com/minfraud/report-transaction/
7
+ class Report
8
+ include ::Minfraud::HTTPService
9
+
10
+ # The Report::Transaction component.
11
+ #
12
+ # @return [Minfraud::Components::Report::Transaction, nil]
13
+ attr_accessor :transaction
14
+
15
+ # @param params [Hash] Hash of parameters. The only supported key is
16
+ # +:transaction+, which should have a
17
+ # +Minfraud::Components::Report::Transaction+ as its value.
18
+ def initialize(params = {})
19
+ @transaction = params[:transaction]
20
+ end
21
+
22
+ # Perform a request to the minFraud Report Transaction API.
23
+ #
24
+ # @return [nil]
25
+ #
26
+ # @raise [Minfraud::AuthorizationError] If there was an authentication
27
+ # problem.
28
+ #
29
+ # @raise [Minfraud::ClientError] If there was a critical problem with one
30
+ # of your inputs.
31
+ #
32
+ # @raise [Minfraud::ServerError] If the server reported an error of some
33
+ # kind.
34
+ def report_transaction
35
+ raw = request.perform(
36
+ verb: :post,
37
+ endpoint: 'transactions/report',
38
+ body: @transaction.to_json,
39
+ )
40
+
41
+ response = ::Minfraud::HTTPService::Response.new(
42
+ status: raw.status.to_i,
43
+ body: raw.body,
44
+ headers: raw.headers
45
+ )
46
+
47
+ ::Minfraud::ErrorHandler.examine(response)
48
+
49
+ nil
50
+ end
51
+
52
+ private
53
+
54
+ def request
55
+ @request ||= Request.new(::Minfraud::HTTPService.configuration)
56
+ end
57
+ end
58
+ end
@@ -1,10 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Minfraud
4
+ # Resolver provides functionality for setting component attributes.
2
5
  module Resolver
3
6
  class << self
4
- # @param [Object] context an object for variable assignment
5
- # @param [Hash] params a hash of parameters
6
- # @return [Array] a list of supplied params
7
- # @note Raises RequestFormatError once unpermitted key is met
7
+ # Set keys on the context based on the provided parameters.
8
+ #
9
+ # @param context [Object] An object for variable assignment.
10
+ #
11
+ # @param params [Hash] A hash of parameters.
12
+ #
13
+ # @return [Array]
14
+ #
15
+ # @raise [Minfraud::RequestFormatError] If an unexpected key is found.
8
16
  def assign(context, params)
9
17
  Array(params).each do |key, value|
10
18
  raise RequestFormatError, "#{key} does not belong to request document format" unless MAPPING[key]
@@ -15,18 +23,19 @@ module Minfraud
15
23
  end
16
24
  end
17
25
 
18
- # Mapping between components & minFraud request keys
26
+ # @!visibility private
19
27
  MAPPING = {
20
- account: ::Minfraud::Components::Account,
21
- billing: ::Minfraud::Components::Billing,
22
- credit_card: ::Minfraud::Components::CreditCard,
23
- device: ::Minfraud::Components::Device,
24
- email: ::Minfraud::Components::Email,
25
- event: ::Minfraud::Components::Event,
26
- order: ::Minfraud::Components::Order,
27
- payment: ::Minfraud::Components::Payment,
28
- shipping: ::Minfraud::Components::Shipping,
29
- shopping_cart: ::Minfraud::Components::ShoppingCart
30
- }
28
+ account: ::Minfraud::Components::Account,
29
+ billing: ::Minfraud::Components::Billing,
30
+ credit_card: ::Minfraud::Components::CreditCard,
31
+ custom_inputs: ::Minfraud::Components::CustomInputs,
32
+ device: ::Minfraud::Components::Device,
33
+ email: ::Minfraud::Components::Email,
34
+ event: ::Minfraud::Components::Event,
35
+ order: ::Minfraud::Components::Order,
36
+ payment: ::Minfraud::Components::Payment,
37
+ shipping: ::Minfraud::Components::Shipping,
38
+ shopping_cart: ::Minfraud::Components::ShoppingCart,
39
+ }.freeze
31
40
  end
32
41
  end