Sha256: 7e3eb77315126c609c50db4627ed23f99d513aac907eeadd551b4130ac258792

Contents?: true

Size: 1.38 KB

Versions: 1

Compression:

Stored size: 1.38 KB

Contents

require "valid_credit_card"

module ValidCreditCard
  class CreditCard
    CARD_TYPES = {
      visa: /\A4[0-9]{12}(?:[0-9]{3})?\z/,
      master_card: /\A5[1-5][0-9]{14}\z/,
      maestro: /(\A6759[0-9]{2}([0-9]{10})$)|(\A6759[0-9]{2}([0-9]{12})$)|(\A6759[0-9]{2}([0-9]{13})$)/,
      diners_club: /\A3(?:0[0-5]|[68][0-9])[0-9]{11}\z/,
      amex: /\A3[47][0-9]{13}\z/,
      discover: /\A6(?:011|5[0-9]{2})[0-9]{12}\z/,
      jcb: /\A(?:2131|1800|35\d{3})\d{11}\z/
    }

    attr_accessor :number

    # == Initializer
    def initialize(number)
      @number = number.to_s
    end

    def valid?
      (verify_luhn && strip_number.length >= 11 && card_type.present?) || is_test_number?
    end

    def card_type
      CARD_TYPES.select{ |k, v| (strip_number =~ v).present? }.keys[0].to_s
    end

    def is_test_number?
      ValidCreditCard.test_numbers.include?(strip_number)
    end

    def verify_luhn
      total = strip_number.reverse().split(//).inject([0,0]) do |accum, n|
        n = n.to_i
        accum[0] += (accum[1] % 2 == 1 ? rotate(n * 2) : n)
        accum[1] += 1
        accum
      end

      (total[0] % 10 == 0)
    end

    CARD_TYPES.each do |k, v|
      define_method "is_#{k.to_s}?" do
        (strip_number =~ v).present?
      end
    end

    protected

    def strip_number
      number.gsub(/\s/,'')
    end

    def rotate(n)
      n > 9 ? (n % 10 + 1) : n
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
valid_credit_card-0.1.0 lib/valid_credit_card/credit_card.rb