Module: Freemium::CreditCard

Included in:
CreditCard
Defined in:
lib/freemium/credit_card.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

CARD_COMPANIES =
{
  'visa'               => /^4\d{12}(\d{3})?$/,
  'master'             => /^(5[1-5]\d{4}|677189)\d{10}$/,
  'discover'           => /^(6011|65\d{2})\d{12}$/,
  'american_express'   => /^3[47]\d{13}$/,
  'diners_club'        => /^3(0[0-5]|[68]\d)\d{11}$/,
  'jcb'                => /^3528\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[89]\d{11}(\d{2,3})?|670695\d{13})$/
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/freemium/credit_card.rb', line 19

def self.included(base)
  base.class_eval do
    # Essential attributes for a valid, non-bogus creditcards
    attr_accessor :number, :month, :year, :first_name, :last_name

    # Required for Switch / Solo cards
    attr_accessor :start_month, :start_year, :issue_number

    # Optional verification_value (CVV, CVV2 etc). Gateways will try their best to
    # run validation on the passed in value if it is supplied
    attr_accessor :verification_value

    attr_accessible :number, :month, :year, :first_name, :last_name, :start_month, :start_year, :issue_number, :verification_value, :card_type, :zip_code

    has_one :subscription, :class_name => "Subscription"

    before_validation :sanitize_data, :if => :changed?

    validate :validate_card
  end

  base.extend(ClassMethods)
end

Instance Method Details

#addressObject



189
190
191
192
193
194
195
# File 'lib/freemium/credit_card.rb', line 189

def address
  unless @address
    @address = Address.new
    @address.zip = self.zip_code
  end
  @address
end

#changed?Boolean

We’re overriding AR#changed? to include instance vars that aren’t persisted to see if a new card is being set

Returns:

  • (Boolean)


202
203
204
# File 'lib/freemium/credit_card.rb', line 202

def changed?
  card_type_changed? || [:number, :month, :year, :first_name, :last_name, :start_month, :start_year, :issue_number, :verification_value].any? {|attr| !self.send(attr).nil?}
end

#display_numberObject

Show the card number, with all but last 4 numbers replace with “X”. (XXXX-XXXX-XXXX-4338)



180
181
182
183
# File 'lib/freemium/credit_card.rb', line 180

def display_number
  self['display_number'] ||= self.class.mask(number)
  self['display_number']
end

#expiration_dateObject

Provides proxy access to an expiry date object



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/freemium/credit_card.rb', line 146

def expiration_date
  unless self['expiration_date']
    month_days = [nil,31,28,31,30,31,30,31,31,30,31,30,31]
    begin
      month_days[2] = 29 if Date.leap?(@year)
      str = "#{month_days[@month]}/#{@month}/#{@year} 23:59:59"
      self['expiration_date'] = Time.parse(str)
    end
  end
  self['expiration_date']
end

#expired?Boolean

Returns:

  • (Boolean)


158
159
160
161
# File 'lib/freemium/credit_card.rb', line 158

def expired?
  return false unless expiration_date
  Time.now > expiration_date
end

#first_name?Boolean

Returns:

  • (Boolean)


167
168
169
# File 'lib/freemium/credit_card.rb', line 167

def first_name?
  !@first_name.blank?
end

#last_digitsObject



185
186
187
# File 'lib/freemium/credit_card.rb', line 185

def last_digits
  self.class.last_digits(number)
end

#last_name?Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/freemium/credit_card.rb', line 171

def last_name?
  !@last_name.blank?
end

#nameObject



175
176
177
# File 'lib/freemium/credit_card.rb', line 175

def name
  "#{@first_name} #{@last_name}"
end

#name?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/freemium/credit_card.rb', line 163

def name?
  first_name? && last_name?
end

#validate_cardObject

Validation



210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/freemium/credit_card.rb', line 210

def validate_card
  # We don't need to run validations unless it's a new record or the
  # record has changed
  return unless new_record? || changed?

  validate_essential_attributes

  # Bogus card is pretty much for testing purposes. Lets just skip these extra tests if its used
  return if card_type == 'bogus'

  validate_card_type
  validate_card_number
  validate_switch_or_solo_attributes
end