Module: ActiveMerchant::Billing::CreditCardMethods

Included in:
CreditCard
Defined in:
lib/active_merchant/billing/credit_card_methods.rb

Overview

Convenience methods that can be included into a custom Credit Card object, such as an ActiveRecord based Credit Card object.

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

CARD_COMPANY_DETECTORS =
{
  'visa'               => ->(num) { num =~ /^4\d{12}(\d{3})?(\d{3})?$/ },
  'master'             => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), MASTERCARD_RANGES) },
  'elo'                => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), ELO_RANGES) },
  'alelo'              => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), ALELO_RANGES) },
  'discover'           => ->(num) { num =~ /^(6011|65\d{2}|64[4-9]\d)\d{12,15}|(62\d{14,17})$/ },
  'american_express'   => ->(num) { num =~ /^3[47]\d{13}$/ },
  'naranja'            => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), NARANJA_RANGES) },
  'diners_club'        => ->(num) { num =~ /^3(0[0-5]|[68]\d)\d{11}$/ },
  'jcb'                => ->(num) { num =~ /^35(28|29|[3-8]\d)\d{12}$/ },
  'dankort'            => ->(num) { num =~ /^5019\d{12}$/ },
  'maestro'            => ->(num) { (12..19).cover?(num&.size) && in_bin_range?(num.slice(0, 6), MAESTRO_RANGES) },
  'forbrugsforeningen' => ->(num) { num =~ /^600722\d{10}$/ },
  'sodexo'             => ->(num) { num =~ /^(606071|603389|606070|606069|606068|600818)\d{10}$/ },
  'vr'                 => ->(num) { num =~ /^(627416|637036)\d{10}$/ },
  'cabal'              => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 8), CABAL_RANGES) },
  'carnet'             => lambda { |num|
    num&.size == 16 && (
      in_bin_range?(num.slice(0, 6), CARNET_RANGES) ||
      CARNET_BINS.any? { |bin| num.slice(0, bin.size) == bin }
    )
  }
}
ELECTRON_RANGES =
[
  [400115],
  (400837..400839),
  (412921..412923),
  [417935],
  (419740..419741),
  (419773..419775),
  [424519],
  (424962..424963),
  [437860],
  [444000],
  [459472],
  (484406..484411),
  (484413..484414),
  (484418..484418),
  (484428..484455),
  (491730..491759),
]
CARNET_RANGES =
[
  (506199..506499),
]
CARNET_BINS =
Set.new(
  [
    '286900', '502275', '606333', '627535', '636318', '636379', '639388',
    '639484', '639559', '50633601', '50633606', '58877274', '62753500',
    '60462203', '60462204', '588772'
  ]
)
MASTERCARD_RANGES =
[
  (222100..272099),
  (510000..559999),
]
MAESTRO_RANGES =
[
  (561200..561269),
  (561271..561299),
  (561320..561356),
  (581700..581751),
  (581753..581800),
  (589998..591259),
  (591261..596770),
  (596772..598744),
  (598746..599999),
  (600297..600314),
  (600316..600335),
  (600337..600362),
  (600364..600382),
  (601232..601254),
  (601256..601276),
  (601640..601652),
  (601689..601700),
  (602011..602050),
  (639000..639099),
  (670000..679999),
]
ELO_RANGES =

dev.elo.com.br/apis/tabela-de-bins, download csv from left sidebar

[
  506707..506708, 506715..506715, 506718..506722, 506724..506724, 506726..506736, 506739..506739, 506741..506743,
  506745..506747, 506753..506753, 506774..506776, 506778..506778, 509000..509001, 509003..509003, 509007..509007,
  509020..509022, 509035..509035, 509039..509042, 509045..509045, 509048..509048, 509051..509071, 509073..509074,
  509077..509080, 509084..509084, 509091..509094, 509098..509098, 509100..509100, 509104..509104, 509106..509109,
  627780..627780, 636368..636368, 650031..650033, 650035..650045, 650047..650047, 650406..650410, 650434..650436,
  650439..650439, 650485..650504, 650506..650530, 650577..650580, 650582..650591, 650721..650727, 650901..650922,
  650928..650928, 650938..650939, 650946..650948, 650954..650955, 650962..650963, 650967..650967, 650971..650971,
  651652..651667, 651675..651678, 655000..655010, 655012..655015, 655051..655052, 655056..655057
]
ALELO_RANGES =

