activemerchant 1.109.0 → 1.114.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +47 -1
  3. data/README.md +2 -2
  4. data/lib/active_merchant/billing/credit_card.rb +1 -1
  5. data/lib/active_merchant/billing/credit_card_methods.rb +1 -1
  6. data/lib/active_merchant/billing/gateway.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/adyen.rb +17 -6
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +6 -6
  9. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -1
  10. data/lib/active_merchant/billing/gateways/balanced.rb +1 -1
  11. data/lib/active_merchant/billing/gateways/bambora_apac.rb +1 -1
  12. data/lib/active_merchant/billing/gateways/bank_frick.rb +1 -1
  13. data/lib/active_merchant/billing/gateways/blue_snap.rb +74 -16
  14. data/lib/active_merchant/billing/gateways/borgun.rb +1 -1
  15. data/lib/active_merchant/billing/gateways/braintree_blue.rb +7 -7
  16. data/lib/active_merchant/billing/gateways/cardknox.rb +1 -1
  17. data/lib/active_merchant/billing/gateways/cenpos.rb +1 -1
  18. data/lib/active_merchant/billing/gateways/checkout_v2.rb +1 -1
  19. data/lib/active_merchant/billing/gateways/credorax.rb +7 -1
  20. data/lib/active_merchant/billing/gateways/culqi.rb +1 -1
  21. data/lib/active_merchant/billing/gateways/cyber_source.rb +53 -16
  22. data/lib/active_merchant/billing/gateways/decidir.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/digitzs.rb +1 -1
  24. data/lib/active_merchant/billing/gateways/efsnet.rb +1 -1
  25. data/lib/active_merchant/billing/gateways/element.rb +4 -0
  26. data/lib/active_merchant/billing/gateways/eway_rapid.rb +2 -2
  27. data/lib/active_merchant/billing/gateways/ezic.rb +1 -1
  28. data/lib/active_merchant/billing/gateways/fat_zebra.rb +5 -3
  29. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +8 -0
  30. data/lib/active_merchant/billing/gateways/flo2cash.rb +1 -1
  31. data/lib/active_merchant/billing/gateways/global_collect.rb +5 -0
  32. data/lib/active_merchant/billing/gateways/hdfc.rb +1 -1
  33. data/lib/active_merchant/billing/gateways/hps.rb +9 -6
  34. data/lib/active_merchant/billing/gateways/ipp.rb +2 -2
  35. data/lib/active_merchant/billing/gateways/iridium.rb +2 -2
  36. data/lib/active_merchant/billing/gateways/linkpoint.rb +1 -1
  37. data/lib/active_merchant/billing/gateways/litle.rb +1 -1
  38. data/lib/active_merchant/billing/gateways/mastercard.rb +2 -2
  39. data/lib/active_merchant/billing/gateways/mercado_pago.rb +1 -1
  40. data/lib/active_merchant/billing/gateways/netbanx.rb +8 -2
  41. data/lib/active_merchant/billing/gateways/openpay.rb +1 -1
  42. data/lib/active_merchant/billing/gateways/opp.rb +3 -3
  43. data/lib/active_merchant/billing/gateways/optimal_payment.rb +1 -1
  44. data/lib/active_merchant/billing/gateways/orbital.rb +8 -1
  45. data/lib/active_merchant/billing/gateways/pagarme.rb +1 -1
  46. data/lib/active_merchant/billing/gateways/pay_junction.rb +2 -2
  47. data/lib/active_merchant/billing/gateways/payeezy.rb +3 -3
  48. data/lib/active_merchant/billing/gateways/payex.rb +5 -5
  49. data/lib/active_merchant/billing/gateways/payflow.rb +3 -0
  50. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
  51. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +1 -1
  52. data/lib/active_merchant/billing/gateways/paymill.rb +3 -3
  53. data/lib/active_merchant/billing/gateways/payu_latam.rb +4 -1
  54. data/lib/active_merchant/billing/gateways/plugnpay.rb +1 -1
  55. data/lib/active_merchant/billing/gateways/psigate.rb +1 -1
  56. data/lib/active_merchant/billing/gateways/qbms.rb +3 -3
  57. data/lib/active_merchant/billing/gateways/quickbooks.rb +3 -2
  58. data/lib/active_merchant/billing/gateways/qvalent.rb +1 -1
  59. data/lib/active_merchant/billing/gateways/realex.rb +1 -0
  60. data/lib/active_merchant/billing/gateways/redsys.rb +3 -3
  61. data/lib/active_merchant/billing/gateways/sage_pay.rb +4 -4
  62. data/lib/active_merchant/billing/gateways/skip_jack.rb +1 -1
  63. data/lib/active_merchant/billing/gateways/stripe.rb +2 -2
  64. data/lib/active_merchant/billing/gateways/telr.rb +1 -1
  65. data/lib/active_merchant/billing/gateways/trans_first.rb +1 -1
  66. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -2
  67. data/lib/active_merchant/billing/gateways/trust_commerce.rb +7 -7
  68. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +4 -4
  69. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +1 -1
  70. data/lib/active_merchant/billing/gateways/worldpay_us.rb +2 -2
  71. data/lib/active_merchant/version.rb +1 -1
  72. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c4b380a0488ea2f5e78175b1dfa65fee57051b7015f0b890da0bbc38d720b19
