activemerchant 1.44.1 → 1.45.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 (58) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -3
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG +48 -0
  5. data/CONTRIBUTORS +12 -0
  6. data/README.md +15 -5
  7. data/lib/active_merchant/billing.rb +2 -0
  8. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  9. data/lib/active_merchant/billing/gateway.rb +36 -4
  10. data/lib/active_merchant/billing/gateways/adyen.rb +6 -2
  11. data/lib/active_merchant/billing/gateways/authorize_net.rb +332 -255
  12. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  13. data/lib/active_merchant/billing/gateways/bogus.rb +9 -9
  14. data/lib/active_merchant/billing/gateways/borgun.rb +0 -1
  15. data/lib/active_merchant/billing/gateways/braintree_blue.rb +8 -0
  16. data/lib/active_merchant/billing/gateways/cashnet.rb +17 -10
  17. data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
  18. data/lib/active_merchant/billing/gateways/conekta.rb +1 -1
  19. data/lib/active_merchant/billing/gateways/cyber_source.rb +1 -1
  20. data/lib/active_merchant/billing/gateways/elavon.rb +3 -3
  21. data/lib/active_merchant/billing/gateways/eway_rapid.rb +114 -13
  22. data/lib/active_merchant/billing/gateways/finansbank.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
  24. data/lib/active_merchant/billing/gateways/hps.rb +27 -20
  25. data/lib/active_merchant/billing/gateways/iats_payments.rb +68 -35
  26. data/lib/active_merchant/billing/gateways/litle.rb +36 -1
  27. data/lib/active_merchant/billing/gateways/merchant_one.rb +0 -1
  28. data/lib/active_merchant/billing/gateways/merchant_ware.rb +8 -4
  29. data/lib/active_merchant/billing/gateways/mercury.rb +17 -10
  30. data/lib/active_merchant/billing/gateways/moneris.rb +11 -6
  31. data/lib/active_merchant/billing/gateways/moneris_us.rb +126 -33
  32. data/lib/active_merchant/billing/gateways/money_movers.rb +0 -1
  33. data/lib/active_merchant/billing/gateways/net_registry.rb +6 -1
  34. data/lib/active_merchant/billing/gateways/network_merchants.rb +5 -5
  35. data/lib/active_merchant/billing/gateways/nmi.rb +241 -5
  36. data/lib/active_merchant/billing/gateways/openpay.rb +1 -0
  37. data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -1
  38. data/lib/active_merchant/billing/gateways/orbital.rb +6 -4
  39. data/lib/active_merchant/billing/gateways/pay_junction.rb +9 -5
  40. data/lib/active_merchant/billing/gateways/payex.rb +19 -9
  41. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +2 -2
  42. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  43. data/lib/active_merchant/billing/gateways/payscout.rb +0 -2
  44. data/lib/active_merchant/billing/gateways/pin.rb +1 -1
  45. data/lib/active_merchant/billing/gateways/psigate.rb +1 -2
  46. data/lib/active_merchant/billing/gateways/redsys.rb +37 -40
  47. data/lib/active_merchant/billing/gateways/secure_pay.rb +181 -9
  48. data/lib/active_merchant/billing/gateways/stripe.rb +106 -31
  49. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  50. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +38 -10
  51. data/lib/active_merchant/billing/gateways/webpay.rb +14 -0
  52. data/lib/active_merchant/billing/payment_token.rb +21 -0
  53. data/lib/active_merchant/billing/response.rb +2 -1
  54. data/lib/active_merchant/country.rb +6 -1
  55. data/lib/active_merchant/version.rb +1 -1
  56. metadata +8 -3
  57. metadata.gz.sig +0 -0
  58. data/lib/active_merchant/billing/gateways/samurai.rb +0 -130
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
4
4
  self.live_url = 'https://api.conekta.io/'
5
5
 
6
6
  self.supported_countries = ['MX']
7
- self.supported_cardtypes = [:visa, :master]
7
+ self.supported_cardtypes = [:visa, :master, :american_express]
8
8
  self.homepage_url = 'https://conekta.io/'
9
9
  self.display_name = 'Conekta Gateway'
10
10
  self.money_format = :cents
@@ -523,7 +523,7 @@ module ActiveMerchant #:nodoc:
523
523
  end
524
524
 
525
525
  xml.tag! 'status', options[:subscription][:status] if options[:subscription][:status]
