noctivityinc-activemerchant 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/CHANGELOG +506 -0
  2. data/CONTRIBUTORS +134 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +136 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant/billing/avs_result.rb +98 -0
  7. data/lib/active_merchant/billing/base.rb +57 -0
  8. data/lib/active_merchant/billing/check.rb +68 -0
  9. data/lib/active_merchant/billing/credit_card.rb +159 -0
  10. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  11. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  12. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  13. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  14. data/lib/active_merchant/billing/gateway.rb +163 -0
  15. data/lib/active_merchant/billing/gateways/authorize_net.rb +654 -0
  16. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +736 -0
  17. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +244 -0
  18. data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
  19. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  20. data/lib/active_merchant/billing/gateways/bogus.rb +98 -0
  21. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  22. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  23. data/lib/active_merchant/billing/gateways/cyber_source.rb +406 -0
  24. data/lib/active_merchant/billing/gateways/data_cash.rb +593 -0
  25. data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
  26. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  27. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  28. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  29. data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
  30. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  31. data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
  32. data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
  33. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
  34. data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -0
  35. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  36. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  37. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  38. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  39. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  40. data/lib/active_merchant/billing/gateways/ogone.rb +279 -0
  41. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  42. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  43. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  44. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  45. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  46. data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
  47. data/lib/active_merchant/billing/gateways/payflow_express.rb +138 -0
  48. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  49. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  50. data/lib/active_merchant/billing/gateways/payment_express.rb +230 -0
  51. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
  52. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  53. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  54. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  55. data/lib/active_merchant/billing/gateways/paypal_express.rb +130 -0
  56. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
  57. data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
  58. data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
  59. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  60. data/lib/active_merchant/billing/gateways/quantum.rb +272 -0
  61. data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
  62. data/lib/active_merchant/billing/gateways/realex.rb +200 -0
  63. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  64. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  65. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  66. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  67. data/lib/active_merchant/billing/gateways/sage_pay.rb +309 -0
  68. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  69. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  70. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
  71. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  72. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  73. data/lib/active_merchant/billing/gateways/smart_ps.rb +265 -0
  74. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  75. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  76. data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
  77. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  78. data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
  79. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  80. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  81. data/lib/active_merchant/billing/gateways.rb +18 -0
  82. data/lib/active_merchant/billing/integrations/action_view_helper.rb +79 -0
  83. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  84. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  85. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  86. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  87. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  88. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  89. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  90. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  91. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  92. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  93. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  94. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  95. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  96. data/lib/active_merchant/billing/integrations/helper.rb +93 -0
  97. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  98. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  99. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  100. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  101. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  102. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  103. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  104. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  105. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  106. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  107. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  108. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  109. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  110. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  111. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  112. data/lib/active_merchant/billing/integrations/quickpay.rb +17 -0
  113. data/lib/active_merchant/billing/integrations/return.rb +35 -0
  114. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  115. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  116. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  117. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  118. data/lib/active_merchant/billing/integrations.rb +29 -0
  119. data/lib/active_merchant/billing/response.rb +32 -0
  120. data/lib/active_merchant/billing.rb +9 -0
  121. data/lib/active_merchant/lib/connection.rb +170 -0
  122. data/lib/active_merchant/lib/country.rb +319 -0
  123. data/lib/active_merchant/lib/error.rb +4 -0
  124. data/lib/active_merchant/lib/post_data.rb +22 -0
  125. data/lib/active_merchant/lib/posts_data.rb +47 -0
  126. data/lib/active_merchant/lib/requires_parameters.rb +16 -0
  127. data/lib/active_merchant/lib/utils.rb +18 -0
  128. data/lib/active_merchant/lib/validateable.rb +76 -0
  129. data/lib/active_merchant.rb +46 -0
  130. data/lib/certs/cacert.pem +7815 -0
  131. data/lib/support/gateway_support.rb +58 -0
  132. metadata +204 -0
