activemerchant 1.22.0 → 1.23.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,5 +1,19 @@
1
1
  = ActiveMerchant CHANGELOG
2
2
 
3
+ == Version 1.23.0 (May 23, 2012)
4
+
5
+ * Add Litle gateway [GregDrake]
6
+ * PaymentExpress gateway: add support for BillingId and DpsBillingId for token [mikel]
7
+ * 2checkout integration: Add ability to auto settle [craigchristenson]
8
+ * 2checkout integration: Switch default mode to single page [craigchristenson]
9
+ * Cybersource: Revert - Add retrieve method to pull details on a
10
+ stored card [jduff]
11
+ * Cybersource: Revert - Add recurring payment support [jduff]
12
+ * PaymentExpress: add Cvc2Presence flag when submitting verification
13
+ value [jduff]
14
+ * SecurePayAU: fix CreditCard check [jduff]
15
+ * Barclays: fix order capture [csaunders/ntalbott/jduff]
16
+
3
17
  == Version 1.22.0 (May 17, 2012)
4
18
 
5
19
  * Remove version restriction for money gem [ylansegal]
@@ -666,7 +680,7 @@
666
680
  * Fix errors on base of CreditCard [josh.bassett]
667
681
  * Update product to use Rubigen instead of stolen Rails generator [cody]
668
682
  * Mimic directory structure of unit tests in remote tests [cody]
669
- * Restructure the location of the remote tests [cody]
683
+ * Restructure the location of the remote tests [cody]
670
684
  * Ensure DataCash order_id is limited to 30 characters [cody]
671
685
  * Return the pretty messages from PayJunction based on the return code [cody]
672
686
  * make CreditCard.require_verification_value = true the default [cody]
@@ -732,7 +746,7 @@
732
746
  * Enhance credit card error messages [manfred]
733
747
  * Use HashWithIndifferentAccess for CreditCard for compatibility with Rails applications [michael.j.mangino]
734
748
  * Fix nil exception when no response reason text is found in Authorize.net [cody]
735
- * Add support for PayJunction [Matt Sanders]
749
+ * Add support for PayJunction [Matt Sanders]
736
750
  * Change billing_address to shipping_address in PayPal Integration helper, as billing_address was incorrect. Addresses passed to billing_address for the PayPal helper will no longer be added to the form. This will break existing code, as the address will not be passed.
737
751
  * Remove switch patterns from card detection that were eliminated on July 1, 2007 [cody]
738
752
  * Format the issue number in Payflow requests to always be 2 digits [cody]
@@ -770,7 +784,7 @@
770
784
  * Update and test PslCardGateway [cody]
771
785
  * Add Laser card type [cody]
772
786
  * Update Nochex documentation [cody]
773
- * Sanitize the Realex order_id [cody]
787
+ * Sanitize the Realex order_id [cody]
774
788
  * Add support for Irish Realex payment gateway [John Ward, cody]
775
789
  * Move credit_card helper method to the test_helper [cody]
776
790
  * Update PayflowExpressResponse to match the interface of the PayflowExpressResponse. Add :no_shipping and :address_override options to PayflowExpress [cody]
@@ -828,7 +842,7 @@
828
842
  * Update DataCash tests and format merchant reference number to meet DataCash's requirements [MoneySpyder, cody]
829
843
  * Add Datacash gateway [MoneySpyder, cody]
830
844
  * VERIFY_PEER on all SSL requests [cody]
831
- * Add support for 2Checkout [cody]
845
+ * Add support for 2Checkout [cody]
832
846
 
833
847
  == Version 1.0.3
834
848
 
@@ -859,7 +873,7 @@
859
873
  * Moneris now uses the same layout as the authorized.net plugin
860
874
  * Added authorized.net
861
875
  * Changed default to :test mode. Set to production with ActiveMerchant::Billing::Base.gateway_mode = :production
862
- * More refactoring
876
+ * More refactoring
863
877
  * Refactored a bit so that there is space for billing and shipping area. None of the shipping aids are fleshed out yet. Needs more work.
864
878
  * Added Moneris support
865
879
  * Credit card in memory object resembling a AR object
data/CONTRIBUTORS CHANGED
@@ -301,3 +301,7 @@ MiGS gateway (April 2012)
301
301
  ePay integration (April 2012)
302
302
 
303
303
  * Michael (ePay)