526
- xml.tag! 'amount', options[:subscription][:amount] if options[:subscription][:amount]
526
+ xml.tag! 'amount', amount(options[:subscription][:amount]) if options[:subscription][:amount]
527
527
  xml.tag! 'numberOfPayments', options[:subscription][:occurrences] if options[:subscription][:occurrences]
528
528
  xml.tag! 'automaticRenew', options[:subscription][:automatic_renew] if options[:subscription][:automatic_renew]
529
529
  xml.tag! 'frequency', options[:subscription][:frequency] if options[:subscription][:frequency]
@@ -249,13 +249,13 @@ module ActiveMerchant #:nodoc:
249
249
  form[:salestax] = options[:tax] if options[:tax].present?
250
250
  end
251
251
 
252
- def add_address(form,options)
252
+ def add_address(form, options)
253
253
  billing_address = options[:billing_address] || options[:address]
254
254
 
255
255
  if billing_address
256
256
  form[:avs_address] = billing_address[:address1].to_s.slice(0, 30)
257
257
  form[:address2] = billing_address[:address2].to_s.slice(0, 30)
258
- form[:avs_zip] = billing_address[:zip].to_s.slice(0, 10)
258
+ form[:avs_zip] = billing_address[:zip].to_s.gsub(/[^a-zA-Z0-9]/, '').slice(0, 9)
259
259
  form[:city] = billing_address[:city].to_s.slice(0, 30)
260
260
  form[:state] = billing_address[:state].to_s.slice(0, 10)
261
261
  form[:company] = billing_address[:company].to_s.slice(0, 50)
@@ -337,7 +337,7 @@ module ActiveMerchant #:nodoc:
337
337
  resp = {}
338
338
  msg.split(self.delimiter).collect{|li|
339
339
  key, value = li.split("=")
340
- resp[key.strip.gsub(/^ssl_/, '')] = value.to_s.strip
340
+ resp[key.to_s.strip.gsub(/^ssl_/, '')] = value.to_s.strip
341
341
  }
342
342
  resp
343
343
  end
@@ -13,6 +13,8 @@ module ActiveMerchant #:nodoc:
13
13
  self.display_name = "eWAY Rapid 3.1"
14
14
  self.default_currency = "AUD"
15
15
 
16
+ class_attribute :partner_id
17
+
16
18
  def initialize(options = {})
17
19
  requires!(options, :login, :password)
18
20
  super
@@ -49,6 +51,7 @@ module ActiveMerchant #:nodoc:
49
51
  add_invoice(params, amount, options)
50
52
  add_customer_data(params, options)
51
53
  add_credit_card(params, payment_method, options)
54
+ params['Method'] = payment_method.respond_to?(:number) ? 'ProcessPayment' : 'TokenPayment'
52
55
  commit(url_for('Transaction'), params)
53
56
  end
54
57
 
@@ -58,6 +61,7 @@ module ActiveMerchant #:nodoc:
58
61
  add_invoice(params, amount, options)
59
62
  add_customer_data(params, options)
60
63
  add_credit_card(params, payment_method, options)
64
+ params['Method'] = 'Authorise'
61
65
  commit(url_for('Authorisation'), params)
62
66
  end
63
67
 
@@ -172,6 +176,10 @@ module ActiveMerchant #:nodoc:
172
176
  params['CustomerIP'] = options[:ip] if options[:ip]
173
177
  params['TransactionType'] = options[:transaction_type] || 'Purchase'
174
178
  params['DeviceID'] = options[:application_id] || application_id
179
+ if partner = options[:partner_id] || partner_id
180
+ params['PartnerID'] = truncate(partner, 50)
181
+ end
182
+ params
175
183
  end
176
184
 
177
185
  def add_invoice(params, money, options, key = "Payment")
@@ -220,7 +228,6 @@ module ActiveMerchant #:nodoc:
220
228
  return unless credit_card
221
229
  params['Customer'] ||= {}
222
230
  if credit_card.respond_to? :number
223
- params['Method'] = 'ProcessPayment'
224
231
  card_details = params['Customer']['CardDetails'] = {}
225
232
  card_details['Name'] = truncate(credit_card.name)
226
233
  card_details['Number'] = credit_card.number
@@ -228,7 +235,6 @@ module ActiveMerchant #:nodoc:
228
235
  card_details['ExpiryYear'] = "%02d" % (credit_card.year || 0)
229
236
  card_details['CVN'] = credit_card.verification_value
230
237
  else