Alelo provides BIN ranges by e-mailing them out periodically. The BINs beginning with the digit 4 overlap with Visa’s range of valid card numbers. By placing the ‘alelo’ entry in CARD_COMPANY_DETECTORS below the ‘visa’ entry, we identify these cards as Visa. This works because transactions with such cards will run on Visa rails.

[
  402588..402588, 404347..404347, 405876..405876, 405882..405882, 405884..405884,
  405886..405886, 430471..430471, 438061..438061, 438064..438064, 470063..470066,
  496067..496067, 506699..506704, 506706..506706, 506713..506714, 506716..506716,
  506749..506750, 506752..506752, 506754..506756, 506758..506762, 506764..506767,
  506770..506771, 509015..509019, 509880..509882, 509884..509885, 509987..509988
]
CABAL_RANGES =
[
  60420100..60440099,
  58965700..58965799,
  60352200..60352299
]
NARANJA_RANGES =
[
  589562..589562
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.in_bin_range?(number, ranges) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
133
134
135
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 130

def self.in_bin_range?(number, ranges)
  bin = number.to_i
  ranges.any? do |range|
    range.cover?(bin)
  end
end

.included(base) ⇒ Object



126
127
128
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 126

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#card_verification_value_length(brand) ⇒ Object



170
171
172
173
174
175
176
177
178
179
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 170

def card_verification_value_length(brand)
  case brand
  when 'american_express'
    4
  when 'maestro'
    0
  else
    3
  end
end

#credit_card?Boolean

Returns:

  • (Boolean)


141
142
143
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 141

def credit_card?
  true
end

#electron?Boolean

Returns if the card matches known Electron BINs

Returns:

  • (Boolean)


186
187
188
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 186

def electron?
  self.class.electron?(number)
end

#valid_card_verification_value?(cvv, brand) ⇒ Boolean

Credit card providers have 3 digit verification values This isn’t standardised, these are called various names such as CVC, CVV, CID, CSC and more See: en.wikipedia.org/wiki/Card_security_code American Express is the exception with 4 digits

Below are links from the card providers with their requirements visa: usa.visa.com/personal/security/3-digit-security-code.jsp master: www.mastercard.com/ca/merchant/en/getstarted/Anatomy_MasterCard.html jcb: www.jcbcard.com/security/info.html diners_club: www.dinersclub.com/assets/DinersClub_card_ID_features.pdf discover: www.discover.com/credit-cards/help-center/glossary.html american_express: online.americanexpress.com/myca/fuidfyp/us/action?request_type=un_fuid&Face=en_US

Returns:

  • (Boolean)


166
167
168
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 166

def valid_card_verification_value?(cvv, brand)
  cvv.to_s =~ /^\d{#{card_verification_value_length(brand)}}$/
end

#valid_expiry_year?(year) ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 145

def valid_expiry_year?(year)
  (Time.now.year..Time.now.year + 20).cover?(year.to_i)
end

#valid_issue_number?(number) ⇒ Boolean

Returns:

  • (Boolean)


181
182
183
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 181

def valid_issue_number?(number)
  (number.to_s =~ /^\d{1,2}$/)
end

#valid_month?(month) ⇒ Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 137

def valid_month?(month)
  (1..12).cover?(month.to_i)
end

#valid_start_year?(year) ⇒ Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/active_merchant/billing/credit_card_methods.rb', line 149

def valid_start_year?(year)
  ((year.to_s =~ /^\d{4}$/) && (year.to_i > 1987))
end