304
+
305
+ Litle gateway (May 2012)
306
+
307
+ * Gregory Drake (GregDrake)
data/README.md CHANGED
@@ -108,6 +108,7 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
108
108
  * [iTransact](http://www.itransact.com/) - US
109
109
  * [JetPay](http://www.jetpay.com) - US
110
110
  * [LinkPoint](http://www.linkpoint.com/) - US
111
+ * [Litle](http://www.litle.com/) - US
111
112
  * [Merchant e-Solutions](http://merchante-solutions.com/) - US
112
113
  * [MerchantWare](http://merchantwarehouse.com/merchantware) - US
113
114
  * [MasterCard Internet Gateway Service (MiGS)](http://mastercard.com/mastercardsps) - AU, AE, BD, BN, EG, HK, ID, IN, JO, KW, LB, LK, MU, MV, MY, NZ, OM, PH, QA, SA, SG, TT, VN
@@ -153,10 +153,10 @@ module ActiveMerchant #:nodoc:
153
153
  {
154
154
  :success => success,
155
155
  :message => message,
156
- :authorization => find(doc, "//Transaction/Id"),
156
+ :transaction_id => find(doc, "//Transaction/Id"),
157
157
  :avs_result => find(doc, "//Transaction/AvsRespCode"),
158
158
  :cvv_result => find(doc, "//Transaction/Cvv2Resp"),
159
- :order_id => find(doc, "//OrderFormDoc/Transaction/Id"),
159
+ :authorization => find(doc, "//OrderFormDoc/Id"),
160
160
  :raw_response => @response
161
161
  }
162
162
  end
@@ -3,37 +3,35 @@ module ActiveMerchant #:nodoc:
3
3
  # See the remote and mocked unit test files for example usage. Pay special attention to the contents of the options hash.
4
4
  #
5
5
  # Initial setup instructions can be found in http://cybersource.com/support_center/implementation/downloads/soap_api/SOAP_toolkits.pdf
6
- #
7
- # Debugging
6
+ #
7
+ # Debugging
8
8
  # If you experience an issue with this gateway be sure to examine the transaction information from a general transaction search inside the CyberSource Business
9
- # Center for the full error messages including field names.
9
+ # Center for the full error messages including field names.
10
10
  #
11
11
  # Important Notes
12
- # * AVS and CVV only work against the production server. You will always get back X for AVS and no response for CVV against the test server.
13
- # * Nexus is the list of states or provinces where you have a physical presence. Nexus is used to calculate tax. Leave blank to tax everyone.
14
- # * If you want to calculate VAT for overseas customers you must supply a registration number in the options hash as vat_reg_number.
12
+ # * AVS and CVV only work against the production server. You will always get back X for AVS and no response for CVV against the test server.
13
+ # * Nexus is the list of states or provinces where you have a physical presence. Nexus is used to calculate tax. Leave blank to tax everyone.
14
+ # * If you want to calculate VAT for overseas customers you must supply a registration number in the options hash as vat_reg_number.
15
15
  # * productCode is a value in the line_items hash that is used to tell CyberSource what kind of item you are selling. It is used when calculating tax/VAT.
16
16
  # * All transactions use dollar values.
17
17
  class CyberSourceGateway < Gateway
18
18
  TEST_URL = 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor'
19
19
  LIVE_URL = 'https://ics2ws.ic3.com/commerce/1.x/transactionProcessor'
20
-
21
- XSD_VERSION = "1.69"
22
-
20
+
23
21
  # visa, master, american_express, discover
24
22
  self.supported_cardtypes = [:visa, :master, :american_express, :discover]
25
23
  self.supported_countries = ['US']
26
24
  self.default_currency = 'USD'
27
25
  self.homepage_url = 'http://www.cybersource.com'
28
26
  self.display_name = 'CyberSource'
29
-
27
+
30
28
  # map credit card to the CyberSource expected representation
31
29
  @@credit_card_codes = {
32
30
  :visa => '001',
33
31
  :master => '002',
34
32
  :american_express => '003',
35
33
  :discover => '004'
36
- }
34
+ }
37
35
 
38
36
  # map response codes to something humans can read
39
37
  @@response_codes = {
@@ -45,17 +43,17 @@ module ActiveMerchant #:nodoc:
45
43
  :r152 => "The request was received, but a service timed out",
46
44
  :r200 => "The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the AVS check",
47
45
  :r201 => "The issuing bank has questions about the request",
48
- :r202 => "Expired card",
49
- :r203 => "General decline of the card",
50
- :r204 => "Insufficient funds in the account",
51
- :r205 => "Stolen or lost card",
52
- :r207 => "Issuing bank unavailable",
53
- :r208 => "Inactive card or card not authorized for card-not-present transactions",
54
- :r209 => "American Express Card Identifiction Digits (CID) did not match",
55
- :r210 => "The card has reached the credit limit",
56
- :r211 => "Invalid card verification number",
57
- :r221 => "The customer matched an entry on the processor's negative file",
58
- :r230 => "The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the card verification check",
46
+ :r202 => "Expired card",
47
+ :r203 => "General decline of the card",
48
+ :r204 => "Insufficient funds in the account",
49
+ :r205 => "Stolen or lost card",
50
+ :r207 => "Issuing bank unavailable",
51
+ :r208 => "Inactive card or card not authorized for card-not-present transactions",
52
+ :r209 => "American Express Card Identifiction Digits (CID) did not match",
53
+ :r210 => "The card has reached the credit limit",
54
+ :r211 => "Invalid card verification number",
55
+ :r221 => "The customer matched an entry on the processor's negative file",
56
+ :r230 => "The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the card verification check",
59
57
  :r231 => "Invalid account number",
60
58
  :r232 => "The card type is not accepted by the payment processor",
61
59
  :r233 => "General decline by the processor",
@@ -74,44 +72,44 @@ module ActiveMerchant #:nodoc:
74
72
  :r247 => "You requested a credit for a capture that was previously voided",
75
73
  :r250 => "The request was received, but a time-out occurred with the payment processor",
76
74
  :r254 => "Your CyberSource account is prohibited from processing stand-alone refunds",
77
- :r255 => "Your CyberSource account is not configured to process the service in the country you specified"
75
+ :r255 => "Your CyberSource account is not configured to process the service in the country you specified"
78
76
  }
79
77
 
80
78
  # These are the options that can be used when creating a new CyberSource Gateway object.
79
+ #
80
+ # :login => your username
81
81
  #
82
- # :login => your username
83
- #
84
- # :password => the transaction key you generated in the Business Center
82
+ # :password => the transaction key you generated in the Business Center
85
83
  #
86
84
  # :test => true sets the gateway to test mode
87
85
  #
88
- # :vat_reg_number => your VAT registration number
86
+ # :vat_reg_number => your VAT registration number
89
87
  #
90
88
  # :nexus => "WI CA QC" sets the states/provinces where you have a physical presense for tax purposes
91
89
  #
92
- # :ignore_avs => true don't want to use AVS so continue processing even if AVS would have failed
90
+ # :ignore_avs => true don't want to use AVS so continue processing even if AVS would have failed
93
91
  #
94
- # :ignore_cvv => true don't want to use CVV so continue processing even if CVV would have failed
92
+ # :ignore_cvv => true don't want to use CVV so continue processing even if CVV would have failed
95
93
  def initialize(options = {})
96
94
  requires!(options, :login, :password)
97
95
  @options = options
98
96
  super
99
- end
97
+ end
100
98
 
101
99
  # Should run against the test servers or not?
102
100
  def test?
103
101
  @options[:test] || Base.gateway_mode == :test
104
102
  end
105
-
106
- # Request an authorization for an amount from CyberSource
103
+
104
+ # Request an authorization for an amount from CyberSource
107
105
  #
108
- # You must supply an :order_id in the options hash
106
+ # You must supply an :order_id in the options hash
109
107
  def authorize(money, creditcard, options = {})
110
108
  requires!(options, :order_id, :email)
111
109
  setup_address_hash(options)
112
110
  commit(build_auth_request(money, creditcard, options), options )
113
111
  end
114
-
112
+
115
113
  def auth_reversal(money, identification, options = {})
116
114
  commit(build_auth_reversal_request(money, identification, options), options)
117
115
  end
@@ -123,18 +121,13 @@ module ActiveMerchant #:nodoc:
123
121
  end
124
122
 
125
123
  # Purchase is an auth followed by a capture
126
- # You must supply an order_id in the options hash
127
- def purchase(money, payment_source, options = {})
124
+ # You must supply an order_id in the options hash
125
+ def purchase(money, creditcard, options = {})
128
126
  requires!(options, :order_id, :email)
129
127
  setup_address_hash(options)
130
- if payment_source.is_a?(String)
131
- requires!(options, [:type, :credit_card, :check])
132
- commit(build_subscription_purchase_request(money, payment_source, options), options)
133
- else
134
- commit(build_purchase_request(money, payment_source, options), options)
135
- end
128
+ commit(build_purchase_request(money, creditcard, options), options)
136
129
  end
137
-
130
+
138
131
  def void(identification, options = {})
139
132
  commit(build_void_request(identification, options), options)
140
133
  end
@@ -142,80 +135,17 @@ module ActiveMerchant #:nodoc:
142
135
  def refund(money, identification, options = {})
143
136
  commit(build_credit_request(money, identification, options), options)
144
137
  end
145
-
138
+
146
139
  def credit(money, identification, options = {})
147
140
  deprecated CREDIT_DEPRECATION_MESSAGE
148
141
  refund(money, identification, options)
149
142
  end
150
143
 
151
- # Creates or updates a cybersource customer profile, aka a subscription with type "on-demand"
152
- # to charge the card while creating a profile, pass options[:setup_fee] => money
153
- def store(credit_card_or_reference, options = {})
154
-
155
- requires!(options, :order_id)
156
- setup_address_hash(options)
157
-
158
- if credit_card_or_reference.respond_to?(:number)
159
- # create subscription
160
- requires!(options, :billing_address, :email)
161
- requires!(options[:billing_address], :first_name, :last_name)
162
-
163
- # set subscription options for storing the credit card
164
- options[:subscription] ||={}
165
- options[:subscription].merge!(:frequency => "on-demand", :amount => 0, :auto_renew => false)
166
-
167
- setup_address_hash(options)
168
- request = build_create_subscription_request(credit_card_or_reference, options)
169
- else
170
- # update subscription
171
- request = build_update_subscription_request(credit_card_or_reference, options)
172
- end
173
-
174
- commit(request, options)
175
- end
176
-
177
- # retrieves a customer subscription/profile
178
- def retrieve(reference, options = {})
179
- requires!(options, :order_id)
180
- commit(build_retrieve_subscription_request(reference, options), options)
181
- end
182
-
183
- # removes a customer subscription/profile
184
- def unstore(reference, options = {})
185
- requires!(options, :order_id)
186
- commit(build_delete_subscription_request(reference, options), options)
187
- end
188
-
189
- # Creates or updates a Cybersource recurring payment profile/subscription
190
- def recurring(money, credit_card_or_reference, options = {})
191
- requires!(options, :order_id, :subscription)
192
- requires!(options[:subscription], [:frequency, "on-demand", "weekly", "bi-weekly", "semi-monthly", "quarterly", "quad-weekly", "semi-annually", "annually"])
193
-
194
- options[:subscription].merge!(:amount => money)
195
-
196
- setup_address_hash(options)
197
-
198
- if credit_card_or_reference.respond_to?(:number)
199
- # create subscription
200
- requires!(options, :billing_address, :email)
201
- requires!(options[:billing_address], :first_name, :last_name)
202
-
203
- setup_address_hash(options)
204
- request = build_create_subscription_request(credit_card_or_reference, options)
205
- else
206
- # update subscription
207
- request = build_update_subscription_request(credit_card_or_reference, options)
208
- end
209
-
210
- commit(request, options)
211
- end
212
-
213
-
214
144
  # CyberSource requires that you provide line item information for tax calculations
215
145
  # If you do not have prices for each item or want to simplify the situation then pass in one fake line item that costs the subtotal of the order
216
146
  #
217
- # The line_item hash goes in the options hash and should look like
218
- #
147
+ # The line_item hash goes in the options hash and should look like
148
+ #
219
149
  # :line_items => [
220
150
  # {
221
151
  # :declared_value => '1',
@@ -235,23 +165,22 @@ module ActiveMerchant #:nodoc:
235
165
  #
236
166
  # This functionality is only supported by this particular gateway may
237
167
  # be changed at any time
238
- def calculate_tax(options)
168
+ def calculate_tax(creditcard, options)
239
169
  requires!(options, :line_items)
240
-
241
170
  setup_address_hash(options)
242
- commit(build_tax_calculation_request(options), options)
171
+ commit(build_tax_calculation_request(creditcard, options), options)
243
172
  end
244
-
245
- private
246
- # Create all address hash key value pairs so that we still function if we were only provided with one or two of them
173
+
174
+ private
175
+ # Create all address hash key value pairs so that we still function if we were only provided with one or two of them
247
176
  def setup_address_hash(options)
248
177
  options[:billing_address] = options[:billing_address] || options[:address] || {}
249
178
  options[:shipping_address] = options[:shipping_address] || {}
250
179
  end
251
-
180
+
252
181
  def build_auth_request(money, creditcard, options)
253
182
  xml = Builder::XmlMarkup.new :indent => 2
254
- add_address(xml, options[:billing_address], options)
183
+ add_address(xml, creditcard, options[:billing_address], options)
255
184
  add_purchase_data(xml, money, true, options)
256
185
  add_creditcard(xml, creditcard)
257
186
  add_auth_service(xml)
@@ -259,17 +188,17 @@ module ActiveMerchant #:nodoc:
259
188
  xml.target!
260
189
  end
261
190
 
262
- def build_tax_calculation_request(options)
191
+ def build_tax_calculation_request(creditcard, options)
263
192
  xml = Builder::XmlMarkup.new :indent => 2
264
- add_address(xml, options[:billing_address], options, false)
265
- add_address(xml, options[:shipping_address], options, true) unless options[:shipping_address].empty?
193
+ add_address(xml, creditcard, options[:billing_address], options, false)
194
+ add_address(xml, creditcard, options[:shipping_address], options, true)
266
195
  add_line_item_data(xml, options)
267
196
  add_purchase_data(xml, 0, false, options)
268
- add_tax_service(xml, options)
197
+ add_tax_service(xml)
269
198
  add_business_rules_data(xml)
270
199
  xml.target!
271
200
  end
272
-
201
+
273
202
  def build_capture_request(money, authorization, options)
274
203
  order_id, request_id, request_token = authorization.split(";")
275
204
  options[:order_id] = order_id
@@ -279,22 +208,22 @@ module ActiveMerchant #:nodoc:
279
208
  add_capture_service(xml, request_id, request_token)
280
209
  add_business_rules_data(xml)
281
210
  xml.target!
282
- end
211
+ end
283
212
 
284
- def build_purchase_request(money, payment_source, options)
213
+ def build_purchase_request(money, creditcard, options)
285
214
  xml = Builder::XmlMarkup.new :indent => 2
286
- add_address(xml, options[:billing_address], options)
215
+ add_address(xml, creditcard, options[:billing_address], options)
287
216
  add_purchase_data(xml, money, true, options)
288
- add_payment_source(xml, payment_source)
289
- add_purchase_service(xml, payment_source, options)
217
+ add_creditcard(xml, creditcard)
218
+ add_purchase_service(xml, options)
290
219
  add_business_rules_data(xml)
291
220
  xml.target!
292
221
  end
293
-
222
+
294
223
  def build_void_request(identification, options)
295
224
  order_id, request_id, request_token = identification.split(";")
296
225
  options[:order_id] = order_id
297
-
226
+
298
227
  xml = Builder::XmlMarkup.new :indent => 2
299
228
  add_void_service(xml, request_id, request_token)
300
229
  xml.target!
@@ -312,84 +241,11 @@ module ActiveMerchant #:nodoc:
312
241
  def build_credit_request(money, identification, options)
313
242
  order_id, request_id, request_token = identification.split(";")
314
243
  options[:order_id] = order_id
315
-
244
+
316
245
  xml = Builder::XmlMarkup.new :indent => 2
317
246
  add_purchase_data(xml, money, true, options)
318
247
  add_credit_service(xml, request_id, request_token)
319
-
320
- xml.target!
321
- end
322
-
323
- def build_create_subscription_request(payment_source, options)
324
- xml = Builder::XmlMarkup.new :indent => 2
325
- add_address(xml, options[:billing_address], options)
326
- add_purchase_data(xml, options[:setup_fee], true, options)
327
-
328
-
329
- case determine_funding_source(payment_source)
330
- when :credit_card then add_creditcard(xml, payment_source)
331
- when :check then add_check(xml, payment_source)
332
- else raise ArgumentError, "Unsupported funding source provided"
333
- end
334
-
335
- add_subscription(xml, options, payment_source)
336
- add_subscription_create_service(xml, options)
337
- add_business_rules_data(xml)
338
- xml.target!
339
- end
340
-
341
- def build_update_subscription_request(identification, options)
342
- reference_code, subscription_id, request_token = identification.split(";")
343
- options[:subscription] ||= {}
344
- options[:subscription][:subscription_id] = subscription_id
345
-
346
- xml = Builder::XmlMarkup.new :indent => 2
347
- add_address(xml, options[:billing_address], options) unless options[:billing_address].blank?
348
- add_purchase_data(xml, options[:setup_fee], true, options) unless options[:setup_fee].blank?
349
- add_creditcard(xml, options[:credit_card]) if options[:credit_card]
350
- add_subscription(xml, options)
351
- add_subscription_update_service(xml, options)
352
- add_business_rules_data(xml)
353
- xml.target!
354
- end
355
-
356
- def build_retrieve_subscription_request(identification, options)
357
- reference_code, subscription_id, request_token = identification.split(";")
358
- options[:subscription] ||= {}
359
- options[:subscription][:subscription_id] = subscription_id
360
-
361
- xml = Builder::XmlMarkup.new :indent => 2
362
- add_subscription(xml, options)
363
- add_subscription_retrieve_service(xml, options)
364
- xml.target!
365
- end
366
-
367
- def build_delete_subscription_request(identification, options)
368
- reference_code, subscription_id, request_token = identification.split(";")
369
- options[:subscription] ||= {}
370
- options[:subscription][:subscription_id] = subscription_id
371
-
372
- xml = Builder::XmlMarkup.new :indent => 2
373
- add_subscription(xml, options)
374
- add_subscription_delete_service(xml, options)
375
- xml.target!
376
- end
377
-
378
- def build_subscription_purchase_request(money, identification, options)
379
- reference_code, subscription_id, request_token = identification.split(";")
380
- options[:subscription] ||= {}
381
- options[:subscription][:subscription_id] = subscription_id
382
-
383
- xml = Builder::XmlMarkup.new :indent => 2
384
- add_purchase_data(xml, money, true, options)
385
- add_subscription(xml, options)
386
-
387
- case options[:type]
388
- when :credit_card then add_cc_purchase_service(xml, options)
389
- when :check then add_check_service(xml)
390
- end
391
-
392
- add_business_rules_data(xml)
248
+
393
249
  xml.target!
394
250
  end
395
251
 
@@ -397,13 +253,13 @@ module ActiveMerchant #:nodoc:
397
253
  xml.tag! 'businessRules' do
398
254
  xml.tag!('ignoreAVSResult', 'true') if @options[:ignore_avs]
399
255
  xml.tag!('ignoreCVResult', 'true') if @options[:ignore_cvv]
400
- end
256
+ end
401
257
  end
402
-
258
+
403
259
  def add_line_item_data(xml, options)
404
260
  options[:line_items].each_with_index do |value, index|
405
261
  xml.tag! 'item', {'id' => index} do
406
- xml.tag! 'unitPrice', amount(value[:declared_value])
262
+ xml.tag! 'unitPrice', amount(value[:declared_value])
407
263
  xml.tag! 'quantity', value[:quantity]
408
264
  xml.tag! 'productCode', value[:code] || 'shipping_only'
409
265
  xml.tag! 'productName', value[:description]
@@ -411,51 +267,37 @@ module ActiveMerchant #:nodoc:
411
267
  end
412
268
  end
413
269
  end
414
-
270
+
415
271
  def add_merchant_data(xml, options)
416
272
  xml.tag! 'merchantID', @options[:login]
417
273
  xml.tag! 'merchantReferenceCode', options[:order_id]
418
274
  xml.tag! 'clientLibrary' ,'Ruby Active Merchant'
419
- xml.tag! 'clientLibraryVersion', VERSION
420
- xml.tag! 'clientEnvironment' , RUBY_PLATFORM
421
- end
422
-
423
- def add_payment_source(xml, source, options={})
424
- case determine_funding_source(source)
425
- #when :subscription then add_customer_vault_id(params, source)
426
- when :credit_card then add_creditcard(xml, source)
427
- when :check then add_check(xml, source)
428
- end
275
+ xml.tag! 'clientLibraryVersion', '1.0'
276
+ xml.tag! 'clientEnvironment' , 'Linux'
429
277
  end
430
278
 
431
- def add_purchase_data(xml, money, include_grand_total = false, options={})
432
- money ||=0
279
+ def add_purchase_data(xml, money = 0, include_grand_total = false, options={})
433
280
  xml.tag! 'purchaseTotals' do
434
281
  xml.tag! 'currency', options[:currency] || currency(money)
435
- xml.tag!('grandTotalAmount', amount(money)) if include_grand_total
282
+ xml.tag!('grandTotalAmount', amount(money)) if include_grand_total
436
283
  end
437
284
  end
438
285
 
439
- def add_address(xml, address, options, shipTo = false)
286
+ def add_address(xml, creditcard, address, options, shipTo = false)
440
287
  xml.tag! shipTo ? 'shipTo' : 'billTo' do
441
- xml.tag! 'firstName', address[:first_name]
442
- xml.tag! 'lastName', address[:last_name]
443
- xml.tag! 'street1', address[:address1]
444
- xml.tag! 'street2', address[:address2]
445
- xml.tag! 'city', address[:city]
446
- xml.tag! 'state', address[:state]
447
- xml.tag! 'postalCode', address[:zip]
448
- xml.tag! 'country', address[:country]
449
- xml.tag! 'company', address[:company] unless address[:company].blank?
450
- xml.tag! 'companyTaxID', address[:companyTaxID] unless address[:company_tax_id].blank?
451
- xml.tag! 'phoneNumber', address[:phone_number] unless address[:phone_number].blank?
452
- xml.tag! 'email', options[:email] unless options[:email].blank?
453
- xml.tag! 'driversLicenseNumber', options[:drivers_license_number] unless options[:drivers_license_number].blank?
454
- xml.tag! 'driversLicenseState', options[:drivers_license_state] unless options[:drivers_license_state].blank?
455
- end
456
- end
457
-
458
- def add_creditcard(xml, creditcard)
288
+ xml.tag! 'firstName', creditcard.first_name
289
+ xml.tag! 'lastName', creditcard.last_name
290
+ xml.tag! 'street1', address[:address1]
291
+ xml.tag! 'street2', address[:address2]
292
+ xml.tag! 'city', address[:city]
293
+ xml.tag! 'state', address[:state]
294
+ xml.tag! 'postalCode', address[:zip]
295
+ xml.tag! 'country', address[:country]
296
+ xml.tag! 'email', options[:email]
297
+ end
298
+ end
299
+
300
+ def add_creditcard(xml, creditcard)
459
301
  xml.tag! 'card' do
460
302
  xml.tag! 'accountNumber', creditcard.number
461
303
  xml.tag! 'expirationMonth', format(creditcard.month, :two_digits)
@@ -465,35 +307,15 @@ module ActiveMerchant #:nodoc:
465
307
  end
466
308
  end
467
309
 
468
- def add_check(xml, check)
469
- #convert check object account type into cybs account type code
470
- if check.account_type == "checking"
471
- accountType = check.account_holder_type == "business" ? 'X' : 'C'
472
- else
473
- accountType = 'S'
474
- end
475
-
476
- xml.tag! 'check' do
477
- xml.tag! 'accountNumber', check.account_number
478
- xml.tag! 'accountType', accountType
479
- xml.tag! 'bankTransitNumber', check.routing_number
480
- xml.tag! 'checkNumber', check.number if check.number
481
- end
482
- end
483
-
484
- def add_check_service(xml)
485
- xml.tag! 'ecDebitService', {'run' => 'true'}
486
- end
487
-
488
- def add_tax_service(xml, options)
310
+ def add_tax_service(xml)
489
311
  xml.tag! 'taxService', {'run' => 'true'} do
490
- xml.tag!('nexus', options[:nexus]) unless options[:nexus].blank?
491
- xml.tag!('sellerRegistration', @ptions[:vat_reg_number]) unless options[:vat_reg_number].blank?
312
+ xml.tag!('nexus', @options[:nexus]) unless @options[:nexus].blank?
313
+ xml.tag!('sellerRegistration', @options[:vat_reg_number]) unless @options[:vat_reg_number].blank?
492
314
  end
493
315
  end
494
316
 
495
317
  def add_auth_service(xml)
496
- xml.tag! 'ccAuthService', {'run' => 'true'}
318
+ xml.tag! 'ccAuthService', {'run' => 'true'}
497
319
  end
498
320
 
499
321
  def add_capture_service(xml, request_id, request_token)
@@ -503,18 +325,11 @@ module ActiveMerchant #:nodoc:
503
325
  end
504
326
  end
505
327
 
506
- def add_purchase_service(xml, source, options)
507
- case determine_funding_source(source)
508
- when :credit_card then add_cc_purchase_service(xml, options)
509
- when :check then add_check_service(xml)
510
- end
511
- end
512
-
513
- def add_cc_purchase_service(xml, options)
328
+ def add_purchase_service(xml, options)
514
329
  xml.tag! 'ccAuthService', {'run' => 'true'}
515
330
  xml.tag! 'ccCaptureService', {'run' => 'true'}
516
331
  end
517
-
332
+
518
333
  def add_void_service(xml, request_id, request_token)
519
334
  xml.tag! 'voidService', {'run' => 'true'} do
520
335
  xml.tag! 'voidRequestID', request_id
@@ -536,47 +351,7 @@ module ActiveMerchant #:nodoc:
536
351
  end
537
352
  end
538
353
 
539
-
540
- def add_subscription_create_service(xml, options)
541
- add_cc_purchase_service(xml, options) if options[:setup_fee]
542
- xml.tag! 'paySubscriptionCreateService', {'run' => 'true'}
543
- end
544
-
545
- def add_subscription_update_service(xml, options)
546
- add_cc_purchase_service(xml, options) if options[:setup_fee]
547
- xml.tag! 'paySubscriptionUpdateService', {'run' => 'true'}
548
- end
549
-
550
- def add_subscription_retrieve_service(xml, options)
551
- xml.tag! 'paySubscriptionRetrieveService', {'run' => 'true'}
552
- end
553
-
554
- def add_subscription_delete_service(xml, options)
555
- xml.tag! 'paySubscriptionDeleteService', {'run' => 'true'}
556
- end
557
-
558
- def add_subscription(xml, options, payment_source=nil)
559
- if payment_source
560
- xml.tag! 'subscription' do
561
- xml.tag! 'paymentMethod', determine_funding_source(payment_source).to_s.gsub(/_/, " ")
562
- end
563
- end
564
-
565
- xml.tag! 'recurringSubscriptionInfo' do
566
- xml.tag! 'subscriptionID', options[:subscription][:subscription_id]
567
- xml.tag! 'status', options[:subscription][:status] if options[:subscription][:status]
568
- xml.tag! 'amount', options[:subscription][:amount] if options[:subscription][:amount]
569
- xml.tag! 'numberOfPayments', options[:subscription][:occurrences] if options[:subscription][:occurrences]
570
- xml.tag! 'automaticRenew', options[:subscription][:auto_renew] if options[:subscription][:auto_renew]
571
- xml.tag! 'frequency', options[:subscription][:frequency] if options[:subscription][:frequency]
572
- xml.tag! 'startDate', options[:subscription][:start_date].strftime("%Y%m%d") if options[:subscription][:start_date]
573
- xml.tag! 'endDate', options[:subscription][:end_date].strftime("%Y%m%d") if options[:subscription][:end_date]
574
- xml.tag! 'approvalRequired', options[:subscription][:approval_required] || false
575
- xml.tag! 'event', options[:subscription][:event] if options[:subscription][:event]
576
- xml.tag! 'billPayment', options[:subscription][:bill_payment] if options[:subscription][:bill_payment]
577
- end
578
- end
579
-
354
+
580
355
  # Where we actually build the full SOAP request using builder
581
356
  def build_request(body, options)
582
357
  xml = Builder::XmlMarkup.new :indent => 2
@@ -591,32 +366,31 @@ module ActiveMerchant #:nodoc:
591
366
  end
592
367
  end
593
368
  xml.tag! 's:Body', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'} do
594
- xml.tag! 'requestMessage', {'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{XSD_VERSION}"} do
369
+ xml.tag! 'requestMessage', {'xmlns' => 'urn:schemas-cybersource-com:transaction-data-1.32'} do
595
370
  add_merchant_data(xml, options)
596
371
  xml << body
597
372
  end
598
373
  end
599
374
  end
600
- xml.target!
375
+ xml.target!
601
376
  end
602
-
377
+
603
378
  # Contact CyberSource, make the SOAP request, and parse the reply into a Response object
604
379
  def commit(request, options)
605
- request = build_request(request, options)
606
- post_response = ssl_post(test? ? TEST_URL : LIVE_URL, request)
607
- response = parse(post_response)
380
+ response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, build_request(request, options)))
381
+
608
382
  success = response[:decision] == "ACCEPT"
609
- message = @@response_codes[('r' + response[:reasonCode]).to_sym] rescue response[:message]
383
+ message = @@response_codes[('r' + response[:reasonCode]).to_sym] rescue response[:message]
610
384
  authorization = success ? [ options[:order_id], response[:requestID], response[:requestToken] ].compact.join(";") : nil
611
-
612
- Response.new(success, message, response,
613
- :test => test?,
385
+
386
+ Response.new(success, message, response,
387
+ :test => test?,
614
388
  :authorization => authorization,
615
389
  :avs_result => { :code => response[:avsCode] },
616
390
  :cvv_result => response[:cvCode]
617
391
  )
618
392
  end
619
-
393
+
620
394
  # Parse the SOAP response
621
395
  # Technique inspired by the Paypal Gateway
622
396
  def parse(xml)
@@ -624,19 +398,19 @@ module ActiveMerchant #:nodoc:
624
398
  xml = REXML::Document.new(xml)
625
399
  if root = REXML::XPath.first(xml, "//c:replyMessage")
626
400
  root.elements.to_a.each do |node|
627
- case node.name
401
+ case node.name
628
402
  when 'c:reasonCode'
629
403
  reply[:message] = reply(node.text)
630
404
  else
631
405
  parse_element(reply, node)
632
406
  end
633
407
  end
634
- elsif root = REXML::XPath.first(xml, "//soap:Fault")
408
+ elsif root = REXML::XPath.first(xml, "//soap:Fault")
635
409
  parse_element(reply, root)
636
410
  reply[:message] = "#{reply[:faultcode]}: #{reply[:faultstring]}"
637
411
  end
638
412
  return reply
639
- end
413
+ end
640
414
 
641
415
  def parse_element(reply, node)
642
416
  if node.has_elements?
@@ -645,22 +419,12 @@ module ActiveMerchant #:nodoc:
645
419
  if node.parent.name =~ /item/
646
420
  parent = node.parent.name + (node.parent.attributes["id"] ? "_" + node.parent.attributes["id"] : '')
647
421
  reply[(parent + '_' + node.name).to_sym] = node.text
648
- else
422
+ else
649
423
  reply[node.name.to_sym] = node.text
650
424
  end
651
425
  end
652
426
  return reply
653
427
  end
654
-
655
- def determine_funding_source(source)
656
- case
657
- when source.is_a?(String) then :subscription
658
- when CreditCard.card_companies.keys.include?(card_brand(source)) then :credit_card
659
- when card_brand(source) == 'check' then :check
660
- else raise ArgumentError, "Unsupported funding source provided"
661
- end
662
- end
663
-
664
- end
665
- end
666
- end
428
+ end
429
+ end
430
+ end