231
- params['Method'] = 'TokenPayment'
232
238
  add_customer_token(params, credit_card)
233
239
  end
234
240
  end
@@ -280,13 +286,18 @@ module ActiveMerchant #:nodoc:
280
286
  end
281
287
  end
282
288
 
289
+ def parse_errors(message)
290
+ errors = message.split(',').collect{|code| MESSAGES[code.strip]}.flatten.join(',')
291
+ errors.presence || message
292
+ end
293
+
283
294
  def message_from(succeeded, response)
284
295
  if response['Errors']
285
- (MESSAGES[response['Errors']] || response['Errors'])
286
- elsif response['Responsecode']
287
- ActiveMerchant::Billing::EwayGateway::MESSAGES[response['ResponseCode']]
296
+ parse_errors(response['Errors'])
288
297
  elsif response['ResponseMessage']
289
- (MESSAGES[response['ResponseMessage']] || response['ResponseMessage'])
298
+ parse_errors(response['ResponseMessage'])
299
+ elsif response['ResponseCode']
300
+ ActiveMerchant::Billing::EwayGateway::MESSAGES[response['ResponseCode']]
290
301
  elsif succeeded
291
302
  "Succeeded"
292
303
  else
@@ -336,6 +347,64 @@ module ActiveMerchant #:nodoc:
336
347
  'A2010' => 'Approved For Partial Amount Successful',
337
348
  'A2011' => 'Approved, VIP Successful',
338
349
  'A2016' => 'Approved, Update Track 3 Successful',
350
+ 'D4401' => 'Refer to Issuer Failed',
351
+ 'D4402' => 'Refer to Issuer, special Failed',
352
+ 'D4403' => 'No Merchant Failed',
353
+ 'D4404' => 'Pick Up Card Failed',
354
+ 'D4405' => 'Do Not Honour Failed',
355
+ 'D4406' => 'Error Failed',
356
+ 'D4407' => 'Pick Up Card, Special Failed',
357
+ 'D4409' => 'Request In Progress Failed',
358
+ 'D4412' => 'Invalid Transaction Failed',
359
+ 'D4413' => 'Invalid Amount Failed',
360
+ 'D4414' => 'Invalid Card Number Failed',
361
+ 'D4415' => 'No Issuer Failed',
362
+ 'D4419' => 'Re-enter Last Transaction Failed',
363
+ 'D4421' => 'No Action Taken Failed',
364
+ 'D4422' => 'Suspected Malfunction Failed',
365
+ 'D4423' => 'Unacceptable Transaction Fee Failed',
366
+ 'D4425' => 'Unable to Locate Record On File Failed',
367
+ 'D4430' => 'Format Error Failed ',
368
+ 'D4431' => 'Bank Not Supported By Switch Failed',
369
+ 'D4433' => 'Expired Card, Capture Failed ',
370
+ 'D4434' => 'Suspected Fraud, Retain Card Failed',
371
+ 'D4435' => 'Card Acceptor, Contact Acquirer, Retain Card Failed',
372
+ 'D4436' => 'Restricted Card, Retain Card Failed',
373
+ 'D4437' => 'Contact Acquirer Security Department, Retain Card Failed',
374
+ 'D4438' => 'PIN Tries Exceeded, Capture Failed',
375
+ 'D4439' => 'No Credit Account Failed',
376
+ 'D4440' => 'Function Not Supported Failed',
377
+ 'D4441' => 'Lost Card Failed',
378
+ 'D4442' => 'No Universal Account Failed',
379
+ 'D4443' => 'Stolen Card Failed',
380
+ 'D4444' => 'No Investment Account Failed',
381
+ 'D4451' => 'Insufficient Funds Failed',
382
+ 'D4452' => 'No Cheque Account Failed',
383
+ 'D4453' => 'No Savings Account Failed',
384
+ 'D4454' => 'Expired Card Failed',
385
+ 'D4455' => 'Incorrect PIN Failed',
386
+ 'D4456' => 'No Card Record Failed',
387
+ 'D4457' => 'Function Not Permitted to Cardholder Failed',
388
+ 'D4458' => 'Function Not Permitted to Terminal Failed',
389
+ 'D4459' => 'Suspected Fraud Failed',
390
+ 'D4460' => 'Acceptor Contact Acquirer Failed',
391
+ 'D4461' => 'Exceeds Withdrawal Limit Failed',
392
+ 'D4462' => 'Restricted Card Failed',
393
+ 'D4463' => 'Security Violation Failed',
394
+ 'D4464' => 'Original Amount Incorrect Failed',
395
+ 'D4466' => 'Acceptor Contact Acquirer, Security Failed',
396
+ 'D4467' => 'Capture Card Failed',
397
+ 'D4475' => 'PIN Tries Exceeded Failed',
398
+ 'D4482' => 'CVV Validation Error Failed',
399
+ 'D4490' => 'Cut off In Progress Failed',
400
+ 'D4491' => 'Card Issuer Unavailable Failed',
401
+ 'D4492' => 'Unable To Route Transaction Failed',
402
+ 'D4493' => 'Cannot Complete, Violation Of The Law Failed',
403
+ 'D4494' => 'Duplicate Transaction Failed',
404
+ 'D4496' => 'System Error Failed',
405
+ 'D4497' => 'MasterPass Error Failed',
406
+ 'D4498' => 'PayPal Create Transaction Error Failed',
407
+ 'D4499' => 'Invalid Transaction for Auth/Void Failed',
339
408
  'S5000' => 'System Error',