4
- data.tar.gz: 0067c05edeb3396266fdeb63366e56fe4b2c96e9ded24957405798a36d2f4f73
3
+ metadata.gz: 4d467cbeefbc698298d8e87dc6f9655cb8105cd6b949753082696802cd667d15
4
+ data.tar.gz: e7a09ed0f9dbead854bf3bab3940e2a335109aa4a76c2a8f2f824c27a2236833
5
5
  SHA512:
6
- metadata.gz: 789d158841099fcb4fab1873328480657352a44febdcc938bb86897cedd1db568fc5139082272ba4415dde7a8f07dc9f75f93eaea95dab6cc7bc26a01698b091
7
- data.tar.gz: 4d64a064ffa8d589780a785da3e1eabb2d3633db5c2ce6bbf0cf0998944f7c1bc25e4a09b557f9922bc1fe8b68f2ab2d3ef4a56dd441b9a50646911fdd5075d4
6
+ metadata.gz: 45db32004cb0fb161a6ae422b64b3401d9c6b3bf780549ba17cc50b2f94e79f94baa76353fdc5cfbad771423613ab5a3030b164e69f1de8ae44c612cd6982bf2
7
+ data.tar.gz: 2ea821b491e9c6cd21442c7563fcac422d42190a8a222583d15783fc1e1a87f77894a6d4eac7a41a5bb1c63d69c59cc17f2d6aaf1540d0d01e5ae4ee168e2b5f
data/CHANGELOG CHANGED
@@ -2,6 +2,53 @@
2
2
 
3
3
  == HEAD
4
4
 
