yetanothernguyen-activemerchant 1.16.0 → 1.21.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/CHANGELOG +95 -0
- data/CONTRIBUTORS +29 -0
- data/lib/active_merchant/billing/credit_card.rb +105 -19
- data/lib/active_merchant/billing/credit_card_methods.rb +5 -1
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +24 -2
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +104 -18
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +110 -4
- data/lib/active_merchant/billing/gateways/beanstream.rb +29 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +9 -4
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +4 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/certo_direct.rb +279 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +9 -9
- data/lib/active_merchant/billing/gateways/elavon.rb +2 -1
- data/lib/active_merchant/billing/gateways/epay.rb +12 -6
- data/lib/active_merchant/billing/gateways/eway_managed.rb +46 -12
- data/lib/active_merchant/billing/gateways/exact.rb +5 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +3 -3
- data/lib/active_merchant/billing/gateways/ipay88.rb +157 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +3 -3
- data/lib/active_merchant/billing/gateways/itransact.rb +450 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +1 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +4 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +244 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +94 -56
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +277 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +57 -34
- data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -1
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +2 -2
- data/lib/active_merchant/billing/gateways/payflow.rb +10 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +8 -5
- data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +43 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +93 -40
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +8 -3
- data/lib/active_merchant/billing/gateways/qbms.rb +4 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +97 -22
- data/lib/active_merchant/billing/gateways/realex.rb +5 -1
- data/lib/active_merchant/billing/gateways/samurai.rb +121 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +136 -49
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +1 -1
- data/lib/active_merchant/billing/gateways/skip_jack.rb +7 -2
- data/lib/active_merchant/billing/gateways/stripe.rb +51 -19
- data/lib/active_merchant/billing/gateways/usa_epay.rb +13 -184
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1496 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +206 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +2 -2
- data/lib/active_merchant/billing/gateways/viaklix.rb +1 -1
- data/lib/active_merchant/billing/gateways/worldpay.rb +1 -1
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +6 -2
- data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +228 -0
- data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +340 -0
- data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +38 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +4 -4
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +31 -0
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +55 -0
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
- data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
- data/lib/active_merchant/billing/integrations/helper.rb +19 -2
- data/lib/active_merchant/billing/integrations/ipay88/helper.rb +120 -0
- data/lib/active_merchant/billing/integrations/ipay88/return.rb +121 -0
- data/lib/active_merchant/billing/integrations/ipay88.rb +40 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +1 -1
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
- data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +4 -4
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +18 -2
- data/lib/active_merchant/billing/integrations/two_checkout.rb +1 -2
- data/lib/active_merchant/railtie.rb +7 -7
- data/lib/active_merchant/railtie.rb.orig +19 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/active_merchant.rb +23 -10
- data/lib/active_merchant.rb.orig +78 -0
- metadata +147 -63
- data/lib/active_merchant/common/connection.rb +0 -177
- data/lib/active_merchant/common/country.rb +0 -328
- data/lib/active_merchant/common/error.rb +0 -26
- data/lib/active_merchant/common/post_data.rb +0 -24
- data/lib/active_merchant/common/posts_data.rb +0 -63
- data/lib/active_merchant/common/requires_parameters.rb +0 -16
- data/lib/active_merchant/common/utils.rb +0 -22
- data/lib/active_merchant/common/validateable.rb +0 -81
- data/lib/active_merchant/common.rb +0 -14
- data/lib/certs/cacert.pem +0 -7815
@@ -0,0 +1,279 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class CertoDirectGateway < Gateway
|
4
|
+
class_attribute :gateway_url
|
5
|
+
self.gateway_url = "https://secure.certodirect.com/gateway/process/v2"
|
6
|
+
|
7
|
+
self.supported_countries = [
|
8
|
+
"BE", "BG", "CZ", "DK", "DE", "EE", "IE", "EL", "ES", "FR",
|
9
|
+
"IT", "CY", "LV", "LT", "LU", "HU", "MT", "NL", "AT", "PL",
|
10
|
+
"PT", "RO", "SI", "SK", "FI", "SE", "UK"
|
11
|
+
]
|
12
|
+
|
13
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
14
|
+
self.homepage_url = 'http://www.certodirect.com/'
|
15
|
+
self.display_name = 'CertoDirect'
|
16
|
+
|
17
|
+
# Creates a new CertoDirectGateway
|
18
|
+
#
|
19
|
+
# The gateway requires that a valid login and password be passed
|
20
|
+
# in the +options+ hash.
|
21
|
+
#
|
22
|
+
# ==== Options
|
23
|
+
#
|
24
|
+
# * <tt>:login</tt> -- The CertoDirect Shop ID (REQUIRED)
|
25
|
+
# * <tt>:password</tt> -- The CertoDirect Shop Password. (REQUIRED)
|
26
|
+
# * <tt>:test</tt> -- +true+ or +false+. If true, perform transactions against the test server.
|
27
|
+
# Otherwise, perform transactions against the production server.
|
28
|
+
def initialize(options = {})
|
29
|
+
requires!(options, :login, :password)
|
30
|
+
@options = options
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
# Perform a purchase, which is essentially an authorization and capture in a single operation.
|
35
|
+
#
|
36
|
+
# ==== Parameters
|
37
|
+
#
|
38
|
+
# * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
|
39
|
+
# * <tt>credit_card</tt> -- The CreditCard details for the transaction.
|
40
|
+
# * <tt>options</tt> -- A hash of optional parameters.
|
41
|
+
def purchase(money, credit_card, options = {})
|
42
|
+
requires!(options, :email, :currency, :ip, :description)
|
43
|
+
|
44
|
+
commit(build_sale_request(money, credit_card, options))
|
45
|
+
end
|
46
|
+
|
47
|
+
# Refund a transaction.
|
48
|
+
#
|
49
|
+
# This transaction indicates to the gateway that
|
50
|
+
# money should flow from the merchant to the customer.
|
51
|
+
#
|
52
|
+
# ==== Parameters
|
53
|
+
#
|
54
|
+
# * <tt>money</tt> -- The amount to be credited to the customer as an Integer value in cents.
|
55
|
+
# * <tt>identification</tt> -- The ID of the original order against which the refund is being issued.
|
56
|
+
# * <tt>options</tt> -- A hash of parameters.
|
57
|
+
def refund(money, identification, options = {})
|
58
|
+
requires!(options, :reason)
|
59
|
+
|
60
|
+
commit(build_refund_request(money, identification, options))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Performs an authorization, which reserves the funds on the customer's credit card, but does not
|
64
|
+
# charge the card.
|
65
|
+
#
|
66
|
+
# ==== Parameters
|
67
|
+
#
|
68
|
+
# * <tt>money</tt> -- The amount to be authorized as an Integer value in cents.
|
69
|
+
# * <tt>credit_card</tt> -- The CreditCard details for the transaction.
|
70
|
+
# * <tt>options</tt> -- A hash of optional parameters.
|
71
|
+
def authorize(money, credit_card, options = {})
|
72
|
+
requires!(options, :email, :currency, :ip, :description)
|
73
|
+
|
74
|
+
commit(build_authorize_request(money, credit_card, options))
|
75
|
+
end
|
76
|
+
|
77
|
+
# Captures the funds from an authorized transaction.
|
78
|
+
#
|
79
|
+
# ==== Parameters
|
80
|
+
#
|
81
|
+
# * <tt>money</tt> -- The amount to be captured as an Integer value in cents.
|
82
|
+
# * <tt>identification</tt> -- The authorization returned from the previous authorize request.
|
83
|
+
def capture(money, identification, options = {})
|
84
|
+
commit(build_capture_request(money, identification))
|
85
|
+
end
|
86
|
+
|
87
|
+
# Void a previous transaction
|
88
|
+
#
|
89
|
+
# ==== Parameters
|
90
|
+
#
|
91
|
+
# * <tt>money</tt> -- The amount to be captured as an Integer value in cents.
|
92
|
+
# * <tt>identification</tt> - The authorization returned from the previous authorize request.
|
93
|
+
def void(money, identification, options = {})
|
94
|
+
commit(build_void_request(money, identification))
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create a recurring payment.
|
98
|
+
#
|
99
|
+
# ==== Parameters
|
100
|
+
#
|
101
|
+
# * <tt>options</tt> -- A hash of parameters.
|
102
|
+
#
|
103
|
+
# ==== Options
|
104
|
+
#
|
105
|
+
def recurring(identification, options={})
|
106
|
+
commit(build_recurring_request(identification, options))
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def commit(request_xml)
|
113
|
+
begin
|
114
|
+
response = Hash.from_xml(ssl_post(gateway_url, request_xml, headers))
|
115
|
+
Response.new(success?(response),
|
116
|
+
message(response),
|
117
|
+
response,
|
118
|
+
:test => test?,
|
119
|
+
:authorization => authorization(response))
|
120
|
+
rescue ResponseError => e
|
121
|
+
raise e unless e.response.code == '403'
|
122
|
+
response = Hash.from_xml(e.response.body)['response']
|
123
|
+
Response.new(false, message(response), {}, :test => test?)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def build_sale_request(money, credit_card, options)
|
128
|
+
build_request_xml('Sale') do |xml|
|
129
|
+
add_order(xml, money, credit_card, options)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def build_authorize_request(money, credit_card, options)
|
134
|
+
build_request_xml('Authorize') do |xml|
|
135
|
+
add_order(xml, money, credit_card, options)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def build_refund_request(money, identification, options)
|
140
|
+
build_request_xml('Refund') do |xml|
|
141
|
+
add_reference_info(xml, money, identification, options)
|
142
|
+
xml.tag! 'reason', options[:reason]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def build_capture_request(money, identification)
|
147
|
+
build_request_xml('Capture') do |xml|
|
148
|
+
add_reference_info(xml, money, identification, options)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def build_void_request(money, identification)
|
153
|
+
build_request_xml('Void') do |xml|
|
154
|
+
add_reference_info(xml, money, identification, options)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def build_recurring_request(identification, options)
|
159
|
+
build_request_xml('Sale') do |xml|
|
160
|
+
xml.tag! 'order' do |xml|
|
161
|
+
xml.tag!('test', 'true') if test?
|
162
|
+
xml.tag! 'initial_order_id', identification, :type => 'integer'
|
163
|
+
|
164
|
+
add_order_details(xml, options[:amount], options) if has_any_order_details_key?(options)
|
165
|
+
add_address(xml, 'billing_address', options[:billing_address]) if options[:billing_address]
|
166
|
+
add_address(xml, 'shipping_address', options[:shipping_address]) if options[:shipping_address]
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def build_request_xml(type, &block)
|
172
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
173
|
+
xml.tag! 'transaction' do
|
174
|
+
xml.tag! 'type', type
|
175
|
+
yield(xml)
|
176
|
+
end
|
177
|
+
xml.target!
|
178
|
+
end
|
179
|
+
|
180
|
+
def add_order(xml, money, credit_card, options)
|
181
|
+
xml.tag! 'order' do
|
182
|
+
xml.tag!('test', 'true') if test?
|
183
|
+
|
184
|
+
xml.tag!('return_url', options[:return_url]) if options[:return_url]
|
185
|
+
xml.tag!('cancel_url', options[:cancel_url]) if options[:cancel_url]
|
186
|
+
|
187
|
+
xml.tag! 'payment_method_type', 'CreditCard'
|
188
|
+
xml.tag! 'payment_method' do
|
189
|
+
xml.tag! 'number', credit_card.number
|
190
|
+
xml.tag! 'exp_month', "%02i" % credit_card.month
|
191
|
+
xml.tag! 'exp_year', credit_card.year
|
192
|
+
xml.tag! 'holder', credit_card.name
|
193
|
+
xml.tag! 'verification_value', credit_card.verification_value
|
194
|
+
end
|
195
|
+
|
196
|
+
add_order_details(xml, money, options)
|
197
|
+
add_address(xml, 'billing_address', options[:billing_address]) if options[:billing_address]
|
198
|
+
add_address(xml, 'shipping_address', options[:shipping_address]) if options[:shipping_address]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def add_order_details(xml, money, options)
|
203
|
+
xml.tag! 'details' do
|
204
|
+
xml.tag!('amount', localized_amount(money, options[:currency]), :type => 'decimal') if money
|
205
|
+
xml.tag!('currency', options[:currency]) if options[:currency]
|
206
|
+
xml.tag!('email', options[:email]) if options[:email]
|
207
|
+
xml.tag!('ip', options[:ip]) if options[:ip]
|
208
|
+
xml.tag!('shipping', options[:shipping], :type => 'decimal') if options[:shipping]
|
209
|
+
xml.tag!('description', options[:description]) if options[:description]
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def add_reference_info(xml, money, identification, options)
|
214
|
+
xml.tag! 'order_id', identification, :type => 'integer'
|
215
|
+
xml.tag! 'amount', localized_amount(money, options[:currency]), :type => 'decimal'
|
216
|
+
end
|
217
|
+
|
218
|
+
def add_address(xml, address_type, address)
|
219
|
+
xml.tag! address_type do
|
220
|
+
xml.tag! 'address', address[:address1]
|
221
|
+
xml.tag! 'city', address[:city]
|
222
|
+
xml.tag! 'country', address[:country]
|
223
|
+
xml.tag! 'first_name', address[:first_name]
|
224
|
+
xml.tag! 'last_name', address[:last_name]
|
225
|
+
xml.tag! 'state', address[:state]
|
226
|
+
xml.tag! 'phone', address[:phone]
|
227
|
+
xml.tag! 'zip', address[:zip]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def has_any_order_details_key?(options)
|
232
|
+
[ :currency, :amount, :email, :ip, :shipping, :description ].any? do |key|
|
233
|
+
options.has_key?(key)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def success?(response)
|
238
|
+
%w(completed forwarding).include?(state(response)) and
|
239
|
+
status(response) == 'success'
|
240
|
+
end
|
241
|
+
|
242
|
+
def error?(response)
|
243
|
+
response['errors']
|
244
|
+
end
|
245
|
+
|
246
|
+
def state(response)
|
247
|
+
response["transaction"].try(:[], "state")
|
248
|
+
end
|
249
|
+
|
250
|
+
def status(response)
|
251
|
+
response['transaction'].try(:[], 'response').try(:[], 'status')
|
252
|
+
end
|
253
|
+
|
254
|
+
def authorization(response)
|
255
|
+
error?(response) ? nil : response["transaction"]["order"]['id'].to_s
|
256
|
+
end
|
257
|
+
|
258
|
+
def message(response)
|
259
|
+
return response['errors'].join('; ') if error?(response)
|
260
|
+
|
261
|
+
if state(response) == 'completed'
|
262
|
+
response["transaction"]["response"]["message"]
|
263
|
+
else
|
264
|
+
response['transaction']['message']
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def headers
|
269
|
+
{ 'authorization' => basic_auth,
|
270
|
+
'Accept' => 'application/xml',
|
271
|
+
'Content-Type' => 'application/xml' }
|
272
|
+
end
|
273
|
+
|
274
|
+
def basic_auth
|
275
|
+
'Basic ' + ["#{@options[:login]}:#{@options[:password]}"].pack('m').delete("\r\n")
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -60,7 +60,7 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
def void(identification, options = {})
|
61
61
|
requires!(options, :order_id)
|
62
62
|
original_transaction_id, original_transaction_amount = identification.split(";")
|
63
|
-
commit(:void_transaction, {:reference_number => format_reference_number(options[:order_id]), :
|
63
|
+
commit(:void_transaction, {:reference_number => format_reference_number(options[:order_id]), :transaction_id => original_transaction_id})
|
64
64
|
end
|
65
65
|
|
66
66
|
def voice_authorize(money, authorization_code, creditcard, options = {})
|
@@ -90,7 +90,7 @@ module ActiveMerchant #:nodoc:
|
|
90
90
|
:reference_number => format_reference_number(options[:order_id]),
|
91
91
|
:transaction_amount => amount(money),
|
92
92
|
:original_transaction_amount => original_transaction_amount,
|
93
|
-
:
|
93
|
+
:original_transaction_id => original_transaction_id,
|
94
94
|
:client_ip_address => options[:ip]
|
95
95
|
}
|
96
96
|
end
|
@@ -191,7 +191,7 @@ module ActiveMerchant #:nodoc:
|
|
191
191
|
transaction = root.add_element(action.to_s.camelize)
|
192
192
|
|
193
193
|
actions[action].each do |key|
|
194
|
-
transaction.add_element(key
|
194
|
+
transaction.add_element(key).text = parameters[key.underscore.to_sym] unless parameters[key.underscore.to_sym].blank?
|
195
195
|
end
|
196
196
|
|
197
197
|
xml.to_s
|
@@ -217,18 +217,18 @@ module ActiveMerchant #:nodoc:
|
|
217
217
|
ACTIONS
|
218
218
|
end
|
219
219
|
|
220
|
-
CREDIT_CARD_FIELDS =
|
220
|
+
CREDIT_CARD_FIELDS = %w(AuthorizationNumber ClientIpAddress BillingAddress BillingCity BillingState BillingPostalCode BillingCountry BillingName CardVerificationValue ExpirationMonth ExpirationYear ReferenceNumber TransactionAmount AccountNumber )
|
221
221
|
|
222
222
|
ACTIONS = {
|
223
223
|
:credit_card_authorize => CREDIT_CARD_FIELDS,
|
224
224
|
:credit_card_charge => CREDIT_CARD_FIELDS,
|
225
225
|
:credit_card_voice_authorize => CREDIT_CARD_FIELDS,
|
226
226
|
:credit_card_capture => CREDIT_CARD_FIELDS,
|
227
|
-
:credit_card_credit => CREDIT_CARD_FIELDS
|
228
|
-
:credit_card_refund =>
|
229
|
-
:void_transaction =>
|
230
|
-
:credit_card_settle =>
|
231
|
-
:system_check =>
|
227
|
+
:credit_card_credit => CREDIT_CARD_FIELDS + ["OriginalTransactionAmount"],
|
228
|
+
:credit_card_refund => %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress),
|
229
|
+
:void_transaction => %w(ReferenceNumber TransactionID),
|
230
|
+
:credit_card_settle => %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress),
|
231
|
+
:system_check => %w(SystemCheck),
|
232
232
|
}
|
233
233
|
end
|
234
234
|
end
|
@@ -30,7 +30,8 @@ module ActiveMerchant #:nodoc:
|
|
30
30
|
# puts response.authorization # Retrieve the unique transaction ID returned by Elavon
|
31
31
|
#
|
32
32
|
class ElavonGateway < ViaklixGateway
|
33
|
-
self.test_url =
|
33
|
+
self.test_url = 'https://demo.myvirtualmerchant.com/VirtualMerchantDemo/process.do'
|
34
|
+
self.live_url = 'https://www.myvirtualmerchant.com/VirtualMerchant/process.do'
|
34
35
|
|
35
36
|
self.display_name = 'Elavon MyVirtualMerchant'
|
36
37
|
self.supported_countries = ['US', 'CA']
|
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
|
|
8
8
|
self.money_format = :cents
|
9
9
|
self.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master,
|
10
10
|
:american_express, :diners_club, :jcb, :maestro]
|
11
|
-
self.supported_countries = ['DK']
|
11
|
+
self.supported_countries = ['DK', 'SE', 'NO']
|
12
12
|
self.homepage_url = 'http://epay.dk/'
|
13
13
|
self.display_name = 'ePay'
|
14
14
|
|
@@ -53,7 +53,7 @@ module ActiveMerchant #:nodoc:
|
|
53
53
|
# login: merchant number
|
54
54
|
# password: referrer url (for authorize authentication)
|
55
55
|
def initialize(options = {})
|
56
|
-
requires!(options, :login
|
56
|
+
requires!(options, :login)
|
57
57
|
@options = options
|
58
58
|
super
|
59
59
|
end
|
@@ -180,15 +180,21 @@ module ActiveMerchant #:nodoc:
|
|
180
180
|
end
|
181
181
|
|
182
182
|
def do_authorize(params)
|
183
|
-
headers = {
|
184
|
-
|
185
|
-
}
|
183
|
+
headers = {}
|
184
|
+
headers['Referer'] = (options[:password] || "activemerchant.org")
|
186
185
|
|
187
186
|
response = raw_ssl_request(:post, 'https://' + API_HOST + '/auth/default.aspx', authorize_post_data(params), headers)
|
188
187
|
|
189
188
|
# Authorize gives the response back by redirecting with the values in
|
190
189
|
# the URL query
|
191
|
-
|
190
|
+
if location = response['Location']
|
191
|
+
query = CGI::parse(URI.parse(location.gsub(' ', '%20')).query)
|
192
|
+
else
|
193
|
+
return {
|
194
|
+
'accept' => '0',
|
195
|
+
'errortext' => 'No Location header returned.'
|
196
|
+
}
|
197
|
+
end
|
192
198
|
|
193
199
|
result = {}
|
194
200
|
query.each_pair do |k,v|
|
@@ -45,7 +45,7 @@ module ActiveMerchant #:nodoc:
|
|
45
45
|
|
46
46
|
add_creditcard(post, creditcard)
|
47
47
|
add_address(post, billing_address)
|
48
|
-
add_misc_fields(post,
|
48
|
+
add_misc_fields(post, options)
|
49
49
|
|
50
50
|
commit("CreateCustomer", post)
|
51
51
|
end
|
@@ -63,17 +63,30 @@ module ActiveMerchant #:nodoc:
|
|
63
63
|
post[:managedCustomerID]=billing_id
|
64
64
|
add_creditcard(post, creditcard)
|
65
65
|
add_address(post, billing_address)
|
66
|
-
add_misc_fields(post,
|
66
|
+
add_misc_fields(post, options)
|
67
67
|
|
68
68
|
commit("UpdateCustomer", post)
|
69
69
|
end
|
70
70
|
|
71
|
-
#
|
71
|
+
# Process a payment in the given amount against the stored credit card given by billing_id
|
72
|
+
#
|
73
|
+
# ==== Parameters
|
74
|
+
#
|
75
|
+
# * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
|
76
|
+
# * <tt>billing_id</tt> -- The eWay provided card/customer token to charge (managedCustomerID)
|
77
|
+
# * <tt>options</tt> -- A hash of optional parameters.
|
78
|
+
#
|
79
|
+
# ==== Options
|
80
|
+
#
|
81
|
+
# * <tt>:order_id</tt> -- The order number, passed to eWay as the "Invoice Reference"
|
82
|
+
# * <tt>:invoice</tt> -- The invoice number, passed to eWay as the "Invoice Reference" unless :order_id is also given
|
83
|
+
# * <tt>:description</tt> -- A description of the payment, passed to eWay as the "Invoice Description"
|
72
84
|
def purchase(money, billing_id, options={})
|
73
85
|
post = {}
|
74
86
|
post[:managedCustomerID] = billing_id.to_s
|
75
87
|
post[:amount]=money
|
76
|
-
|
88
|
+
add_invoice(post, options)
|
89
|
+
|
77
90
|
commit("ProcessPayment", post)
|
78
91
|
end
|
79
92
|
|
@@ -102,14 +115,21 @@ private
|
|
102
115
|
end
|
103
116
|
|
104
117
|
def add_misc_fields(post, options)
|
105
|
-
post[:CustomerRef]=options[:customer_ref]
|
106
|
-
post[:Title]=options[:title]
|
107
|
-
post[:Company]=options[:company]
|
108
|
-
post[:JobDesc]=options[:job_desc]
|
109
|
-
post[:Email]=options[:email]
|
110
|
-
post[:URL]=options[:url]
|
118
|
+
post[:CustomerRef]=options[:billing_address][:customer_ref] || options[:customer]
|
119
|
+
post[:Title]=options[:billing_address][:title]
|
120
|
+
post[:Company]=options[:billing_address][:company]
|
121
|
+
post[:JobDesc]=options[:billing_address][:job_desc]
|
122
|
+
post[:Email]=options[:billing_address][:email] || options[:email]
|
123
|
+
post[:URL]=options[:billing_address][:url]
|
124
|
+
post[:Comments]=options[:description]
|
125
|
+
end
|
126
|
+
|
127
|
+
def add_invoice(post, options)
|
128
|
+
post[:invoiceReference] = options[:order_id] || options[:invoice]
|
129
|
+
post[:invoiceDescription] = options[:description]
|
111
130
|
end
|
112
131
|
|
132
|
+
|
113
133
|
# add credit card details to be stored by eway. NOTE eway requires "title" field
|
114
134
|
def add_creditcard(post, creditcard)
|
115
135
|
post[:CCNumber] = creditcard.number
|
@@ -168,6 +188,7 @@ private
|
|
168
188
|
reply[:message]=REXML::XPath.first(node, '//ewayTrxnError').text
|
169
189
|
reply[:success]=(REXML::XPath.first(node, '//ewayTrxnStatus').text == 'True')
|
170
190
|
reply[:auth_code]=REXML::XPath.first(node, '//ewayAuthCode').text
|
191
|
+
reply[:transaction_number]=REXML::XPath.first(node, '//ewayTrxnNumber').text
|
171
192
|
reply
|
172
193
|
end
|
173
194
|
|
@@ -188,7 +209,12 @@ private
|
|
188
209
|
# Where we build the full SOAP 1.2 request using builder
|
189
210
|
def soap_request(arguments, action)
|
190
211
|
# eWay demands all fields be sent, but contain an empty string if blank
|
191
|
-
post=
|
212
|
+
post = case action
|
213
|
+
when 'ProcessPayment'
|
214
|
+
default_payment_fields.merge(arguments)
|
215
|
+
else
|
216
|
+
default_customer_fields.merge(arguments)
|
217
|
+
end
|
192
218
|
|
193
219
|
xml = Builder::XmlMarkup.new :indent => 2
|
194
220
|
xml.instruct!
|
@@ -211,7 +237,7 @@ private
|
|
211
237
|
xml.target!
|
212
238
|
end
|
213
239
|
|
214
|
-
def
|
240
|
+
def default_customer_fields
|
215
241
|
hash={}
|
216
242
|
%w( CustomerRef Title FirstName LastName Company JobDesc Email Address Suburb State PostCode Country Phone Mobile Fax URL Comments CCNumber CCNameOnCard CCExpiryMonth CCExpiryYear ).each do |field|
|
217
243
|
hash[field.to_sym]=''
|
@@ -219,6 +245,14 @@ private
|
|
219
245
|
return hash
|
220
246
|
end
|
221
247
|
|
248
|
+
def default_payment_fields
|
249
|
+
hash={}
|
250
|
+
%w( managedCustomerID amount invoiceReference invoiceDescription ).each do |field|
|
251
|
+
hash[field.to_sym]=''
|
252
|
+
end
|
253
|
+
return hash
|
254
|
+
end
|
255
|
+
|
222
256
|
class EwayResponse < Response
|
223
257
|
# add a method to response so we can easily get the eway token "ManagedCustomerID"
|
224
258
|
def token
|
@@ -68,6 +68,11 @@ module ActiveMerchant #:nodoc:
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def credit(money, authorization, options = {})
|
71
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
72
|
+
refund(money, authorization, options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def refund(money, authorization, options = {})
|
71
76
|
commit(:credit, build_capture_or_credit_request(money, authorization, options))
|
72
77
|
end
|
73
78
|
|
@@ -219,7 +219,7 @@ module ActiveMerchant #:nodoc:
|
|
219
219
|
cert_data = OpenSSL::X509::Certificate.new(cert_file).to_s
|
220
220
|
cert_data = cert_data.sub(/-----BEGIN CERTIFICATE-----/, '')
|
221
221
|
cert_data = cert_data.sub(/-----END CERTIFICATE-----/, '')
|
222
|
-
fingerprint =
|
222
|
+
fingerprint = Base64.decode64(cert_data)
|
223
223
|
fingerprint = Digest::SHA1.hexdigest(fingerprint)
|
224
224
|
return fingerprint.upcase
|
225
225
|
end
|
@@ -227,12 +227,12 @@ module ActiveMerchant #:nodoc:
|
|
227
227
|
def sign_message(private_key_data, password, data)
|
228
228
|
private_key = OpenSSL::PKey::RSA.new(private_key_data, password)
|
229
229
|
signature = private_key.sign(OpenSSL::Digest::SHA1.new, data.gsub('\s', ''))
|
230
|
-
return
|
230
|
+
return Base64.encode64(signature).gsub(/\n/, '')
|
231
231
|
end
|
232
232
|
|
233
233
|
def verify_message(cert_file, data, signature)
|
234
234
|
public_key = OpenSSL::X509::Certificate.new(cert_file).public_key
|
235
|
-
return public_key.verify(OpenSSL::Digest::SHA1.new,
|
235
|
+
return public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), data)
|
236
236
|
end
|
237
237
|
|
238
238
|
def status_response_verified?(response)
|