credit_card_info 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7e1751e3d0337ae28f147917b8091ea6a4413a8e5c8e4fc0f73cab67e717415f
4
+ data.tar.gz: ec9285e450f14ec6dea2141f8e5218ce46119acd1e23fe66ac9400cc18755d14
5
+ SHA512:
6
+ metadata.gz: 5dcabba34c37dc559488a2d8d24f1f91621fb89c044c0806efb82571ef12f926f48f83d843928b65728692c0256a1346c68e7ac97c98ae70f101f527041fd2c3
7
+ data.tar.gz: 3461a76e7c6d17574ad2765e7c196f9a1992fda4fc73e97ab0f804d06d075f703c09ccacea6c989a02e70230e0c1c6e23e2459288dda8da395e6edddbe40d6a8
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2022-03-11
4
+
5
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in credit-card-info.gemspec
6
+ gemspec
7
+
8
+ group :development, :test do
9
+ gem "rake", "~> 13.0"
10
+ gem "rubocop", "~> 1.11.0"
11
+ gem "rubocop-performance", "~> 1.10"
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,53 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ credit_card_info (0.1.0)
5
+ credit_card_bins (~> 0.0.1)
6
+ dry-configurable (>= 0.13)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ast (2.4.2)
12
+ concurrent-ruby (1.1.9)
13
+ credit_card_bins (0.0.3)
14
+ dry-configurable (0.14.0)
15
+ concurrent-ruby (~> 1.0)
16
+ dry-core (~> 0.6)
17
+ dry-core (0.7.1)
18
+ concurrent-ruby (~> 1.0)
19
+ parallel (1.21.0)
20
+ parser (3.1.1.0)
21
+ ast (~> 2.4.1)
22
+ rainbow (3.1.1)
23
+ rake (13.0.6)
24
+ regexp_parser (2.2.1)
25
+ rexml (3.2.5)
26
+ rubocop (1.11.0)
27
+ parallel (~> 1.10)
28
+ parser (>= 3.0.0.0)
29
+ rainbow (>= 2.2.2, < 4.0)
30
+ regexp_parser (>= 1.8, < 3.0)
31
+ rexml
32
+ rubocop-ast (>= 1.2.0, < 2.0)
33
+ ruby-progressbar (~> 1.7)
34
+ unicode-display_width (>= 1.4.0, < 3.0)
35
+ rubocop-ast (1.16.0)
36
+ parser (>= 3.1.1.0)
37
+ rubocop-performance (1.13.3)
38
+ rubocop (>= 1.7.0, < 2.0)
39
+ rubocop-ast (>= 0.4.0)
40
+ ruby-progressbar (1.11.0)
41
+ unicode-display_width (2.1.0)
42
+
43
+ PLATFORMS
44
+ x86_64-linux
45
+
46
+ DEPENDENCIES
47
+ credit_card_info!
48
+ rake (~> 13.0)
49
+ rubocop (~> 1.11.0)
50
+ rubocop-performance (~> 1.10)
51
+
52
+ BUNDLED WITH
53
+ 2.2.15
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2022 credit_card_info
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # CreditCardInfo
2
+
3
+ The Issuer Identification Number (IIN), previously known as Bank Identification Number (BIN) is the first six numbers of a credit card.
4
+ These identify the institution that issued the card to the card holder and
5
+ provide useful information about the card that can help make your payments flow smarter.
6
+
7
+ Uses two data providers:
8
+ * First bincodes.com API (require registration and api key).
9
+ * Second 'credit_card_bins' gem data.
10
+
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'credit_card_info'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle install
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install credit_card_info
27
+
28
+
29
+ ## Configuration
30
+
31
+ ```ruby
32
+ CreditCardInfo::Config.configure do |config|
33
+ config.bincodes.api_key = "your_api_key"
34
+ config.bincodes.api_url = "https://api.bincodes.com"
35
+
36
+ # class for make HttpRequests
37
+ config.bincodes.http_klass = Net::HTTP
38
+ # set timeout for api request (10 by default)
39
+ config.bincodes.timeout = 10
40
+
41
+
42
+ # set cache provider class, Rails.cache by default when using in Rails application
43
+ config.cache.provider = Rails.cache
44
+ # set cache keys lifeitime, default is 31 day
45
+ config.cache.ttl = 2678400
46
+ # set cache keys prefix, result key will be prefix:bin
47
+ config.cache.key_prefix = "ccinfo"
48
+
49
+ # also you can use custom logger instance, default is Rails.logger for Rails apps, and stdout for others
50
+ config.logger = Logger.new($stdout)
51
+ end
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ You just need make call:
57
+
58
+ ```ruby
59
+ bin = '515735'
60
+ CreditCardInfo.fetch(bin)
61
+ # {
62
+ # bin: "515735",
63
+ # bank: "CITIBANK, N.A.",
64
+ # card: "MASTERCARD",
65
+ # type: "CREDIT",
66
+ # level: "WORLD CARD",
67
+ # country: "United States",
68
+ # countrycode: "US"
69
+ # }
70
+ ```
71
+
72
+ By default that call will be search firstly via bincodes.com, and if find nothing will search via `credit_card_bins` gem.
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "credit_card_info"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/credit_card_info/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "credit_card_info"
7
+ s.version = CreditCardInfo::VERSION
8
+ s.authors = ["Alexey Zhuravlev"]
9
+ s.email = ["alexey.g.zhuravlev@gmail.com"]
10
+ s.summary = "Find credit card info by BIN(IIN)"
11
+ s.description = <<-DESC
12
+ Fetch credit card info from www.bincodes.com with configurable fallback to https://github.com/hugolantaume/credit_card_bins data.
13
+ Also provides caching results for decreasing bincodesAPI request count/
14
+ DESC
15
+
16
+ s.license = "MIT"
17
+ s.homepage = "https://github.com/azhuravlev/credit_card_info"
18
+
19
+ s.metadata["allowed_push_host"] = "https://rubygems.org"
20
+
21
+ s.required_ruby_version = ">= 2.7"
22
+
23
+ s.add_dependency "credit_card_bins", "~> 0.0.1"
24
+ s.add_dependency "dry-configurable", ">= 0.13"
25
+
26
+ s.files = `find *`.split("\n").uniq.sort.reject(&:empty?)
27
+ s.test_files = `find spec/*`.split("\n")
28
+ s.executables = []
29
+ s.require_paths = ["lib"]
30
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditCardInfo
4
+ class Cache
5
+ def self.fetch(code, &block)
6
+ return yield unless config.provider
7
+
8
+ config.provider.fetch("#{config.key_prefix}:#{code}", expires_in: config.ttl, &block)
9
+ end
10
+
11
+ def self.config
12
+ CreditCardInfo.config.cache
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "dry-configurable"
5
+
6
+ module CreditCardInfo
7
+ class Config
8
+ extend Dry::Configurable
9
+
10
+ setting :bincodes do
11
+ setting :api_key, default: ""
12
+ setting :api_url, default: "https://api.bincodes.com"
13
+ setting :timeout, default: 10
14
+ setting :http_klass, default: Net::HTTP
15
+ end
16
+
17
+ setting :cache do
18
+ setting :provider, default: defined?(Rails) ? Rails.cache : nil
19
+ setting :ttl, default: 2678400 # 31 days
20
+ setting :key_prefix, default: "ccinfo"
21
+ end
22
+
23
+ setting :logger, default: defined?(Rails) ? Rails.logger : Logger.new($stdout)
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "json"
6
+
7
+ module CreditCardInfo
8
+ module Providers
9
+ class Bincodes
10
+ def self.fetch(code)
11
+ uri = URI("#{config.api_url}/bin/json/#{config.api_key}/#{code}")
12
+
13
+ http = config.http_klass.new(uri.host, uri.port)
14
+ http.use_ssl = true
15
+ http.read_timeout = config.timeout
16
+
17
+ request = Net::HTTP::Get.new(uri)
18
+ response = http.start { |h| h.request(request) }
19
+
20
+ parse_response(response)
21
+ rescue StandardError => e
22
+ CreditCardInfo::Response.new(error: { code: e.class, message: e.message })
23
+ end
24
+
25
+ def self.parse_response(response)
26
+ unless response.is_a?(Net::HTTPSuccess)
27
+ return CreditCardInfo::Response.new(error: { code: response.code,
28
+ message: "Unexpected error from bincodes api" })
29
+ end
30
+
31
+ data = JSON.parse(response.body, symbolize_names: true)
32
+
33
+ CreditCardInfo::Response.new(data: data).tap do |res|
34
+ res.error = { code: data[:error], message: data[:message] } if data[:error]
35
+ end
36
+ rescue JSONError => e
37
+ CreditCardInfo::Response.new(error: { code: e.class, message: "Invalid data from bincodes api: #{body}" })
38
+ end
39
+
40
+ def self.config
41
+ CreditCardInfo.config.bincodes
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "credit_card_bins"
4
+
5
+ module CreditCardInfo
6
+ module Providers
7
+ class CreditCardBins
8
+ def self.fetch(code)
9
+ bin = CreditCardBin.new(code)
10
+ CreditCardInfo::Response.new(
11
+ data: {
12
+ bin: bin.bin,
13
+ bank: bin.issuer,
14
+ card: bin.brand,
15
+ type: bin.type,
16
+ level: bin.category,
17
+ country: bin.data.dig("country", "name"),
18
+ countrycode: bin.data.dig("country", "alpha_2")
19
+ }
20
+ )
21
+ rescue StandardError => e
22
+ CreditCardInfo::Response.new(error: { code: e.class, message: e.message })
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "providers/bincodes"
4
+ require_relative "providers/credit_card_bins"
5
+
6
+ module CreditCardInfo
7
+ module Proxy
8
+ # @return [Hash, NilClass] bin description
9
+ def self.fetch(code)
10
+ bincode_response = Providers::Bincodes.fetch(code)
11
+ return bincode_response.data if bincode_response.valid?
12
+
13
+ bincode_response.log_error
14
+
15
+ card_bins_response = Providers::CreditCardBins.fetch(code)
16
+ return card_bins_response.data if card_bins_response.valid?
17
+
18
+ card_bins_response.log_error
19
+
20
+ nil
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditCardInfo
4
+ Response = Struct.new(:error, :data, keyword_init: true)
5
+ INFO_METHODS = %i[
6
+ bin
7
+ bank
8
+ card
9
+ type
10
+ level
11
+ country
12
+ countrycode
13
+ ].freeze
14
+
15
+ class Response
16
+ INFO_METHODS.each do |m|
17
+ define_method(m) { data.fetch(m, "") }
18
+ end
19
+
20
+ def valid?
21
+ error.nil?
22
+ end
23
+
24
+ def log_error
25
+ return unless CreditCardInfo.logger
26
+
27
+ CreditCardInfo.logger.warn "Wrong response: error_code=#{error[:code]} error_message=#{error[:message]}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditCardInfo
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "credit_card_info/proxy"
4
+ require "credit_card_info/cache"
5
+ require "credit_card_info/config"
6
+ require "credit_card_info/response"
7
+ require "credit_card_info/version"
8
+
9
+ module CreditCardInfo
10
+ class Error < StandardError; end
11
+
12
+ def self.config
13
+ @config ||= Config.config
14
+ end
15
+
16
+ def self.fetch(value)
17
+ code = extract_bin(value)
18
+ Cache.fetch(code) { Proxy.fetch(code) }
19
+ end
20
+
21
+ def self.logger
22
+ @logger ||= config.logger
23
+ end
24
+
25
+ # @return [String] first 5 digits of credit card number i.e. BIN
26
+ def self.extract_bin(value)
27
+ value.to_s.delete("\s")[0..5]
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: credit_card_info
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexey Zhuravlev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: credit_card_bins
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-configurable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.13'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.13'
41
+ description: |2
42
+ Fetch credit card info from www.bincodes.com with configurable fallback to https://github.com/hugolantaume/credit_card_bins data.
43
+ Also provides caching results for decreasing bincodesAPI request count/
44
+ email:
45
+ - alexey.g.zhuravlev@gmail.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - CHANGELOG.md
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - LICENSE
54
+ - README.md
55
+ - Rakefile
56
+ - bin/console
57
+ - credit_card_info.gemspec
58
+ - lib/credit_card_info.rb
59
+ - lib/credit_card_info/cache.rb
60
+ - lib/credit_card_info/config.rb
61
+ - lib/credit_card_info/providers/bincodes.rb
62
+ - lib/credit_card_info/providers/credit_card_bins.rb
63
+ - lib/credit_card_info/proxy.rb
64
+ - lib/credit_card_info/response.rb
65
+ - lib/credit_card_info/version.rb
66
+ homepage: https://github.com/azhuravlev/credit_card_info
67
+ licenses:
68
+ - MIT
69
+ metadata:
70
+ allowed_push_host: https://rubygems.org
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '2.7'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubygems_version: 3.1.6
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Find credit card info by BIN(IIN)
90
+ test_files: []