5
+ == Version 1.114.0
6
+ * BlueSnap: Add address1,address2,phone,shipping_* support #3749
7
+ * BlueSnap: Protect against `nil` metadata [carrigan] #3752
8
+ * Cybersource: [CyberSource] Ensure the default address doesn't override `ActionController::Parameters` [pi3r] #3755
9
+
10
+ == Version 1.113.0
11
+ * Orbital: Add cardIndicators field [meagabeth] #3734
12
+ * Openpay: Add Colombia to supported countries [molbrown] #3740
13
+ * Mercado Pago: Update Device Id Header field [cdmackeyfree] #3741
14
+ * RuboCop: Fix Style/TrailingCommaInHashLiteral [leila-alderman] #3718
15
+ * RuboCop: Fix Naming/PredicateName [leila-alderman] #3724
16
+ * RuboCop: Fix Style/Attr [leila-alderman] #3728
17
+ * Payflow: Use application_id to set buttonsource [britth] #3737
18
+ * HPS: Enable refunds using capture transaction [britth] #3738
19
+ * Quickbooks: Omit empty strings in address [leila-alderman] #3743
20
+ * BlueSnap: Add transactionMetaData support #3745
21
+ * Orbital: Fix typo in PC3DtlLineTot field [naashton] #3736
22
+ * Credorax: Send first and last name parameters for CFT transactions [britth] #3748
23
+ * Orbital: Update CardIndicators field to fix bug [meagabeth] #3746
24
+ * CyberSource: Always send default address [leila-alderman] #3747
25
+ * Netbanx: Reject partial refund on pending status [rockyhakjoong] #3735
26
+
27
+ == Version 1.112.0
28
+ * Cybersource: add `maestro` and `diners_club` eci brand mapping [bbraschi] #3708
29
+ * Cybersource: Ensure Partner Solution Id placement conforms to schema [britth] #3715
30
+ * Adyen: Adyen: Pass `subMerchantId` as `additionalData` [naashton] #3714
31
+ * Litle: Omit checkNum when nil [leila-alderman] #3719
32
+ * PayU Latam: Improve error response [esmitperez] #3717
33
+ * Vantiv: Vantiv Express - CardPresentCode, PaymentType, SubmissionType, DuplicateCheckDisableFlag [esmitperez] #3730,#3731
34
+ * Cybersource: Ensure issueradditionaldata comes before partnerSolutionId [britth] #3733
35
+
36
+ == Version 1.111.0
37
+ * Fat Zebra: standardized 3DS fields and card on file extra data for Visa scheme rules [montdidier] #3409
38
+ * Realex: Change 3DSecure v1 message_version to a valid format [shuhala] #3702
39
+ * Ingenico/ GlobalCollect: Add field for installments [cdmackeyfree] #3707
40
+ * Cybersource: do not send 3DS fields if 'cavv` is missing and `commerceIndicator` is inferred [bbraschi] #3712
41
+
42
+ == Version 1.110.0
43
+ * FirstData e4 v27+: Strip linebreaks from address [curiousepic] #3693
44
+ * Adyen: Change shopper_email to email and shopper_ip to ip [rikterbeek] #3675
45
+ * FirstData e4 v27+ Fix strip_line_breaks method [carrigan] #3695
46
+ * Cybersource: Set authorization on the response even when in fraud review [pi3r] #3701
47
+ * Cybersource: Add fields to override stored creds [leila-alderman] #3689
48
+ * Cybersource: Conditionally find stored credentials [therufs] #3696 #3697
49
+ * Cybersource: Update logic to send cavv as xid for 3DS2 [douglas] #3699
50
+ * Credorax: Default 3ds_browsercolordepth to 32 when passed as 30 [britth] #3700
51
+
5
52
  == Version 1.109.0
6
53
  * Remove reference to `Billing::Integrations` [pi3r] #3692
7
54
  * DLocal: Handle nil address1 [molbrown] #3661
@@ -26,7 +73,6 @@
26
73
  * RuboCop: Fix Style/TrailingUnderscoreVariable [leila-alderman] #3663
27
74
  * RuboCop: Fix Style/WordArray [leila-alderman] #3664
28
75
  * RuboCop: Fix Style/SymbolArray [leila-alderman] #3665
29
-
30
76
  * Mercado-Pago: Notification url GSF [cdmackeyfree] #3678
31
77
  * Credorax: Update logic for setting 3ds_homephonecountry [britth] #3691
