activemerchant 1.112.0 → 1.113.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +17 -0
  3. data/lib/active_merchant/billing/credit_card.rb +1 -1
  4. data/lib/active_merchant/billing/credit_card_methods.rb +1 -1
  5. data/lib/active_merchant/billing/gateway.rb +1 -1
  6. data/lib/active_merchant/billing/gateways/adyen.rb +2 -2
  7. data/lib/active_merchant/billing/gateways/authorize_net.rb +6 -6
  8. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -1
  9. data/lib/active_merchant/billing/gateways/balanced.rb +1 -1
  10. data/lib/active_merchant/billing/gateways/bambora_apac.rb +1 -1
  11. data/lib/active_merchant/billing/gateways/bank_frick.rb +1 -1
  12. data/lib/active_merchant/billing/gateways/blue_snap.rb +49 -12
  13. data/lib/active_merchant/billing/gateways/borgun.rb +1 -1
  14. data/lib/active_merchant/billing/gateways/braintree_blue.rb +7 -7
  15. data/lib/active_merchant/billing/gateways/cardknox.rb +1 -1
  16. data/lib/active_merchant/billing/gateways/cenpos.rb +1 -1
  17. data/lib/active_merchant/billing/gateways/checkout_v2.rb +1 -1
  18. data/lib/active_merchant/billing/gateways/credorax.rb +6 -0
  19. data/lib/active_merchant/billing/gateways/culqi.rb +1 -1
  20. data/lib/active_merchant/billing/gateways/cyber_source.rb +4 -2
  21. data/lib/active_merchant/billing/gateways/decidir.rb +1 -1
  22. data/lib/active_merchant/billing/gateways/digitzs.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/efsnet.rb +1 -1
  24. data/lib/active_merchant/billing/gateways/eway_rapid.rb +2 -2
  25. data/lib/active_merchant/billing/gateways/ezic.rb +1 -1
  26. data/lib/active_merchant/billing/gateways/flo2cash.rb +1 -1
  27. data/lib/active_merchant/billing/gateways/hdfc.rb +1 -1
  28. data/lib/active_merchant/billing/gateways/hps.rb +9 -6
  29. data/lib/active_merchant/billing/gateways/ipp.rb +2 -2
  30. data/lib/active_merchant/billing/gateways/iridium.rb +2 -2
  31. data/lib/active_merchant/billing/gateways/linkpoint.rb +1 -1
  32. data/lib/active_merchant/billing/gateways/mastercard.rb +2 -2
  33. data/lib/active_merchant/billing/gateways/mercado_pago.rb +1 -1
  34. data/lib/active_merchant/billing/gateways/netbanx.rb +4 -2
  35. data/lib/active_merchant/billing/gateways/openpay.rb +1 -1
  36. data/lib/active_merchant/billing/gateways/opp.rb +3 -3
  37. data/lib/active_merchant/billing/gateways/optimal_payment.rb +1 -1
  38. data/lib/active_merchant/billing/gateways/orbital.rb +8 -1
  39. data/lib/active_merchant/billing/gateways/pagarme.rb +1 -1
  40. data/lib/active_merchant/billing/gateways/pay_junction.rb +2 -2
  41. data/lib/active_merchant/billing/gateways/payeezy.rb +3 -3
  42. data/lib/active_merchant/billing/gateways/payex.rb +5 -5
  43. data/lib/active_merchant/billing/gateways/payflow.rb +3 -0
  44. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
  45. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +1 -1
  46. data/lib/active_merchant/billing/gateways/paymill.rb +3 -3
  47. data/lib/active_merchant/billing/gateways/plugnpay.rb +1 -1
  48. data/lib/active_merchant/billing/gateways/psigate.rb +1 -1
  49. data/lib/active_merchant/billing/gateways/qbms.rb +3 -3
  50. data/lib/active_merchant/billing/gateways/quickbooks.rb +3 -2
  51. data/lib/active_merchant/billing/gateways/qvalent.rb +1 -1
  52. data/lib/active_merchant/billing/gateways/redsys.rb +3 -3
  53. data/lib/active_merchant/billing/gateways/sage_pay.rb +4 -4
  54. data/lib/active_merchant/billing/gateways/skip_jack.rb +1 -1
  55. data/lib/active_merchant/billing/gateways/stripe.rb +2 -2
  56. data/lib/active_merchant/billing/gateways/telr.rb +1 -1
  57. data/lib/active_merchant/billing/gateways/trans_first.rb +1 -1
  58. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -2
  59. data/lib/active_merchant/billing/gateways/trust_commerce.rb +7 -7
  60. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +4 -4
  61. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +1 -1
  62. data/lib/active_merchant/billing/gateways/worldpay_us.rb +2 -2
  63. data/lib/active_merchant/version.rb +1 -1
  64. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b190bcb3ae62de72a04d6ccf0bdbf8118bf3a7ed933047623376c19462f5300c
