lib/active_merchant/billing/gateways/blue_snap.rb in activemerchant-1.112.0 vs lib/active_merchant/billing/gateways/blue_snap.rb in activemerchant-1.113.0
- old
+ new
@@ -56,11 +56,11 @@
'line1: N, zip: M, name: U' => 'W',
'line1: N, zip: M, name: M' => 'L',
'line1: N, zip: M, name: N' => 'W',
'line1: N, zip: N, name: U' => 'N',
'line1: N, zip: N, name: M' => 'K',
- 'line1: N, zip: N, name: N' => 'N',
+ 'line1: N, zip: N, name: N' => 'N'
}
BANK_ACCOUNT_TYPE_MAPPING = {
'personal_checking' => 'CONSUMER_CHECKING',
'personal_savings' => 'CONSUMER_SAVINGS',
@@ -210,24 +210,40 @@
doc.send('expiration-month', card.month)
doc.send('expiration-year', card.year)
end
end
- def add_description(doc, description)
+ def add_metadata(doc, options)
+ transaction_meta_data = options.fetch(:transaction_meta_data, {})
+ return if transaction_meta_data.empty? && !options[:description]
+
doc.send('transaction-meta-data') do
- doc.send('meta-data') do
- doc.send('meta-key', 'description')
- doc.send('meta-value', truncate(description, 500))
- doc.send('meta-description', 'Description')
+ # ensure backwards compatibility for calls expecting :description
+ # to become meta-data fields.
+ if options[:description]
+ doc.send('meta-data') do
+ doc.send('meta-key', 'description')
+ doc.send('meta-value', truncate(options[:description], 500))
+ doc.send('meta-description', 'Description')
+ end
end
+
+ # https://developers.bluesnap.com/v8976-XML/docs/meta-data
+ transaction_meta_data.each do |entry|
+ doc.send('meta-data') do
+ doc.send('meta-key', truncate(entry[:meta_key], 40))
+ doc.send('meta-value', truncate(entry[:meta_value], 500))
+ doc.send('meta-description', truncate(entry[:meta_description], 40))
+ end
+ end
end
end
def add_order(doc, options)
doc.send('merchant-transaction-id', truncate(options[:order_id], 50)) if options[:order_id]
doc.send('soft-descriptor', options[:soft_descriptor]) if options[:soft_descriptor]
- add_description(doc, options[:description]) if options[:description]
+ add_metadata(doc, options)
add_3ds(doc, options[:three_d_secure]) if options[:three_d_secure]
add_level_3_data(doc, options)
end
def add_address(doc, options)
@@ -313,11 +329,11 @@
doc.send('vaulted-shopper-id', vaulted_shopper_id) if vaulted_shopper_id
add_echeck_transaction(doc, payment_method_details.payment_method, options, vaulted_shopper_id.present?) if payment_method_details.check?
add_fraud_info(doc, options)
- add_description(doc, options)
+ add_metadata(doc, options)
end
def add_echeck_transaction(doc, check, options, vaulted_shopper)
unless vaulted_shopper
doc.send('payer-info') do
@@ -348,23 +364,44 @@
return forbidden_response(response.body) if response.code.to_i == 403
parsed = {}
doc = Nokogiri::XML(response.body)
doc.root.xpath('*').each do |node|
+ name = node.name.downcase
+
if node.elements.empty?
- parsed[node.name.downcase] = node.text
+ parsed[name] = node.text
+ elsif name == 'transaction-meta-data'
+ metadata = []
+ node.elements.each { |m|
+ metadata.push parse_metadata_entry(m)
+ }
+
+ parsed['transaction-meta-data'] = metadata
else
- node.elements.each do |childnode|
+ node.elements.each { |childnode|
parse_element(parsed, childnode)
- end
+ }
end
end
parsed['content-location-header'] = response['content-location']
parsed
end
+ def parse_metadata_entry(node)
+ entry = {}
+
+ node.elements.each { |e|
+ entry = entry.merge({
+ e.name => e.text
+ })
+ }
+
+ entry
+ end
+
def parse_element(parsed, node)
if !node.elements.empty?
node.elements.each { |e| parse_element(parsed, e) }
else
parsed[node.name.downcase] = node.text
@@ -474,10 +511,10 @@
end
def headers
{
'Content-Type' => 'application/xml',
- 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip),
+ 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip)
}
end
def build_xml_request(action, payment_method_details)
builder = Nokogiri::XML::Builder.new