diff --git a/core/app/models/spree/credit_card.rb b/core/app/models/spree/credit_card.rb index b49c3be40e6..47c6142ed78 100644 --- a/core/app/models/spree/credit_card.rb +++ b/core/app/models/spree/credit_card.rb @@ -27,14 +27,22 @@ class CreditCard < Spree::Base # needed for some of the ActiveMerchant gateways (eg. SagePay) alias_attribute :brand, :cc_type + # Taken from ActiveMerchant + # https://github.com/activemerchant/active_merchant/blob/2f2acd4696e8de76057b5ed670b9aa022abc1187/lib/active_merchant/billing/credit_card_methods.rb#L5 CARD_TYPES = { - visa: /^4[0-9]{12}(?:[0-9]{3})?$/, - master: /(^5[1-5][0-9]{14}$)|(^6759[0-9]{2}([0-9]{10})$)|(^6759[0-9]{2}([0-9]{12})$)|(^6759[0-9]{2}([0-9]{13})$)/, - diners_club: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/, - american_express: /^3[47][0-9]{13}$/, - discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/, - jcb: /^(?:2131|1800|35\d{3})\d{11}$/ - } + 'visa' => /^4\d{12}(\d{3})?(\d{3})?$/, + 'master' => /^(5[1-5]\d{4}|677189|222[1-9]\d{2}|22[3-9]\d{3}|2[3-6]\d{4}|27[01]\d{3}|2720\d{2})\d{10}$/, + 'discover' => /^(6011|65\d{2}|64[4-9]\d)\d{12}|(62\d{14})$/, + 'american_express' => /^3[47]\d{13}$/, + 'diners_club' => /^3(0[0-5]|[68]\d)\d{11}$/, + 'jcb' => /^35(28|29|[3-8]\d)\d{12}$/, + 'switch' => /^6759\d{12}(\d{2,3})?$/, + 'solo' => /^6767\d{12}(\d{2,3})?$/, + 'dankort' => /^5019\d{12}$/, + 'maestro' => /^(5[06-8]|6\d)\d{10,17}$/, + 'forbrugsforeningen' => /^600722\d{10}$/, + 'laser' => /^(6304|6706|6709|6771(?!89))\d{8}(\d{4}|\d{6,7})?$/ + }.freeze def address_attributes=(attributes) self.address = Address.immutable_merge(address, attributes) @@ -98,8 +106,10 @@ def set_last_digits # @return [String] the credit card type if it can be determined from the # number, otherwise the empty string def try_type_from_number - numbers = number.delete(' ') if number - CARD_TYPES.find{ |type, pattern| return type.to_s if numbers =~ pattern }.to_s + CARD_TYPES.each do |type, pattern| + return type if number =~ pattern + end + '' end # @return [Boolean] true when a verification value is present diff --git a/core/spec/models/spree/credit_card_spec.rb b/core/spec/models/spree/credit_card_spec.rb index 17c5cd9211b..59d8a57f4e6 100644 --- a/core/spec/models/spree/credit_card_spec.rb +++ b/core/spec/models/spree/credit_card_spec.rb @@ -257,6 +257,10 @@ def self.payment_states credit_card.cc_type = '' expect(credit_card.cc_type).to eq('master') + credit_card.number = '2221000000000000' + credit_card.cc_type = '' + expect(credit_card.cc_type).to eq('master') + credit_card.number = '378282246310005' credit_card.cc_type = '' expect(credit_card.cc_type).to eq('american_express')