32
78
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Active Merchant
2
- [![Build Status](https://travis-ci.org/activemerchant/active_merchant.png?branch=master)](https://travis-ci.org/activemerchant/active_merchant)
3
- [![Code Climate](https://codeclimate.com/github/activemerchant/active_merchant.png)](https://codeclimate.com/github/activemerchant/active_merchant)
2
+ [![Build Status](https://travis-ci.org/activemerchant/active_merchant.svg?branch=master)](https://travis-ci.org/activemerchant/active_merchant)
3
+ [![Code Climate](https://codeclimate.com/github/activemerchant/active_merchant.svg)](https://codeclimate.com/github/activemerchant/active_merchant)
4
4
 
5
5
  Active Merchant is an extraction from the ecommerce system [Shopify](http://www.shopify.com).
6
6
  Shopify's requirements for a simple and unified API to access dozens of different payment
@@ -190,7 +190,7 @@ module ActiveMerchant #:nodoc:
190
190
  'contactless' => 'Data was read by a Contactless EMV kernel. Issuer script results are not available.',
191
191
  'contactless_magstripe' => 'Contactless data was read with a non-EMV protocol.',
192
192
  'contact' => 'Data was read using the EMV protocol. Issuer script results may follow.',
193
- 'contact_quickchip' => 'Data was read by the Quickchip EMV kernel. Issuer script results are not available.',
193
+ 'contact_quickchip' => 'Data was read by the Quickchip EMV kernel. Issuer script results are not available.'
194
194
  }
195
195
 
196
196
  # Returns the ciphertext of the card's encrypted PIN.
@@ -329,7 +329,7 @@ module ActiveMerchant #:nodoc:
329
329
  54 => 3, # 6 * 2 - 9
330
330
  55 => 5, # etc ...
331
331
  56 => 7,
332
- 57 => 9,
332
+ 57 => 9
333
333
  }.freeze
334
334
 
335
335
  # Checks the validity of a card number by use of the Luhn Algorithm.
@@ -95,7 +95,7 @@ module ActiveMerchant #:nodoc:
95
95
  pickup_card: 'pick_up_card',
96
96
  config_error: 'config_error',
97
97
  test_mode_live_card: 'test_mode_live_card',
98
- unsupported_feature: 'unsupported_feature',
98
+ unsupported_feature: 'unsupported_feature'
99
99
  }
100
100
 
101
101
  cattr_reader :implementations
@@ -26,7 +26,7 @@ module ActiveMerchant #:nodoc:
26
26
  '132' => STANDARD_ERROR_CODE[:incorrect_address],
27
27
  '133' => STANDARD_ERROR_CODE[:incorrect_address],
28
28
  '134' => STANDARD_ERROR_CODE[:incorrect_address],
29
- '135' => STANDARD_ERROR_CODE[:incorrect_address],
29
+ '135' => STANDARD_ERROR_CODE[:incorrect_address]
30
30
  }
31
31
 
32
32
  def initialize(options={})
@@ -196,9 +196,6 @@ module ActiveMerchant #:nodoc:
196
196
 
197
197
  def add_extra_data(post, payment, options)
198
198
  post[:telephoneNumber] = options[:billing_address][:phone] if options.dig(:billing_address, :phone)
199
- post[:shopperEmail] = options[:shopper_email] if options[:shopper_email]
200
- post[:shopperIP] = options[:shopper_ip] if options[:shopper_ip]
201
- post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement]
202
199
  post[:fraudOffset] = options[:fraud_offset] if options[:fraud_offset]
203
200
  post[:selectedBrand] = options[:selected_brand] if options[:selected_brand]
204
201
  post[:selectedBrand] ||= NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard)
@@ -212,11 +209,25 @@ module ActiveMerchant #:nodoc:
212
209
  post[:additionalData][:authorisationType] = options[:authorisation_type] if options[:authorisation_type]
213
210
  post[:additionalData][:adjustAuthorisationData] = options[:adjust_authorisation_data] if options[:adjust_authorisation_data]
214
211
  post[:additionalData][:industryUsage] = options[:industry_usage] if options[:industry_usage]
215
- post[:additionalData][:updateShopperStatement] = options[:update_shopper_statement] if options[:update_shopper_statement]
216
212
  post[:additionalData][:RequestedTestAcquirerResponseCode] = options[:requested_test_acquirer_response_code] if options[:requested_test_acquirer_response_code] && test?
217
213
  post[:deviceFingerprint] = options[:device_fingerprint] if options[:device_fingerprint]
214
+ add_shopper_data(post, options)
218
215
  add_risk_data(post, options)
219
216
  add_shopper_reference(post, options)
217
+ add_merchant_data(post, options)
218
+ end
219
+
220
+ def add_shopper_data(post, options)
221
+ post[:shopperEmail] = options[:email] if options[:email]
222
+ post[:shopperEmail] = options[:shopper_email] if options[:shopper_email]
223
+ post[:shopperIP] = options[:ip] if options[:ip]
224
+ post[:shopperIP] = options[:shopper_ip] if options[:shopper_ip]
225
+ post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement]
226
+ post[:additionalData][:updateShopperStatement] = options[:update_shopper_statement] if options[:update_shopper_statement]
227
+ end
228
+
229
+ def add_merchant_data(post, options)
230
+ post[:additionalData][:subMerchantId] = options[:sub_merchant_id] if options[:sub_merchant_id]
220
231
  end
221
232
 
222
233
  def add_risk_data(post, options)
@@ -232,7 +243,7 @@ module ActiveMerchant #:nodoc:
232
243
  splits = []
233
244
  split_data.each do |split|
234
245
  amount = {
235
- value: split['amount']['value'],
246
+ value: split['amount']['value']
236
247
  }
237
248
  amount[:currency] = split['amount']['currency'] if split['amount']['currency']
238
249
 
@@ -54,7 +54,7 @@ module ActiveMerchant
54
54
  '37' => STANDARD_ERROR_CODE[:invalid_expiry_date],
55
55
  '378' => STANDARD_ERROR_CODE[:invalid_cvc],
56
56
  '38' => STANDARD_ERROR_CODE[:expired_card],
57
- '384' => STANDARD_ERROR_CODE[:config_error],
57
+ '384' => STANDARD_ERROR_CODE[:config_error]
58
58
  }
59
59
 
60
60
  MARKET_TYPE = {
@@ -771,7 +771,7 @@ module ActiveMerchant
771
771
  end
772
772
 
773
773
  def parse(action, raw_response, options = {})
774
- if is_cim_action?(action) || action == :verify_credentials
774
+ if cim_action?(action) || action == :verify_credentials
775
775
  parse_cim(raw_response, options)
776
776
  else
777
777
  parse_normal(action, raw_response)
@@ -802,7 +802,7 @@ module ActiveMerchant
802
802
  end
803
803
  end
804
804
 
805
- def is_cim_action?(action)
805
+ def cim_action?(action)
806
806
  action.to_s.start_with?('cim')
807
807
  end
808
808
 
@@ -824,7 +824,7 @@ module ActiveMerchant
824
824
  'deleteCustomerProfileRequest'
825
825
  elsif action == :verify_credentials
826
826
  'authenticateTestRequest'
827
- elsif is_cim_action?(action)
827
+ elsif cim_action?(action)
828
828
  'createCustomerProfileTransactionRequest'
829
829
  else
830
830
  'createTransactionRequest'
@@ -1006,7 +1006,7 @@ module ActiveMerchant
1006
1006
 
1007
1007
  def auth_was_for_cim?(authorization)
1008
1008
  _, _, action = split_authorization(authorization)
1009
- action && is_cim_action?(action)
1009
+ action && cim_action?(action)
1010
1010
  end
1011
1011
 
1012
1012
  def parse_direct_response_elements(response, options)
@@ -1059,7 +1059,7 @@ module ActiveMerchant
1059
1059
  card_type: parts[51] || '',
1060
1060
  split_tender_id: parts[52] || '',
1061
1061
  requested_amount: parts[53] || '',
1062
- balance_on_card: parts[54] || '',
1062
+ balance_on_card: parts[54] || ''
1063
1063
  }
1064
1064
  end
1065
1065
  end
@@ -928,7 +928,7 @@ module ActiveMerchant #:nodoc:
928
928
  'card_type' => direct_response_fields[51] || '',
929
929
  'split_tender_id' => direct_response_fields[52] || '',
930
930
  'requested_amount' => direct_response_fields[53] || '',
931
- 'balance_on_card' => direct_response_fields[54] || '',
931
+ 'balance_on_card' => direct_response_fields[54] || ''
932
932
  }