4
- data.tar.gz: f189cc282450940147eab25223d1046382edb063c5df42205f954931df22bce3
3
+ metadata.gz: e55d83260a0ec7b9a824a6313782d8c2b086d55aeb33d99554a09a18836f40a5
4
+ data.tar.gz: 35b24d3dd8e61c096ec4f5ef5d241a5ae3f905f32ba159e4332be36942cd3c56
5
5
  SHA512:
6
- metadata.gz: 720b7a70402af86c246c1f28cd2d5d310a84edc6528718b15bb3d6183001e1b1d083dfb43e5f8d2e89dddcaa75f385e1154059fd0e1d6ce6f4b168bd469cf119
7
- data.tar.gz: c8206af39075a57a3c4d201ef0d80a2cd775509cd62e5f6f5bdcfbf60809a0dd4bfe16e61ed587f42a1f75ebbbe893c1f97947886e9c758e289cd6993f3f7ac5
6
+ metadata.gz: 337249552ee4b5fd33ff2ca257cfcc90265e9aff657b5c42f42563aae070fd583308f5e6cfe05ed5ba1d23a791bac04edf50d0b8afce796c051d36f0b0dca256
7
+ data.tar.gz: d21728f2c2448e36842ccf5c38d64bf21ace79bd61ddf37367cf08f62ec98d33e0e277d5c5d21adb32ae7db4b03b15fa8e9f6d18b3acdf2be46ac153141585da
data/CHANGELOG CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  == HEAD
4
4
 
5
+ == Version 1.113.0
6
+ * Orbital: Add cardIndicators field [meagabeth] #3734
7
+ * Openpay: Add Colombia to supported countries [molbrown] #3740
8
+ * Mercado Pago: Update Device Id Header field [cdmackeyfree] #3741
9
+ * RuboCop: Fix Style/TrailingCommaInHashLiteral [leila-alderman] #3718
10
+ * RuboCop: Fix Naming/PredicateName [leila-alderman] #3724
11
+ * RuboCop: Fix Style/Attr [leila-alderman] #3728
12
+ * Payflow: Use application_id to set buttonsource [britth] #3737
13
+ * HPS: Enable refunds using capture transaction [britth] #3738
14
+ * Quickbooks: Omit empty strings in address [leila-alderman] #3743
15
+ * BlueSnap: Add transactionMetaData support #3745
16
+ * Orbital: Fix typo in PC3DtlLineTot field [naashton] #3736
17
+ * Credorax: Send first and last name parameters for CFT transactions [britth] #3748
18
+ * Orbital: Update CardIndicators field to fix bug [meagabeth] #3746
19
+ * CyberSource: Always send default address [leila-alderman] #3747
20
+ * Netbanx: Reject partial refund on pending status [rockyhakjoong] #3735
21
+
5
22
  == Version 1.112.0
6
23
  * Cybersource: add `maestro` and `diners_club` eci brand mapping [bbraschi] #3708
7
24
  * Cybersource: Ensure Partner Solution Id placement conforms to schema [britth] #3715
@@ -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={})
@@ -243,7 +243,7 @@ module ActiveMerchant #:nodoc:
243
243
  splits = []
244
244
  split_data.each do |split|
245
245
  amount = {
246
- value: split['amount']['value'],
246
+ value: split['amount']['value']
247
247
  }
