activemerchant 1.56.0 → 1.57.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +42 -0
  3. data/lib/active_merchant/billing/gateways/authorize_net.rb +52 -21
  4. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -0
  5. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +243 -0
  6. data/lib/active_merchant/billing/gateways/bpoint.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/braintree_blue.rb +11 -11
  8. data/lib/active_merchant/billing/gateways/bridge_pay.rb +37 -8
  9. data/lib/active_merchant/billing/gateways/card_stream.rb +36 -11
  10. data/lib/active_merchant/billing/gateways/checkout_v2.rb +3 -0
  11. data/lib/active_merchant/billing/gateways/clearhaus.rb +2 -2
  12. data/lib/active_merchant/billing/gateways/creditcall.rb +1 -1
  13. data/lib/active_merchant/billing/gateways/cyber_source.rb +12 -1
  14. data/lib/active_merchant/billing/gateways/element.rb +335 -0
  15. data/lib/active_merchant/billing/gateways/forte.rb +8 -0
  16. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
  17. data/lib/active_merchant/billing/gateways/litle.rb +1 -1
  18. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +2 -1
  19. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +165 -0
  20. data/lib/active_merchant/billing/gateways/payeezy.rb +54 -12
  21. data/lib/active_merchant/billing/gateways/sage.rb +379 -128
  22. data/lib/active_merchant/billing/gateways/stripe.rb +13 -3
  23. data/lib/active_merchant/billing/gateways/trans_first.rb +26 -6
  24. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +573 -0
  25. data/lib/active_merchant/billing/gateways/worldpay.rb +7 -0
  26. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +11 -0
  27. data/lib/active_merchant/version.rb +1 -1
  28. metadata +7 -6
  29. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +0 -89
  30. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +0 -115
  31. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +0 -149
  32. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +0 -97
@@ -6,8 +6,8 @@ module ActiveMerchant #:nodoc:
6
6
  self.display_name = "BridgePay"
7
7
  self.homepage_url = "http://www.bridgepaynetwork.com/"
8
8
 
9
- self.test_url = "https://gatewaystage.itstgate.com/SmartPayments/transact.asmx"
10
- self.live_url = "https://gateway.itstgate.com/SmartPayments/transact.asmx"
9
+ self.test_url = "https://gatewaystage.itstgate.com/SmartPayments/transact3.asmx"
10
+ self.live_url = "https://gateway.itstgate.com/SmartPayments/transact3.asmx"
11
11
 
12
12
  self.supported_countries = ["CA", "US"]
13
13
  self.default_currency = "USD"
@@ -75,6 +75,17 @@ module ActiveMerchant #:nodoc:
75
75
  end
76
76
  end
77
77
 
78
+ def store(creditcard, options={})
79
+ post = initialize_required_fields('')
80
+ post[:transaction] = 'Create'
81
+ post[:CardNumber] = creditcard.number
82
+ post[:CustomerPaymentInfoKey] = ''
83
+ post[:token] = ''
84
+ add_payment_method(post, creditcard)
85
+
86
+ commit(post)
87
+ end
88
+
78
89
  def supports_scrubbing?
79
90
  true
80
91
  end
@@ -96,6 +107,8 @@ module ActiveMerchant #:nodoc:
96
107
  post[:ExpDate] = expdate(payment_method)
97
108
  post[:CardNum] = payment_method.number
98
109
  post[:CVNum] = payment_method.verification_value
110
+ elsif payment_method.is_a?(String)
111
+ add_token(post, payment_method)
99
112
  else
100
113
  post[:CheckNum] = payment_method.number
101
114
  post[:TransitNum] = payment_method.routing_number
@@ -105,6 +118,11 @@ module ActiveMerchant #:nodoc:
105
118
  end
106
119
  end
107
120
 
121
+ def add_token(post, payment_method)
122
+ payment_method = payment_method.split("|")
123
+ post[:ExtData] = "<Force>T</Force><CardVault><Transaction>Read</Transaction><CustomerPaymentInfoKey>#{payment_method[1]}</CustomerPaymentInfoKey><Token>#{payment_method[0]}</Token><ExpDate>#{payment_method[2]}</ExpDate></CardVault>"
124
+ end
125
+
108
126
  def initialize_required_fields(transaction_type)
109
127
  post = {}
110
128
  post[:TransType] = transaction_type
@@ -164,9 +182,8 @@ module ActiveMerchant #:nodoc:
164
182
  end
165
183
 
166
184
  def commit(parameters)