933
933
  )
934
934
  end
@@ -254,7 +254,7 @@ module ActiveMerchant #:nodoc:
254
254
  'Authorization' => 'Basic ' + Base64.encode64(@options[:login].to_s + ':').strip,
255
255
  'User-Agent' => "Balanced/v1.1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
256
256
  'Accept' => 'application/vnd.api+json;revision=1.1',
257
- 'X-Balanced-User-Agent' => @@ua,
257
+ 'X-Balanced-User-Agent' => @@ua
258
258
  }
259
259
  end
260
260
  end
@@ -18,7 +18,7 @@ module ActiveMerchant #:nodoc:
18
18
  '05' => STANDARD_ERROR_CODE[:card_declined],
19
19
  '06' => STANDARD_ERROR_CODE[:processing_error],
20
20
  '14' => STANDARD_ERROR_CODE[:invalid_number],
21
- '54' => STANDARD_ERROR_CODE[:expired_card],
21
+ '54' => STANDARD_ERROR_CODE[:expired_card]
22
22
  }
23
23
 
24
24
  def initialize(options={})
@@ -24,7 +24,7 @@ module ActiveMerchant #:nodoc:
24
24
  'authonly' => 'CC.PA',
25
25
  'capture' => 'CC.CP',
26
26
  'refund' => 'CC.RF',
