module OffsitePayments::Integrations::RealexOffsite::Common

Constants

CANADIAN_STATES
COUNTRY_PHONE_NUMBERS
CURRENCY_SPECIAL_MINOR_UNITS
US_STATES

Public Instance Methods

add_field(name, value) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 547
def add_field(name, value)
  return if name.blank? || value.blank?
  @fields[name.to_s] = validate(name.to_s, value.to_s)
end
adjust_phone_number_length(country_calling_code, phone_number) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 444
def adjust_phone_number_length(country_calling_code, phone_number)
  country_calling_code[0...3] + '|' + phone_number[0...15]
end
copy_billing_address() click to toggle source

if HPP_ADDRESS_MATCH_INDICATOR is set to TRUE HPP requires the shipping address to be sent from the billing address

# File lib/offsite_payments/integrations/realex_offsite.rb, line 503
def copy_billing_address
  @fields.select { |k, _| k.start_with? 'HPP_BILLING_' }
         .each do |k, v|
           add_field("HPP_SHIPPING_#{k.split('HPP_BILLING_')[1]}", v)
         end
end
create_signature(fields, secret) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 395
def create_signature(fields, secret)
  data = fields.join('.')
  digest = Digest::SHA1.hexdigest(data)
  signed = "#{digest}.#{secret}"
  Digest::SHA1.hexdigest(signed)
end
extract_address_match_indicator(value) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 440
def extract_address_match_indicator(value)
  value ? 'TRUE' : 'FALSE'
end
extract_avs_code(params={}) click to toggle source

This method is used for generating the “BILLING_CODE” field, which is only needed for US, CA and GB. This field is generated by concatenating the zip field and the first line of address with a pipe(|) between them if the country is GB, we remove the non-numeric characters

# File lib/offsite_payments/integrations/realex_offsite.rb, line 429
def extract_avs_code(params={})
  country_code = lookup_country_code(params[:country], :alpha2)
  return unless params[:zip] && params[:address1] && ['US', 'CA', 'GB'].include?(country_code)
  code = [params[:zip], params[:address1]]
  code = code.collect{|p| extract_digits(p) } if params[:country] == 'GB'
  code = code.reject{|p| p.empty? }.join('|')
  # Since this field accepts only a few characters, we remove the ones that are not accepted,
  # and trim the white spaces
  code = code.gsub(/[^a-z0-9_\-| ]+/i, '').strip
end
extract_digits(value) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 419
def extract_digits(value)
  return unless value
  value.scan(/\d+/).join('')
end
format_amount(amount, currency) click to toggle source

Realex accepts currency amounts as an integer in the lowest value e.g.

format_amount(110.56, 'GBP')
=> 11056
# File lib/offsite_payments/integrations/realex_offsite.rb, line 406
def format_amount(amount, currency)
  units = CURRENCY_SPECIAL_MINOR_UNITS[currency] || 2
  multiple = 10**units
  return ((amount || 0).to_d * multiple.to_d).to_i
end
format_amount_as_float(amount, currency) click to toggle source

Realex returns currency amount as an integer

# File lib/offsite_payments/integrations/realex_offsite.rb, line 413
def format_amount_as_float(amount, currency)
  units = CURRENCY_SPECIAL_MINOR_UNITS[currency] || 2
  divisor = 10**units
  return ((amount || 0).to_d / divisor.to_d)
end
format_phone_number(phone_number, country_code) click to toggle source

The home phone number provided by the Cardholder. Should be In format: of ‘CountryCallingCode|Number’ for example, ‘1|123456789’.

# File lib/offsite_payments/integrations/realex_offsite.rb, line 450
def format_phone_number(phone_number, country_code)
  return nil if phone_number.nil?

  country_number = COUNTRY_PHONE_NUMBERS[country_code] || { :code => '0', :length => [] }

  # Remove non-digit characters
  processed_number = phone_number.gsub(/\D/, '')
  return '0|0' if [[], ['0']].include? processed_number.chars.uniq

  # Allow Italy and Ivory Coast to have leading zero, as they use it as a part of some phone numbers
  if ['IT', 'CI'].include?(country_code) && /\A0[1-9]\d*/.match(processed_number)
    return adjust_phone_number_length(country_number[:code], processed_number)
  end

  return '0|0' if processed_number == country_number[:code]
  
  # Remove leading zero(s)
  processed_number = processed_number.gsub(/\A0*/, '')

  # Check if the potential Singapore calling code is not the local prefix
  if country_code == 'SG' &&
    processed_number.start_with?(country_number[:code]) &&
    country_number[:length].include?(processed_number.length)
  then
    return adjust_phone_number_length(country_number[:code], processed_number)
  end

  # Remove country calling code from the processed number and try to fix trivial mistakes
  if processed_number.start_with?(country_number[:code]) ||
    (!(country_number[:length].include?(processed_number.length)) &&
    country_number[:length].include?(processed_number.length - country_number[:code].length) &&
    (country_number[:code].chars.sort == processed_number[0...country_number[:code].length].chars.sort))
  then
    processed_number = processed_number[country_number[:code].length..-1]
  end

  # Limit returned string to 3 characters + | + 15 characters
  adjust_phone_number_length(country_number[:code], processed_number)
