minfraud 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3dd67d789e955bf5a4d4bb1b1900439ae8a3b386
4
+ data.tar.gz: a6b08f07d7adf54d3df09823bb17b5d53644c354
5
+ SHA512:
6
+ metadata.gz: f55e059b7e4d96be4d6b92247c3580bb4b5be5299a4f59264e2eaaf9c913e2b0c4ee1ac2b8786282c8bd255ffb343772e4311115343eff106c4e6c6dc91695aa
7
+ data.tar.gz: 85f7b208c1d116987a4754355d7ee4ec2295ea6a151a741eaf29d3280ba4ad8dcf04397817d454cced3cf712abbca6a687da19356cba66445bfb31af8d54d315
@@ -0,0 +1,7 @@
1
+ pkg
2
+ .project
3
+ Gemfile.lock
4
+ .rvmrc
5
+ *.rbc
6
+ *~
7
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at kushnir.yb@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in minfraud.gemspec
4
+ gem 'coveralls', require: false
5
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 kushnir.yb
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,108 @@
1
+ # Simple Ruby Wrapper to the MaxMind minFraud API
2
+
3
+ [![Code Climate](https://codeclimate.com/github/kushniryb/minfraud-api-v2/badges/gpa.svg)](https://codeclimate.com/github/kushniryb/minfraud-api-v2)
4
+ [![Coverage Status](https://coveralls.io/repos/github/kushniryb/minfraud-api-v2/badge.svg?branch=master)](https://coveralls.io/github/kushniryb/minfraud-api-v2?branch=master)
5
+ [![Build Status](https://travis-ci.org/kushniryb/minfraud-api-v2.svg?branch=master)](https://travis-ci.org/kushniryb/minfraud-api-v2)
6
+
7
+ Compatible with version minFraud API v2.0
8
+
9
+ [minFraud API documentation](http://dev.maxmind.com/minfraud/)
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'minfraud'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ ```ruby
22
+ $ bundle
23
+ ```
24
+
25
+ Or install it yourself as:
26
+ ```
27
+ $ gem install minfraud
28
+ ```
29
+
30
+ ## Configuration
31
+
32
+ User Id and License Key are required to work with minFraud API
33
+
34
+ ```ruby
35
+ Minfraud.configure do |c|
36
+ c.license_key = 'your_license_key'
37
+ c.user_id = 'your_user_id'
38
+ end
39
+ ```
40
+
41
+ ## Usage
42
+ ```ruby
43
+ Minfraud.configure do |c|
44
+ c.user_id = 'user_id' # your minFraud user id
45
+ c.license_key = 'license_key' # your minFraud license key
46
+ end
47
+
48
+ # You can either provide a hash of params to initializer
49
+ assessment = Minfraud::Assessments.new(
50
+ device: {
51
+ ip_address: '1.2.3.4.5'
52
+ }
53
+ )
54
+ # or create a component and assign them to assessments object directly, e.g
55
+ device = Minfraud::Components::Device.new(ip_address: '1.2.3.4.5')
56
+ assessment = Minfraud::Assessments.new(device: device)
57
+ # or
58
+ assessment = Minfraud::Assessments.new
59
+ assessment.device = device
60
+
61
+
62
+ # There are multiple components that reflect minFraud request top level keys
63
+ # You can now call 3 different minFraud endpoints: score, insights, factors
64
+ assessment.insights
65
+ assessment.factors
66
+
67
+ result = assessment.score # => Minfraud::Response instance
68
+
69
+ result.status # => Response status code
70
+ result.code # => minFraud specific response code
71
+ result.body # => Mashified body
72
+ result.headers # => Response headers
73
+
74
+ # You can also change data inbetween requests
75
+ first_request = assessment.insights
76
+ assessment.device.ip_address = '22.22.22.33'
77
+ second_request = assessment.insights
78
+ ```
79
+
80
+ ### Exception handling
81
+
82
+ Gem is supplied with four different types of exceptions:
83
+ ```ruby
84
+ # Raised if unpermitted key is provided to Minfraud::Assessments initializer
85
+ class RequestFormatError < BaseError; end
86
+
87
+ # Raised if IP address is absent / it is reserved / JSON body can not be decoded
88
+ class ClientError < BaseError; end
89
+
90
+ # Raised if there are some problems with the user id and / or license key
91
+ class AuthorizationError < BaseError; end
92
+
93
+ # Raised if minFraud returns an error, or if there is an HTTP error
94
+ class ServerError < BaseError; end
95
+
96
+ # Raised if assigned value does not belong to enum list
97
+ class NotEnumValueError < BaseError; end
98
+ ```
99
+
100
+ ## Contributing
101
+
102
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/kushniryb/minfraud-api-v2]. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
103
+
104
+
105
+ ## License
106
+
107
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
108
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "minfraud"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,49 @@
1
+ require 'minfraud'
2
+ require 'minfraud/enum'
3
+ require 'minfraud/components/base'
4
+ require 'minfraud/components/account'
5
+ require 'minfraud/components/addressable'
6
+ require 'minfraud/components/billing'
7
+ require 'minfraud/components/credit_card'
8
+ require 'minfraud/components/device'
9
+ require 'minfraud/components/email'
10
+ require 'minfraud/components/event'
11
+ require 'minfraud/components/order'
12
+ require 'minfraud/components/payment'
13
+ require 'minfraud/components/shopping_cart_item'
14
+ require 'minfraud/components/shipping'
15
+ require 'minfraud/components/shopping_cart'
16
+ require 'minfraud/components/device'
17
+ require 'minfraud/resolver'
18
+ require 'minfraud/version'
19
+ require 'minfraud/errors'
20
+ require 'minfraud/http_service'
21
+ require 'minfraud/http_service/request'
22
+ require 'minfraud/http_service/response'
23
+ require 'minfraud/error_handler'
24
+ require 'minfraud/assessments'
25
+
26
+ module Minfraud
27
+ class << self
28
+ # @!attribute user_id
29
+ # @return [String] MaxMind username that is used for authorization
30
+ attr_accessor :user_id
31
+
32
+ # @!attribute license_key
33
+ # @return [String] MaxMind license key that is used for authorization
34
+ attr_accessor :license_key
35
+
36
+ # @yield [self] to accept configuration settings
37
+ def configure
38
+ yield self
39
+ end
40
+
41
+ # @return [Hash] with the current configuration
42
+ def configuration
43
+ {
44
+ user_id: @user_id,
45
+ license_key: @license_key
46
+ }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,82 @@
1
+ module Minfraud
2
+ class Assessments
3
+ include ::Minfraud::HTTPService
4
+ include ::Minfraud::Resolver
5
+
6
+ # @attribute account
7
+ # @return [Minfraud::Components::Account] Account component
8
+ attr_accessor :account
9
+
10
+ # @attribute billing
11
+ # @return [Minfraud::Components::Billing] Billing component
12
+ attr_accessor :billing
13
+
14
+ # @attribute credit_card
15
+ # @return [Minfraud::Components::CreditCard] CreditCard component
16
+ attr_accessor :credit_card
17
+
18
+ # @attribute device
19
+ # @return [Minfraud::Components::Device] Device component
20
+ attr_accessor :device
21
+
22
+ # @attribute email
23
+ # @return [Minfraud::Components::Email] Email component
24
+ attr_accessor :email
25
+
26
+ # @attribute event
27
+ # @return [Minfraud::Components::Event] Event component
28
+ attr_accessor :event
29
+
30
+ # @attribute order
31
+ # @return [Minfraud::Components::Order] Order component
32
+ attr_accessor :order
33
+
34
+ # @attribute payment
35
+ # @return [Minfraud::Components::Payment] Payment component
36
+ attr_accessor :payment
37
+
38
+ # @!attribute shipping
39
+ # @return [Minfraud::Components::Shipping] Shipping component
40
+ attr_accessor :shipping
41
+
42
+ # @!attribute shopping_cart
43
+ # @return [Minfraud::Components::ShoppingCarat] ShoppingCart component
44
+ attr_accessor :shopping_cart
45
+
46
+ # @param [Hash] params hash of parameters
47
+ # @param [Minfraud::Resolver] resolver resolver that maps params to components
48
+ # @return [Minfraud::Assessments] Assessments instance
49
+ def initialize(params = {}, resolver = ::Minfraud::Resolver)
50
+ resolver.assign(context: self, params: params)
51
+ end
52
+
53
+ # These methods correspond to the minFraud API endpoints and require the same set of params
54
+ # Raises an error in case of invalid response
55
+ # @return [Minfraud::HTTPService::Response] Wrapped minFraud response
56
+ %w(score insights factors).each do |endpoint|
57
+ define_method endpoint do
58
+ raw = request.perform(verb: :post, endpoint: endpoint, body: request_body)
59
+ response = ::Minfraud::HTTPService::Response.new(
60
+ status: raw.status.to_i,
61
+ body: raw.body,
62
+ headers: raw.headers
63
+ )
64
+
65
+ ::Minfraud::ErrorHandler.inspect(response)
66
+ end
67
+ end
68
+
69
+ private
70
+ # Creates a unified request body from components converted to JSON
71
+ # @return [Hash] Request body
72
+ def request_body
73
+ MAPPING.keys.inject({}) { |mem, e| mem.merge!(e.to_s => send(e)&.to_json) }
74
+ end
75
+
76
+ # Creates memoized Minfraud::HTTPService::Request instance
77
+ # @return [Minfraud::HTTPService::Request] Request instance based on configuration params
78
+ def request
79
+ @request ||= Request.new(::Minfraud::HTTPService.configuration)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,23 @@
1
+ module Minfraud
2
+ module Components
3
+ class Account < Base
4
+ # @attribute user_id
5
+ # @return [String] A unique user ID associated with the end-user in your system.
6
+ # If your system allows the login name for the account to be changed, this should not be the login name for the account,
7
+ # but rather should be an internal ID that does not change. This is not your MaxMind user ID
8
+ attr_accessor :user_id
9
+
10
+ # @attribute username_md5
11
+ # @return [String] An MD5 hash as a hexadecimal string of the username or login name associated with the account
12
+ attr_accessor :username_md5
13
+
14
+ # Creates Minfraud::Components::Account instance
15
+ # @param [Hash] params hash of parameters
16
+ # @return [Minfraud::Components::Account] a Account instance
17
+ def initialize(params = {})
18
+ @user_id = params[:user_id]
19
+ @username_md5 = params[:username_md5]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,67 @@
1
+ module Minfraud
2
+ module Components
3
+ class Addressable < Base
4
+ # @attribute first_name
5
+ # @return [String] The first name of the end user as provided in their billing / shipping information
6
+ attr_accessor :first_name
7
+
8
+ # @attribute last_name
9
+ # @return [String] The last name of the end user as provided in their billing / shipping information
10
+ attr_accessor :last_name
11
+
12
+ # @attribute company
13
+ # @return [String] The company of the end user as provided in their billing / shipping information
14
+ attr_accessor :company
15
+
16
+ # @attribute address
17
+ # @return [String] The first line of the user’s billing / shipping address
18
+ attr_accessor :address
19
+
20
+ # @attribute address_2
21
+ # @return [String] The second line of the user’s billing / shipping address
22
+ attr_accessor :address_2
23
+
24
+ # @attribute city
25
+ # @return [String] The city of the user’s billing / shipping address
26
+ attr_accessor :city
27
+
28
+ # @attribute region
29
+ # @return [String] The ISO 3166-2 subdivision code for the user’s billing / shipping address
30
+ attr_accessor :region
31
+
32
+ # @attribute country
33
+ # @return [String] The two character ISO 3166-1 alpha-2 country code of the user’s billing / shipping address
34
+ attr_accessor :country
35
+
36
+ # @attribute postal
37
+ # @return [String] The postal code of the user’s billing / shipping address
38
+ attr_accessor :postal
39
+
40
+ # @attribute phone_number
41
+ # @return [String] The phone number without the country code for the user’s billing / shipping address
42
+ attr_accessor :phone_number
43
+
44
+ # @attribute phone_country_code
45
+ # @return [String] The country code for phone number associated with the user’s billing / shipping address
46
+ attr_accessor :phone_country_code
47
+
48
+ # Creates Minfraud::Components::Addressable instance
49
+ # This class is used as a parent class for Billing and Shipping components
50
+ # @param [Hash] params hash of parameters
51
+ # @return [Minfraud::Components::Addressable] an Addressable instance
52
+ def initialize(params = {})
53
+ @first_name = params[:first_name]
54
+ @last_name = params[:last_name]
55
+ @company = params[:company]
56
+ @address = params[:address]
57
+ @address_2 = params[:address_2]
58
+ @city = params[:city]
59
+ @region = params[:region]
60
+ @country = params[:country]
61
+ @postal = params[:postal]
62
+ @phone_number = params[:phone_number]
63
+ @phone_country_code = params[:phone_country_code]
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,13 @@
1
+ module Minfraud
2
+ module Components
3
+ # Note: This class is used as a parent class for all other components
4
+ # It defines a method which is used for basic JSON representation of PORO objects
5
+ class Base
6
+ # @return [Hash] a JSON representation of component attributes
7
+ def to_json
8
+ instance_variables.inject({}) { |mem, e| mem.merge!(e.to_s.gsub(/@/, '') => instance_variable_get(e).to_s) }
9
+ .delete_if { |_, v| v.empty? }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Minfraud
2
+ module Components
3
+ class Billing < Addressable; end
4
+ end
5
+ end
@@ -0,0 +1,47 @@
1
+ module Minfraud
2
+ module Components
3
+ class CreditCard < Base
4
+ # @attribute issuer_id_number
5
+ # # @return [String] The issuer ID number for the credit card. This is the first 6 digits of the credit card number.
6
+ # It identifies the issuing bank
7
+ attr_accessor :issuer_id_number
8
+
9
+ # @attribute last_4_digits
10
+ # @return [String] The last four digits of the credit card number
11
+ attr_accessor :last_4_digits
12
+
13
+ # @attribute bank_name
14
+ # @return [String] The name of the issuing bank as provided by the end user
15
+ attr_accessor :bank_name
16
+
17
+ # @attribute bank_phone_country_code
18
+ # @return [String] The phone country code for the issuing bank as provided by the end user
19
+ attr_accessor :bank_phone_country_code
20
+
21
+ # @attribute phone_phone_number
22
+ # @return [String] The phone number, without the country code, for the issuing bank as provided by the end user
23
+ attr_accessor :bank_phone_number
24
+
25
+ # @attribute avs_result
26
+ # @return [String] The address verification system (AVS) check result, as returned to you by the credit card processor
27
+ attr_accessor :avs_result
28
+
29
+ # @attribute cvv_result
30
+ # @return [String] The card verification value (CVV) code as provided by the payment processor
31
+ attr_accessor :cvv_result
32
+
33
+ # Creates Minfraud::Components::CreditCard instance
34
+ # @param [Hash] params hash of parameters
35
+ # @return [Minfraud::Components::CreditCard] a CreditCard instance
36
+ def initialize(params = {})
37
+ @bank_phone_country_code = params[:bank_phone_country_code]
38
+ @issuer_id_number = params[:issuer_id_number]
39
+ @last_4_digits = params[:last_4_digits]
40
+ @bank_name = params[:bank_name]
41
+ @bank_phone_number = params[:bank_phone_number]
42
+ @avs_result = params[:avs_result]
43
+ @cvv_result = params[:cvv_result]
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,27 @@
1
+ module Minfraud
2
+ module Components
3
+ class Device < Base
4
+ # @!attribute ip_address
5
+ # @return [String] The IP address associated with the device used by the customer in the transaction.
6
+ # The IP address must be in IPv4 or IPv6 presentation format
7
+ attr_accessor :ip_address
8
+
9
+ # @attribute user_agent
10
+ # @return [String] The HTTP "User-Agent" header of the browser used in the transaction
11
+ attr_accessor :user_agent
12
+
13
+ # @attribute :accept_language
14
+ # @return [String] The HTTP "Accept-Language" header of the browser used in the transaction
15
+ attr_accessor :accept_language
16
+
17
+ # Creates Minfraud::Components::Device instance
18
+ # @param [Hash] params hash of parameters
19
+ # @return [Minfraud::Components::Device] a Device instance
20
+ def initialize(params = {})
21
+ @ip_address = params[:ip_address]
22
+ @user_agent = params[:user_agent]
23
+ @accept_language = params[:accept_language]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ module Minfraud
2
+ module Components
3
+ class Email < Base
4
+ # @attribute address
5
+ # @return [String] This field must be either a valid email address or an MD5 of the email used in the transaction
6
+ attr_accessor :address
7
+
8
+ # @attribute domain
9
+ # @return [String] The domain of the email address used in the transaction
10
+ attr_accessor :domain
11
+
12
+ # Creates Minfraud::Components::Email instance
13
+ # @param [Hash] params hash of parameters
14
+ # @return [Minfraud::Components::Email] an Email instance
15
+ def initialize(params = {})
16
+ @address = params[:address]
17
+ @domain = params[:domain]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module Minfraud
2
+ module Components
3
+ class Event < Base
4
+ include ::Minfraud::Enum
5
+ # @attribute transaction_id
6
+ # @return [String] Internal ID for the transaction. Used to locate a specific transaction in minFraud logs
7
+ attr_accessor :transaction_id
8
+
9
+ # @attribute shop_id
10
+ # @return [String] Internal ID for the shop, affiliate, or merchant this order is coming from
11
+ attr_accessor :shop_id
12
+
13
+ # @attribute time
14
+ # @return [String] The date and time the event occurred. The string must be in the RFC 3339 date-time format.
15
+ # If this field is not in the request, the current time will be used
16
+ attr_accessor :time
17
+
18
+ # @attribute type
19
+ # @return [String] The type of event being scored. The valid types are:
20
+ # => account_creation
21
+ # => account_login
22
+ # => purchase
23
+ # => recurring_purchase
24
+ # => referral
25
+ # => survey
26
+ enum_accessor :type, [:account_creation, :account_login, :purchase, :recurring_purchase, :referral, :survey]
27
+
28
+ # Creates Minfraud::Components::Event instance
29
+ # @param [Hash] params hash of parameters
30
+ # @return [Minfraud::Components::Event] an Event instance
31
+ def initialize(params = {})
32
+ @transaction_id = params[:transaction_id]
33
+ @shop_id = params[:shop_id]
34
+ @time = params[:time]
35
+ @type = params[:type]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,51 @@
1
+ module Minfraud
2
+ module Components
3
+ class Order < Base
4
+ # @attribute amount
5
+ # @return [Decimal] The total order amount for the transaction
6
+ attr_accessor :amount
7
+
8
+ # @attribute currency
9
+ # @return [String] The ISO 4217 currency code for the currency used in the transaction
10
+ attr_accessor :currency
11
+
12
+ # @attribute discount_code
13
+ # @return [String] The discount code applied to the transaction. If multiple discount codes are used,
14
+ # please separate them with a comma.
15
+ attr_accessor :discount_code
16
+
17
+ # @attribute affiliate_id
18
+ # @return [String] The ID of the affiliate where the order is coming from
19
+ attr_accessor :affiliate_id
20
+
21
+ # @attribute subaffiliate_id
22
+ # @return [String] The ID of the sub-affiliate where the order is coming from
23
+ attr_accessor :subaffiliate_id
24
+
25
+ # @attribute :referrer_uri
26
+ # @return [String] The URI of the referring site for this order
27
+ attr_accessor :referrer_uri
28
+
29
+ # @attribute :is_gift
30
+ # @return [Boolean] Whether order was marked as a gift by the purchaser
31
+ attr_accessor :is_gift
32
+
33
+ # @attribute :has_gift_message
34
+ # @return [Boolean] Whether the purchaser included a gift message
35
+ attr_accessor :has_gift_message
36
+
37
+ # Creates Minfraud::Components::Order instance
38
+ # @param [Hash] params hash of parameters
39
+ # @return [Minfraud::Components::Order] an Order instance
40
+ def initialize (params = {})
41
+ @has_gift_message = params[:has_gift_message]
42
+ @affiliate_id = params[:affiliate_id]
43
+ @subaffiliate_id = params[:subaffiliate_id]
44
+ @currency = params[:currency]
45
+ @discount_code = params[:discount_cide]
46
+ @referrer_uri = params[:referrer_uri]
47
+ @is_gift = params[:is_gift]
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,40 @@
1
+ module Minfraud
2
+ module Components
3
+ class Payment < Base
4
+ include ::Minfraud::Enum
5
+ # @attribute processor
6
+ # @return [String] The payment processor used for the transaction
7
+ enum_accessor :processor, [
8
+ :adyen, :altapay, :amazon_payments, :authorizenet, :balanced, :beanstream,
9
+ :bluepay, :braintree, :ccnow, :chase_paymentech, :cielo, :collector, :compropago,
10
+ :concept_payments, :conekta, :cuentadigital, :dalpay, :dibs, :digital_river, :ecomm365,
11
+ :elavon, :epay, :eprocessing_network, :eway, :first_data, :global_payments, :ingenico,
12
+ :internetsecure, :intuit_quickbooks_payments, :iugu, :mastercard_payment_gateway,
13
+ :mercadopago, :merchant_esolutions, :mirjeh, :mollie, :moneris_solutions, :nmi,
14
+ :openpaymx, :optimal_payments, :orangepay, :other, :pacnet_services, :payfast,
15
+ :paygate, :payone, :paypal, :payplus, :paystation, :paytrace, :paytrail, :payture,
16
+ :payu, :payulatam, :pinpayments, :princeton_payment_solutions, :psigate, :qiwi,
17
+ :quickpay, :raberil, :rede, :redpagos, :rewardspay, :sagepay, :simplify_commerce,
18
+ :skrill, :smartcoin, :sps_decidir, :stripe, :telerecargas, :towah, :usa_epay,
19
+ :verepay, :vindicia, :virtual_card_services, :vme, :worldpay
20
+ ]
21
+
22
+ # @attribute was_authorized
23
+ # @return [Boolean] The authorization outcome from the payment processor. If the transaction has not yet been approved or denied, do not include this field
24
+ attr_accessor :was_authorized
25
+
26
+ # @attribute decline_code
27
+ # @return [String] The decline code as provided by your payment processor. If the transaction was not declined, do not include this field
28
+ attr_accessor :decline_code
29
+
30
+ # Creates Minfraud::Components::Payment instance
31
+ # @param [Hash] params hash of parameters
32
+ # @return [Minfraud::Components::Payment] Payment instance
33
+ def initialize(params = {})
34
+ @was_authorized = params[:was_authorized]
35
+ @decline_code = params[:decline_code]
36
+ @processor = params[:processor]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,22 @@
1
+ module Minfraud
2
+ module Components
3
+ class Shipping < Addressable
4
+ include ::Minfraud::Enum
5
+ # @attribute delivery_speed
6
+ # @return [String] The shipping delivery speed for the order. The valid values are:
7
+ # => same_day
8
+ # => overnight
9
+ # => expedited
10
+ # => standard
11
+ enum_accessor :delivery_speed, [:same_day, :overnight, :expedited, :standard]
12
+
13
+ # Creates Minfraud::Components::Shipping instance
14
+ # @param [Hash] params hash of parameters
15
+ # @return [Minfraud::Components::Shipping] Shipping instance
16
+ def initialize(params = {})
17
+ @delivery_speed = params[:delivery_speed]
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ module Minfraud
2
+ module Components
3
+ class ShoppingCart < Base
4
+ # @attribute items
5
+ # @return [Array] An array of Minfraud::Components::ShoppingCartItem instances
6
+
7
+ attr_accessor :items
8
+ # Creates Minfraud::Components::ShoppingCart instance
9
+ # @param [Hash] params hash of parameters
10
+ # @return [Minfraud::Components::ShoppingCart] ShoppingCart instance
11
+ def initialize(params = {})
12
+ @items = params.map(&method(:resolve))
13
+ end
14
+
15
+ # @return [Array] a JSON representation of Minfraud::Components::ShoppingCart items
16
+ def to_json
17
+ @items.map(&:to_json)
18
+ end
19
+
20
+ private
21
+
22
+ # @param [Hash] params hash of parameters for Minfraud::Components::ShoppingCartItem
23
+ # @return [Minfraud::Components::ShoppingCart] ShoppingCart instance
24
+ def resolve(params)
25
+ ShoppingCartItem.new(params)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ module Minfraud
2
+ module Components
3
+ class ShoppingCartItem < Base
4
+ # @attribute category
5
+ # @return [String] The category of the item
6
+ attr_accessor :category
7
+
8
+ # @attribute item_id
9
+ # @return [String] The internal ID of the item
10
+ attr_accessor :item_id
11
+
12
+ # @attribute quantity
13
+ # @return [Integer] The quantity of the item in the shopping cart
14
+ attr_accessor :quantity
15
+
16
+ # @attribute price
17
+ # @return [Float] The per-unit price of this item in the shopping cart. This should use the same currency as the order currency
18
+ attr_accessor :price
19
+
20
+ # Creates Minfraud::Components::ShoppingCartItem instance
21
+ # @param [Hash] params hash of parameters
22
+ # @return [Minfraud::Components::ShoppingCartItem] ShoppingCartItem instance
23
+ def initialize(params = {})
24
+ @category = params[:category]
25
+ @item_id = params[:item_id]
26
+ @quantity = params[:quantity]
27
+ @price = params[:price]
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+
@@ -0,0 +1,30 @@
1
+ module Minfraud
2
+ module Enum
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def mapping
9
+ @mapping ||= {}
10
+ end
11
+
12
+ def enum_accessor(attribute, assignable_values)
13
+ mapping[attribute] = assignable_values.map(&:to_s)
14
+
15
+ self.class.instance_eval do
16
+ define_method("#{attribute}_values") { mapping[attribute] }
17
+ end
18
+
19
+ self.class_eval do
20
+ define_method("#{attribute}") { instance_variable_get("@#{attribute}") }
21
+
22
+ define_method "#{attribute}=" do |value|
23
+ raise NotEnumValueError, 'Value is not permitted' unless self.class.mapping[attribute].include?(value.to_s)
24
+ instance_variable_set("@#{attribute}", value.to_s)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,45 @@
1
+ module Minfraud
2
+ module ErrorHandler
3
+ class << self
4
+ # Returns a response if status code is 200, rises an error otherwise
5
+ # @param [Minfraud::HTTPService::Response] response
6
+ # @return [Minfraud::HTTPService::Response] if status code is 200
7
+ def inspect(response)
8
+ return response if response.status == 200
9
+
10
+ raise *STATUS_CODES.fetch(response.code&.intern, [ServerError, 'Service not available'])
11
+ end
12
+
13
+ # A hash that maps status codes returned by minFraud with errors & messages
14
+ STATUS_CODES = {
15
+ IP_ADDRESS_INVALID: [
16
+ ClientError, 'You have no supplied a valid IPv4 or IPv6 address'
17
+ ],
18
+ IP_ADDRESS_REQUIRED: [
19
+ ClientError, 'You have not supplied an IP address which is required filed'
20
+ ],
21
+ IP_ADDRESS_RESERVED: [
22
+ ClientError, 'You have supplied an IP address which is reserved'
23
+ ],
24
+ JSON_INVALID: [
25
+ ClientError, 'JSON body cannot be decoded'
26
+ ],
27
+ AUTHORIZATION_INVALID: [
28
+ AuthorizationError, 'Invalid license key and / or user id'
29
+ ],
30
+ LICENSE_KEY_REQUIRED: [
31
+ AuthorizationError, 'You have not supplied a license key'
32
+ ],
33
+ USER_ID_REQUIRED: [
34
+ AuthorizationError, 'You have not supplied a user id'
35
+ ],
36
+ INSUFFICIENT_FUNDS: [
37
+ ClientError, 'The license key you have provided does not have a sufficient funds to use this service'
38
+ ],
39
+ PERMISSION_REQUIRED: [
40
+ ClientError, 'You do not have permission to use this service'
41
+ ]
42
+ }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,10 @@
1
+ module Minfraud
2
+ # A list of Minfraud custom errors
3
+ class BaseError < StandardError; end
4
+
5
+ class NotEnumValueError < BaseError; end
6
+ class RequestFormatError < BaseError; end
7
+ class ClientError < BaseError; end
8
+ class AuthorizationError < BaseError; end
9
+ class ServerError < BaseError; end
10
+ end
@@ -0,0 +1,31 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module Minfraud
5
+ module HTTPService
6
+ class << self
7
+ # @return [Hash] default HTTPService configuration
8
+ def configuration
9
+ {
10
+ middleware: DEFAULT_MIDDLEWARE,
11
+ server: DEFAULT_SERVER
12
+ }
13
+ end
14
+ end
15
+
16
+ # Minfraud default middleware stack
17
+ DEFAULT_MIDDLEWARE = Proc.new do |builder|
18
+ builder.request :json
19
+
20
+ builder.basic_auth *::Minfraud.configuration.values
21
+
22
+ builder.response :mashify
23
+ builder.response :json, content_type: /\bjson$/
24
+
25
+ builder.adapter Faraday.default_adapter
26
+ end
27
+
28
+ # Minfraud default server
29
+ DEFAULT_SERVER = 'https://minfraud.maxmind.com/minfraud/v2.0'
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ require 'faraday'
2
+
3
+ module Minfraud
4
+ module HTTPService
5
+ class Request
6
+ # @attribute middleware
7
+ # @return [Proc] A proc containing Faraday configuration
8
+ attr_reader :middleware
9
+
10
+ # @attribute server
11
+ # @return [String] an API endpoint
12
+ attr_reader :server
13
+
14
+ # Creates Minfraud::HTTPService::Request instance
15
+ # @param [Hash] params hash of parameters
16
+ # @return [Minfraud::HTTPService::Request] Request instance
17
+ def initialize(params)
18
+ @middleware = params[:middleware]
19
+ @server = params[:server]
20
+ end
21
+
22
+ # Performs an HTTP request to the specified endpoint with given body
23
+ # @param [Hash] params hash of parameters.
24
+ # @return [Farday::Response] Faraday::Response instance
25
+ def perform(params)
26
+ adapter.send(*params.values_at(:verb, :endpoint, :body))
27
+ end
28
+
29
+ private
30
+ # Creates memoized Faraday::Connection instance
31
+ # @return [Faraday::Connection] Faraday::Connection instance
32
+ def adapter
33
+ @adapter ||= Faraday.new(server, {}, &middleware)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,36 @@
1
+ module Minfraud
2
+ module HTTPService
3
+ class Response
4
+ # @attribute status
5
+ # @return [Integer] HTTP response status
6
+ attr_reader :status
7
+
8
+ # @attribute body
9
+ # @return [Hash] HTTP response body
10
+ attr_reader :body
11
+
12
+ # @attribute headers
13
+ # @return [Hash] HTTP response headers
14
+ attr_reader :headers
15
+
16
+ # @attribute code
17
+ # @return [String] minFraud specific HTTP response code
18
+ attr_reader :code
19
+
20
+ # Creates Minfraud::HTTPService::Response instance
21
+ # @param [Hash] params hash of parameters
22
+ # @return [Minfraud::HTTPService::Response] Response instance
23
+ def initialize(params)
24
+ @status = params[:status]
25
+ @body = params[:body]
26
+ @headers = params[:headers]
27
+ end
28
+
29
+ # Returns minFraud specific response code
30
+ # @return [String] minFraud specific request code
31
+ def code
32
+ body.code if body.respond_to?(:code)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ module Minfraud
2
+ module Resolver
3
+ 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
8
+ def assign(context:, params:)
9
+ Array(params).each do |key, value|
10
+ raise RequestFormatError, "#{key} does not belong to request document format" unless MAPPING[key]
11
+
12
+ entity = MAPPING[key].new(value) unless value.is_a?(MAPPING[key])
13
+ context.send("#{key}=", entity || value)
14
+ end
15
+ end
16
+ end
17
+
18
+ # Mapping between components & minFraud request keys
19
+ 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
+ }
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Minfraud
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'minfraud/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "minfraud"
8
+ spec.version = Minfraud::VERSION
9
+ spec.authors = ["kushnir.yb"]
10
+ spec.email = ["kushnir.yb@gmail.com"]
11
+
12
+ spec.summary = %q{Ruby interface to the MaxMind minFraud v2.0 API services}
13
+ spec.homepage = "https://github.com/kushniryb/minfraud-api-v2"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency 'faraday'
22
+ spec.add_runtime_dependency 'faraday_middleware'
23
+ spec.add_development_dependency "bundler", "~> 1.12"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0"
26
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minfraud
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - kushnir.yb
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-10-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description:
84
+ email:
85
+ - kushnir.yb@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - CODE_OF_CONDUCT.md
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/console
99
+ - bin/setup
100
+ - lib/minfraud.rb
101
+ - lib/minfraud/assessments.rb
102
+ - lib/minfraud/components/account.rb
103
+ - lib/minfraud/components/addressable.rb
104
+ - lib/minfraud/components/base.rb
105
+ - lib/minfraud/components/billing.rb
106
+ - lib/minfraud/components/credit_card.rb
107
+ - lib/minfraud/components/device.rb
108
+ - lib/minfraud/components/email.rb
109
+ - lib/minfraud/components/event.rb
110
+ - lib/minfraud/components/order.rb
111
+ - lib/minfraud/components/payment.rb
112
+ - lib/minfraud/components/shipping.rb
113
+ - lib/minfraud/components/shopping_cart.rb
114
+ - lib/minfraud/components/shopping_cart_item.rb
115
+ - lib/minfraud/enum.rb
116
+ - lib/minfraud/error_handler.rb
117
+ - lib/minfraud/errors.rb
118
+ - lib/minfraud/http_service.rb
119
+ - lib/minfraud/http_service/request.rb
120
+ - lib/minfraud/http_service/response.rb
121
+ - lib/minfraud/resolver.rb
122
+ - lib/minfraud/version.rb
123
+ - minfraud.gemspec
124
+ homepage: https://github.com/kushniryb/minfraud-api-v2
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.6.6
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Ruby interface to the MaxMind minFraud v2.0 API services
148
+ test_files: []
149
+ has_rdoc: