activemerchant 1.44.1 → 1.45.0

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