end
get_message(key) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 523
def get_message(key)
  case key
    when 'HPP_CUSTOMER_EMAIL' then 'Invalid E-mail address.'
    when 'HPP_CUSTOMER_PHONENUMBER_MOBILE' then 'Invalid Telephone. The selected payment method only allows numbers, spaces or punctuation (+, |), and no more than 19 characters.'
    when 'HPP_BILLING_STREET1', 'HPP_SHIPPING_STREET1', 'HPP_BILLING_STREET2', 'HPP_SHIPPING_STREET2' then 'Invalid Street address. The selected payment method only allows letters, numbers, spaces or punctuation, and no more than 50 characters per line.'
    when 'HPP_BILLING_CITY', 'HPP_SHIPPING_CITY' then 'Invalid City. The selected payment method only allows letters, numbers, spaces or punctuation, and no more than 40 characters.'
    when 'HPP_BILLING_COUNTRY', 'HPP_SHIPPING_COUNTRY' then 'Invalid Country code.'
    when 'HPP_BILLING_POSTALCODE', 'HPP_SHIPPING_POSTALCODE' then 'Invalid Zip/Postal Code. The selected payment method only allows letters, numbers, spaces or punctuation, and no more than 16 characters.'
    when 'HPP_BILLING_STATE', 'HPP_SHIPPING_STATE' then 'Invalid State.'
  end
end
get_pattern(key) click to toggle source

Validations

# File lib/offsite_payments/integrations/realex_offsite.rb, line 511
def get_pattern(key)
  case key
    when 'HPP_CUSTOMER_EMAIL' then /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,24})*$/
    when 'HPP_CUSTOMER_PHONENUMBER_MOBILE' then /^([0-9 +]){1,3}(\|){0,1}([0-9 +]){1,15}$/
    when 'HPP_BILLING_STREET1', 'HPP_SHIPPING_STREET1', 'HPP_BILLING_STREET2', 'HPP_SHIPPING_STREET2' then /^[ÀÁÂÃÂÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåªæçèéêëìíîïðñòóôõöº÷ø¤ùúûüýþÿ~L~N~Z~\~^~_¥a-zA-Z0-9.'";\s,\+\-£\/@!\?%\*:$#\[\]|=\\&\u0152\u0153\u017D\u0161\u017E\u0178\u20AC]{1,50}$/
    when 'HPP_BILLING_CITY', 'HPP_SHIPPING_CITY' then /^[ÀÁÂÃÂÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåªæçèéêëìíîïðñòóôõöº÷ø¤ùúûüýþÿ~L~N~Z~\~^~_¥a-zA-Z0-9.'";\s,\+\-£\/@!\?%\*:$#\[\]|=\\&\u0152\u0153\u017D\u0161\u017E\u0178\u20AC]{1,40}$/
    when 'HPP_BILLING_COUNTRY', 'HPP_SHIPPING_COUNTRY' then /^([0-9])*$/
    when 'HPP_BILLING_POSTALCODE', 'HPP_SHIPPING_POSTALCODE' then /^[a-zA-Z0-9\-\s]{1,16}$/
    when 'HPP_BILLING_STATE', 'HPP_SHIPPING_STATE' then /^([A-Z])*$/
  end
end
lookup_state_code(country_code, state) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 490
def lookup_state_code(country_code, state)
  case country_code
  when 'CA'
    state_code = CANADIAN_STATES.find { |code, state_name| state_name.downcase == state.downcase}
    state_code ? state_code.first : state
  when 'US'
    state_code = US_STATES.find { |code, state_name| state_name.downcase == state.downcase}
    state_code ? state_code.first : state
  end
end
validate(key, value) click to toggle source
# File lib/offsite_payments/integrations/realex_offsite.rb, line 535
def validate(key, value)
  pattern = get_pattern(key)

  return value unless pattern.present?

  if value =~pattern
    return value
  else
    raise ArgumentError, get_message(key)
  end
end