27
- 'void' => 'CC.RV',
27
+ 'void' => 'CC.RV'
28
28
  }
29
29
 
30
30
  def initialize(options={})
@@ -58,7 +58,7 @@ module ActiveMerchant
58
58
  'line1: N, zip: M, name: N' => 'W',
59
59
  'line1: N, zip: N, name: U' => 'N',
60
60
  'line1: N, zip: N, name: M' => 'K',
61
- 'line1: N, zip: N, name: N' => 'N',
61
+ 'line1: N, zip: N, name: N' => 'N'
62
62
  }
63
63
 
64
64
  BANK_ACCOUNT_TYPE_MAPPING = {
@@ -177,7 +177,7 @@ module ActiveMerchant
177
177
  add_order(doc, options)
178
178
  doc.send('store-card', options[:store_card] || false)
179
179
  add_amount(doc, money, options)
180
- add_fraud_info(doc, options)
180
+ add_fraud_info(doc, payment_method, options)
181
181
 
182
182
  if payment_method.is_a?(String)
183
183
  doc.send('vaulted-shopper-id', payment_method)
@@ -200,6 +200,7 @@ module ActiveMerchant
200
200
  doc.send('last-name', payment_method.last_name)
201
201
  doc.send('personal-identification-number', options[:personal_identification_number]) if options[:personal_identification_number]
202
202
  doc.email(options[:email]) if options[:email]
203
+ doc.phone(options[:phone_number]) if options[:phone_number]
203
204
  add_address(doc, options)
204
205
  end
205
206
 
@@ -212,12 +213,28 @@ module ActiveMerchant
212
213
  end
213
214
  end
214
215
 
215
- def add_description(doc, description)
216
+ def add_metadata(doc, options)
217
+ transaction_meta_data = options[:transaction_meta_data] || []
218
+ return if transaction_meta_data.empty? && !options[:description]
219
+
216
220
  doc.send('transaction-meta-data') do
217
- doc.send('meta-data') do
218
- doc.send('meta-key', 'description')
219
- doc.send('meta-value', truncate(description, 500))
220
- doc.send('meta-description', 'Description')
221
+ # ensure backwards compatibility for calls expecting :description
222
+ # to become meta-data fields.
223
+ if options[:description]
224
+ doc.send('meta-data') do
225
+ doc.send('meta-key', 'description')
226
+ doc.send('meta-value', truncate(options[:description], 500))
227
+ doc.send('meta-description', 'Description')
228
+ end
229
+ end
230
+
231
+ # https://developers.bluesnap.com/v8976-XML/docs/meta-data
232
+ transaction_meta_data.each do |entry|
233
+ doc.send('meta-data') do
234
+ doc.send('meta-key', truncate(entry[:meta_key], 40))
235
+ doc.send('meta-value', truncate(entry[:meta_value], 500))
236
+ doc.send('meta-description', truncate(entry[:meta_description], 40))
237
+ end
221
238
  end
222
239
  end
223
240
  end
@@ -225,7 +242,7 @@ module ActiveMerchant
225
242
  def add_order(doc, options)
226
243
  doc.send('merchant-transaction-id', truncate(options[:order_id], 50)) if options[:order_id]
227
244
  doc.send('soft-descriptor', options[:soft_descriptor]) if options[:soft_descriptor]
228
- add_description(doc, options[:description]) if options[:description]
245
+ add_metadata(doc, options)
229
246
  add_3ds(doc, options[:three_d_secure]) if options[:three_d_secure]
230
247
  add_level_3_data(doc, options)
231
248
  end
@@ -236,7 +253,8 @@ module ActiveMerchant
236
253
 
237
254
  doc.country(address[:country]) if address[:country]
238
255
  doc.state(address[:state]) if address[:state] && STATE_CODE_COUNTRIES.include?(address[:country])
239
- doc.address(address[:address]) if address[:address]
256
+ doc.address(address[:address1]) if address[:address1]
257
+ doc.address2(address[:address2]) if address[:address2]
240
258
  doc.city(address[:city]) if address[:city]
241
259
  doc.zip(address[:zip]) if address[:zip]
242
260
  end
@@ -298,12 +316,31 @@ module ActiveMerchant
298
316
  doc.send('transaction-id', authorization)
299
317
  end
300
318
 
301
- def add_fraud_info(doc, options)
319
+ def add_fraud_info(doc, payment_method, options)
302
320
  doc.send('transaction-fraud-info') do
303
321
  doc.send('shopper-ip-address', options[:ip]) if options[:ip]
322
+
323
+ unless payment_method.is_a? String
324
+ doc.send('shipping-contact-info') do
325
+ add_shipping_contact_info(doc, payment_method, options)
326
+ end
327
+ end
304
328
  end
305
329
  end
306
330
 
331
+ def add_shipping_contact_info(doc, payment_method, options)
332
+ # https://developers.bluesnap.com/v8976-XML/docs/shipping-contact-info
333
+ doc.send('first-name', payment_method.first_name)
334
+ doc.send('last-name', payment_method.last_name)
335
+
336
+ doc.country(options[:shipping_country]) if options[:shipping_country]
337
+ doc.state(options[:shipping_state]) if options[:shipping_state] && STATE_CODE_COUNTRIES.include?(options[:shipping_country])
338
+ doc.address1(options[:shipping_address1]) if options[:shipping_address1]
339
+ doc.address2(options[:shipping_address2]) if options[:shipping_address2]
340
+ doc.city(options[:shipping_city]) if options[:shipping_city]
341
+ doc.zip(options[:shipping_zip]) if options[:shipping_zip]
342
+ end
343
+
307
344
  def add_alt_transaction_purchase(doc, money, payment_method_details, options)
308
345
  doc.send('merchant-transaction-id', truncate(options[:order_id], 50)) if options[:order_id]
309
346
  doc.send('soft-descriptor', options[:soft_descriptor]) if options[:soft_descriptor]
@@ -314,8 +351,8 @@ module ActiveMerchant
314
351
 
315
352
  add_echeck_transaction(doc, payment_method_details.payment_method, options, vaulted_shopper_id.present?) if payment_method_details.check?
316
353
 
317
- add_fraud_info(doc, options)
318
- add_description(doc, options)
354
+ add_fraud_info(doc, payment_method_details.payment_method, options)
355
+ add_metadata(doc, options)
319
356
  end
320
357
 
321
358
  def add_echeck_transaction(doc, check, options, vaulted_shopper)
@@ -350,12 +387,21 @@ module ActiveMerchant
350
387
  parsed = {}
351
388
  doc = Nokogiri::XML(response.body)
352
389
  doc.root.xpath('*').each do |node|
390
+ name = node.name.downcase
391
+
353
392
  if node.elements.empty?
354
- parsed[node.name.downcase] = node.text
393
+ parsed[name] = node.text
394
+ elsif name == 'transaction-meta-data'
395
+ metadata = []
396
+ node.elements.each { |m|
397
+ metadata.push parse_metadata_entry(m)
398
+ }
399
+
400
+ parsed['transaction-meta-data'] = metadata
355
401
  else
356
- node.elements.each do |childnode|
402
+ node.elements.each { |childnode|
357
403
  parse_element(parsed, childnode)
358
- end
404
+ }
359
405
  end
360
406
  end
361
407
 
@@ -363,6 +409,18 @@ module ActiveMerchant
363
409
  parsed
364
410
  end
365
411
 
412
+ def parse_metadata_entry(node)
413
+ entry = {}
414
+
415
+ node.elements.each { |e|
416
+ entry = entry.merge({
417
+ e.name => e.text
418
+ })
419
+ }
420
+
421
+ entry
422
+ end
423
+
366
424
  def parse_element(parsed, node)
367
425
  if !node.elements.empty?
368
426
  node.elements.each { |e| parse_element(parsed, e) }
@@ -476,7 +534,7 @@ module ActiveMerchant
476
534
  def headers
477
535
  {
478
536
  'Content-Type' => 'application/xml',
479
- 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip),
537
+ 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip)
480
538
  }
