class ActiveModel::Validations::CreditCardFieldsValidator
Constants
- ERROR_TYPES
- PROVIDERS
Attributes
cc_cvv[RW]
cc_first_name[RW]
cc_last_name[RW]
cc_month[RW]
cc_number[RW]
cc_owner[RW]
cc_providers[RW]
cc_type[RW]
cc_year[RW]
custom_messages[RW]
options[RW]
using_owner[RW]
Public Class Methods
new(options={})
click to toggle source
# File lib/validate_credit_card_fields.rb, line 30 def initialize(options={}) @options = options @custom_messages = {} @cc_number = init_option(:number, :cc_number) @cc_cvv = init_option(:cvv, :cc_cvv) @cc_month = init_option(:month, :cc_month) @cc_year = init_option(:year, :cc_year) @cc_providers = options[:providers] @using_owner = !options[:owner].nil? || options[:first_name].nil? || options[:last_name].nil? if @using_owner @cc_owner = init_option(:owner, :cc_owner) else @cc_first_name = init_option(:first_name, :cc_first_name) @cc_last_name = init_option(:last_name, :cc_last_name) end end
Public Instance Methods
init_option(key, default)
click to toggle source
# File lib/validate_credit_card_fields.rb, line 47 def init_option(key, default) if options[key].is_a? Hash init_option_from_hash options[key], default else options[key] || default end end
init_option_from_hash(hash, default)
click to toggle source
# File lib/validate_credit_card_fields.rb, line 55 def init_option_from_hash(hash, default) field_name = hash[:field] || default custom_messages[field_name] = hash.select{ |k,_| ERROR_TYPES.include? k } field_name end
validate(record)
click to toggle source
# File lib/validate_credit_card_fields.rb, line 61 def validate(record) @record = record check_fields_format @cc_type = get_cc_type validate_fields_presence validate_cc_number validate_cc_cvv validate_cc_month validate_cc_year validate_cc_expiry_date end
Private Instance Methods
add_error(field, message)
click to toggle source
# File lib/validate_credit_card_fields.rb, line 141 def add_error(field, message) @record.errors.add(field, error_message(field, message)) if @record.errors[field].blank? end
check_fields_format()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 161 def check_fields_format invalid_attr = validated_fields.find do |attr| !@record.public_send(attr).is_a?(NilClass) && !@record.public_send(attr).is_a?(String) end if invalid_attr raise CCTypeError, "#{invalid_attr} is a #{@record.public_send(invalid_attr).class}, String expected." end end
error_message(field, message)
click to toggle source
# File lib/validate_credit_card_fields.rb, line 153 def error_message(field, message) custom_messages[field].try(:[], message) || translate_error(message) end
get_cc_number()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 149 def get_cc_number @record.public_send(cc_number).try(:delete, ' ') end
get_cc_type()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 145 def get_cc_type PROVIDERS.find{ |_, regex| regex.match(get_cc_number) }.try(:first) end
luhn_algorithm_valid?()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 129 def luhn_algorithm_valid? return true if @cc_type == :china_union s1 = s2 = 0 get_cc_number.to_s.reverse.chars.each_slice(2) do |odd, even| s1 += odd.to_i double = even.to_i * 2 double -= 9 if double >= 10 s2 += double end (s1 + s2) % 10 == 0 end
translate_error(error)
click to toggle source
# File lib/validate_credit_card_fields.rb, line 157 def translate_error error ::I18n.t("errors.messages.#{error}") end
validate_cc_cvv()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 94 def validate_cc_cvv length = (@cc_type == :amex) ? 4 : 3 unless !@cc_type.nil? && (/\A\d{#{length}}\z/).match(@record.public_send(cc_cvv)) add_error(cc_cvv, :invalid) end end
validate_cc_expiry_date()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 113 def validate_cc_expiry_date if (@record.errors.messages.keys & [cc_year, cc_month]).empty? year = "20#{@record.public_send(cc_year)}".to_i month = @record.public_send(cc_month).to_i date = Date.new(year, month).next_month.prev_day if date < Date.today field = if date.year < Date.today.year cc_year else cc_month end add_error(field, :invalid) end end end
validate_cc_month()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 101 def validate_cc_month unless (/\A\d{2}\z/).match("%02d" % @record.public_send(cc_month).to_i) && @record.public_send(cc_month).to_i.between?(1, 12) add_error(cc_month, :invalid) end end
validate_cc_number()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 85 def validate_cc_number err = if @cc_type.nil? || !luhn_algorithm_valid? :invalid elsif !cc_providers.blank? && !cc_providers.include?(@cc_type) :inclusion end add_error(cc_number, err) if err end
validate_cc_year()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 107 def validate_cc_year unless (/\A\d{2}\z/).match(@record.public_send(cc_year)) && (@record.public_send(cc_year).to_i >= Date.today.year-2000) add_error(cc_year, :invalid) end end
validate_fields_presence()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 79 def validate_fields_presence validated_fields.each do |field| add_error(field, :blank) if @record.public_send(field).blank? end end
validated_fields()
click to toggle source
# File lib/validate_credit_card_fields.rb, line 75 def validated_fields [cc_number, cc_cvv, cc_month, cc_year] + (using_owner ? [cc_owner] : [cc_first_name, cc_last_name]) end