activemerchant 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +226 -0
- data/CONTRIBUTERS +52 -0
- data/README +34 -24
- data/Rakefile +152 -0
- data/gem-public_cert.pem +20 -0
- data/init.rb +3 -0
- data/lib/active_merchant.rb +3 -1
- data/lib/active_merchant/billing/credit_card.rb +21 -17
- data/lib/active_merchant/billing/credit_card_methods.rb +17 -19
- data/lib/active_merchant/billing/gateway.rb +160 -44
- data/lib/active_merchant/billing/gateways.rb +2 -15
- data/lib/active_merchant/billing/gateways/authorize_net.rb +21 -21
- data/lib/active_merchant/billing/gateways/bogus.rb +6 -6
- data/lib/active_merchant/billing/gateways/brain_tree.rb +191 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +207 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +402 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +41 -97
- data/lib/active_merchant/billing/gateways/efsnet.rb +256 -0
- data/lib/active_merchant/billing/gateways/eway.rb +77 -29
- data/lib/active_merchant/billing/gateways/exact.rb +230 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -33
- data/lib/active_merchant/billing/gateways/moneris.rb +155 -125
- data/lib/active_merchant/billing/gateways/net_registry.rb +257 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +407 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +163 -25
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +56 -38
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +10 -1
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +9 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +36 -11
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +6 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +7 -3
- data/lib/active_merchant/billing/gateways/payment_express.rb +261 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +18 -4
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +31 -15
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +8 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +33 -8
- data/lib/active_merchant/billing/gateways/plugnpay.rb +300 -0
- data/lib/active_merchant/billing/gateways/protx.rb +285 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +13 -12
- data/lib/active_merchant/billing/gateways/psl_card.rb +297 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +197 -0
- data/lib/active_merchant/billing/gateways/realex.rb +212 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +136 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +43 -20
- data/lib/active_merchant/billing/gateways/usa_epay.rb +6 -5
- data/lib/active_merchant/billing/gateways/verifi.rb +235 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +171 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +0 -2
- data/lib/active_merchant/billing/integrations/helper.rb +8 -1
- data/lib/active_merchant/billing/integrations/nochex.rb +62 -1
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +9 -16
- data/lib/active_merchant/billing/integrations/notification.rb +1 -1
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +59 -46
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +14 -47
- data/lib/active_merchant/lib/error.rb +4 -0
- data/lib/active_merchant/lib/post_data.rb +22 -0
- data/lib/active_merchant/lib/posts_data.rb +23 -5
- data/lib/active_merchant/lib/requires_parameters.rb +2 -2
- data/lib/active_merchant/lib/validateable.rb +1 -1
- data/lib/support/gateway_support.rb +45 -0
- data/lib/tasks/cia.rb +1 -1
- data/script/generate +14 -0
- data/script/generator/base.rb +45 -0
- data/script/generator/generator.rb +24 -0
- data/script/generator/generators/gateway/gateway_generator.rb +14 -0
- data/script/generator/generators/gateway/templates/gateway.rb +73 -0
- data/script/generator/generators/gateway/templates/gateway_test.rb +41 -0
- data/script/generator/generators/gateway/templates/remote_gateway_test.rb +56 -0
- data/script/generator/generators/integration/integration_generator.rb +25 -0
- data/script/generator/generators/integration/templates/helper.rb +34 -0
- data/script/generator/generators/integration/templates/helper_test.rb +54 -0
- data/script/generator/generators/integration/templates/integration.rb +18 -0
- data/script/generator/generators/integration/templates/module_test.rb +9 -0
- data/script/generator/generators/integration/templates/notification.rb +100 -0
- data/script/generator/generators/integration/templates/notification_test.rb +41 -0
- data/script/generator/manifest.rb +20 -0
- data/test/extra/binding_of_caller.rb +80 -0
- data/test/extra/breakpoint.rb +547 -0
- data/test/fixtures.yml +251 -0
- data/test/remote_tests/remote_authorize_net_test.rb +113 -0
- data/test/remote_tests/remote_brain_tree_test.rb +78 -0
- data/test/remote_tests/remote_card_stream_test.rb +160 -0
- data/test/remote_tests/remote_cyber_source_test.rb +130 -0
- data/test/remote_tests/remote_data_cash_test.rb +155 -0
- data/test/remote_tests/remote_efsnet_test.rb +93 -0
- data/test/remote_tests/remote_eway_test.rb +71 -0
- data/test/remote_tests/remote_exact_test.rb +59 -0
- data/test/remote_tests/remote_gestpay_integration_test.rb +37 -0
- data/test/remote_tests/remote_linkpoint_test.rb +144 -0
- data/test/remote_tests/remote_moneris_test.rb +110 -0
- data/test/remote_tests/remote_net_registry_test.rb +120 -0
- data/test/remote_tests/remote_pay_junction_test.rb +162 -0
- data/test/remote_tests/remote_payflow_express_test.rb +50 -0
- data/test/remote_tests/remote_payflow_test.rb +241 -0
- data/test/remote_tests/remote_payflow_uk_test.rb +172 -0
- data/test/remote_tests/remote_payment_express_test.rb +136 -0
- data/test/remote_tests/remote_paypal_express_test.rb +49 -0
- data/test/remote_tests/remote_paypal_integration_test.rb +14 -0
- data/test/remote_tests/remote_paypal_test.rb +163 -0
- data/test/remote_tests/remote_plugnpay_test.rb +70 -0
- data/test/remote_tests/remote_protx_test.rb +184 -0
- data/test/remote_tests/remote_psigate_test.rb +87 -0
- data/test/remote_tests/remote_psl_card_test.rb +105 -0
- data/test/remote_tests/remote_quickpay_test.rb +182 -0
- data/test/remote_tests/remote_realex_test.rb +227 -0
- data/test/remote_tests/remote_secure_pay_test.rb +36 -0
- data/test/remote_tests/remote_trans_first_test.rb +37 -0
- data/test/remote_tests/remote_trust_commerce_test.rb +136 -0
- data/test/remote_tests/remote_usa_epay_test.rb +57 -0
- data/test/remote_tests/remote_verifi_test.rb +107 -0
- data/test/remote_tests/remote_viaklix_test.rb +53 -0
- data/test/test_helper.rb +132 -0
- data/test/unit/base_test.rb +61 -0
- data/test/unit/country_code_test.rb +33 -0
- data/test/unit/country_test.rb +64 -0
- data/test/unit/credit_card_formatting_test.rb +24 -0
- data/test/unit/credit_card_methods_test.rb +37 -0
- data/test/unit/credit_card_test.rb +365 -0
- data/test/unit/gateways/authorize_net_test.rb +140 -0
- data/test/unit/gateways/bogus_test.rb +43 -0
- data/test/unit/gateways/brain_tree_test.rb +77 -0
- data/test/unit/gateways/card_stream_test.rb +37 -0
- data/test/unit/gateways/cyber_source_test.rb +151 -0
- data/test/unit/gateways/data_cash_test.rb +23 -0
- data/test/unit/gateways/efsnet_test.rb +70 -0
- data/test/unit/gateways/eway_test.rb +105 -0
- data/test/unit/gateways/exact_test.rb +118 -0
- data/test/unit/gateways/gateway_test.rb +24 -0
- data/test/unit/gateways/linkpoint_test.rb +165 -0
- data/test/unit/gateways/moneris_test.rb +167 -0
- data/test/unit/gateways/net_registry_test.rb +478 -0
- data/test/unit/gateways/pay_junction_test.rb +61 -0
- data/test/unit/gateways/payflow_express_test.rb +165 -0
- data/test/unit/gateways/payflow_express_uk_test.rb +14 -0
- data/test/unit/gateways/payflow_test.rb +230 -0
- data/test/unit/gateways/payflow_uk_test.rb +68 -0
- data/test/unit/gateways/payment_express_test.rb +215 -0
- data/test/unit/gateways/paypal_express_test.rb +222 -0
- data/test/unit/gateways/paypal_test.rb +241 -0
- data/test/unit/gateways/plugnpay_test.rb +79 -0
- data/test/unit/gateways/protx_test.rb +110 -0
- data/test/unit/gateways/psigate_test.rb +110 -0
- data/test/unit/gateways/psl_card_test.rb +51 -0
- data/test/unit/gateways/quickpay_test.rb +125 -0
- data/test/unit/gateways/realex_test.rb +150 -0
- data/test/unit/gateways/secure_pay_test.rb +78 -0
- data/test/unit/gateways/trans_first_test.rb +125 -0
- data/test/unit/gateways/trust_commerce_test.rb +57 -0
- data/test/unit/gateways/usa_epay_test.rb +117 -0
- data/test/unit/gateways/verifi_test.rb +91 -0
- data/test/unit/gateways/viaklix_test.rb +72 -0
- data/test/unit/integrations/action_view_helper_test.rb +54 -0
- data/test/unit/integrations/bogus_module_test.rb +16 -0
- data/test/unit/integrations/chronopay_module_test.rb +9 -0
- data/test/unit/integrations/gestpay_module_test.rb +10 -0
- data/test/unit/integrations/helpers/bogus_helper_test.rb +28 -0
- data/test/unit/integrations/helpers/chronopay_helper_test.rb +67 -0
- data/test/unit/integrations/helpers/gestpay_helper_test.rb +100 -0
- data/test/unit/integrations/helpers/nochex_helper_test.rb +53 -0
- data/test/unit/integrations/helpers/paypal_helper_test.rb +162 -0
- data/test/unit/integrations/helpers/two_checkout_helper_test.rb +92 -0
- data/test/unit/integrations/nochex_module_test.rb +9 -0
- data/test/unit/integrations/notifications/chronopay_notification_test.rb +66 -0
- data/test/unit/integrations/notifications/gestpay_notification_test.rb +60 -0
- data/test/unit/integrations/notifications/nochex_notification_test.rb +51 -0
- data/test/unit/integrations/notifications/notification_test.rb +41 -0
- data/test/unit/integrations/notifications/paypal_notification_test.rb +85 -0
- data/test/unit/integrations/notifications/two_checkout_notification_test.rb +55 -0
- data/test/unit/integrations/paypal_module_test.rb +24 -0
- data/test/unit/integrations/two_checkout_module_test.rb +9 -0
- data/test/unit/post_data_test.rb +55 -0
- data/test/unit/response_test.rb +14 -0
- data/test/unit/validateable_test.rb +56 -0
- metadata +160 -7
- metadata.gz.sig +0 -0
- data/lib/active_merchant/billing/gateways/payflow/f73e89fd.0 +0 -17
|
@@ -15,14 +15,11 @@ module ActiveMerchant #:nodoc:
|
|
|
15
15
|
# First, make sure you have everything setup correctly and all of your dependencies in place with:
|
|
16
16
|
#
|
|
17
17
|
# require 'rubygems'
|
|
18
|
-
# require 'money'
|
|
19
18
|
# require 'active_merchant'
|
|
20
19
|
#
|
|
21
|
-
#
|
|
20
|
+
# ActiveMerchant expects amounts to be Integer values in cents
|
|
22
21
|
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# tendollar = Money.us_dollar(1000)
|
|
22
|
+
# tendollar = 1000
|
|
26
23
|
#
|
|
27
24
|
# Next, create a credit card object using a TC approved test card.
|
|
28
25
|
#
|
|
@@ -103,42 +100,60 @@ module ActiveMerchant #:nodoc:
|
|
|
103
100
|
attr_reader :options
|
|
104
101
|
|
|
105
102
|
self.money_format = :cents
|
|
103
|
+
self.supported_cardtypes = [:visa, :master, :discover, :american_express, :diners_club, :jcb]
|
|
104
|
+
self.supported_countries = ['US']
|
|
105
|
+
self.homepage_url = 'http://www.trustcommerce.com/'
|
|
106
|
+
self.display_name = 'TrustCommerce'
|
|
106
107
|
|
|
108
|
+
# Creates a new TrustCommerceGateway
|
|
109
|
+
#
|
|
110
|
+
# The gateway requires that a valid login and password be passed
|
|
111
|
+
# in the +options+ hash.
|
|
112
|
+
#
|
|
113
|
+
# ==== Options
|
|
114
|
+
#
|
|
115
|
+
# * <tt>:login</tt> -- The TrustCommerce account login.
|
|
116
|
+
# * <tt>:password</tt> -- The TrustCommerce account password.
|
|
117
|
+
# * <tt>:test => +true+ or +false+</tt> -- Perform test transactions
|
|
118
|
+
#
|
|
119
|
+
# ==== Test Account Credentials
|
|
120
|
+
# * <tt>:login</tt> -- TestMerchant
|
|
121
|
+
# * <tt>:password</tt> -- password
|
|
107
122
|
def initialize(options = {})
|
|
108
123
|
requires!(options, :login, :password)
|
|
109
|
-
|
|
110
|
-
@options =
|
|
111
|
-
:login => "TestMerchant",
|
|
112
|
-
:password => "password"
|
|
113
|
-
}.update(options)
|
|
114
|
-
|
|
124
|
+
|
|
125
|
+
@options = options
|
|
115
126
|
super
|
|
116
127
|
end
|
|
117
128
|
|
|
129
|
+
def test?
|
|
130
|
+
@options[:test] || Base.gateway_mode == :test
|
|
131
|
+
end
|
|
132
|
+
|
|
118
133
|
# authorize() is the first half of the preauth(authorize)/postauth(capture) model. The TC API docs call this
|
|
119
134
|
# preauth, we preserve active_merchant's nomenclature of authorize() for consistency with the rest of the library. This
|
|
120
135
|
# method simply checks to make sure funds are available for a transaction, and returns a transid that can be used later to
|
|
121
136
|
# postauthorize (capture) the funds.
|
|
122
137
|
|
|
123
|
-
def authorize(money,
|
|
138
|
+
def authorize(money, creditcard_or_billing_id, options = {})
|
|
124
139
|
parameters = {
|
|
125
140
|
:amount => amount(money),
|
|
126
141
|
}
|
|
127
142
|
|
|
128
|
-
|
|
143
|
+
add_payment_source(parameters, creditcard_or_billing_id)
|
|
129
144
|
add_address(parameters, options)
|
|
130
145
|
commit('preauth', parameters)
|
|
131
146
|
end
|
|
132
147
|
|
|
133
148
|
# purchase() is a simple sale. This is one of the most common types of transactions, and is extremely simple. All that you need
|
|
134
|
-
# to process a purchase are an amount in cents or a money object and a creditcard object.
|
|
149
|
+
# to process a purchase are an amount in cents or a money object and a creditcard object or billingid string.
|
|
135
150
|
|
|
136
|
-
def purchase(money,
|
|
151
|
+
def purchase(money, creditcard_or_billing_id, options = {})
|
|
137
152
|
parameters = {
|
|
138
153
|
:amount => amount(money),
|
|
139
154
|
}
|
|
140
155
|
|
|
141
|
-
|
|
156
|
+
add_payment_source(parameters, creditcard_or_billing_id)
|
|
142
157
|
add_address(parameters, options)
|
|
143
158
|
commit('sale', parameters)
|
|
144
159
|
end
|
|
@@ -235,12 +250,16 @@ module ActiveMerchant #:nodoc:
|
|
|
235
250
|
|
|
236
251
|
commit('unstore', parameters)
|
|
237
252
|
end
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
253
|
+
|
|
254
|
+
private
|
|
255
|
+
def add_payment_source(params, source)
|
|
256
|
+
if source.is_a?(String)
|
|
257
|
+
add_billing_id(params, source)
|
|
258
|
+
else
|
|
259
|
+
add_creditcard(params, source)
|
|
260
|
+
end
|
|
241
261
|
end
|
|
242
262
|
|
|
243
|
-
private
|
|
244
263
|
def expdate(creditcard)
|
|
245
264
|
year = sprintf("%.4i", creditcard.year)
|
|
246
265
|
month = sprintf("%.2i", creditcard.month)
|
|
@@ -256,6 +275,10 @@ module ActiveMerchant #:nodoc:
|
|
|
256
275
|
params[:cvv] = creditcard.verification_value if creditcard.verification_value?
|
|
257
276
|
end
|
|
258
277
|
|
|
278
|
+
def add_billing_id(params, billingid)
|
|
279
|
+
params[:billingid] = billingid
|
|
280
|
+
end
|
|
281
|
+
|
|
259
282
|
def add_address(params, options)
|
|
260
283
|
address = options[:billing_address] || options[:address]
|
|
261
284
|
|
|
@@ -8,6 +8,11 @@ module ActiveMerchant #:nodoc:
|
|
|
8
8
|
attr_reader :url
|
|
9
9
|
attr_reader :response
|
|
10
10
|
attr_reader :options
|
|
11
|
+
|
|
12
|
+
self.supported_cardtypes = [:visa, :master, :american_express]
|
|
13
|
+
self.supported_countries = ['US']
|
|
14
|
+
self.homepage_url = 'http://www.usa_epay.com/'
|
|
15
|
+
self.display_name = 'USA ePay'
|
|
11
16
|
|
|
12
17
|
def initialize(options = {})
|
|
13
18
|
requires!(options, :login)
|
|
@@ -39,11 +44,7 @@ module ActiveMerchant #:nodoc:
|
|
|
39
44
|
post = {:refNum => authorization}
|
|
40
45
|
commit('capture', money, post)
|
|
41
46
|
end
|
|
42
|
-
|
|
43
|
-
def self.supported_cardtypes
|
|
44
|
-
[:visa, :master, :american_express]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
+
|
|
47
48
|
private
|
|
48
49
|
|
|
49
50
|
def expdate(creditcard)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
require 'rexml/document'
|
|
2
|
+
|
|
3
|
+
module ActiveMerchant #:nodoc:
|
|
4
|
+
module Billing #:nodoc:
|
|
5
|
+
class VerifiGateway < Gateway
|
|
6
|
+
class VerifiPostData < PostData
|
|
7
|
+
# Fields that will be send even if they are blank
|
|
8
|
+
self.required_fields = [ :amount, :type, :ccnumber, :ccexp, :firstname, :lastname,
|
|
9
|
+
:company, :address1, :address2, :city, :state, :zip, :country, :phone ]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
URL = 'https://secure.verifi.com/gw/api/transact.php'
|
|
13
|
+
|
|
14
|
+
RESPONSE_CODE_MESSAGES = {
|
|
15
|
+
"100" => "Transaction was Approved",
|
|
16
|
+
"200" => "Transaction was Declined by Processor",
|
|
17
|
+
"201" => "Do Not Honor",
|
|
18
|
+
"202" => "Insufficient Funds",
|
|
19
|
+
"203" => "Over Limit",
|
|
20
|
+
"204" => "Transaction not allowed",
|
|
21
|
+
"220" => "Incorrect payment Data",
|
|
22
|
+
"221" => "No Such Card Issuer",
|
|
23
|
+
"222" => "No Card Number on file with Issuer",
|
|
24
|
+
"223" => "Expired Card",
|
|
25
|
+
"224" => "Invalid Expiration Date",
|
|
26
|
+
"225" => "Invalid Card Security Code",
|
|
27
|
+
"240" => "Call Issuer for Further Information",
|
|
28
|
+
"250" => "Pick Up Card",
|
|
29
|
+
"251" => "Lost Card",
|
|
30
|
+
"252" => "Stolen Card",
|
|
31
|
+
"253" => "Fraudulent Card",
|
|
32
|
+
"260" => "Declined With further Instructions Available (see response text)",
|
|
33
|
+
"261" => "Declined - Stop All Recurring Payments",
|
|
34
|
+
"262" => "Declined - Stop this Recurring Program",
|
|
35
|
+
"263" => "Declined - Update Cardholder Data Available",
|
|
36
|
+
"264" => "Declined - Retry in a few days",
|
|
37
|
+
"300" => "Transaction was Rejected by Gateway",
|
|
38
|
+
"400" => "Transaction Error Returned by Processor",
|
|
39
|
+
"410" => "Invalid Merchant Configuration",
|
|
40
|
+
"411" => "Merchant Account is Inactive",
|
|
41
|
+
"420" => "Communication Error",
|
|
42
|
+
"421" => "Communication Error with Issuer",
|
|
43
|
+
"430" => "Duplicate Transaction at Processor",
|
|
44
|
+
"440" => "Processor Format Error",
|
|
45
|
+
"441" => "Invalid Transaction Information",
|
|
46
|
+
"460" => "Processor Feature Not Available",
|
|
47
|
+
"461" => "Unsupported Card Type"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
SUCCESS = 1
|
|
51
|
+
|
|
52
|
+
TRANSACTIONS = {
|
|
53
|
+
:authorization => 'auth',
|
|
54
|
+
:purchase => 'sale',
|
|
55
|
+
:capture => 'capture',
|
|
56
|
+
:void => 'void',
|
|
57
|
+
:credit => 'credit',
|
|
58
|
+
:refund => 'refund'
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
self.supported_countries = ['US']
|
|
62
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
|
63
|
+
self.homepage_url = 'http://www.verifi.com/'
|
|
64
|
+
self.display_name = 'Verifi'
|
|
65
|
+
|
|
66
|
+
attr_reader :url
|
|
67
|
+
attr_reader :response
|
|
68
|
+
attr_reader :options
|
|
69
|
+
|
|
70
|
+
def initialize(options = {})
|
|
71
|
+
requires!(options, :login, :password)
|
|
72
|
+
@options = options
|
|
73
|
+
super
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def purchase(money, creditcard, options = {})
|
|
77
|
+
sale_authorization_or_credit_template(:purchase, money, creditcard, options)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def authorize(money, creditcard, options = {})
|
|
81
|
+
sale_authorization_or_credit_template(:authorization, money, creditcard, options)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def capture(money, authorization, options = {})
|
|
85
|
+
capture_void_or_refund_template(:capture, money, authorization, options)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def void(authorization, options = {})
|
|
89
|
+
capture_void_or_refund_template(:void, 0, authorization, options)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def credit(money, creditcard_or_authorization, options = {})
|
|
93
|
+
if creditcard_or_authorization.is_a?(String)
|
|
94
|
+
capture_void_or_refund_template(:refund, money, creditcard_or_authorization, options)
|
|
95
|
+
else
|
|
96
|
+
sale_authorization_or_credit_template(:credit, money, creditcard_or_authorization, options)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def sale_authorization_or_credit_template(trx_type, money, creditcard, options = {})
|
|
103
|
+
post = VerifiPostData.new
|
|
104
|
+
add_security_key_data(post, options, money)
|
|
105
|
+
add_creditcard(post, creditcard)
|
|
106
|
+
add_addresses(post, options)
|
|
107
|
+
add_customer_data(post, options)
|
|
108
|
+
add_invoice_data(post, options)
|
|
109
|
+
add_optional_data(post, options)
|
|
110
|
+
commit(trx_type, money, post)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def capture_void_or_refund_template(trx_type, money, authorization, options)
|
|
114
|
+
post = VerifiPostData.new
|
|
115
|
+
post[:transactionid] = authorization
|
|
116
|
+
|
|
117
|
+
commit(trx_type, money, post)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def add_creditcard(post, creditcard)
|
|
121
|
+
post[:ccnumber] = creditcard.number
|
|
122
|
+
post[:ccexp] = expdate(creditcard)
|
|
123
|
+
post[:firstname] = creditcard.first_name
|
|
124
|
+
post[:lastname] = creditcard.last_name
|
|
125
|
+
post[:cvv] = creditcard.verification_value
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def expdate(creditcard)
|
|
129
|
+
year = sprintf("%.4i", creditcard.year)
|
|
130
|
+
month = sprintf("%.2i", creditcard.month)
|
|
131
|
+
|
|
132
|
+
"#{month}#{year[-2..-1]}"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def add_addresses(post, options)
|
|
136
|
+
if billing_address = options[:billing_address] || options[:address]
|
|
137
|
+
post[:company] = billing_address[:company]
|
|
138
|
+
post[:address1] = billing_address[:address1]
|
|
139
|
+
post[:address2] = billing_address[:address2]
|
|
140
|
+
post[:city] = billing_address[:city]
|
|
141
|
+
post[:state] = billing_address[:state]
|
|
142
|
+
post[:zip] = billing_address[:zip]
|
|
143
|
+
post[:country] = billing_address[:country]
|
|
144
|
+
post[:phone] = billing_address[:phone]
|
|
145
|
+
post[:fax] = billing_address[:fax]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
if shipping_address = options[:shipping_address] || billing_address
|
|
149
|
+
post[:shipping_firstname] = shipping_address[:first_name]
|
|
150
|
+
post[:shipping_lastname] = shipping_address[:last_name]
|
|
151
|
+
post[:shipping_company] = shipping_address[:company]
|
|
152
|
+
post[:shipping_address1] = shipping_address[:address1]
|
|
153
|
+
post[:shipping_address2] = shipping_address[:address2]
|
|
154
|
+
post[:shipping_city] = shipping_address[:city]
|
|
155
|
+
post[:shipping_state] = shipping_address[:state]
|
|
156
|
+
post[:shipping_zip] = shipping_address[:zip]
|
|
157
|
+
post[:shipping_country] = shipping_address[:country]
|
|
158
|
+
post[:shipping_email] = shipping_address[:email]
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def add_customer_data(post, options)
|
|
163
|
+
post[:email] = options[:email]
|
|
164
|
+
post[:ipaddress] = options[:ip]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def add_invoice_data(post, options)
|
|
168
|
+
post[:orderid] = options[:order_id]
|
|
169
|
+
post[:ponumber] = options[:invoice]
|
|
170
|
+
post[:orderdescription] = options[:description]
|
|
171
|
+
post[:tax] = options[:tax]
|
|
172
|
+
post[:shipping] = options[:shipping]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def add_optional_data(post, options)
|
|
176
|
+
post[:billing_method] = options[:billing_method]
|
|
177
|
+
post[:website] = options[:website]
|
|
178
|
+
post[:descriptor] = options[:descriptor]
|
|
179
|
+
post[:descriptor_phone] = options[:descriptor_phone]
|
|
180
|
+
post[:cardholder_auth] = options[:cardholder_auth]
|
|
181
|
+
post[:cavv] = options[:cavv]
|
|
182
|
+
post[:xid] = options[:xid]
|
|
183
|
+
post[:customer_receipt] = options[:customer_receipt]
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def add_security_key_data(post, options, money)
|
|
187
|
+
# MD5(username|password|orderid|amount|time)
|
|
188
|
+
now = Time.now.to_i.to_s
|
|
189
|
+
md5 = Digest::MD5.new
|
|
190
|
+
md5 << @options[:login].to_s + "|"
|
|
191
|
+
md5 << @options[:password].to_s + "|"
|
|
192
|
+
md5 << options[:order_id].to_s + "|"
|
|
193
|
+
md5 << amount(money).to_s + "|"
|
|
194
|
+
md5 << now
|
|
195
|
+
post[:key] = md5.hexdigest
|
|
196
|
+
post[:time] = now
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def commit(trx_type, money, post)
|
|
200
|
+
|
|
201
|
+
post[:amount] = amount(money)
|
|
202
|
+
|
|
203
|
+
if result = test_result_from_cc_number(post[:ccnumber])
|
|
204
|
+
return result
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
data = ssl_post(URL, post_data(trx_type, post), 'Content-type' => "application/x-www-form-urlencoded")
|
|
208
|
+
@response = parse(data)
|
|
209
|
+
|
|
210
|
+
success = @response[:response].to_i == SUCCESS
|
|
211
|
+
message = @response[:response_code_message] ? @response[:response_code_message] : ""
|
|
212
|
+
|
|
213
|
+
Response.new(success, message, @response,
|
|
214
|
+
:test => test?,
|
|
215
|
+
:authorization => @response[:transactionid]
|
|
216
|
+
)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def parse(body)
|
|
220
|
+
results = {}
|
|
221
|
+
CGI.parse(body).each { |key, value| results[key.intern] = value[0] }
|
|
222
|
+
results[:response_code_message] = RESPONSE_CODE_MESSAGES[results[:response_code]] if results[:response_code]
|
|
223
|
+
results
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def post_data(trx_type, post)
|
|
227
|
+
post[:username] = @options[:login]
|
|
228
|
+
post[:password] = @options[:password]
|
|
229
|
+
post[:type] = TRANSACTIONS[trx_type]
|
|
230
|
+
|
|
231
|
+
post.to_s
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
|
2
|
+
module Billing #:nodoc:
|
|
3
|
+
class ViaklixGateway < Gateway
|
|
4
|
+
TEST_URL = 'https://demo.viaklix.com/process.asp'
|
|
5
|
+
LIVE_URL = 'https://www.viaklix.com/process.asp'
|
|
6
|
+
|
|
7
|
+
APPROVED = '0'
|
|
8
|
+
|
|
9
|
+
self.supported_cardtypes = [:visa, :master, :american_express]
|
|
10
|
+
self.supported_countries = ['US']
|
|
11
|
+
self.display_name = 'ViaKLIX'
|
|
12
|
+
self.homepage_url = 'http://viaklix.com'
|
|
13
|
+
|
|
14
|
+
# Initialize the Gateway
|
|
15
|
+
#
|
|
16
|
+
# The gateway requires that a valid login and password be passed
|
|
17
|
+
# in the +options+ hash.
|
|
18
|
+
#
|
|
19
|
+
# ==== Options
|
|
20
|
+
#
|
|
21
|
+
# * <tt>:login</tt> -- Merchant ID
|
|
22
|
+
# * <tt>:password</tt> -- PIN
|
|
23
|
+
# * <tt>:user</tt> -- Specify a subuser of the account (optional)
|
|
24
|
+
# * <tt>:test => +true+ or +false+</tt> -- Force test transactions
|
|
25
|
+
def initialize(options = {})
|
|
26
|
+
requires!(options, :login, :password)
|
|
27
|
+
@options = options
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Make a purchase
|
|
32
|
+
def purchase(money, creditcard, options = {})
|
|
33
|
+
form = {}
|
|
34
|
+
add_invoice(form, options)
|
|
35
|
+
add_creditcard(form, creditcard)
|
|
36
|
+
add_address(form, options)
|
|
37
|
+
add_customer_data(form, options)
|
|
38
|
+
commit('SALE', money, form)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Make a credit to a card (Void can only be done from the virtual terminal)
|
|
42
|
+
# Viaklix does not support credits by reference. You must pass in the credit card
|
|
43
|
+
def credit(money, creditcard, options = {})
|
|
44
|
+
if creditcard.is_a?(String)
|
|
45
|
+
raise ArgumentError, "Reference credits are not supported. Please supply the original credit card"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
form = {}
|
|
49
|
+
add_invoice(form, options)
|
|
50
|
+
add_creditcard(form, creditcard)
|
|
51
|
+
add_address(form, options)
|
|
52
|
+
add_customer_data(form, options)
|
|
53
|
+
commit('CREDIT', money, form)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
def add_customer_data(form, options)
|
|
58
|
+
form[:email] = options[:email] unless options[:email].blank?
|
|
59
|
+
form[:customer_code] = options[:customer].to_s.slice(0, 17) unless options[:customer].blank?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def add_invoice(form,options)
|
|
63
|
+
form[:invoice_number] = options[:order_id] || options[:invoice]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def add_address(form,options)
|
|
67
|
+
billing_address = options[:billing_address] || options[:address]
|
|
68
|
+
|
|
69
|
+
if billing_address
|
|
70
|
+
form[:avs_address] = billing_address[:address1]
|
|
71
|
+
form[:avs_zip] = billing_address[:zip]
|
|
72
|
+
form[:city] = billing_address[:city]
|
|
73
|
+
form[:state] = billing_address[:state]
|
|
74
|
+
form[:company] = billing_address[:company]
|
|
75
|
+
form[:phone] = billing_address[:phone]
|
|
76
|
+
form[:country] = billing_address[:country]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
shipping_address = options[:shipping_address] || billing_address
|
|
80
|
+
|
|
81
|
+
if shipping_address
|
|
82
|
+
first_name, last_name = parse_first_and_last_name(shipping_address[:name])
|
|
83
|
+
form[:ship_to_first_name] = first_name
|
|
84
|
+
form[:ship_to_last_name] = last_name
|
|
85
|
+
form[:ship_to_address] = shipping_address[:address1]
|
|
86
|
+
form[:ship_to_city] = shipping_address[:city]
|
|
87
|
+
form[:ship_to_state] = shipping_address[:state]
|
|
88
|
+
form[:ship_to_company] = shipping_address[:company]
|
|
89
|
+
form[:ship_to_country] = shipping_address[:country]
|
|
90
|
+
form[:ship_to_zip] = shipping_address[:zip]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def parse_first_and_last_name(value)
|
|
95
|
+
name = value.to_s.split(' ')
|
|
96
|
+
|
|
97
|
+
last_name = name.pop || ''
|
|
98
|
+
first_name = name.join(' ')
|
|
99
|
+
[ first_name, last_name ]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def add_creditcard(form, creditcard)
|
|
103
|
+
form[:card_number] = creditcard.number
|
|
104
|
+
form[:exp_date] = expdate(creditcard)
|
|
105
|
+
|
|
106
|
+
if creditcard.verification_value?
|
|
107
|
+
form[:cvv2cvc2] = creditcard.verification_value
|
|
108
|
+
form[:cvv2] = 'present'
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
form[:first_name] = creditcard.first_name
|
|
112
|
+
form[:last_name] = creditcard.last_name
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def preamble
|
|
116
|
+
result = {
|
|
117
|
+
'merchant_id' => @options[:login],
|
|
118
|
+
'pin' => @options[:password],
|
|
119
|
+
'show_form' => 'false',
|
|
120
|
+
'test_mode' => @options[:test] ? 'TRUE' : 'FALSE',
|
|
121
|
+
'result_format' => 'ASCII',
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
result['user_id'] = @options[:user] unless @options[:user].blank?
|
|
125
|
+
result
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def commit(action, money, parameters)
|
|
129
|
+
if result = test_result_from_cc_number(parameters[:card_number])
|
|
130
|
+
return result
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
parameters[:amount] = amount(money)
|
|
134
|
+
parameters[:transaction_type] = action
|
|
135
|
+
|
|
136
|
+
msg = ssl_post(test? ? TEST_URL : LIVE_URL, post_data(parameters))
|
|
137
|
+
|
|
138
|
+
@response = parse(msg)
|
|
139
|
+
success = @response['result'] == APPROVED
|
|
140
|
+
message = @response['result_message']
|
|
141
|
+
|
|
142
|
+
Response.new(success, message, @response,
|
|
143
|
+
:test => @options[:test] || test?,
|
|
144
|
+
:authorization => @response['txn_id']
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def post_data(parameters)
|
|
149
|
+
result = preamble
|
|
150
|
+
result.merge!(parameters)
|
|
151
|
+
result.collect { |key, value| "ssl_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def expdate(creditcard)
|
|
155
|
+
year = sprintf("%.4i", creditcard.year)
|
|
156
|
+
month = sprintf("%.2i", creditcard.month)
|
|
157
|
+
"#{month}#{year[2..3]}"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Parse the response message
|
|
161
|
+
def parse(msg)
|
|
162
|
+
resp = Hash.new;
|
|
163
|
+
msg.split("\r\n").collect{|li|
|
|
164
|
+
key, value = li.split("=")
|
|
165
|
+
resp[key.gsub(/^ssl_/, '')] = value.to_s.strip
|
|
166
|
+
}
|
|
167
|
+
resp
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|