481
539
  end
482
540
 
@@ -176,7 +176,7 @@ module ActiveMerchant #:nodoc:
176
176
 
177
177
  def headers
178
178
  {
179
- 'Authorization' => 'Basic ' + Base64.strict_encode64(@options[:username].to_s + ':' + @options[:password].to_s),
179
+ 'Authorization' => 'Basic ' + Base64.strict_encode64(@options[:username].to_s + ':' + @options[:password].to_s)
180
180
  }
181
181
  end
182
182
 
@@ -234,7 +234,7 @@ module ActiveMerchant #:nodoc:
234
234
  phone: options[:phone] || (options[:billing_address][:phone] if options[:billing_address] &&
235
235
  options[:billing_address][:phone]),
236
236
  id: options[:customer],
237
- device_data: options[:device_data],
237
+ device_data: options[:device_data]
238
238
  }.merge credit_card_params
239
239
  result = @braintree_gateway.customer.create(merge_credit_card_options(parameters, options))
240
240
  Response.new(result.success?, message_from_result(result),
@@ -258,7 +258,7 @@ module ActiveMerchant #:nodoc:
258
258
  cvv: credit_card.verification_value,
259
259
  expiration_month: credit_card.month.to_s.rjust(2, '0'),
260
260
  expiration_year: credit_card.year.to_s,
261
- device_data: options[:device_data],
261
+ device_data: options[:device_data]
262
262
  }
