aktivemerchant 2.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG +1596 -0
- data/CONTRIBUTORS +511 -0
- data/MIT-LICENSE +20 -0
- data/README.md +18 -0
- data/lib/active_merchant.rb +108 -0
- data/lib/active_merchant/billing.rb +13 -0
- data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +72 -0
- data/lib/active_merchant/billing/check.rb +76 -0
- data/lib/active_merchant/billing/compatibility.rb +120 -0
- data/lib/active_merchant/billing/credit_card.rb +352 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/gateway.rb +268 -0
- data/lib/active_merchant/billing/gateways.rb +17 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
- data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
- data/lib/active_merchant/billing/gateways/app55.rb +176 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
- data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
- data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
- data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
- data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
- data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
- data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
- data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
- data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
- data/lib/active_merchant/billing/gateways/epay.rb +275 -0
- data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
- data/lib/active_merchant/billing/gateways/eway.rb +214 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
- data/lib/active_merchant/billing/gateways/exact.rb +218 -0
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
- data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
- data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
- data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
- data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
- data/lib/active_merchant/billing/gateways/hps.rb +288 -0
- data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
- data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
- data/lib/active_merchant/billing/gateways/litle.rb +346 -0
- data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
- data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
- data/lib/active_merchant/billing/gateways/migs.rb +265 -0
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
- data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
- data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
- data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
- data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
- data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
- data/lib/active_merchant/billing/gateways/payex.rb +412 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
- data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
- data/lib/active_merchant/billing/gateways/payway.rb +207 -0
- data/lib/active_merchant/billing/gateways/pin.rb +197 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
- data/lib/active_merchant/billing/gateways/realex.rb +298 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
- data/lib/active_merchant/billing/gateways/sage.rb +175 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
- data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
- data/lib/active_merchant/billing/gateways/tns.rb +227 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
- data/lib/active_merchant/billing/gateways/transax.rb +23 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
- data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
- data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
- data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
- data/lib/active_merchant/billing/model.rb +30 -0
- data/lib/active_merchant/billing/payment_token.rb +21 -0
- data/lib/active_merchant/billing/rails.rb +3 -0
- data/lib/active_merchant/billing/response.rb +91 -0
- data/lib/active_merchant/country.rb +332 -0
- data/lib/active_merchant/empty.rb +20 -0
- data/lib/active_merchant/errors.rb +29 -0
- data/lib/active_merchant/offsite_payments_shim.rb +19 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/support/gateway_support.rb +71 -0
- data/lib/support/outbound_hosts.rb +25 -0
- data/lib/support/ssl_verify.rb +93 -0
- metadata +400 -0
@@ -0,0 +1,219 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
|
6
|
+
class EfsnetGateway < Gateway
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
9
|
+
self.homepage_url = 'http://www.concordefsnet.com/'
|
10
|
+
self.display_name = 'Efsnet'
|
11
|
+
|
12
|
+
self.test_url = 'https://testefsnet.concordebiz.com/efsnet.dll'
|
13
|
+
self.live_url = 'https://efsnet.concordebiz.com/efsnet.dll'
|
14
|
+
|
15
|
+
# login is your Store ID
|
16
|
+
# password is your Store Key
|
17
|
+
def initialize(options = {})
|
18
|
+
requires!(options, :login, :password)
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def authorize(money, creditcard, options = {})
|
23
|
+
request = build_credit_card_request(money, creditcard, options)
|
24
|
+
commit(:credit_card_authorize, request)
|
25
|
+
end
|
26
|
+
|
27
|
+
def purchase(money, creditcard, options = {})
|
28
|
+
request = build_credit_card_request(money, creditcard, options)
|
29
|
+
commit(:credit_card_charge, request)
|
30
|
+
end
|
31
|
+
|
32
|
+
def capture(money, identification, options = {})
|
33
|
+
request = build_refund_or_settle_request(money, identification, options)
|
34
|
+
commit(:credit_card_settle, request)
|
35
|
+
end
|
36
|
+
|
37
|
+
def credit(money, identification_or_credit_card, options = {})
|
38
|
+
if identification_or_credit_card.is_a?(String)
|
39
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
40
|
+
# Perform authorization reversal
|
41
|
+
refund(money, identification_or_credit_card, options)
|
42
|
+
else
|
43
|
+
# Perform credit
|
44
|
+
request = build_credit_card_request(money, identification_or_credit_card, options)
|
45
|
+
commit(:credit_card_credit, request)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def refund(money, reference, options = {})
|
50
|
+
# Perform authorization reversal
|
51
|
+
request = build_refund_or_settle_request(money, reference, options)
|
52
|
+
commit(:credit_card_refund, request)
|
53
|
+
end
|
54
|
+
|
55
|
+
def void(identification, options = {})
|
56
|
+
requires!(options, :order_id)
|
57
|
+
original_transaction_id, _ = identification.split(";")
|
58
|
+
commit(:void_transaction, {:reference_number => format_reference_number(options[:order_id]), :transaction_id => original_transaction_id})
|
59
|
+
end
|
60
|
+
|
61
|
+
def voice_authorize(money, authorization_code, creditcard, options = {})
|
62
|
+
options[:authorization_number] = authorization_code
|
63
|
+
request = build_credit_card_request(money, creditcard, options)
|
64
|
+
commit(:credit_card_voice_authorize, request)
|
65
|
+
end
|
66
|
+
|
67
|
+
def force(money, authorization_code, creditcard, options = {})
|
68
|
+
options[:authorization_number] = authorization_code
|
69
|
+
request = build_credit_card_request(money, creditcard, options)
|
70
|
+
commit(:credit_card_capture, request)
|
71
|
+
end
|
72
|
+
|
73
|
+
def system_check
|
74
|
+
commit(:system_check, {})
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def build_refund_or_settle_request(money, identification, options = {})
|
80
|
+
original_transaction_id, original_transaction_amount = identification.split(";")
|
81
|
+
|
82
|
+
requires!(options, :order_id)
|
83
|
+
|
84
|
+
{
|
85
|
+
:reference_number => format_reference_number(options[:order_id]),
|
86
|
+
:transaction_amount => amount(money),
|
87
|
+
:original_transaction_amount => original_transaction_amount,
|
88
|
+
:original_transaction_id => original_transaction_id,
|
89
|
+
:client_ip_address => options[:ip]
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_credit_card_request(money, creditcard, options = {})
|
94
|
+
requires!(options, :order_id)
|
95
|
+
|
96
|
+
post = {
|
97
|
+
:reference_number => format_reference_number(options[:order_id]),
|
98
|
+
:authorization_number => options[:authorization_number],
|
99
|
+
:transaction_amount => amount(money),
|
100
|
+
:client_ip_address => options[:ip]
|
101
|
+
|
102
|
+
}
|
103
|
+
add_creditcard(post,creditcard)
|
104
|
+
add_address(post,options)
|
105
|
+
post
|
106
|
+
end
|
107
|
+
|
108
|
+
def format_reference_number(number)
|
109
|
+
number.to_s.slice(0,12)
|
110
|
+
end
|
111
|
+
|
112
|
+
def add_address(post,options)
|
113
|
+
if address = options[:billing_address] || options[:address]
|
114
|
+
if address[:address2]
|
115
|
+
post[:billing_address] = address[:address1].to_s << ' ' << address[:address2].to_s
|
116
|
+
else
|
117
|
+
post[:billing_address] = address[:address1].to_s
|
118
|
+
end
|
119
|
+
post[:billing_city] = address[:city].to_s
|
120
|
+
post[:billing_state] = address[:state].blank? ? 'n/a' : address[:state]
|
121
|
+
post[:billing_postal_code] = address[:zip].to_s
|
122
|
+
post[:billing_country] = address[:country].to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
if address = options[:shipping_address]
|
126
|
+
if address[:address2]
|
127
|
+
post[:shipping_address] = address[:address1].to_s << ' ' << address[:address2].to_s
|
128
|
+
else
|
129
|
+
post[:shipping_address] = address[:address1].to_s
|
130
|
+
end
|
131
|
+
post[:shipping_city] = address[:city].to_s
|
132
|
+
post[:shipping_state] = address[:state].blank? ? 'n/a' : address[:state]
|
133
|
+
post[:shipping_postal_code] = address[:zip].to_s
|
134
|
+
post[:shipping_country] = address[:country].to_s
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_creditcard(post, creditcard)
|
139
|
+
post[:billing_name] = creditcard.name if creditcard.name
|
140
|
+
post[:account_number] = creditcard.number
|
141
|
+
post[:card_verification_value] = creditcard.verification_value if creditcard.verification_value?
|
142
|
+
post[:expiration_month] = sprintf("%.2i", creditcard.month)
|
143
|
+
post[:expiration_year] = sprintf("%.4i", creditcard.year)[-2..-1]
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def commit(action, parameters)
|
148
|
+
response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(action, parameters), 'Content-Type' => 'text/xml'))
|
149
|
+
|
150
|
+
Response.new(success?(response), message_from(response[:result_message]), response,
|
151
|
+
:test => test?,
|
152
|
+
:authorization => authorization_from(response, parameters),
|
153
|
+
:avs_result => { :code => response[:avs_response_code] },
|
154
|
+
:cvv_result => response[:cvv_response_code]
|
155
|
+
)
|
156
|
+
end
|
157
|
+
|
158
|
+
def success?(response)
|
159
|
+
response[:response_code] == '0'
|
160
|
+
end
|
161
|
+
|
162
|
+
def authorization_from(response, params)
|
163
|
+
[ response[:transaction_id], params[:transaction_amount] ].compact.join(';')
|
164
|
+
end
|
165
|
+
|
166
|
+
def parse(xml)
|
167
|
+
response = {}
|
168
|
+
|
169
|
+
xml = REXML::Document.new(xml)
|
170
|
+
|
171
|
+
xml.elements.each('//Reply//TransactionReply/*') do |node|
|
172
|
+
|
173
|
+
response[node.name.underscore.to_sym] = normalize(node.text)
|
174
|
+
|
175
|
+
end unless xml.root.nil?
|
176
|
+
|
177
|
+
response
|
178
|
+
end
|
179
|
+
|
180
|
+
def post_data(action, parameters = {})
|
181
|
+
xml = REXML::Document.new("<?xml version='1.0' encoding='UTF-8'?>")
|
182
|
+
root = xml.add_element("Request")
|
183
|
+
root.attributes["StoreID"] = options[:login]
|
184
|
+
root.attributes["StoreKey"] = options[:password]
|
185
|
+
root.attributes["ApplicationID"] = 'ot 1.0'
|
186
|
+
transaction = root.add_element(action.to_s.camelize)
|
187
|
+
|
188
|
+
actions[action].each do |key|
|
189
|
+
transaction.add_element(key).text = parameters[key.underscore.to_sym] unless parameters[key.underscore.to_sym].blank?
|
190
|
+
end
|
191
|
+
|
192
|
+
xml.to_s
|
193
|
+
end
|
194
|
+
|
195
|
+
def message_from(message)
|
196
|
+
return 'Unspecified error' if message.blank?
|
197
|
+
message.gsub(/[^\w]/, ' ').split.join(" ").capitalize
|
198
|
+
end
|
199
|
+
|
200
|
+
def actions
|
201
|
+
ACTIONS
|
202
|
+
end
|
203
|
+
|
204
|
+
CREDIT_CARD_FIELDS = %w(AuthorizationNumber ClientIpAddress BillingAddress BillingCity BillingState BillingPostalCode BillingCountry BillingName CardVerificationValue ExpirationMonth ExpirationYear ReferenceNumber TransactionAmount AccountNumber )
|
205
|
+
|
206
|
+
ACTIONS = {
|
207
|
+
:credit_card_authorize => CREDIT_CARD_FIELDS,
|
208
|
+
:credit_card_charge => CREDIT_CARD_FIELDS,
|
209
|
+
:credit_card_voice_authorize => CREDIT_CARD_FIELDS,
|
210
|
+
:credit_card_capture => CREDIT_CARD_FIELDS,
|
211
|
+
:credit_card_credit => CREDIT_CARD_FIELDS + ["OriginalTransactionAmount"],
|
212
|
+
:credit_card_refund => %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress),
|
213
|
+
:void_transaction => %w(ReferenceNumber TransactionID),
|
214
|
+
:credit_card_settle => %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress),
|
215
|
+
:system_check => %w(SystemCheck),
|
216
|
+
}
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,348 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/viaklix'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# = Elavon Virtual Merchant Gateway
|
6
|
+
#
|
7
|
+
# == Example use:
|
8
|
+
#
|
9
|
+
# gateway = ActiveMerchant::Billing::ElavonGateway.new(
|
10
|
+
# :login => "my_virtual_merchant_id",
|
11
|
+
# :password => "my_virtual_merchant_pin",
|
12
|
+
# :user => "my_virtual_merchant_user_id" # optional
|
13
|
+
# )
|
14
|
+
#
|
15
|
+
# # set up credit card obj as in main ActiveMerchant example
|
16
|
+
# creditcard = ActiveMerchant::Billing::CreditCard.new(
|
17
|
+
# :type => 'visa',
|
18
|
+
# :number => '41111111111111111',
|
19
|
+
# :month => 10,
|
20
|
+
# :year => 2011,
|
21
|
+
# :first_name => 'Bob',
|
22
|
+
# :last_name => 'Bobsen'
|
23
|
+
# )
|
24
|
+
#
|
25
|
+
# # run request
|
26
|
+
# response = gateway.purchase(1000, creditcard) # authorize and capture 10 USD
|
27
|
+
#
|
28
|
+
# puts response.success? # Check whether the transaction was successful
|
29
|
+
# puts response.message # Retrieve the message returned by Elavon
|
30
|
+
# puts response.authorization # Retrieve the unique transaction ID returned by Elavon
|
31
|
+
#
|
32
|
+
class ElavonGateway < Gateway
|
33
|
+
class_attribute :test_url, :live_url, :delimiter, :actions
|
34
|
+
|
35
|
+
self.test_url = 'https://demo.myvirtualmerchant.com/VirtualMerchantDemo/process.do'
|
36
|
+
self.live_url = 'https://www.myvirtualmerchant.com/VirtualMerchant/process.do'
|
37
|
+
|
38
|
+
self.display_name = 'Elavon MyVirtualMerchant'
|
39
|
+
self.supported_countries = %w(US CA PR DE IE NO PL LU BE NL)
|
40
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
41
|
+
self.homepage_url = 'http://www.elavon.com/'
|
42
|
+
|
43
|
+
self.delimiter = "\n"
|
44
|
+
self.actions = {
|
45
|
+
:purchase => 'CCSALE',
|
46
|
+
:credit => 'CCCREDIT',
|
47
|
+
:refund => 'CCRETURN',
|
48
|
+
:authorize => 'CCAUTHONLY',
|
49
|
+
:capture => 'CCFORCE',
|
50
|
+
:void => 'CCDELETE',
|
51
|
+
:store => 'CCGETTOKEN',
|
52
|
+
:update => 'CCUPDATETOKEN',
|
53
|
+
}
|
54
|
+
|
55
|
+
# Initialize the Gateway
|
56
|
+
#
|
57
|
+
# The gateway requires that a valid login and password be passed
|
58
|
+
# in the +options+ hash.
|
59
|
+
#
|
60
|
+
# ==== Options
|
61
|
+
#
|
62
|
+
# * <tt>:login</tt> -- Merchant ID
|
63
|
+
# * <tt>:password</tt> -- PIN
|
64
|
+
# * <tt>:user</tt> -- Specify a subuser of the account (optional)
|
65
|
+
# * <tt>:test => +true+ or +false+</tt> -- Force test transactions
|
66
|
+
def initialize(options = {})
|
67
|
+
requires!(options, :login, :password)
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
# Make a purchase
|
72
|
+
def purchase(money, payment_method, options = {})
|
73
|
+
form = {}
|
74
|
+
add_salestax(form, options)
|
75
|
+
add_invoice(form, options)
|
76
|
+
if payment_method.is_a?(String)
|
77
|
+
add_token(form, payment_method)
|
78
|
+
else
|
79
|
+
add_creditcard(form, payment_method)
|
80
|
+
end
|
81
|
+
add_address(form, options)
|
82
|
+
add_customer_data(form, options)
|
83
|
+
add_test_mode(form, options)
|
84
|
+
commit(:purchase, money, form)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Authorize a credit card for a given amount.
|
88
|
+
#
|
89
|
+
# ==== Parameters
|
90
|
+
# * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
|
91
|
+
# * <tt>credit_card</tt> - The CreditCard details for the transaction.
|
92
|
+
# * <tt>options</tt>
|
93
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
94
|
+
def authorize(money, creditcard, options = {})
|
95
|
+
form = {}
|
96
|
+
add_salestax(form, options)
|
97
|
+
add_invoice(form, options)
|
98
|
+
add_creditcard(form, creditcard)
|
99
|
+
add_address(form, options)
|
100
|
+
add_customer_data(form, options)
|
101
|
+
add_test_mode(form, options)
|
102
|
+
commit(:authorize, money, form)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Capture authorized funds from a credit card.
|
106
|
+
#
|
107
|
+
# ==== Parameters
|
108
|
+
# * <tt>money</tt> - The amount to be captured as an Integer value in cents.
|
109
|
+
# * <tt>authorization</tt> - The approval code returned from the initial authorization.
|
110
|
+
# * <tt>options</tt>
|
111
|
+
# * <tt>:credit_card</tt> - The CreditCard details from the initial transaction (required).
|
112
|
+
def capture(money, authorization, options = {})
|
113
|
+
requires!(options, :credit_card)
|
114
|
+
|
115
|
+
form = {}
|
116
|
+
add_salestax(form, options)
|
117
|
+
add_approval_code(form, authorization)
|
118
|
+
add_invoice(form, options)
|
119
|
+
add_creditcard(form, options[:credit_card])
|
120
|
+
add_customer_data(form, options)
|
121
|
+
add_test_mode(form, options)
|
122
|
+
commit(:capture, money, form)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Refund a transaction.
|
126
|
+
#
|
127
|
+
# This transaction indicates to the gateway that
|
128
|
+
# money should flow from the merchant to the customer.
|
129
|
+
#
|
130
|
+
# ==== Parameters
|
131
|
+
#
|
132
|
+
# * <tt>money</tt> -- The amount to be credited to the customer as an Integer value in cents.
|
133
|
+
# * <tt>identification</tt> -- The ID of the original transaction against which the refund is being issued.
|
134
|
+
# * <tt>options</tt> -- A hash of parameters.
|
135
|
+
def refund(money, identification, options = {})
|
136
|
+
form = {}
|
137
|
+
add_txn_id(form, identification)
|
138
|
+
add_test_mode(form, options)
|
139
|
+
commit(:refund, money, form)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Void a previous transaction
|
143
|
+
#
|
144
|
+
# ==== Parameters
|
145
|
+
#
|
146
|
+
# * <tt>authorization</tt> - The authorization returned from the previous request.
|
147
|
+
def void(identification, options = {})
|
148
|
+
form = {}
|
149
|
+
add_txn_id(form, identification)
|
150
|
+
add_test_mode(form, options)
|
151
|
+
commit(:void, nil, form)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Make a credit to a card. Use the refund method if you'd like to credit using
|
155
|
+
# previous transaction
|
156
|
+
#
|
157
|
+
# ==== Parameters
|
158
|
+
# * <tt>money</tt> - The amount to be credited as an Integer value in cents.
|
159
|
+
# * <tt>creditcard</tt> - The credit card to be credited.
|
160
|
+
# * <tt>options</tt>
|
161
|
+
def credit(money, creditcard, options = {})
|
162
|
+
if creditcard.is_a?(String)
|
163
|
+
raise ArgumentError, "Reference credits are not supported. Please supply the original credit card or use the #refund method."
|
164
|
+
end
|
165
|
+
|
166
|
+
form = {}
|
167
|
+
add_invoice(form, options)
|
168
|
+
add_creditcard(form, creditcard)
|
169
|
+
add_address(form, options)
|
170
|
+
add_customer_data(form, options)
|
171
|
+
add_test_mode(form, options)
|
172
|
+
commit(:credit, money, form)
|
173
|
+
end
|
174
|
+
|
175
|
+
def verify(credit_card, options = {})
|
176
|
+
MultiResponse.run(:use_first_response) do |r|
|
177
|
+
r.process { authorize(100, credit_card, options) }
|
178
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def store(creditcard, options = {})
|
183
|
+
form = {}
|
184
|
+
add_creditcard(form, creditcard)
|
185
|
+
add_address(form, options)
|
186
|
+
add_customer_data(form, options)
|
187
|
+
add_test_mode(form, options)
|
188
|
+
add_verification(form, options)
|
189
|
+
form[:add_token] = 'Y'
|
190
|
+
commit(:store, nil, form)
|
191
|
+
end
|
192
|
+
|
193
|
+
def update(token, creditcard, options = {})
|
194
|
+
form = {}
|
195
|
+
add_token(form, token)
|
196
|
+
add_creditcard(form, creditcard)
|
197
|
+
add_address(form, options)
|
198
|
+
add_customer_data(form, options)
|
199
|
+
add_test_mode(form, options)
|
200
|
+
commit(:update, nil, form)
|
201
|
+
end
|
202
|
+
|
203
|
+
private
|
204
|
+
|
205
|
+
def add_invoice(form,options)
|
206
|
+
form[:invoice_number] = (options[:order_id] || options[:invoice]).to_s.slice(0, 10)
|
207
|
+
form[:description] = options[:description].to_s.slice(0, 255)
|
208
|
+
end
|
209
|
+
|
210
|
+
def add_approval_code(form, authorization)
|
211
|
+
form[:approval_code] = authorization.split(';').first
|
212
|
+
end
|
213
|
+
|
214
|
+
def add_txn_id(form, authorization)
|
215
|
+
form[:txn_id] = authorization.split(';').last
|
216
|
+
end
|
217
|
+
|
218
|
+
def authorization_from(response)
|
219
|
+
[response['approval_code'], response['txn_id']].join(';')
|
220
|
+
end
|
221
|
+
|
222
|
+
def add_creditcard(form, creditcard)
|
223
|
+
form[:card_number] = creditcard.number
|
224
|
+
form[:exp_date] = expdate(creditcard)
|
225
|
+
|
226
|
+
if creditcard.verification_value?
|
227
|
+
add_verification_value(form, creditcard)
|
228
|
+
end
|
229
|
+
|
230
|
+
form[:first_name] = creditcard.first_name.to_s.slice(0, 20)
|
231
|
+
form[:last_name] = creditcard.last_name.to_s.slice(0, 30)
|
232
|
+
end
|
233
|
+
|
234
|
+
def add_token(form, token)
|
235
|
+
form[:token] = token
|
236
|
+
end
|
237
|
+
|
238
|
+
def add_verification_value(form, creditcard)
|
239
|
+
form[:cvv2cvc2] = creditcard.verification_value
|
240
|
+
form[:cvv2cvc2_indicator] = '1'
|
241
|
+
end
|
242
|
+
|
243
|
+
def add_customer_data(form, options)
|
244
|
+
form[:email] = options[:email].to_s.slice(0, 100) unless options[:email].blank?
|
245
|
+
form[:customer_code] = options[:customer].to_s.slice(0, 10) unless options[:customer].blank?
|
246
|
+
end
|
247
|
+
|
248
|
+
def add_salestax(form, options)
|
249
|
+
form[:salestax] = options[:tax] if options[:tax].present?
|
250
|
+
end
|
251
|
+
|
252
|
+
def add_address(form, options)
|
253
|
+
billing_address = options[:billing_address] || options[:address]
|
254
|
+
|
255
|
+
if billing_address
|
256
|
+
form[:avs_address] = billing_address[:address1].to_s.slice(0, 30)
|
257
|
+
form[:address2] = billing_address[:address2].to_s.slice(0, 30)
|
258
|
+
form[:avs_zip] = billing_address[:zip].to_s.gsub(/[^a-zA-Z0-9]/, '').slice(0, 9)
|
259
|
+
form[:city] = billing_address[:city].to_s.slice(0, 30)
|
260
|
+
form[:state] = billing_address[:state].to_s.slice(0, 10)
|
261
|
+
form[:company] = billing_address[:company].to_s.slice(0, 50)
|
262
|
+
form[:phone] = billing_address[:phone].to_s.slice(0, 20)
|
263
|
+
form[:country] = billing_address[:country].to_s.slice(0, 50)
|
264
|
+
end
|
265
|
+
|
266
|
+
if shipping_address = options[:shipping_address]
|
267
|
+
first_name, last_name = parse_first_and_last_name(shipping_address[:name])
|
268
|
+
form[:ship_to_first_name] = first_name.to_s.slice(0, 20)
|
269
|
+
form[:ship_to_last_name] = last_name.to_s.slice(0, 30)
|
270
|
+
form[:ship_to_address1] = shipping_address[:address1].to_s.slice(0, 30)
|
271
|
+
form[:ship_to_address2] = shipping_address[:address2].to_s.slice(0, 30)
|
272
|
+
form[:ship_to_city] = shipping_address[:city].to_s.slice(0, 30)
|
273
|
+
form[:ship_to_state] = shipping_address[:state].to_s.slice(0, 10)
|
274
|
+
form[:ship_to_company] = shipping_address[:company].to_s.slice(0, 50)
|
275
|
+
form[:ship_to_country] = shipping_address[:country].to_s.slice(0, 50)
|
276
|
+
form[:ship_to_zip] = shipping_address[:zip].to_s.slice(0, 10)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def add_verification(form, options)
|
281
|
+
form[:verify] = 'Y' if options[:verify]
|
282
|
+
end
|
283
|
+
|
284
|
+
def parse_first_and_last_name(value)
|
285
|
+
name = value.to_s.split(' ')
|
286
|
+
|
287
|
+
last_name = name.pop || ''
|
288
|
+
first_name = name.join(' ')
|
289
|
+
[ first_name, last_name ]
|
290
|
+
end
|
291
|
+
|
292
|
+
def add_test_mode(form, options)
|
293
|
+
form[:test_mode] = 'TRUE' if options[:test_mode]
|
294
|
+
end
|
295
|
+
|
296
|
+
def message_from(response)
|
297
|
+
success?(response) ? response['result_message'] : response['errorMessage']
|
298
|
+
end
|
299
|
+
|
300
|
+
def success?(response)
|
301
|
+
!response.has_key?('errorMessage')
|
302
|
+
end
|
303
|
+
|
304
|
+
def commit(action, money, parameters)
|
305
|
+
parameters[:amount] = amount(money)
|
306
|
+
parameters[:transaction_type] = self.actions[action]
|
307
|
+
|
308
|
+
response = parse( ssl_post(test? ? self.test_url : self.live_url, post_data(parameters)) )
|
309
|
+
|
310
|
+
Response.new(response['result'] == '0', message_from(response), response,
|
311
|
+
:test => @options[:test] || test?,
|
312
|
+
:authorization => authorization_from(response),
|
313
|
+
:avs_result => { :code => response['avs_response'] },
|
314
|
+
:cvv_result => response['cvv2_response']
|
315
|
+
)
|
316
|
+
end
|
317
|
+
|
318
|
+
def post_data(parameters)
|
319
|
+
result = preamble
|
320
|
+
result.merge!(parameters)
|
321
|
+
result.collect { |key, value| "ssl_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
322
|
+
end
|
323
|
+
|
324
|
+
def preamble
|
325
|
+
result = {
|
326
|
+
'merchant_id' => @options[:login],
|
327
|
+
'pin' => @options[:password],
|
328
|
+
'show_form' => 'false',
|
329
|
+
'result_format' => 'ASCII'
|
330
|
+
}
|
331
|
+
|
332
|
+
result['user_id'] = @options[:user] unless @options[:user].blank?
|
333
|
+
result
|
334
|
+
end
|
335
|
+
|
336
|
+
def parse(msg)
|
337
|
+
resp = {}
|
338
|
+
msg.split(self.delimiter).collect{|li|
|
339
|
+
key, value = li.split("=")
|
340
|
+
resp[key.to_s.strip.gsub(/^ssl_/, '')] = value.to_s.strip
|
341
|
+
}
|
342
|
+
resp
|
343
|
+
end
|
344
|
+
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|