167
- url = url(parameters[:TransitNum] ? 'ProcessCheck' : 'ProcessCreditCard')
168
185
  data = post_data(parameters)
169
- raw = parse(ssl_post(url, data))
186
+ raw = parse(ssl_post(url(parameters), data))
170
187
 
171
188
  Response.new(
172
189
  success_from(raw),
@@ -177,9 +194,17 @@ module ActiveMerchant #:nodoc:
177
194
  )
178
195
  end
179
196
 
180
- def url(action)
181
- base = test? ? test_url : live_url
182
- "#{base}/#{action}"
197
+ def url(params)
198
+ if params[:transaction]
199
+ "#{base_url}/ManageCardVault"
200
+ else
201
+ action = params[:TransitNum] ? 'ProcessCheck' : 'ProcessCreditCard'
202
+ "#{base_url}/#{action}"
203
+ end
204
+ end
205
+
206
+ def base_url
207
+ test? ? test_url : live_url
183
208
  end
184
209
 
185
210
  def success_from(response)
@@ -191,7 +216,11 @@ module ActiveMerchant #:nodoc:
191
216
  end
192
217
 
193
218
  def authorization_from(response)
194
- [response[:authcode], response[:pnref]].join("|")
219
+ if response[:token]
220
+ [response[:token], response[:customerpaymentinfokey], response[:expdate]].join("|")
221
+ else
222
+ [response[:authcode], response[:pnref]].join("|")
223
+ end
195
224
  end
196
225
 
197
226
  def split_authorization(authorization)
@@ -75,11 +75,12 @@ module ActiveMerchant #:nodoc:
75
75
 
76
76
  def authorize(money, creditcard, options = {})
77
77
  post = {}
78
+ add_pair(post, :captureDelay, -1)
78
79
  add_amount(post, money, options)
79
80
  add_invoice(post, creditcard, money, options)
80
81
  add_creditcard(post, creditcard)
81
82
  add_customer_data(post, options)
82
- commit('PREAUTH', post)
83
+ commit('SALE', post)
83
84
  end
84
85
 
85
86
  def purchase(money, creditcard, options = {})
@@ -94,8 +95,9 @@ module ActiveMerchant #:nodoc:
94
95
  def capture(money, authorization, options = {})
95
96
  post = {}
96
97
  add_pair(post, :xref, authorization)
97
- add_amount(post, money, options)
98
- commit('SALE', post)
98
+ add_pair(post, :amount, amount(money), :required => true)
99
+
100
+ commit('CAPTURE', post)
99
101
  end
100
102
 
101
103
  def refund(money, authorization, options = {})
@@ -154,8 +156,8 @@ module ActiveMerchant #:nodoc:
154
156
  add_pair(post, :item1GrossValue, amount(money))
155
157
  end
156
158
 
157
- add_pair(post, :threeDSRequired, (options[:threeds_required] || @threeds_required) ? 'Y' : 'N')
158
159
  add_pair(post, :type, options[:type] || '1')
160
+ add_threeds_required(post, options)
159
161
  end
160
162
 
161
163
  def add_creditcard(post, credit_card)
@@ -175,6 +177,10 @@ module ActiveMerchant #:nodoc:
175
177
  add_pair(post, :cardCVV, credit_card.verification_value)
176
178
  end
177
179
 
180
+ def add_threeds_required(post, options)
181
+ add_pair(post, :threeDSRequired, (options[:threeds_required] || @threeds_required) ? 'Y' : 'N')
182
+ end
183
+
178
184
  def add_hmac(post)
179
185
  result = post.sort.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
180
186
  result = Digest::SHA512.hexdigest("#{result}#{@options[:shared_secret]}")
@@ -194,11 +200,10 @@ module ActiveMerchant #:nodoc:
194
200
  end
195
201
 
196
202
  def commit(action, parameters)
197
-
203
+ parameters.update(:countryCode => self.supported_countries[0]) unless action == 'CAPTURE'
198
204
  parameters.update(
199
205
  :merchantID => @options[:login],
200
- :action => action,
201
- :countryCode => self.supported_countries[0],
206
+ :action => action
202
207
  )
203
208
  # adds a signature to the post hash/array
204
209
  add_hmac(parameters)
@@ -211,13 +216,32 @@ module ActiveMerchant #:nodoc:
211
216
  :test => test?,
212
217
  :authorization => response[:xref],
213
218
  :cvv_result => CVV_CODE[response[:avscv2ResponseCode].to_s[0, 1]],
