module ActiveMerchant #:nodoc: module Billing #:nodoc: module Integrations #:nodoc: class Helper #:nodoc: attr_reader :fields class_inheritable_accessor :service_url class_inheritable_hash :mappings class_inheritable_accessor :country_format self.country_format = :alpha2 def initialize(order, account, options = {}) valid_keys = [:amount, :currency] options.assert_valid_keys(valid_keys) @fields = {} self.order = order self.account = account self.amount = options[:amount] self.currency = options[:currency] end def self.mapping(attribute, options = {}) self.mappings ||= {} self.mappings[attribute] = options end def add_field(name, value) return if name.blank? || value.blank? @fields[name.to_s] = value.to_s end def add_fields(subkey, params = {}) params.each do |k, v| field = mappings[subkey][k] add_field(field, v) unless field.blank? end end def billing_address(params = {}) code = lookup_country_code(params.delete(:country)) add_field(mappings[:billing_address][:country], code) if mappings[:billing_address] add_fields(:billing_address, params) end def form_fields @fields end private def lookup_country_code(name_or_code) country = Country.find(name_or_code) country.code(country_format).to_s rescue InvalidCountryCodeError name_or_code end def method_missing(method_id, *args) method_id = method_id.to_s.gsub(/=$/, '').to_sym # Return and do nothing if the mapping was not found. This allows # For easy substitution of the different integrations return if mappings[method_id].nil? mapping = mappings[method_id] case mapping when Array mapping.each{ |field| add_field(field, args.last) } when Hash options = args.last.is_a?(Hash) ? args.pop : {} mapping.each{ |key, field| add_field(field, options[key]) } else add_field(mapping, args.last) end end end end end end