activemerchant 1.109.0 → 1.114.0

Sign up to get free protection for your applications and to get access to all the features.
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