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 +0 -0
- data/CHANGELOG +19 -5
- data/CONTRIBUTORS +4 -0
- data/README.md +1 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +2 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +106 -342
- data/lib/active_merchant/billing/gateways/litle.rb +275 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +1 -1
- data/lib/active_merchant/billing/gateways/payment_express.rb +59 -12
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +3 -2
- data/lib/active_merchant/billing/integrations/two_checkout.rb +1 -1
- data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +51 -34
- data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +71 -46
- data/lib/active_merchant/version.rb +1 -1
- metadata +168 -127
- metadata.gz.sig +2 -3
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
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
|
-
:
|
156
|
+
:transaction_id => find(doc, "//Transaction/Id"),
|
157
157
|
:avs_result => find(doc, "//Transaction/AvsRespCode"),
|
158
158
|
:cvv_result => find(doc, "//Transaction/Cvv2Resp"),
|
159
|
-
:
|
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
|
-
# :
|
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,
|
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
|
-
|
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)
|
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
|
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,
|
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
|
-
|
289
|
-
add_purchase_service(xml,
|
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',
|
420
|
-
xml.tag! 'clientEnvironment' ,
|
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',
|
442
|
-
xml.tag! 'lastName',
|
443
|
-
xml.tag! 'street1',
|
444
|
-
xml.tag! 'street2',
|
445
|
-
xml.tag! 'city',
|
446
|
-
xml.tag! 'state',
|
447
|
-
xml.tag! 'postalCode',
|
448
|
-
xml.tag! 'country',
|
449
|
-
xml.tag! '
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
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
|
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', @
|
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,
|
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' =>
|
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
|
-
|
606
|
-
|
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
|
-
|
656
|
-
|
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
|