214
- :avs_result => {
215
- :postal_match => AVS_POSTAL_MATCH[response[:avscv2ResponseCode].to_s[1, 1]],
216
- :street_match => AVS_STREET_MATCH[response[:avscv2ResponseCode].to_s[2, 1]]
217
- }
219
+ :avs_result => avs_from(response)
218
220
  )
219
221
  end
220
222
 
223
+ def avs_from(response)
224
+ postal_match = AVS_POSTAL_MATCH[response[:avscv2ResponseCode].to_s[1, 1]]
225
+ street_match = AVS_STREET_MATCH[response[:avscv2ResponseCode].to_s[2, 1]]
226
+
227
+ code = if postal_match == "Y" && street_match == "Y"
228
+ "M"
229
+ elsif postal_match == "Y"
230
+ "P"
231
+ elsif street_match == "Y"
232
+ "A"
233
+ else
234
+ "I"
235
+ end
236
+
237
+ AVSResult.new({
238
+ :code => code,
239
+ :postal_match => postal_match,
240
+ :street_match => street_match
241
+ })
242
+ end
243
+
244
+
221
245
  def currency_code(currency)
222
246
  CURRENCY_CODES[currency]
223
247
  end
@@ -229,6 +253,7 @@ module ActiveMerchant #:nodoc:
229
253
  def add_pair(post, key, value, options = {})
230
254
  post[key] = value if !value.blank? || options[:required]
231
255
  end
256
+
232
257
  end
233
258
  end
234
259
  end
@@ -78,6 +78,9 @@ module ActiveMerchant #:nodoc:
78
78
  post[:value] = amount(money)
79
79
  post[:trackId] = options[:order_id]
80
80
  post[:currency] = options[:currency] || currency(money)
81
+ post[:descriptor] = {}
82
+ post[:descriptor][:name] = options[:descriptor_name] if options[:descriptor_name]
83
+ post[:descriptor][:city] = options[:descriptor_city] if options[:descriptor_city]
81
84
  end
82
85
 
83
86
  def add_payment_method(post, payment_method)
@@ -90,7 +90,7 @@ module ActiveMerchant #:nodoc:
90
90
  # options - A standard ActiveMerchant options hash
91
91
  def capture(amount, authorization, options={})
92
92
  post = {}
93
- add_amount(post, amount, options)
93
+ add_invoice(post, amount, options)
94
94
 
95
95
  commit("/authorizations/#{authorization}/captures", post)
96
96
  end
@@ -145,7 +145,7 @@ module ActiveMerchant #:nodoc:
145
145
  def add_invoice(post, money, options)
146
146
  add_amount(post, money, options)
147
147
  post[:reference] = options[:order_id] if options[:order_id]
148
- post[:text_on_statement] = options[:description] if options[:description]
148
+ post[:text_on_statement] = options[:text_on_statement] if options[:text_on_statement]
149
149
  end
150
150
 
151
151
  def add_amount(post, amount, options)
@@ -120,7 +120,7 @@ module ActiveMerchant #:nodoc:
120
120
 
121
121
  def add_card_details(xml, payment_method, options={})
122
122
  xml.CardDetails do
123
- xml.Manual(type: "cnp") do
123
+ xml.Manual(type: "ecommerce") do
124
124
  xml.PAN payment_method.number
125
125
  xml.ExpiryDate exp_date(payment_method)
126
126
  xml.CSC payment_method.verification_value unless empty?(payment_method.verification_value)
@@ -33,7 +33,7 @@ module ActiveMerchant #:nodoc:
33
33
  self.test_url = 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor'
34
34
  self.live_url = 'https://ics2ws.ic3.com/commerce/1.x/transactionProcessor'
35
35
 
36
- XSD_VERSION = "1.109"
36
+ XSD_VERSION = "1.121"
37
37
 
38
38
  # visa, master, american_express, discover
39
39
  self.supported_cardtypes = [:visa, :master, :american_express, :discover]
@@ -261,6 +261,7 @@ module ActiveMerchant #:nodoc:
261
261
  def build_auth_request(money, creditcard_or_reference, options)
262
262
  xml = Builder::XmlMarkup.new :indent => 2
263
263
  add_payment_method_or_subscription(xml, money, creditcard_or_reference, options)
264
+ add_mdd_fields(xml, options)
264
265
  add_auth_service(xml, creditcard_or_reference, options)
265
266
  add_business_rules_data(xml, creditcard_or_reference, options)