@@ -0,0 +1,283 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class MerchantWareGateway < Gateway
4
+ URL = 'https://ps1.merchantware.net/MerchantWARE/ws/RetailTransaction/TXRetail.asmx'
5
+
6
+ self.supported_countries = ['US']
7
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
8
+ self.homepage_url = 'http://merchantwarehouse.com/merchantware'
9
+ self.display_name = 'MerchantWARE'
10
+
11
+ ENV_NAMESPACES = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
12
+ "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
13
+ "xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/"
14
+ }
15
+ TX_NAMESPACE = "http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail"
16
+
17
+ ACTIONS = {
18
+ :purchase => "IssueKeyedSale",
19
+ :authorize => "IssueKeyedPreAuth",
20
+ :capture => "IssuePostAuth",
21
+ :void => "IssueVoid",
22
+ :credit => "IssueKeyedRefund",
23
+ :reference_credit => "IssueRefundByReference"
24
+ }
25
+
26
+ # Creates a new MerchantWareGateway
27
+ #
28
+ # The gateway requires that a valid login, password, and name be passed
29
+ # in the +options+ hash.
30
+ #
31
+ # ==== Options
32
+ #
33
+ # * <tt>:login</tt> - The MerchantWARE SiteID.
34
+ # * <tt>:password</tt> - The MerchantWARE Key.
35
+ # * <tt>:name</tt> - The MerchantWARE Name.
36
+ def initialize(options = {})
37
+ requires!(options, :login, :password, :name)
38
+ @options = options
39
+ super
40
+ end
41
+
42
+ # Authorize a credit card for a given amount.
43
+ #
44
+ # ==== Parameters
45
+ # * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
46
+ # * <tt>credit_card</tt> - The CreditCard details for the transaction.
47
+ # * <tt>options</tt>
48
+ # * <tt>:order_id</tt> - A unique reference for this order (required).
49
+ # * <tt>:billing_address</tt> - The billing address for the cardholder.
50
+ def authorize(money, credit_card, options = {})
51
+ request = build_purchase_request(:authorize, money, credit_card, options)
52
+ commit(:authorize, request)
53
+ end
54
+
55
+ # Authorize and immediately capture funds from a credit card.
56
+ #
57
+ # ==== Parameters
58
+ # * <tt>money</tt> - The amount to be authorized as anInteger value in cents.
59
+ # * <tt>credit_card</tt> - The CreditCard details for the transaction.
60
+ # * <tt>options</tt>
61
+ # * <tt>:order_id</tt> - A unique reference for this order (required).
62
+ # * <tt>:billing_address</tt> - The billing address for the cardholder.
63
+ def purchase(money, credit_card, options = {})
64
+ request = build_purchase_request(:purchase, money, credit_card, options)
65
+ commit(:purchase, request)
66
+ end
67
+
68
+ # Capture authorized funds from a credit card.
69
+ #
70
+ # ==== Parameters
71
+ # * <tt>money</tt> - The amount to be captured as anInteger value in cents.
72
+ # * <tt>authorization</tt> - The authorization string returned from the initial authorization.
73
+ def capture(money, authorization, options = {})
74
+ request = build_capture_request(:capture, money, authorization, options)
75
+ commit(:capture, request)
76
+ end
77
+
78
+ # Void a transaction.
79
+ #
80
+ # ==== Parameters
81
+ # * <tt>authorization</tt> - The authorization string returned from the initial authorization or purchase.
82
+ def void(authorization, options = {})
83
+ reference, options[:order_id] = split_reference(authorization)
84
+
85
+ request = soap_request(:void) do |xml|
86
+ add_reference(xml, reference)
87
+ end
88
+ commit(:void, request)
89
+ end
90
+
91
+ # Refund an amount back a cardholder
92
+ #
93
+ # ==== Parameters
94
+ #
95
+ # * <tt>money</tt> - The amount to be refunded as an Integer value in cents.
96
+ # * <tt>identification</tt> - The credit card you want to refund or the authorization for the existing transaction you are refunding.
97
+ # * <tt>options</tt>
98
+ # * <tt>:order_id</tt> - A unique reference for this order (required when performing a non-referenced credit)
99
+ def credit(money, identification, options = {})
100
+ if identification.is_a?(String)
101
+ perform_reference_credit(money, identification, options)
102
+ else
103
+ perform_credit(money, identification, options)
104
+ end
105
+ end
106
+
107
+ private
108
+
109
+ def soap_request(action)
110
+ xml = Builder::XmlMarkup.new :indent => 2
111
+ xml.instruct!
112
+ xml.tag! "env:Envelope", ENV_NAMESPACES do
113
+ xml.tag! "env:Body" do
114
+ xml.tag! ACTIONS[action], "xmlns" => TX_NAMESPACE do
115
+ add_credentials(xml)
116
+ yield xml
117
+ end
118
+ end
119
+ end
120
+ xml.target!
121
+ end
122
+
123
+ def build_purchase_request(action, money, credit_card, options)
124
+ requires!(options, :order_id)
125
+
126
+ request = soap_request(action) do |xml|
127
+ add_invoice(xml, options)
128
+ add_amount(xml, money)
129
+ add_credit_card(xml, credit_card)
130
+ add_address(xml, options)
131
+ end
132
+ end
133
+
134
+ def build_capture_request(action, money, identification, options)
135
+ reference, options[:order_id] = split_reference(identification)
136
+
137
+ request = soap_request(action) do |xml|
138
+ add_reference(xml, reference)
139
+ add_invoice(xml, options)
140
+ add_amount(xml, money)
141
+ end
142
+ end
143
+
144
+ def perform_reference_credit(money, identification, options)
145
+ reference, options[:order_id] = split_reference(identification)
146
+
147
+ request = soap_request(:reference_credit) do |xml|
148
+ add_reference(xml, reference)
149
+ add_invoice(xml, options)
150
+ add_amount(xml, money, "strOverrideAmount")
151
+ end
152
+
153
+ commit(:reference_credit, request)
154
+ end
155
+
156
+ def perform_credit(money, credit_card, options)
157
+ requires!(options, :order_id)
158
+
159
+ request = soap_request(:credit) do |xml|
160
+ add_invoice(xml, options)
161
+ add_amount(xml, money)
162
+ add_credit_card(xml, credit_card)
163
+ end
164
+
165
+ commit(:credit, request)
166
+ end
167
+
168
+ def add_credentials(xml)
169
+ xml.tag! "strSiteId", @options[:login]
170
+ xml.tag! "strKey", @options[:password]
171
+ xml.tag! "strName", @options[:name]
172
+ end
173
+
174
+ def expdate(credit_card)
175
+ year = sprintf("%.4i", credit_card.year)
176
+ month = sprintf("%.2i", credit_card.month)
177
+
178
+ "#{month}#{year[-2..-1]}"
179
+ end
180
+
181
+ def add_invoice(xml, options)
182
+ xml.tag! "strOrderNumber", options[:order_id].to_s.gsub(/[^\w]/, '').slice(0, 25)
183
+ end
184
+
185
+ def add_amount(xml, money, tag = "strAmount")
186
+ xml.tag! tag, amount(money)
187
+ end
188
+
189
+ def add_reference(xml, reference)
190
+ xml.tag! "strReferenceCode", reference
191
+ end
192
+
193
+ def add_address(xml, options)
194
+ if address = options[:billing_address] || options[:address]
195
+ xml.tag! "strAVSStreetAddress", address[:address1]
196
+ xml.tag! "strAVSZipCode", address[:zip]
197
+ end
198
+ end
199
+
200
+ def add_credit_card(xml, credit_card)
201
+ xml.tag! "strPAN", credit_card.number
202
+ xml.tag! "strExpDate", expdate(credit_card)
203
+ xml.tag! "strCardHolder", credit_card.name
204
+ xml.tag! "strCVCode", credit_card.verification_value if credit_card.verification_value?
205
+ end
206
+
207
+ def split_reference(reference)
208
+ reference.to_s.split(";")
209
+ end
210
+
211
+ def parse(action, data)
212
+ response = {}
213
+ xml = REXML::Document.new(data)
214
+
215
+ root = REXML::XPath.first(xml, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
216
+
217
+ root.elements.each do |element|
218
+ response[element.name] = element.text
219
+ end
220
+
221
+ status, code, message = response["ApprovalStatus"].split(";")
222
+ response[:status] = status
223
+
224
+ if response[:success] = status == "APPROVED"
225
+ response[:message] = status
226
+ else
227
+ response[:message] = message
228
+ response[:failure_code] = code
229
+ end
230
+
231
+ response
232
+ end
233
+
234
+ def parse_error(http_response)
235
+ response = {}
236
+ response[:http_code] = http_response.code
237
+ response[:http_message] = http_response.message
238
+ response[:success] = false
239
+
240
+ document = REXML::Document.new(http_response.body)
241
+
242
+ node = REXML::XPath.first(document, "//soap:Fault")
243
+
244
+ node.elements.each do |element|
245
+ response[element.name] = element.text
246
+ end
247
+
248
+ response[:message] = response["faultstring"].to_s.gsub("\n", " ")
249
+ response
250
+ rescue REXML::ParseException => e
251
+ response[:http_body] = http_response.body
252
+ response[:message] = "Failed to parse the failed response"
253
+ response
254
+ end
255
+
256
+ def commit(action, request)
257
+ begin
258
+ data = ssl_post(URL, request,
259
+ "Content-Type" => 'text/xml; charset=utf-8',
260
+ "SOAPAction" => "http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail/#{ACTIONS[action]}"
261
+ )
262
+ response = parse(action, data)
263
+ rescue ActiveMerchant::ResponseError => e
264
+ response = parse_error(e.response)
265
+ end
266
+
267
+ Response.new(response[:success], response[:message], response,
268
+ :test => test?,
269
+ :authorization => authorization_from(response),
270
+ :avs_result => { :code => response["AVSResponse"] },
271
+ :cvv_result => response["CVResponse"]
272
+ )
273
+ end
274
+
275
+ def authorization_from(response)
276
+ if response[:success]
277
+ [ response["ReferenceID"], response["OrderNumber"] ].join(";")
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/modern_payments_cim'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class ModernPaymentsGateway < Gateway
6
+ self.supported_countries = ModernPaymentsCimGateway.supported_countries
7
+ self.supported_cardtypes = ModernPaymentsCimGateway.supported_cardtypes
8
+ self.homepage_url = ModernPaymentsCimGateway.homepage_url
9
+ self.display_name = ModernPaymentsCimGateway.display_name
10
+
11
+ def initialize(options = {})
12
+ requires!(options, :login, :password)
13
+ @options = options
14
+ super
15
+ end
16
+
17
+ def purchase(money, credit_card, options = {})
18
+ customer_response = cim.create_customer(options)
19
+ return customer_response unless customer_response.success?
20
+
21
+ customer_id = customer_response.params["create_customer_result"]
22
+
23
+ card_response = cim.modify_customer_credit_card(customer_id, credit_card)
24
+ return card_response unless card_response.success?
25
+
26
+ cim.authorize_credit_card_payment(customer_id, money)
27
+ end
28
+
29
+ private
30
+ def cim
31
+ @cim ||= ModernPaymentsCimGateway.new(@options)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,220 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class ModernPaymentsCimGateway < Gateway #:nodoc:
4
+ TEST_URL = "https://secure.modpay.com/netservices/test/ModpayTest.asmx"
5
+ LIVE_URL = 'https://secure.modpay.com/ws/modpay.asmx'
6
+
7
+ LIVE_XMLNS = "https://secure.modpay.com/ws/"
8
+ TEST_XMLNS = "https://secure.modpay.com/netservices/test/"
9
+
10
+ self.supported_countries = ['US']
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
12
+ self.homepage_url = 'http://www.modpay.com'
13
+ self.display_name = 'Modern Payments'
14
+
15
+ SUCCESS_MESSAGE = "Transaction accepted"
16
+ FAILURE_MESSAGE = "Transaction failed"
17
+ ERROR_MESSAGE = "Transaction error"
18
+
19
+ PAYMENT_METHOD = {
20
+ :check => 1,
21
+ :credit_card => 2
22
+ }
23
+
24
+ def initialize(options = {})
25
+ requires!(options, :login, :password)
26
+ @options = options
27
+ super
28
+ end
29
+
30
+ def create_customer(options = {})
31
+ post = {}
32
+ add_customer_data(post, options)
33
+ add_address(post, options)
34
+
35
+ commit('CreateCustomer', post)
36
+ end
37
+
38
+ def modify_customer_credit_card(customer_id, credit_card)
39
+ raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
40
+
41
+ post = {}
42
+ add_customer_id(post, customer_id)
43
+ add_credit_card(post, credit_card)
44
+
45
+ commit('ModifyCustomerCreditCard', post)
46
+ end
47
+
48
+ def authorize_credit_card_payment(customer_id, amount)
49
+ raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
50
+
51
+ post = {}
52
+ add_customer_id(post, customer_id)
53
+ add_amount(post, amount)
54
+
55
+ commit('AuthorizeCreditCardPayment', post)
56
+ end
57
+
58
+ def create_payment(customer_id, amount, options = {})
59
+ raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
60
+
61
+ post = {}
62
+ add_customer_id(post, customer_id)
63
+ add_amount(post, amount)
64
+ add_payment_details(post, options)
65
+
66
+ commit('CreatePayment', post)
67
+ end
68
+
69
+ private
70
+ def add_payment_details(post, options)
71
+ post[:pmtDate] = (options[:payment_date] || Time.now.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
72
+ post[:pmtType] = PAYMENT_METHOD[options[:payment_method] || :credit_card]
73
+ end
74
+
75
+ def add_amount(post, money)
76
+ post[:pmtAmount] = amount(money)
77
+ end
78
+
79
+ def add_customer_id(post, customer_id)
80
+ post[:custId] = customer_id
81
+ end
82
+
83
+ def add_customer_data(post, options)
84
+ post[:acctNum] = options[:customer]
85
+ end
86
+
87
+ def add_address(post, options)
88
+ address = options[:billing_address] || options[:address] || {}
89
+
90
+ if name = address[:name]
91
+ segments = name.split(' ')
92
+ post[:lastName] = segments.pop
93
+ post[:firstName] = segments.join(' ')
94
+ else
95
+ post[:firstName] = address[:first_name]
96
+ post[:lastName] = address[:last_name]
97
+ end
98
+
99
+ post[:address] = address[:address1]
100
+ post[:city] = address[:city]
101
+ post[:state] = address[:state]
102
+ post[:zip] = address[:zip]
103
+ post[:phone] = address[:phone]
104
+ post[:fax] = address[:fax]
105
+ post[:email] = options[:email]
106
+ end
107
+
108
+ def add_credit_card(post, credit_card)
109
+ post[:ccName] = credit_card.name
110
+ post[:ccNum] = credit_card.number
111
+ post[:expMonth] = credit_card.month
112
+ post[:expYear] = credit_card.year
113
+ end
114
+
115
+ def build_request(action, params)
116
+ xml = Builder::XmlMarkup.new :indent => 2
117
+ xml.instruct!
118
+ xml.tag! 'env:Envelope',
119
+ { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
120
+ 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
121
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' } do
122
+
123
+ xml.tag! 'env:Body' do
124
+ xml.tag! action, { "xmlns" => xmlns(action) } do
125
+ xml.tag! "clientId", @options[:login]
126
+ xml.tag! "clientCode", @options[:password]
127
+ params.each {|key, value| xml.tag! key, value }
128
+ end
129
+ end
130
+ end
131
+ xml.target!
132
+ end
133
+
134
+ def xmlns(action)
135
+ if test? && action == 'AuthorizeCreditCardPayment'
136
+ TEST_XMLNS
137
+ else
138
+ LIVE_XMLNS
139
+ end
140
+ end
141
+
142
+ def url(action)
143
+ if test? && action == 'AuthorizeCreditCardPayment'
144
+ TEST_URL
145
+ else
146
+ LIVE_URL
147
+ end
148
+ end
149
+
150
+ def commit(action, params)
151
+ data = ssl_post(url(action), build_request(action, params),
152
+ { 'Content-Type' =>'text/xml; charset=utf-8',
153
+ 'SOAPAction' => "#{xmlns(action)}#{action}" }
154
+ )
155
+
156
+ response = parse(action, data)
157
+ Response.new(successful?(action, response), message_from(action, response), response,
158
+ :test => test?,
159
+ :authorization => authorization_from(action, response),
160
+ :avs_result => { :code => response[:avs_code] }
161
+ )
162
+ end
163
+
164
+ def authorization_from(action, response)
165
+ response[authorization_key(action)]
166
+ end
167
+
168
+ def authorization_key(action)
169
+ action == "AuthorizeCreditCardPayment" ? :trans_id : "#{action.underscore}_result".to_sym
170
+ end
171
+
172
+ def successful?(action, response)
173
+ key = authorization_key(action)
174
+
175
+ if key == :trans_id
176
+ response[:approved] == "true"
177
+ else
178
+ response[key].to_i > 0
179
+ end
180
+ end
181
+
182
+ def message_from(action, response)
183
+ if response[:faultcode]
184
+ ERROR_MESSAGE
185
+ elsif successful?(action, response)
186
+ SUCCESS_MESSAGE
187
+ else
188
+ FAILURE_MESSAGE
189
+ end
190
+ end
191
+
192
+ def parse(action, xml)
193
+ response = {}
194
+ response[:action] = action
195
+
196
+ xml = REXML::Document.new(xml)
197
+ if root = REXML::XPath.first(xml, "//#{action}Response")
198
+ root.elements.to_a.each do |node|
199
+ parse_element(response, node)
200
+ end
201
+ elsif root = REXML::XPath.first(xml, "//soap:Fault")
202
+ root.elements.to_a.each do |node|
203
+ response[node.name.underscore.to_sym] = node.text
204
+ end
205
+ end
206
+
207
+ response
208
+ end
209
+
210
+ def parse_element(response, node)
211
+ if node.has_elements?
212
+ node.elements.each{|e| parse_element(response, e) }
213
+ else
214
+ response[node.name.underscore.to_sym] = node.text.to_s.strip
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
220
+