lib/active_merchant/billing/gateways/barclaycard_smartpay.rb in activemerchant-1.58.0 vs lib/active_merchant/billing/gateways/barclaycard_smartpay.rb in activemerchant-1.59.0

- old
+ new

@@ -73,12 +73,10 @@ def verify(creditcard, options = {}) authorize(0, creditcard, options) end def store(creditcard, options = {}) - # ??? require :email and :customer, :order_id? - post = store_request(options) post[:card] = credit_card_hash(creditcard) post[:recurring] = {:contract => 'RECURRING'} commit('store', post) @@ -95,20 +93,45 @@ gsub(%r((card.cvc=)\d+), '\1[FILTERED]') end private + # Smartpay may return AVS codes not covered by standard AVSResult codes. + # Smartpay's descriptions noted below. + AVS_MAPPING = { + '0' => 'R', # Unknown + '1' => 'A', # Address matches, postal code doesn't + '2' => 'N', # Neither postal code nor address match + '3' => 'R', # AVS unavailable + '4' => 'E', # AVS not supported for this card type + '5' => 'U', # No AVS data provided + '6' => 'Z', # Postal code matches, address doesn't match + '7' => 'D', # Both postal code and address match + '8' => 'U', # Address not checked, postal code unknown + '9' => 'B', # Address matches, postal code unknown + '10' => 'N', # Address doesn't match, postal code unknown + '11' => 'U', # Postal code not checked, address unknown + '12' => 'B', # Address matches, postal code not checked + '13' => 'U', # Address doesn't match, postal code not checked + '14' => 'P', # Postal code matches, address unknown + '15' => 'P', # Postal code matches, address not checked + '16' => 'N', # Postal code doesn't match, address unknown + '17' => 'U', # Postal code doesn't match, address not checked + '18' => 'I' # Neither postal code nor address were checked + } + def commit(action, post) request = post_data(flatten_hash(post)) raw_response = ssl_post(build_url(action), request, headers) response = parse(raw_response) Response.new( success_from(response), message_from(response), response, test: test?, + avs_result: AVSResult.new(:code => parse_avs_code(response)), authorization: response['recurringDetailReference'] || response['pspReference'] ) rescue ResponseError => e case e.response.code @@ -122,10 +145,14 @@ end end raise end + def parse_avs_code(response) + AVS_MAPPING[response["avsResult"][0..1].strip] if response["avsResult"] + end + def flatten_hash(hash, prefix = nil) flat_hash = {} hash.each_pair do |key, val| conc_key = prefix.nil? ? key : "#{prefix}.#{key}" if val.is_a?(Hash) @@ -138,11 +165,11 @@ end def headers { 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8', - 'Authorization' => 'Basic ' + Base64.encode64("ws@Company.#{@options[:company]}:#{@options[:password]}").strip + 'Authorization' => 'Basic ' + Base64.strict_encode64("ws@Company.#{@options[:company]}:#{@options[:password]}").strip } end def parse(response) Hash[ @@ -184,14 +211,16 @@ end end def address_hash(address) full_address = "#{address[:address1]} #{address[:address2]}" if address + street = address[:street] if address[:street] + house = address[:houseNumberOrName] if address[:houseNumberOrName] hash = {} hash[:city] = address[:city] if address[:city] - hash[:street] = full_address.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ') - hash[:houseNumberOrName] = full_address.split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ') + hash[:street] = street || full_address.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ') + hash[:houseNumberOrName] = house || full_address.split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ') hash[:postalCode] = address[:zip] if address[:zip] hash[:stateOrProvince] = address[:state] if address[:state] hash[:country] = address[:country] if address[:country] hash end