340
409
  'S5085' => 'Started 3dSecure',
341
410
  'S5086' => 'Routed 3dSecure',
@@ -368,13 +437,14 @@ module ActiveMerchant #:nodoc:
368
437
  'V6042' => 'Customer FirstName Required',
369
438
  'V6043' => 'Customer LastName Required',
370
439
  'V6044' => 'Customer CountryCode Required',
371
- 'V6045' => 'Customer Title Required',
440
+ 'V6045' => 'Customer Title Required ',
372
441
  'V6046' => 'TokenCustomerID Required',
373
442
  'V6047' => 'RedirectURL Required',
443
+ 'V6048' => 'Invalid Checkout URL',
374
444
  'V6051' => 'Invalid Customer FirstName',
375
445
  'V6052' => 'Invalid Customer LastName',
376
446
  'V6053' => 'Invalid Customer CountryCode',
377
- 'V6058' => 'Invalid Customer Title',
447
+ 'V6058' => 'Invalid Customer Title ',
378
448
  'V6059' => 'Invalid RedirectURL',
379
449
  'V6060' => 'Invalid TokenCustomerID',
380
450
  'V6061' => 'Invalid Customer Reference',
@@ -385,7 +455,7 @@ module ActiveMerchant #:nodoc:
385
455
  'V6066' => 'Invalid Customer City',
386
456
  'V6067' => 'Invalid Customer State',
387
457
  'V6068' => 'Invalid Customer PostalCode',
388
- 'V6069' => 'Invalid Customer Email',
458
+ 'V6069' => 'Invalid Customer Email ',
389
459
  'V6070' => 'Invalid Customer Phone',
390
460
  'V6071' => 'Invalid Customer Mobile',
391
461
  'V6072' => 'Invalid Customer Comments',
@@ -402,21 +472,52 @@ module ActiveMerchant #:nodoc:
402
472
  'V6083' => 'Invalid ShippingAddress Phone',
403
473
  'V6084' => 'Invalid ShippingAddress Country',
404
474
  'V6085' => 'Invalid ShippingAddress ShippingMethod',
405
- 'V6086' => 'Invalid ShippingAddress Fax ',
475
+ 'V6086' => 'Invalid ShippingAddress Fax',
406
476
  'V6091' => 'Unknown Customer CountryCode',
407
477
  'V6092' => 'Unknown ShippingAddress CountryCode',
408
478
  'V6100' => 'Invalid EWAY_CARDNAME',
409
479
  'V6101' => 'Invalid EWAY_CARDEXPIRYMONTH',
410
- 'V6102' => 'Invalid EWAY_CARDEXPIRYYEAR',
480
+ 'V6102' => 'Invalid EWAY_CARDEXPIRYYEAR ',
411
481
  'V6103' => 'Invalid EWAY_CARDSTARTMONTH',
412
482
  'V6104' => 'Invalid EWAY_CARDSTARTYEAR',
413
- 'V6105' => 'Invalid EWAY_CARDISSUENUMBER',
483
+ 'V6105' => 'Invalid EWAY_CARDISSUENUMBER ',
414
484
  'V6106' => 'Invalid EWAY_CARDCVN',
415
485
  'V6107' => 'Invalid EWAY_ACCESSCODE',
416
486
  'V6108' => 'Invalid CustomerHostAddress',
417
487
  'V6109' => 'Invalid UserAgent',