263
263
  if options[:billing_address]
264
264
  address = map_address(options[:billing_address])
@@ -320,7 +320,7 @@ module ActiveMerchant #:nodoc:
320
320
  company: address[:company],
321
321
  locality: address[:city],
322
322
  region: address[:state],
323
- postal_code: scrub_zip(address[:zip]),
323
+ postal_code: scrub_zip(address[:zip])
324
324
  }
325
325
 
326
326
  mapped[:country_code_alpha2] = (address[:country] || address[:country_code_alpha2]) if address[:country] || address[:country_code_alpha2]
@@ -508,7 +508,7 @@ module ActiveMerchant #:nodoc:
508
508
  customer_details = {
509
509
  'id' => transaction.customer_details.id,
510
510
  'email' => transaction.customer_details.email,
511
- 'phone' => transaction.customer_details.phone,
511
+ 'phone' => transaction.customer_details.phone
512
512
  }
513
513
 
514
514
  billing_details = {
@@ -518,7 +518,7 @@ module ActiveMerchant #:nodoc:
518
518
  'locality' => transaction.billing_details.locality,
519
519
  'region' => transaction.billing_details.region,
520
520
  'postal_code' => transaction.billing_details.postal_code,
521
- 'country_name' => transaction.billing_details.country_name,
521
+ 'country_name' => transaction.billing_details.country_name
522
522
  }
523
523
 
524
524
  shipping_details = {
@@ -528,7 +528,7 @@ module ActiveMerchant #:nodoc:
528
528
  'locality' => transaction.shipping_details.locality,
529
529
  'region' => transaction.shipping_details.region,
530
530
  'postal_code' => transaction.shipping_details.postal_code,
531
- 'country_name' => transaction.shipping_details.country_name,
531
+ 'country_name' => transaction.shipping_details.country_name
532
532
  }
533
533
  credit_card_details = {
534
534
  'masked_number' => transaction.credit_card_details.masked_number,
@@ -578,7 +578,7 @@ module ActiveMerchant #:nodoc:
578
578
  options: {
579
579
  store_in_vault: options[:store] ? true : false,
580
580
  submit_for_settlement: options[:submit_for_settlement],
581
- hold_in_escrow: options[:hold_in_escrow],
581
+ hold_in_escrow: options[:hold_in_escrow]
582
582
  }
583
583
  }
584
584