266
267
  xml.target!
@@ -291,6 +292,7 @@ module ActiveMerchant #:nodoc:
291
292
  def build_purchase_request(money, payment_method_or_reference, options)
292
293
  xml = Builder::XmlMarkup.new :indent => 2
293
294
  add_payment_method_or_subscription(xml, money, payment_method_or_reference, options)
295
+ add_mdd_fields(xml, options)
294
296
  if !payment_method_or_reference.is_a?(String) && card_brand(payment_method_or_reference) == 'check'
295
297
  add_check_service(xml)
296
298
  else
@@ -476,6 +478,15 @@ module ActiveMerchant #:nodoc:
476
478
  end
477
479
  end
478
480
 
481
+ def add_mdd_fields(xml, options)
482
+ xml.tag! 'merchantDefinedData' do
483
+ (1..20).each do |each|
484
+ key = "mdd_field_#{each}".to_sym
485
+ xml.tag!("field#{each}", options[key]) if options[key]
486
+ end
487
+ end
488
+ end
489
+
479
490
  def add_check(xml, check)
480
491
  xml.tag! 'check' do
481
492
  xml.tag! 'accountNumber', check.account_number
@@ -0,0 +1,335 @@
1
+ require 'nokogiri'
2
+ require 'securerandom'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ class ElementGateway < Gateway
7
+ self.test_url = 'https://certtransaction.elementexpress.com/express.asmx'
8
+ self.live_url = 'https://transaction.elementexpress.com/express.asmx'
9
+
10
+ self.supported_countries = ['US']
11
+ self.default_currency = 'USD'
12
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
13
+
14
+ self.homepage_url = 'http://www.elementps.com'
15
+ self.display_name = 'Element'
16
+
17
+ SERVICE_TEST_URL = 'https://certservices.elementexpress.com/express.asmx'
18
+ SERVICE_LIVE_URL = 'https://service.elementexpress.com/express.asmx'
19
+
20
+ def initialize(options={})
21
+ requires!(options, :account_id, :account_token, :application_id, :acceptor_id, :application_name, :application_version)
22
+ super
23
+ end
24
+
25
+ def purchase(money, payment, options={})
26
+ action = payment.is_a?(Check) ? "CheckSale" : "CreditCardSale"
27
+
28
+ request = build_soap_request do |xml|
29
+ xml.send(action, xmlns: "https://transaction.elementexpress.com") do
30
+ add_credentials(xml)
31
+ add_payment_method(xml, payment)
32
+ add_transaction(xml, money)
33
+ add_terminal(xml, options)
34
+ add_address(xml, options)
35
+ end
36
+ end
37
+
38
+ commit(action, request, money)
39
+ end
40
+
41
+ def authorize(money, payment, options={})
42
+ request = build_soap_request do |xml|
43
+ xml.CreditCardAuthorization(xmlns: "https://transaction.elementexpress.com") do
44
+ add_credentials(xml)
45
+ add_payment_method(xml, payment)
46
+ add_transaction(xml, money)
47
+ add_terminal(xml, options)
48
+ add_address(xml, options)
49
+ end
50
+ end
51
+
52
+ commit('CreditCardAuthorization', request, money)
53
+ end
54
+
55
+ def capture(money, authorization, options={})
56
+ trans_id, _ = split_authorization(authorization)
57
+ options.merge!({trans_id: trans_id})
58
+
59
+ request = build_soap_request do |xml|
60
+ xml.CreditCardAuthorizationCompletion(xmlns: "https://transaction.elementexpress.com") do
61
+ add_credentials(xml)
62
+ add_transaction(xml, money, options)
63
+ add_terminal(xml, options)
64
+ end
65
+ end
66
+
67
+ commit('CreditCardAuthorizationCompletion', request, money)
68
+ end
69
+
70
+ def refund(money, authorization, options={})
71
+ trans_id, _ = split_authorization(authorization)
72
+ options.merge!({trans_id: trans_id})
73
+
74
+ request = build_soap_request do |xml|
75
+ xml.CreditCardReturn(xmlns: "https://transaction.elementexpress.com") do
76
+ add_credentials(xml)
77
+ add_transaction(xml, money, options)
78
+ add_terminal(xml, options)
79
+ end
80
+ end
81
+
82
+ commit('CreditCardReturn', request, money)
83
+ end
84
+
85
+ def void(authorization, options={})
86
+ trans_id, trans_amount = split_authorization(authorization)
87
+ options.merge!({trans_id: trans_id, trans_amount: trans_amount, reversal_type: "Full"})
88
+
89
+ request = build_soap_request do |xml|
90
+ xml.CreditCardReversal(xmlns: "https://transaction.elementexpress.com") do
91
+ add_credentials(xml)
92
+ add_transaction(xml, trans_amount, options)
93
+ add_terminal(xml, options)
94
+ end
95
+ end
96
+
97
+ commit('CreditCardReversal', request, trans_amount)
98
+ end
99
+
100
+ def store(payment, options = {})
101
+ request = build_soap_request do |xml|
102
+ xml.PaymentAccountCreate(xmlns: "https://services.elementexpress.com") do
103
+ add_credentials(xml)
104
+ add_payment_method(xml, payment)
105
+ add_payment_account(xml, payment, options[:payment_account_reference_number] || SecureRandom.hex(20))
106
+ add_address(xml, options)
107
+ end
108
+ end
109
+
110
+ commit('PaymentAccountCreate', request, nil)
111
+ end
112
+
113
+ def verify(credit_card, options={})
114
+ MultiResponse.run(:use_first_response) do |r|
115
+ r.process { authorize(100, credit_card, options) }
116
+ r.process(:ignore_result) { void(r.authorization, options) }
117
+ end
118
+ end
119
+
120
+ def supports_scrubbing?
121
+ true
122
+ end
123
+
124
+ def scrub(transcript)
125
+ transcript.
126
+ gsub(%r((<AccountToken>).+?(</AccountToken>))i, '\1[FILTERED]\2').
127
+ gsub(%r((<CardNumber>).+?(</CardNumber>))i, '\1[FILTERED]\2').
128
+ gsub(%r((<CVV>).+?(</CVV>))i, '\1[FILTERED]\2').
129
+ gsub(%r((<AccountNumber>).+?(</AccountNumber>))i, '\1[FILTERED]\2').
130
+ gsub(%r((<RoutingNumber>).+?(</RoutingNumber>))i, '\1[FILTERED]\2')
131
+ end
132
+
133
+ private
134
+
135
+ def add_credentials(xml)
136
+ xml.credentials do
137
+ xml.AccountID @options[:account_id]
138
+ xml.AccountToken @options[:account_token]
139
+ xml.AcceptorID @options[:acceptor_id]
140
+ end
141
+ xml.application do
142
+ xml.ApplicationID @options[:application_id]
143
+ xml.ApplicationName @options[:application_name]
144
+ xml.ApplicationVersion @options[:application_version]
145
+ end
146
+ end
147
+
148
+ def add_payment_method(xml, payment)
149
+ if payment.is_a?(String)
150
+ add_payment_account_id(xml, payment)
151
+ elsif payment.is_a?(Check)
152
+ add_echeck(xml, payment)
153
+ else
154
+ add_credit_card(xml, payment)
155
+ end
156
+ end
157
+
158
+ def add_payment_account(xml, payment, payment_account_reference_number)
159
+ xml.paymentAccount do
160
+ xml.PaymentAccountType payment_account_type(payment)
161
+ xml.PaymentAccountReferenceNumber payment_account_reference_number
162
+ end
163
+ end
164
+
165
+ def add_payment_account_id(xml, payment)
166
+ xml.extendedParameters do
167
+ xml.ExtendedParameters do
168
+ xml.Key "PaymentAccount"
169
+ xml.Value("xsi:type" => "PaymentAccount") do
170
+ xml.PaymentAccountID payment
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ def add_transaction(xml, money, options = {})
177
+ xml.transaction do
178
+ xml.ReversalType options[:reversal_type] if options[:reversal_type]
179
+ xml.TransactionID options[:trans_id] if options[:trans_id]
180
+ xml.TransactionAmount amount(money.to_i) if money
181
+ xml.MarketCode "Default" if money
182
+ xml.ReferenceNumber options[:order_id] || SecureRandom.hex(20)
183
+ end
184
+ end
185
+
186
+ def add_terminal(xml, options)
187
+ xml.terminal do
188
+ xml.TerminalID "01"
189
+ xml.CardPresentCode "UseDefault"
190
+ xml.CardholderPresentCode "UseDefault"
191
+ xml.CardInputCode "UseDefault"
192
+ xml.CVVPresenceCode "UseDefault"
193
+ xml.TerminalCapabilityCode "UseDefault"
194
+ xml.TerminalEnvironmentCode "UseDefault"
195
+ xml.MotoECICode "NonAuthenticatedSecureECommerceTransaction"
196
+ end
197
+ end
198
+
199
+ def add_credit_card(xml, payment)
200
+ xml.card do
201
+ xml.CardNumber payment.number
202
+ xml.ExpirationMonth format(payment.month, :two_digits)
203
+ xml.ExpirationYear format(payment.year, :two_digits)
204
+ xml.CardholderName payment.first_name + " " + payment.last_name
205
+ xml.CVV payment.verification_value
206
+ end
207
+ end
208
+
209
+ def add_echeck(xml, payment)
210
+ xml.demandDepositAccount do
211
+ xml.AccountNumber payment.account_number
212
+ xml.RoutingNumber payment.routing_number
213
+ xml.DDAAccountType payment.account_type.capitalize
214
+ end
215
+ end
216
+
217
+ def add_address(xml, options)
218
+ if address = options[:billing_address] || options[:address]
219
+ xml.address do
220
+ xml.BillingAddress1 address[:address1] if address[:address1]
221
+ xml.BillingAddress2 address[:address2] if address[:address2]
222
+ xml.BillingCity address[:city] if address[:city]
223
+ xml.BillingState address[:state] if address[:state]
224
+ xml.BillingZipcode address[:zip] if address[:zip]
225
+ xml.BillingEmail address[:email] if address[:email]
226
+ xml.BillingPhone address[:phone_number] if address[:phone_number]
227
+ end
228
+ end
229
+ end
230
+
231
+ def parse(xml)
232
+ response = {}
233
+
234
+ doc = Nokogiri::XML(xml)
235
+ doc.remove_namespaces!
236
+ root = doc.root.xpath("//response/*")
237
+
238
+ if root.empty?
239
+ root = doc.root.xpath("//Response/*")
240
+ end
241
+
242
+ root.each do |node|
243
+ if (node.elements.empty?)
244
+ response[node.name.downcase] = node.text
245
+ else
246
+ node_name = node.name.downcase
247
+ response[node_name] = Hash.new
248
+
249
+ node.elements.each do |childnode|
250
+ response[node_name][childnode.name.downcase] = childnode.text
251
+ end
252
+ end
253
+ end
254
+
255
+ response
256
+ end
257
+
258
+ def commit(action, xml, amount)
259
+ response = parse(ssl_post(url(action), xml, headers(action)))
260
+
261
+ Response.new(
262
+ success_from(response),
263
+ message_from(response),
264
+ response,
265
+ authorization: authorization_from(action, response, amount),
266
+ test: test?
267
+ )
268
+ end
269
+
270
+ def authorization_from(action, response, amount)
271
+ if action == "PaymentAccountCreate"
272
+ response["paymentaccount"]["paymentaccountid"]
273
+ else
274
+ "#{response['transaction']['transactionid']}|#{amount}" if response['transaction']
275
+ end
276
+ end
277
+
278
+ def success_from(response)
279
+ response["expressresponsecode"] == "0"
280
+ end
281
+
282
+ def message_from(response)
283
+ response["expressresponsemessage"]
284
+ end
285
+
286
+ def split_authorization(authorization)
287
+ authorization.split("|")
288
+ end
289
+
290
+ def build_soap_request
291
+ builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
292
+ xml['soap'].Envelope('xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
293
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
294
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/') do
295
+
296
+ xml['soap'].Body do
297
+ yield(xml)
298
+ end
299
+ end
300
+ end
301
+
302
+ builder.to_xml
303
+ end
304
+
305
+ def payment_account_type(payment)
306
+ if payment.is_a?(Check)
307
+ payment_account_type = payment.account_type
308
+ else
309
+ payment_account_type = "CreditCard"
310
+ end
311
+ payment_account_type
312
+ end
313
+
314
+ def url(action)
315
+ if action == "PaymentAccountCreate"
316
+ url = (test? ? SERVICE_TEST_URL : SERVICE_LIVE_URL)
317
+ else
318
+ url = (test? ? test_url : live_url)
319
+ end
320
+ end
321
+
322
+ def interface(action)
323
+ return "transaction" if action != "PaymentAccountCreate"
324
+ return "services" if action == "PaymentAccountCreate"
325
+ end
326
+
327
+ def headers(action)
328
+ {
329
+ "Content-Type" => "text/xml; charset=utf-8",
330
+ "SOAPAction" => "https://#{interface(action)}.elementexpress.com/#{action}"
331
+ }
332
+ end
333
+ end
334
+ end
335
+ end