n8_activemerchant 1.9.3
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/CHANGELOG +574 -0
- data/CONTRIBUTORS +175 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +151 -0
- data/gem-public_cert.pem +20 -0
- data/lib/active_merchant.rb +49 -0
- data/lib/active_merchant/billing.rb +9 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +57 -0
- data/lib/active_merchant/billing/check.rb +68 -0
- data/lib/active_merchant/billing/credit_card.rb +161 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/expiry_date.rb +34 -0
- data/lib/active_merchant/billing/gateway.rb +169 -0
- data/lib/active_merchant/billing/gateways.rb +18 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +654 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +736 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +244 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +102 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +210 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +406 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +593 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
- data/lib/active_merchant/billing/gateways/epay.rb +263 -0
- data/lib/active_merchant/billing/gateways/eway.rb +277 -0
- data/lib/active_merchant/billing/gateways/exact.rb +222 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +222 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +253 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +234 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +279 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +203 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -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 +138 -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 +230 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +145 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
- data/lib/active_merchant/billing/gateways/paysimple/paysimple.rb +333 -0
- data/lib/active_merchant/billing/gateways/paysimple/usaepay.wsdl +1596 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
- data/lib/active_merchant/billing/gateways/realex.rb +200 -0
- data/lib/active_merchant/billing/gateways/sage.rb +146 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +315 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +265 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
- data/lib/active_merchant/billing/gateways/transax.rb +25 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
- data/lib/active_merchant/billing/gateways/usa_epay_soap.rb +154 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
- data/lib/active_merchant/billing/integrations.rb +17 -0
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
- data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
- data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
- data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
- data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
- data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
- data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +188 -0
- data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
- data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
- data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
- data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
- data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
- data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/helper.rb +96 -0
- data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
- data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
- data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
- data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
- data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
- data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/notification.rb +62 -0
- data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
- data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/quickpay.rb +17 -0
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
- data/lib/active_merchant/billing/integrations/return.rb +37 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +109 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +204 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +27 -0
- data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
- data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
- data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
- data/lib/active_merchant/billing/response.rb +32 -0
- data/lib/active_merchant/common.rb +14 -0
- data/lib/active_merchant/common/connection.rb +162 -0
- data/lib/active_merchant/common/country.rb +328 -0
- data/lib/active_merchant/common/error.rb +26 -0
- data/lib/active_merchant/common/post_data.rb +24 -0
- data/lib/active_merchant/common/posts_data.rb +61 -0
- data/lib/active_merchant/common/requires_parameters.rb +16 -0
- data/lib/active_merchant/common/utils.rb +18 -0
- data/lib/active_merchant/common/validateable.rb +76 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/certs/cacert.pem +7815 -0
- data/lib/support/gateway_support.rb +58 -0
- data/lib/support/outbound_hosts.rb +25 -0
- metadata +270 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
|
2
|
+
module Billing #:nodoc:
|
|
3
|
+
class FirstPayGateway < Gateway
|
|
4
|
+
class FirstPayPostData < PostData
|
|
5
|
+
# Fields that will be sent even if they are blank
|
|
6
|
+
self.required_fields = [ :action, :amount, :trackid ]
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# both URLs are IP restricted
|
|
10
|
+
TEST_URL = 'https://apgcert.first-pay.com/AcqENGIN/SecureCapture'
|
|
11
|
+
LIVE_URL = 'https://acqengin.first-pay.com/AcqENGIN/SecureCapture'
|
|
12
|
+
|
|
13
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
|
14
|
+
self.supported_countries = ['US']
|
|
15
|
+
|
|
16
|
+
# The card types supported by the payment gateway
|
|
17
|
+
self.supported_cardtypes = [:visa, :master]
|
|
18
|
+
|
|
19
|
+
# The homepage URL of the gateway
|
|
20
|
+
self.homepage_url = 'http://www.first-pay.com'
|
|
21
|
+
|
|
22
|
+
# The name of the gateway
|
|
23
|
+
self.display_name = 'First Pay'
|
|
24
|
+
|
|
25
|
+
# all transactions are in cents
|
|
26
|
+
self.money_format = :cents
|
|
27
|
+
|
|
28
|
+
ACTIONS = {
|
|
29
|
+
'sale' => 1,
|
|
30
|
+
'credit' => 2,
|
|
31
|
+
'void' => 3
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def initialize(options = {})
|
|
35
|
+
requires!(options, :login, :password)
|
|
36
|
+
@options = options
|
|
37
|
+
super
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def purchase(money, creditcard, options = {})
|
|
41
|
+
post = FirstPayPostData.new
|
|
42
|
+
add_invoice(post, options)
|
|
43
|
+
add_creditcard(post, creditcard)
|
|
44
|
+
add_address(post, options)
|
|
45
|
+
add_customer_data(post, options)
|
|
46
|
+
|
|
47
|
+
commit('sale', money, post)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def credit(money, reference, options = {})
|
|
51
|
+
raise ArgumentError, "Both TransactionID and CreditCard are required" unless reference.is_a?(String) && options[:credit_card]
|
|
52
|
+
|
|
53
|
+
post = FirstPayPostData.new
|
|
54
|
+
add_invoice(post, options)
|
|
55
|
+
add_creditcard(post, options[:credit_card])
|
|
56
|
+
add_address(post, options)
|
|
57
|
+
add_customer_data(post, options)
|
|
58
|
+
add_credit_data(post, reference)
|
|
59
|
+
|
|
60
|
+
commit('credit', money, post)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def void(money, creditcard, options = {})
|
|
64
|
+
post = FirstPayPostData.new
|
|
65
|
+
add_creditcard(post, creditcard)
|
|
66
|
+
add_void_data(post, options)
|
|
67
|
+
add_invoice(post, options)
|
|
68
|
+
add_customer_data(post, options)
|
|
69
|
+
|
|
70
|
+
commit('void', money, post)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def add_customer_data(post, options)
|
|
77
|
+
post[:cardip] = options[:ip]
|
|
78
|
+
post[:email] = options[:email]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def add_address(post, options)
|
|
82
|
+
if billing_address = options[:billing_address] || options[:address]
|
|
83
|
+
post[:addr] = billing_address[:address1].to_s + ' ' + billing_address[:address2].to_s
|
|
84
|
+
post[:city] = billing_address[:city]
|
|
85
|
+
post[:state] = billing_address[:state]
|
|
86
|
+
post[:zip] = billing_address[:zip]
|
|
87
|
+
post[:country] = billing_address[:country]
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def add_invoice(post, options)
|
|
92
|
+
post[:trackid] = rand(Time.now.to_i)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def add_creditcard(post, creditcard)
|
|
96
|
+
post[:member] = creditcard.first_name.to_s + " " + creditcard.last_name.to_s
|
|
97
|
+
post[:card] = creditcard.number
|
|
98
|
+
post[:exp] = expdate(creditcard)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def expdate(credit_card)
|
|
102
|
+
year = sprintf("%.4i", credit_card.year)
|
|
103
|
+
month = sprintf("%.2i", credit_card.month)
|
|
104
|
+
|
|
105
|
+
"#{month}#{year[-2..-1]}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def add_credit_data(post, transaction_id)
|
|
109
|
+
post[:transid] = transaction_id
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def add_void_data(post, options)
|
|
113
|
+
post[:transid] = options[:transactionid]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def commit(action, money, post)
|
|
117
|
+
response = parse( ssl_post(test? ? TEST_URL : LIVE_URL, post_data(action, post, money)) )
|
|
118
|
+
|
|
119
|
+
Response.new(response[:response] == 'CAPTURED', response[:message], response,
|
|
120
|
+
:test => test?,
|
|
121
|
+
:authorization => response[:authorization],
|
|
122
|
+
:avs_result => { :code => response[:avsresponse] },
|
|
123
|
+
:cvv_result => response[:cvvresponse])
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def parse(body)
|
|
127
|
+
response = {}
|
|
128
|
+
|
|
129
|
+
# check for an error first
|
|
130
|
+
if body.include?('!ERROR!')
|
|
131
|
+
response[:response] = 'ERROR'
|
|
132
|
+
response[:message] = error_message_from(body)
|
|
133
|
+
else
|
|
134
|
+
# a capture / not captured response will be : delimited
|
|
135
|
+
split = body.split(':')
|
|
136
|
+
response[:response] = split[0]
|
|
137
|
+
|
|
138
|
+
# FirstPay docs are worthless. turns out the transactionid is required for credits
|
|
139
|
+
# so we need to store that in authorization, not the actual auth.
|
|
140
|
+
if response[:response] == 'CAPTURED'
|
|
141
|
+
response[:message] = 'CAPTURED'
|
|
142
|
+
response[:authorization] = split[9] # actually the transactionid
|
|
143
|
+
response[:auth] = split[1]
|
|
144
|
+
response[:avsresponse] = split[3]
|
|
145
|
+
response[:cvvresponse] = split[17]
|
|
146
|
+
else
|
|
147
|
+
# NOT CAPTURED response
|
|
148
|
+
response[:message] = split[1]
|
|
149
|
+
response[:transactionid] = split[9]
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
return response
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def error_message_from(response)
|
|
157
|
+
# error messages use this format - '!ERROR! 704-MISSING BASIC DATA TYPE:card, exp, zip, addr, member, amount\n'
|
|
158
|
+
response.split("! ")[1].chomp
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def post_data(action, post, money)
|
|
162
|
+
post[:vid] = @options[:login]
|
|
163
|
+
post[:password] = @options[:password]
|
|
164
|
+
post[:action] = ACTIONS[action]
|
|
165
|
+
post[:amount] = amount(money)
|
|
166
|
+
|
|
167
|
+
return post.to_post_data
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
|
2
|
+
module Billing #:nodoc:
|
|
3
|
+
class GarantiGateway < Gateway
|
|
4
|
+
URL = 'https://ccpos.garanti.com.tr/servlet/cc5ApiServer'
|
|
5
|
+
|
|
6
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
|
7
|
+
self.supported_countries = ['US','TR']
|
|
8
|
+
|
|
9
|
+
# The card types supported by the payment gateway
|
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
|
11
|
+
|
|
12
|
+
# The homepage URL of the gateway
|
|
13
|
+
self.homepage_url = 'https://sanalposweb.garanti.com.tr/gvpsui/login/LoginStart.jsp'
|
|
14
|
+
|
|
15
|
+
# The name of the gateway
|
|
16
|
+
self.display_name = 'Garanti Sanal POS'
|
|
17
|
+
|
|
18
|
+
self.default_currency = 'TRL'
|
|
19
|
+
|
|
20
|
+
CURRENCY_CODES = {
|
|
21
|
+
'YTL' => 949,
|
|
22
|
+
'TRL' => 949,
|
|
23
|
+
'USD' => 840,
|
|
24
|
+
'EUR' => 978
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def initialize(options = {})
|
|
29
|
+
requires!(options, :login, :password, :client_id)
|
|
30
|
+
@options = options
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def purchase(money, credit_card, options = {})
|
|
35
|
+
commit(money, build_sale_request(money, credit_card, options))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def authorize(money, credit_card, options = {})
|
|
39
|
+
commit(money, build_authorize_request(money, credit_card, options))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def capture(money, reference, options = {})
|
|
43
|
+
commit(money, build_capture_request(money,reference,options))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def build_xml_request(transaction_type,&block)
|
|
49
|
+
xml = Builder::XmlMarkup.new
|
|
50
|
+
xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
|
|
51
|
+
|
|
52
|
+
xml.tag! 'CC5Request' do
|
|
53
|
+
xml.tag! 'Name', @options[:login]
|
|
54
|
+
xml.tag! 'Password', @options[:password]
|
|
55
|
+
xml.tag! 'ClientId', @options[:client_id]
|
|
56
|
+
xml.tag! 'Mode', if test? then 'R' else 'P' end
|
|
57
|
+
xml.tag! 'Type', transaction_type
|
|
58
|
+
|
|
59
|
+
if block_given?
|
|
60
|
+
yield xml
|
|
61
|
+
else
|
|
62
|
+
xml.target!
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def build_sale_request(money, credit_card, options)
|
|
68
|
+
build_xml_request('Auth') do |xml|
|
|
69
|
+
add_customer_data(xml,options)
|
|
70
|
+
add_order_data(xml,options)
|
|
71
|
+
add_credit_card(xml, credit_card)
|
|
72
|
+
add_addresses(xml, options)
|
|
73
|
+
|
|
74
|
+
xml.tag! 'Total', amount(money)
|
|
75
|
+
xml.tag! 'Currency', currency_code(options[:currency])
|
|
76
|
+
|
|
77
|
+
xml.target!
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def build_authorize_request(money, credit_card, options)
|
|
82
|
+
build_xml_request('PreAuth') do |xml|
|
|
83
|
+
add_customer_data(xml,options)
|
|
84
|
+
add_order_data(xml,options)
|
|
85
|
+
add_credit_card(xml, credit_card)
|
|
86
|
+
add_addresses(xml, options)
|
|
87
|
+
|
|
88
|
+
xml.tag! 'Total', amount(money)
|
|
89
|
+
xml.tag! 'Currency', currency_code(options[:currency])
|
|
90
|
+
|
|
91
|
+
xml.target!
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def build_capture_request(money, reference, options = {})
|
|
97
|
+
build_xml_request('PostAuth') do |xml|
|
|
98
|
+
add_customer_data(xml,options)
|
|
99
|
+
xml.tag! 'OrderId', reference
|
|
100
|
+
xml.tag! 'Total', amount(money)
|
|
101
|
+
xml.tag! 'Currency', currency_code(options[:currency])
|
|
102
|
+
|
|
103
|
+
xml.target!
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def build_void_request(reference, options = {})
|
|
108
|
+
build_xml_request('Void') do |xml|
|
|
109
|
+
add_customer_data(xml,options)
|
|
110
|
+
xml.tag! 'OrderId', reference
|
|
111
|
+
xml.tag! 'Total', amount(money)
|
|
112
|
+
xml.tag! 'Currency', currency_code(options[:currency])
|
|
113
|
+
|
|
114
|
+
xml.target!
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def build_credit_request(money, reference, options = {})
|
|
119
|
+
build_xml_request('Credit') do |xml|
|
|
120
|
+
add_customer_data(xml,options)
|
|
121
|
+
xml.tag! 'OrderId', reference
|
|
122
|
+
xml.tag! 'Total', amount(money)
|
|
123
|
+
xml.tag! 'Currency', currency_code(options[:currency])
|
|
124
|
+
|
|
125
|
+
xml.target!
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def add_customer_data(xml, options)
|
|
130
|
+
xml.tag! 'IPAddress', options[:ip_]
|
|
131
|
+
xml.tag! 'Email', options[:email]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def add_order_data(xml,options)
|
|
135
|
+
xml.tag! 'OrderId', options[:order_id]
|
|
136
|
+
xml.tag! 'GroupId', nil
|
|
137
|
+
xml.tag! 'TransId', nil
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def add_credit_card(xml, credit_card)
|
|
141
|
+
xml.tag! 'Number', credit_card.number
|
|
142
|
+
xml.tag! 'Expires', [format_exp(credit_card.month),format_exp(credit_card.year)].join('/')
|
|
143
|
+
xml.tag! 'Cvv2Val', credit_card.verification_value
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def format_exp(value)
|
|
147
|
+
format(value, :two_digits)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def add_addresses(xml,options)
|
|
151
|
+
if billing_address = options[:billing_address] || options[:address]
|
|
152
|
+
xml.tag! 'BillTo' do
|
|
153
|
+
xml.tag! 'Name', billing_address[:name]
|
|
154
|
+
xml.tag! 'Street1', billing_address[:address1]
|
|
155
|
+
xml.tag! 'Street2', billing_address[:address2]
|
|
156
|
+
xml.tag! 'City', billing_address[:city]
|
|
157
|
+
xml.tag! 'StateProv', billing_address[:state]
|
|
158
|
+
xml.tag! 'PostalCode', billing_address[:zip]
|
|
159
|
+
xml.tag! 'Country', billing_address[:country]
|
|
160
|
+
xml.tag! 'Company', billing_address[:company]
|
|
161
|
+
xml.tag! 'TelVoice', billing_address[:phone]
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
if shipping_address = options[:shipping_address]
|
|
166
|
+
xml.tag! 'ShipTo' do
|
|
167
|
+
xml.tag! 'Name', shipping_address[:name]
|
|
168
|
+
xml.tag! 'Street1', shipping_address[:address1]
|
|
169
|
+
xml.tag! 'Street2', shipping_address[:address2]
|
|
170
|
+
xml.tag! 'City', shipping_address[:city]
|
|
171
|
+
xml.tag! 'StateProv',shipping_address[:state]
|
|
172
|
+
xml.tag! 'PostalCode',shipping_address[:zip]
|
|
173
|
+
xml.tag! 'Country', shipping_address[:country]
|
|
174
|
+
xml.tag! 'Company', shipping_address[:company]
|
|
175
|
+
xml.tag! 'TelVoice', shipping_address[:phone]
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def currency_code(currency)
|
|
181
|
+
CURRENCY_CODES[currency] || CURRENCY_CODES[default_currency]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def commit(money,request)
|
|
185
|
+
raw_response = ssl_post(URL,"DATA=" + request)
|
|
186
|
+
response = parse(raw_response)
|
|
187
|
+
|
|
188
|
+
success = success?(response)
|
|
189
|
+
|
|
190
|
+
Response.new(success,
|
|
191
|
+
success ? 'Approved' : 'Declined',
|
|
192
|
+
response,
|
|
193
|
+
:test => test?,
|
|
194
|
+
:authorization => response[:order_id])
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def parse(body)
|
|
198
|
+
xml = REXML::Document.new(body)
|
|
199
|
+
|
|
200
|
+
response = {}
|
|
201
|
+
xml.root.elements.to_a.each do |node|
|
|
202
|
+
parse_element(response, node)
|
|
203
|
+
end
|
|
204
|
+
response
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def parse_element(response, node)
|
|
208
|
+
if node.has_elements?
|
|
209
|
+
node.elements.each{|element| parse_element(response, element) }
|
|
210
|
+
else
|
|
211
|
+
response[node.name.underscore.to_sym] = node.text
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def success?(response)
|
|
216
|
+
response[:response] == "Approved"
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'check.rb')
|
|
2
|
+
module ActiveMerchant #:nodoc:
|
|
3
|
+
module Billing #:nodoc:
|
|
4
|
+
class InspireGateway < Gateway
|
|
5
|
+
URL = 'https://secure.inspiregateway.net/api/transact.php'
|
|
6
|
+
|
|
7
|
+
self.supported_countries = ['US']
|
|
8
|
+
self.supported_cardtypes = [:visa, :master, :american_express]
|
|
9
|
+
self.homepage_url = 'http://www.inspiregateway.com'
|
|
10
|
+
self.display_name = 'Inspire Commerce'
|
|
11
|
+
# Creates a new InspireGateway
|
|
12
|
+
#
|
|
13
|
+
# The gateway requires that a valid login and password be passed
|
|
14
|
+
# in the +options+ hash.
|
|
15
|
+
#
|
|
16
|
+
# ==== Options
|
|
17
|
+
#
|
|
18
|
+
# * <tt>:login</tt> -- The Inspire Username.
|
|
19
|
+
# * <tt>:password</tt> -- The Inspire Passowrd.
|
|
20
|
+
# See the Inspire Integration Guide for details. (default: +false+)
|
|
21
|
+
def initialize(options = {})
|
|
22
|
+
requires!(options, :login, :password)
|
|
23
|
+
@options = options
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Pass :store => true in the options to store the
|
|
28
|
+
# payment info at Inspire Gateway and get a generated
|
|
29
|
+
# customer_vault_id in the response.
|
|
30
|
+
# Pass :store => some_number_or_string to specify the
|
|
31
|
+
# customer_vault_id InspireGateway should use (make sure it's
|
|
32
|
+
# unique).
|
|
33
|
+
def authorize(money, creditcard, options = {})
|
|
34
|
+
post = {}
|
|
35
|
+
add_invoice(post, options)
|
|
36
|
+
add_payment_source(post, creditcard,options)
|
|
37
|
+
add_address(post, creditcard, options)
|
|
38
|
+
add_customer_data(post, options)
|
|
39
|
+
|
|
40
|
+
commit('auth', money, post)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def purchase(money, payment_source, options = {})
|
|
44
|
+
post = {}
|
|
45
|
+
add_invoice(post, options)
|
|
46
|
+
add_payment_source(post, payment_source, options)
|
|
47
|
+
add_address(post, payment_source, options)
|
|
48
|
+
add_customer_data(post, options)
|
|
49
|
+
|
|
50
|
+
commit('sale', money, post)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def capture(money, authorization, options = {})
|
|
54
|
+
post ={}
|
|
55
|
+
post[:transactionid] = authorization
|
|
56
|
+
commit('capture', money, post)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def void(authorization, options = {})
|
|
60
|
+
post ={}
|
|
61
|
+
post[:transactionid] = authorization
|
|
62
|
+
commit('void', nil, post)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Update the values (such as CC expiration) stored at
|
|
66
|
+
# InspireGateway. The CC number must be supplied in the
|
|
67
|
+
# CreditCard object.
|
|
68
|
+
def update(vault_id, creditcard, options = {})
|
|
69
|
+
post = {}
|
|
70
|
+
post[:customer_vault] = "update_customer"
|
|
71
|
+
add_customer_vault_id(post, vault_id)
|
|
72
|
+
add_creditcard(post, creditcard, options)
|
|
73
|
+
add_address(post, creditcard, options)
|
|
74
|
+
add_customer_data(post, options)
|
|
75
|
+
|
|
76
|
+
commit(nil, nil, post)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def delete(vault_id)
|
|
80
|
+
post = {}
|
|
81
|
+
post[:customer_vault] = "delete_customer"
|
|
82
|
+
add_customer_vault_id(post, vault_id)
|
|
83
|
+
commit(nil, nil, post)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# To match the other stored-value gateways, like TrustCommerce,
|
|
87
|
+
# store and unstore need to be defined
|
|
88
|
+
def store(creditcard, options = {})
|
|
89
|
+
billing_id = options.delete(:billing_id).to_s || true
|
|
90
|
+
authorize(100, creditcard, options.merge(:store => billing_id))
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
alias_method :unstore, :delete
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
def add_customer_data(post, options)
|
|
97
|
+
if options.has_key? :email
|
|
98
|
+
post[:email] = options[:email]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
if options.has_key? :ip
|
|
102
|
+
post[:ipaddress] = options[:ip]
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def add_address(post, creditcard, options)
|
|
107
|
+
if address = options[:billing_address] || options[:address]
|
|
108
|
+
post[:address1] = address[:address1].to_s
|
|
109
|
+
post[:address2] = address[:address2].to_s unless address[:address2].blank?
|
|
110
|
+
post[:company] = address[:company].to_s
|
|
111
|
+
post[:phone] = address[:phone].to_s
|
|
112
|
+
post[:zip] = address[:zip].to_s
|
|
113
|
+
post[:city] = address[:city].to_s
|
|
114
|
+
post[:country] = address[:country].to_s
|
|
115
|
+
post[:state] = address[:state].blank? ? 'n/a' : address[:state]
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def add_invoice(post, options)
|
|
120
|
+
post[:orderid] = options[:order_id].to_s.gsub(/[^\w.]/, '')
|
|
121
|
+
post[:orderdescription] = options[:description]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def add_payment_source(params, source, options={})
|
|
125
|
+
case determine_funding_source(source)
|
|
126
|
+
when :vault then add_customer_vault_id(params, source)
|
|
127
|
+
when :credit_card then add_creditcard(params, source, options)
|
|
128
|
+
when :check then add_check(params, source)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def add_customer_vault_id(params,vault_id)
|
|
133
|
+
params[:customer_vault_id] = vault_id
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def add_creditcard(post, creditcard,options)
|
|
137
|
+
if options[:store]
|
|
138
|
+
post[:customer_vault] = "add_customer"
|
|
139
|
+
post[:customer_vault_id] = options[:store] unless options[:store] == true
|
|
140
|
+
end
|
|
141
|
+
post[:ccnumber] = creditcard.number
|
|
142
|
+
post[:cvv] = creditcard.verification_value if creditcard.verification_value?
|
|
143
|
+
post[:ccexp] = expdate(creditcard)
|
|
144
|
+
post[:firstname] = creditcard.first_name
|
|
145
|
+
post[:lastname] = creditcard.last_name
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def add_check(post, check)
|
|
149
|
+
post[:payment] = 'check' # Set transaction to ACH
|
|
150
|
+
post[:checkname] = check.name # The name on the customer's Checking Account
|
|
151
|
+
post[:checkaba] = check.routing_number # The customer's bank routing number
|
|
152
|
+
post[:checkaccount] = check.account_number # The customer's account number
|
|
153
|
+
post[:account_holder_type] = check.account_holder_type # The customer's type of ACH account
|
|
154
|
+
post[:account_type] = check.account_type # The customer's type of ACH account
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def parse(body)
|
|
158
|
+
results = {}
|
|
159
|
+
body.split(/&/).each do |pair|
|
|
160
|
+
key,val = pair.split(/=/)
|
|
161
|
+
results[key] = val
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
results
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def commit(action, money, parameters)
|
|
168
|
+
parameters[:amount] = amount(money) if money
|
|
169
|
+
|
|
170
|
+
response = parse( ssl_post(URL, post_data(action,parameters)) )
|
|
171
|
+
|
|
172
|
+
Response.new(response["response"] == "1", message_from(response), response,
|
|
173
|
+
:authorization => response["transactionid"],
|
|
174
|
+
:test => test?,
|
|
175
|
+
:cvv_result => response["cvvresponse"],
|
|
176
|
+
:avs_result => { :code => response["avsresponse"] }
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def expdate(creditcard)
|
|
182
|
+
year = sprintf("%.4i", creditcard.year)
|
|
183
|
+
month = sprintf("%.2i", creditcard.month)
|
|
184
|
+
|
|
185
|
+
"#{month}#{year[-2..-1]}"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def message_from(response)
|
|
190
|
+
case response["responsetext"]
|
|
191
|
+
when "SUCCESS","Approved"
|
|
192
|
+
"This transaction has been approved"
|
|
193
|
+
when "DECLINE"
|
|
194
|
+
"This transaction has been declined"
|
|
195
|
+
else
|
|
196
|
+
response["responsetext"]
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def post_data(action, parameters = {})
|
|
201
|
+
post = {}
|
|
202
|
+
post[:username] = @options[:login]
|
|
203
|
+
post[:password] = @options[:password]
|
|
204
|
+
post[:type] = action if action
|
|
205
|
+
|
|
206
|
+
request = post.merge(parameters).map {|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&")
|
|
207
|
+
request
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def determine_funding_source(source)
|
|
211
|
+
case
|
|
212
|
+
when source.is_a?(String) then :vault
|
|
213
|
+
when CreditCard.card_companies.keys.include?(card_brand(source)) then :credit_card
|
|
214
|
+
when card_brand(source) == 'check' then :check
|
|
215
|
+
else raise ArgumentError, "Unsupported funding source provided"
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|