418
488
  'V6110' => 'Invalid EWAY_CARDNUMBER',
419
- 'V6111' => 'Unauthorised API Access, Account Not PCI Certified'
489
+ 'V6111' => 'Unauthorised API Access, Account Not PCI Certified',
490
+ 'V6112' => 'Redundant card details other than expiry year and month',
491
+ 'V6113' => 'Invalid transaction for refund',
492
+ 'V6114' => 'Gateway validation error',
493
+ 'V6115' => 'Invalid DirectRefundRequest, Transaction ID',
494
+ 'V6116' => 'Invalid card data on original TransactionID',
495
+ 'V6117' => 'Invalid CreateAccessCodeSharedRequest, FooterText',
496
+ 'V6118' => 'Invalid CreateAccessCodeSharedRequest, HeaderText',
497
+ 'V6119' => 'Invalid CreateAccessCodeSharedRequest, Language',
498
+ 'V6120' => 'Invalid CreateAccessCodeSharedRequest, LogoUrl ',
499
+ 'V6121' => 'Invalid TransactionSearch, Filter Match Type',
500
+ 'V6122' => 'Invalid TransactionSearch, Non numeric Transaction ID',
501
+ 'V6123' => 'Invalid TransactionSearch,no TransactionID or AccessCode specified',
502
+ 'V6124' => 'Invalid Line Items. The line items have been provided however the totals do not match the TotalAmount field',
503
+ 'V6125' => 'Selected Payment Type not enabled',
504
+ 'V6126' => 'Invalid encrypted card number, decryption failed',
505
+ 'V6127' => 'Invalid encrypted cvn, decryption failed',
506
+ 'V6128' => 'Invalid Method for Payment Type',
507
+ 'V6129' => 'Transaction has not been authorised for Capture/Cancellation',
508
+ 'V6130' => 'Generic customer information error ',
509
+ 'V6131' => 'Generic shipping information error',
510
+ 'V6132' => 'Transaction has already been completed or voided, operation not permitted',
511
+ 'V6133' => 'Checkout not available for Payment Type',
512
+ 'V6134' => 'Invalid Auth Transaction ID for Capture/Void',
513
+ 'V6135' => 'PayPal Error Processing Refund',
514
+ 'V6140' => 'Merchant account is suspended',
515
+ 'V6141' => 'Invalid PayPal account details or API signature',
516
+ 'V6142' => 'Authorise not available for Bank/Branch',
517
+ 'V6150' => 'Invalid Refund Amount',
518
+ 'V6151' => 'Refund amount greater than original transaction',
519
+ 'V6152' => 'Original transaction already refunded for total amount',
520
+ 'V6153' => 'Card type not support by merchant',
420
521
  }
421
522
  end
422
523
  end
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
4
4
  module Billing #:nodoc:
5
5
  class FinansbankGateway < CC5Gateway
6
6
  self.live_url = 'https://www.fbwebpos.com/servlet/cc5ApiServer'
7
- self.test_url = 'https://testsanalpos.est.com.tr/servlet/cc5ApiServer'
7
+ self.test_url = 'https://entegrasyon.asseco-see.com.tr/fim/api'
8
8
 
9
9
  # The countries the gateway supports merchants from as 2 digit ISO country codes
10
10
  self.supported_countries = ['US', 'TR']