248
248
  amount[:currency] = split['amount']['currency'] if split['amount']['currency']
249
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 = {
@@ -212,12 +212,28 @@ module ActiveMerchant
212
212
  end
213
213
  end
214
214
 
215
- def add_description(doc, description)
215
+ def add_metadata(doc, options)
216
+ transaction_meta_data = options.fetch(:transaction_meta_data, {})
217
+ return if transaction_meta_data.empty? && !options[:description]
218
+
216
219
  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')
220
+ # ensure backwards compatibility for calls expecting :description
221
+ # to become meta-data fields.
222
+ if options[:description]
223
+ doc.send('meta-data') do
224
+ doc.send('meta-key', 'description')
225
+ doc.send('meta-value', truncate(options[:description], 500))
226
+ doc.send('meta-description', 'Description')
227
+ end
228
+ end
229
+
230
+ # https://developers.bluesnap.com/v8976-XML/docs/meta-data
231
+ transaction_meta_data.each do |entry|
232
+ doc.send('meta-data') do
233
+ doc.send('meta-key', truncate(entry[:meta_key], 40))
234
+ doc.send('meta-value', truncate(entry[:meta_value], 500))
235
+ doc.send('meta-description', truncate(entry[:meta_description], 40))
236
+ end
221
237
  end
222
238
  end
223
239
  end
@@ -225,7 +241,7 @@ module ActiveMerchant
225
241
  def add_order(doc, options)
226
242
  doc.send('merchant-transaction-id', truncate(options[:order_id], 50)) if options[:order_id]
227
243
  doc.send('soft-descriptor', options[:soft_descriptor]) if options[:soft_descriptor]
228
- add_description(doc, options[:description]) if options[:description]
244
+ add_metadata(doc, options)
229
245
  add_3ds(doc, options[:three_d_secure]) if options[:three_d_secure]
230
246
  add_level_3_data(doc, options)
231
247
  end
@@ -315,7 +331,7 @@ module ActiveMerchant
315
331
  add_echeck_transaction(doc, payment_method_details.payment_method, options, vaulted_shopper_id.present?) if payment_method_details.check?
316
332
 
317
333
  add_fraud_info(doc, options)
318
- add_description(doc, options)
334
+ add_metadata(doc, options)
319
335
  end
320
336
 
321
337
  def add_echeck_transaction(doc, check, options, vaulted_shopper)
@@ -350,12 +366,21 @@ module ActiveMerchant
350
366
  parsed = {}
351
367
  doc = Nokogiri::XML(response.body)
352
368
  doc.root.xpath('*').each do |node|
369
+ name = node.name.downcase
370
+
353
371
  if node.elements.empty?
354
- parsed[node.name.downcase] = node.text
372
+ parsed[name] = node.text
373
+ elsif name == 'transaction-meta-data'
374
+ metadata = []
375
+ node.elements.each { |m|
376
+ metadata.push parse_metadata_entry(m)
377
+ }
378
+
379
+ parsed['transaction-meta-data'] = metadata
355
380
  else
356
- node.elements.each do |childnode|
381
+ node.elements.each { |childnode|
357
382
  parse_element(parsed, childnode)
358
- end
383
+ }
359
384
  end
360
385
  end
361
386
 
@@ -363,6 +388,18 @@ module ActiveMerchant
363
388
  parsed
364
389
  end
365
390
 
391
+ def parse_metadata_entry(node)
392
+ entry = {}
393
+
394
+ node.elements.each { |e|
395
+ entry = entry.merge({
396
+ e.name => e.text
397
+ })
398
+ }
399
+
400
+ entry
401
+ end
402
+
366
403
  def parse_element(parsed, node)
367
404
  if !node.elements.empty?
368
405
  node.elements.each { |e| parse_element(parsed, e) }
@@ -476,7 +513,7 @@ module ActiveMerchant
476
513
  def headers
477
514
  {
478
515
  'Content-Type' => 'application/xml',
479
- 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip),
516
+ 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip)
480
517
  }
481
518
  end
482
519
 
@@ -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
 