@@ -0,0 +1,183 @@
1
+ require 'nokogiri'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class GlobalTransportGateway < Gateway
6
+ self.test_url = 'https://certapia.globalpay.com/GlobalPay/transact.asmx/ProcessCreditCard'
7
+ self.live_url = 'https://api.globalpay.com/GlobalPay/transact.asmx/ProcessCreditCard'
8
+
9
+ self.supported_countries = %w(CA PR US)
10
+ self.default_currency = 'USD'
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
12
+
13
+ self.homepage_url = 'https://www.globalpaymentsinc.com'
14
+ self.display_name = 'Global Transport'
15
+
16
+ # Public: Create a new Global Transport gateway.
17
+ #
18
+ # options - A hash of options:
19
+ # :global_user_name - Your Global user name
20
+ # :global_password - Your Global password
21
+ # :term_type - 3 character field assigned by Global Transport after
22
+ # - your application is certified.
23
+ def initialize(options={})
24
+ requires!(options, :global_user_name, :global_password, :term_type)
25
+ super
26
+ end
27
+
28
+ def purchase(money, payment_method, options={})
29
+ post = {}
30
+ add_invoice(post, money, options)
31
+ add_payment_method(post, payment_method)
32
+ add_address(post, options)
33
+
34
+ commit('Sale', post, options)
35
+ end
36
+
37
+ def authorize(money, payment_method, options={})
38
+ post = {}
39
+ add_invoice(post, money, options)
40
+ add_payment_method(post, payment_method)
41
+ add_address(post, options)
42
+
43
+ commit('Auth', post, options)
44
+ end
45
+
46
+ def capture(money, authorization, options={})
47
+ post = {}
48
+ add_invoice(post, money, options)
49
+ add_auth(post, authorization)
50
+
51
+ commit('Force', post, options)
52
+ end
53
+
54
+ def refund(money, authorization, options={})
55
+ post = {}
56
+ add_invoice(post, money, options)
57
+ add_auth(post, authorization)
58
+
59
+ commit('Return', post, options)
60
+ end
61
+
62
+ def void(authorization, options={})
63
+ post = {}
64
+ add_auth(post, authorization)
65
+
66
+ commit('Void', post, options)
67
+ end
68
+
69
+ def verify(payment_method, options={})
70
+ post = {}
71
+ add_payment_method(post, payment_method)
72
+ add_address(post, options)
73
+
74
+ commit('CardVerify', post, options)
75
+ end
76
+
77
+ private
78
+
79
+ def add_address(post, options)
80
+ if address = (options[:billing_address] || options[:address])
81
+ post[:Street] = address[:address1]
82
+ post[:Zip] = address[:zip]
83
+ end
84
+ end
85
+
86
+ def add_auth(post, authorization)
87
+ post[:PNRef] = authorization
88
+ end
89
+
90
+ def add_invoice(post, money, options)
91
+ currency = (options[:currency] || currency(money))
92
+
93
+ post[:Amount] = localized_amount(money, currency)
94
+ post[:InvNum] = truncate(options[:order_id], 16)
95
+ end
96
+
97
+ def add_payment_method(post, payment_method)
98
+ post[:CardNum] = payment_method.number
99
+ post[:ExpDate] = expdate(payment_method)
100
+ post[:NameOnCard] = payment_method.name
101
+ post[:CVNum] = payment_method.verification_value
102
+ end
103
+
104
+ def parse(body)
105
+ response = {}
106
+
107
+ Nokogiri::XML(body).root.xpath('*').each do |node|
108
+ response[node.name.downcase.to_sym] = node.text
109
+ end
110
+
111
+ response
112
+ end
113
+
114
+ def commit(action, parameters, options)
115
+ raw = parse(ssl_post(url, post_data(action, parameters, options)))
116
+ Response.new(
117
+ success_from(raw),
118
+ message_from(raw),
119
+ raw,
120
+ authorization: authorization_from(raw),
121
+ test: test?,
122
+ avs_result: avs_from(raw),
123
+ cvv_result: cvv_from(raw)
124
+ )
125
+ end
126
+
127
+ def post_data(action, params, options)
128
+ post = default_params
129
+ post[:GlobalUserName] = @options[:global_user_name]
130
+ post[:GlobalPassword] = @options[:global_password]
131
+ post[:TransType] = action
132
+ post[:ExtData] = "<TermType>#{@options[:term_type]}</TermType>"
133
+
134
+ post.merge(params).map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
135
+ end
136
+
137
+ def url
138
+ (test? ? test_url : live_url)
139
+ end
140
+
141
+ def success_from(response)
142
+ (response[:result] == "0")
143
+ end
144
+
145
+ def message_from(response)
146
+ response[:respmsg]
147
+ end
148
+
149
+ def authorization_from(response)
150
+ response[:pnref]
151
+ end
152
+
153
+ def avs_from(response)
154
+ { code: response[:getavsresult] }
155
+ end
156
+
157
+ def cvv_from(response)
158
+ response[:getcvresult]
159
+ end
160
+
161
+ def default_params
162
+ {
163
+ CardNum: '',
164
+ ExpDate: '',
165
+ NameOnCard: '',
166
+ Amount: '',
167
+ PNRef: '',
168
+ Zip: '',
169
+ Street: '',
170
+ CVNum: '',
171
+ MagData: '',
172
+ InvNum: '',
173
+ ExtData: ''
174
+ }
175
+ end
176
+
177
+ def truncate(value, max_size)
178
+ return nil unless value
179
+ value.to_s[0, max_size]
180
+ end
181
+ end
182
+ end
183
+ end