@@ -312,7 +312,7 @@ module ActiveMerchant #:nodoc:
312
312
  Version: '4.5.4',
313
313
  SoftwareName: 'Active Merchant',
314
314
  SoftwareVersion: ActiveMerchant::VERSION.to_s,
315
- Command: command,
315
+ Command: command
316
316
  }
317
317
 
318
318
  seed = SecureRandom.hex(32).upcase
@@ -250,7 +250,7 @@ module ActiveMerchant #:nodoc:
250
250
  '257' => STANDARD_ERROR_CODE[:invalid_cvc],
251
251
  '333' => STANDARD_ERROR_CODE[:expired_card],
252
252
  '1' => STANDARD_ERROR_CODE[:card_declined],
253
- '99' => STANDARD_ERROR_CODE[:processing_error],
253
+ '99' => STANDARD_ERROR_CODE[:processing_error]
254
254
  }
255
255
 
256
256
  def authorization_from(request, response)
@@ -194,7 +194,7 @@ module ActiveMerchant #:nodoc:
194
194
  def headers
195
195
  {
196
196
  'Authorization' => @options[:secret_key],
197
- 'Content-Type' => 'application/json;charset=UTF-8',
197
+ 'Content-Type' => 'application/json;charset=UTF-8'
198
198
  }
199
199
  end
200
200
 
@@ -193,6 +193,7 @@ module ActiveMerchant #:nodoc:
193
193
  add_email(post, options)
194
194
 
195
195
  if options[:referral_cft]
196
+ add_customer_name(post, options)
196
197
  commit(:referral_cft, post)
197
198
  else
198
199
  commit(:refund, post)
@@ -317,6 +318,11 @@ module ActiveMerchant #:nodoc:
317
318
  post[:c3] = options[:email] || 'unspecified@example.com'
318
319
  end
319
320
 
321
+ def add_customer_name(post, options)
322
+ post[:j5] = options[:first_name] if options[:first_name]
323
+ post[:j13] = options[:last_name] if options[:last_name]
324
+ end
325
+
320
326
  def add_3d_secure(post, options)
321
327
  if options[:eci] && options[:xid]
322
328
  add_3d_secure_1_data(post, options)
@@ -205,7 +205,7 @@ module ActiveMerchant #:nodoc:
205
205
  refund: 'SingleCallGenericReverse',
206
206
  tokenize: 'SingleCallTokenServlet',
207
207
  invalidate: 'SingleCallInvalidateToken',
208
- tokenpay: 'SingleCallTokenTransaction',
208
+ tokenpay: 'SingleCallTokenTransaction'
209
209
  }
210
210
 
211
211
  def commit(action, params)
@@ -34,7 +34,7 @@ module ActiveMerchant #:nodoc:
34
34
  american_express: 'aesk',
35
35
  jcb: 'js',
36
36
  discover: 'pb',
37
- diners_club: 'pb',
37
+ diners_club: 'pb'
38
38
  }.freeze
39
39
  DEFAULT_COLLECTION_INDICATOR = 2
40
40
 
@@ -266,7 +266,9 @@ module ActiveMerchant #:nodoc:
266
266
  zip: '00000',
267
267
  country: 'US'
268
268
  }
269
- options[:billing_address] = options[:billing_address] || options[:address] || default_address
269
+
270
+ submitted_address = options[:billing_address] || options[:address] || default_address
271
+ options[:billing_address] = default_address.merge(submitted_address) { |_k, default, submitted| submitted.blank? ? default : submitted }
270
272
  options[:shipping_address] = options[:shipping_address] || {}
271
273
  end
272
274
 
@@ -39,7 +39,7 @@ module ActiveMerchant #:nodoc:
39
39
  76 => STANDARD_ERROR_CODE[:call_issuer],
40
40
  91 => STANDARD_ERROR_CODE[:call_issuer],
41
41
  96 => STANDARD_ERROR_CODE[:processing_error],
42
- 97 => STANDARD_ERROR_CODE[:processing_error],
42
+ 97 => STANDARD_ERROR_CODE[:processing_error]
43
43
  }
44
44
 
45
45
  def initialize(options={})