activemerchant 1.32.0 → 1.33.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 +50 -0
- data/CONTRIBUTORS +8 -0
- data/README.md +6 -4
- data/lib/active_merchant/billing/check.rb +4 -3
- data/lib/active_merchant/billing/credit_card.rb +7 -3
- data/lib/active_merchant/billing/gateways/authorize_net.rb +27 -7
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +8 -1
- data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -185
- data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
- data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +0 -4
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +94 -12
- data/lib/active_merchant/billing/gateways/garanti.rb +0 -4
- data/lib/active_merchant/billing/gateways/litle.rb +41 -11
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +27 -6
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -2
- data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
- data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
- data/lib/active_merchant/billing/gateways/orbital.rb +181 -48
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
- data/lib/active_merchant/billing/gateways/paymill.rb +27 -13
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +11 -6
- data/lib/active_merchant/billing/gateways/paypal_express.rb +25 -7
- data/lib/active_merchant/billing/gateways/pin.rb +5 -5
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +16 -11
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +1 -1
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +21 -16
- data/lib/active_merchant/billing/gateways/sage.rb +10 -5
- data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -4
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
- data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
- data/lib/active_merchant/billing/integrations/dwolla/common.rb +21 -0
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +15 -6
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +11 -6
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +12 -4
- data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
- data/lib/active_merchant/billing/integrations/notification.rb +13 -8
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +13 -1
- data/lib/active_merchant/billing/integrations/payu_in/helper.rb +74 -0
- data/lib/active_merchant/billing/integrations/payu_in/notification.rb +167 -0
- data/lib/active_merchant/billing/integrations/payu_in/return.rb +53 -0
- data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +68 -5
- data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +23 -0
- data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +91 -0
- data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
- data/lib/active_merchant/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +72 -62
- metadata.gz.sig +0 -0
|
@@ -3,21 +3,47 @@ require 'digest/md5'
|
|
|
3
3
|
module ActiveMerchant #:nodoc:
|
|
4
4
|
module Billing #:nodoc:
|
|
5
5
|
class BluePayGateway < Gateway
|
|
6
|
-
class_attribute :
|
|
6
|
+
class_attribute :rebilling_url, :ignore_http_status
|
|
7
7
|
|
|
8
8
|
self.live_url = 'https://secure.bluepay.com/interfaces/bp20post'
|
|
9
9
|
self.rebilling_url = 'https://secure.bluepay.com/interfaces/bp20rebadmin'
|
|
10
10
|
|
|
11
11
|
self.ignore_http_status = true
|
|
12
12
|
|
|
13
|
-
RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3
|
|
14
|
-
AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE = 5, 6, 38
|
|
15
|
-
|
|
16
13
|
CARD_CODE_ERRORS = %w( N S )
|
|
17
14
|
AVS_ERRORS = %w( A E N R W Z )
|
|
18
15
|
AVS_REASON_CODES = %w(27 45)
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
FRAUD_REVIEW_STATUSES = %w( E 0 )
|
|
18
|
+
|
|
19
|
+
FIELD_MAP = {
|
|
20
|
+
'TRANS_ID' => :transaction_id,
|
|
21
|
+
'STATUS' => :response_code,
|
|
22
|
+
'AVS' => :avs_result_code,
|
|
23
|
+
'CVV2'=> :card_code,
|
|
24
|
+
'AUTH_CODE' => :authorization,
|
|
25
|
+
'MESSAGE' => :message,
|
|
26
|
+
'REBID' => :rebid,
|
|
27
|
+
'TRANS_TYPE' => :trans_type,
|
|
28
|
+
'PAYMENT_ACCOUNT_MASK' => :acct_mask,
|
|
29
|
+
'CARD_TYPE' => :card_type,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
REBILL_FIELD_MAP = {
|
|
33
|
+
'REBILL_ID' => :rebill_id,
|
|
34
|
+
'ACCOUNT_ID'=> :account_id,
|
|
35
|
+
'USER_ID' => :user_id,
|
|
36
|
+
'TEMPLATE_ID' => :template_id,
|
|
37
|
+
'STATUS' => :status,
|
|
38
|
+
'CREATION_DATE' => :creation_date,
|
|
39
|
+
'NEXT_DATE' => :next_date,
|
|
40
|
+
'LAST_DATE' => :last_date,
|
|
41
|
+
'SCHED_EXPR' => :schedule,
|
|
42
|
+
'CYCLES_REMAIN' => :cycles_remain,
|
|
43
|
+
'REB_AMOUNT' => :rebill_amount,
|
|
44
|
+
'NEXT_AMOUNT' => :next_amount,
|
|
45
|
+
'USUAL_DATE' => :undoc_usual_date, # Not found in the bp20rebadmin API doc.
|
|
46
|
+
}
|
|
21
47
|
|
|
22
48
|
self.supported_countries = ['US']
|
|
23
49
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
|
|
@@ -25,7 +51,6 @@ module ActiveMerchant #:nodoc:
|
|
|
25
51
|
self.display_name = 'BluePay'
|
|
26
52
|
self.money_format = :dollars
|
|
27
53
|
|
|
28
|
-
|
|
29
54
|
# Creates a new BluepayGateway
|
|
30
55
|
#
|
|
31
56
|
# The gateway requires that a valid Account ID and Secret Key be passed
|
|
@@ -54,24 +79,12 @@ module ActiveMerchant #:nodoc:
|
|
|
54
79
|
# * <tt>options</tt> -- A hash of optional parameters.
|
|
55
80
|
def authorize(money, payment_object, options = {})
|
|
56
81
|
post = {}
|
|
57
|
-
post
|
|
58
|
-
if payment_object != nil && payment_object.class() != String
|
|
59
|
-
payment_object.class() == ActiveMerchant::Billing::Check ?
|
|
60
|
-
add_check(post, payment_object) :
|
|
61
|
-
add_creditcard(post, payment_object)
|
|
62
|
-
else
|
|
63
|
-
post[:MASTER_ID] = payment_object
|
|
64
|
-
end
|
|
82
|
+
add_payment_method(post, payment_object)
|
|
65
83
|
add_invoice(post, options)
|
|
66
84
|
add_address(post, options)
|
|
67
85
|
add_customer_data(post, options)
|
|
68
|
-
if options[:rebill]
|
|
69
|
-
|
|
70
|
-
post[:REB_AMOUNT] = amount(options[:rebill_amount])
|
|
71
|
-
post[:REB_FIRST_DATE] = options[:rebill_start_date]
|
|
72
|
-
post[:REB_EXPR] = options[:rebill_expression]
|
|
73
|
-
post[:REB_CYCLES] = options[:rebill_cycles]
|
|
74
|
-
end
|
|
86
|
+
add_rebill(post, options) if options[:rebill]
|
|
87
|
+
add_duplicate_override(post, options)
|
|
75
88
|
post[:TRANS_TYPE] = 'AUTH'
|
|
76
89
|
commit('AUTH_ONLY', money, post)
|
|
77
90
|
end
|
|
@@ -89,24 +102,12 @@ module ActiveMerchant #:nodoc:
|
|
|
89
102
|
# * <tt>options</tt> -- A hash of optional parameters.,
|
|
90
103
|
def purchase(money, payment_object, options = {})
|
|
91
104
|
post = {}
|
|
92
|
-
post
|
|
93
|
-
if payment_object != nil && payment_object.class() != String
|
|
94
|
-
payment_object.class() == ActiveMerchant::Billing::Check ?
|
|
95
|
-
add_check(post, payment_object) :
|
|
96
|
-
add_creditcard(post, payment_object)
|
|
97
|
-
else
|
|
98
|
-
post[:MASTER_ID] = payment_object
|
|
99
|
-
end
|
|
105
|
+
add_payment_method(post, payment_object)
|
|
100
106
|
add_invoice(post, options)
|
|
101
107
|
add_address(post, options)
|
|
102
108
|
add_customer_data(post, options)
|
|
103
|
-
if options[:rebill]
|
|
104
|
-
|
|
105
|
-
post[:REB_AMOUNT] = amount(options[:rebill_amount])
|
|
106
|
-
post[:REB_FIRST_DATE] = options[:rebill_start_date]
|
|
107
|
-
post[:REB_EXPR] = options[:rebill_expression]
|
|
108
|
-
post[:REB_CYCLES] = options[:rebill_cycles]
|
|
109
|
-
end
|
|
109
|
+
add_rebill(post, options) if options[:rebill]
|
|
110
|
+
add_duplicate_override(post, options)
|
|
110
111
|
post[:TRANS_TYPE] = 'SALE'
|
|
111
112
|
commit('AUTH_CAPTURE', money, post)
|
|
112
113
|
end
|
|
@@ -154,20 +155,17 @@ module ActiveMerchant #:nodoc:
|
|
|
154
155
|
# If the payment_object is a token, then the transaction type will reverse a previous capture or purchase transaction, returning the funds to the customer. If the amount is nil, a full credit will be processed. This is referred to a REFUND transaction in BluePay.
|
|
155
156
|
# If the payment_object is either a CreditCard or Check object, then the transaction type will be an unmatched credit placing funds in the specified account. This is referred to a CREDIT transaction in BluePay.
|
|
156
157
|
# * <tt>options</tt> -- A hash of parameters.
|
|
157
|
-
def refund(money,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
payment_object.class() == ActiveMerchant::Billing::Check ?
|
|
162
|
-
add_check(post, payment_object) :
|
|
163
|
-
add_creditcard(post, payment_object)
|
|
164
|
-
post[:TRANS_TYPE] = 'CREDIT'
|
|
165
|
-
else
|
|
166
|
-
post[:MASTER_ID] = payment_object
|
|
167
|
-
post[:TRANS_TYPE] = 'REFUND'
|
|
158
|
+
def refund(money, identification, options = {})
|
|
159
|
+
if(identification && !identification.kind_of?(String))
|
|
160
|
+
deprecated "refund should only be used to refund a referenced transaction"
|
|
161
|
+
return credit(money, identification, options)
|
|
168
162
|
end
|
|
169
163
|
|
|
170
|
-
|
|
164
|
+
post = {}
|
|
165
|
+
post[:PAYMENT_ACCOUNT] = ''
|
|
166
|
+
post[:MASTER_ID] = identification
|
|
167
|
+
post[:TRANS_TYPE] = 'REFUND'
|
|
168
|
+
post[:NAME1] = (options[:first_name] ? options[:first_name] : "")
|
|
171
169
|
post[:NAME2] = options[:last_name] if options[:last_name]
|
|
172
170
|
post[:ZIP] = options[:zip] if options[:zip]
|
|
173
171
|
add_invoice(post, options)
|
|
@@ -176,9 +174,24 @@ module ActiveMerchant #:nodoc:
|
|
|
176
174
|
commit('CREDIT', money, post)
|
|
177
175
|
end
|
|
178
176
|
|
|
179
|
-
def credit(money,
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
def credit(money, payment_object, options = {})
|
|
178
|
+
if(payment_object && payment_object.kind_of?(String))
|
|
179
|
+
deprecated "credit should only be used to credit a payment method"
|
|
180
|
+
return refund(money, payment_object, options)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
post = {}
|
|
184
|
+
post[:PAYMENT_ACCOUNT] = ''
|
|
185
|
+
add_payment_method(post, payment_object)
|
|
186
|
+
post[:TRANS_TYPE] = 'CREDIT'
|
|
187
|
+
|
|
188
|
+
post[:NAME1] = (options[:first_name] ? options[:first_name] : "")
|
|
189
|
+
post[:NAME2] = options[:last_name] if options[:last_name]
|
|
190
|
+
post[:ZIP] = options[:zip] if options[:zip]
|
|
191
|
+
add_invoice(post, options)
|
|
192
|
+
add_address(post, options)
|
|
193
|
+
add_customer_data(post, options)
|
|
194
|
+
commit('CREDIT', money, post)
|
|
182
195
|
end
|
|
183
196
|
|
|
184
197
|
# Create a new recurring payment.
|
|
@@ -214,9 +227,12 @@ module ActiveMerchant #:nodoc:
|
|
|
214
227
|
# A money object of 1995 cents would be passed into the 'money' parameter.
|
|
215
228
|
def recurring(money, payment_object, options = {})
|
|
216
229
|
requires!(options, :rebill_start_date, :rebill_expression)
|
|
217
|
-
options[:rebill] =
|
|
218
|
-
|
|
219
|
-
|
|
230
|
+
options[:rebill] = true
|
|
231
|
+
if money
|
|
232
|
+
purchase(money, payment_object, options)
|
|
233
|
+
else
|
|
234
|
+
authorize(money, payment_object, options)
|
|
235
|
+
end
|
|
220
236
|
end
|
|
221
237
|
|
|
222
238
|
# View a recurring payment
|
|
@@ -252,11 +268,11 @@ module ActiveMerchant #:nodoc:
|
|
|
252
268
|
requires!(options, :rebill_id)
|
|
253
269
|
post[:REBILL_ID] = options[:rebill_id]
|
|
254
270
|
post[:TRANS_TYPE] = 'SET'
|
|
255
|
-
post[:REB_AMOUNT] = amount(options[:rebill_amount]) if
|
|
256
|
-
post[:NEXT_DATE] = options[:rebill_next_date]
|
|
257
|
-
post[:REB_EXPR] = options[:rebill_expression]
|
|
258
|
-
post[:REB_CYCLES] = options[:rebill_cycles]
|
|
259
|
-
post[:NEXT_AMOUNT] = options[:rebill_next_amount]
|
|
271
|
+
post[:REB_AMOUNT] = amount(options[:rebill_amount]) if options[:rebill_amount]
|
|
272
|
+
post[:NEXT_DATE] = options[:rebill_next_date]
|
|
273
|
+
post[:REB_EXPR] = options[:rebill_expression]
|
|
274
|
+
post[:REB_CYCLES] = options[:rebill_cycles]
|
|
275
|
+
post[:NEXT_AMOUNT] = options[:rebill_next_amount]
|
|
260
276
|
commit('rebill', 'nil', post)
|
|
261
277
|
end
|
|
262
278
|
|
|
@@ -279,117 +295,133 @@ module ActiveMerchant #:nodoc:
|
|
|
279
295
|
private
|
|
280
296
|
|
|
281
297
|
def commit(action, money, fields)
|
|
282
|
-
fields[:AMOUNT] = amount(money) unless
|
|
283
|
-
|
|
284
|
-
action == 'rebill' ? begin url = rebilling_url; fields[:TAMPER_PROOF_SEAL] = calc_rebill_tps(fields) end : begin url = live_url; fields[:TAMPER_PROOF_SEAL] = calc_tps(amount(money), fields) end
|
|
298
|
+
fields[:AMOUNT] = amount(money) unless(fields[:TRANS_TYPE] == 'VOID' || action == 'rebill')
|
|
299
|
+
fields[:MODE] = (test? ? 'TEST' : 'LIVE')
|
|
285
300
|
fields[:ACCOUNT_ID] = @options[:login]
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (response.has_key?('TRANS_ID'))
|
|
291
|
-
response_id = response['TRANS_ID'].to_s()
|
|
292
|
-
elsif (response.has_key?('rebill_id'))
|
|
293
|
-
response_id = response['rebill_id'][0]
|
|
301
|
+
|
|
302
|
+
if action == 'rebill'
|
|
303
|
+
url = rebilling_url
|
|
304
|
+
fields[:TAMPER_PROOF_SEAL] = calc_rebill_tps(fields)
|
|
294
305
|
else
|
|
295
|
-
|
|
306
|
+
url = live_url
|
|
307
|
+
fields[:TAMPER_PROOF_SEAL] = calc_tps(amount(money), fields)
|
|
296
308
|
end
|
|
297
|
-
|
|
298
|
-
cvv2 = (!response[CARD_CODE_RESPONSE_CODE].empty? ? response[CARD_CODE_RESPONSE_CODE] : '')
|
|
299
|
-
Response.new(success?(response), message, response,
|
|
300
|
-
:test => test_mode,
|
|
301
|
-
:authorization => response_id,
|
|
302
|
-
:fraud_review => fraud_review?(response),
|
|
303
|
-
:avs_result => { :code => avs },
|
|
304
|
-
:cvv_result => cvv2
|
|
305
|
-
)
|
|
309
|
+
parse(ssl_post(url, post_data(action, fields)))
|
|
306
310
|
end
|
|
307
311
|
|
|
308
|
-
def
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
312
|
+
def parse_recurring(response_fields, opts={}) # expected status?
|
|
313
|
+
parsed = {}
|
|
314
|
+
response_fields.each do |k,v|
|
|
315
|
+
mapped_key = REBILL_FIELD_MAP.include?(k) ? REBILL_FIELD_MAP[k] : k
|
|
316
|
+
parsed[mapped_key] = v
|
|
313
317
|
end
|
|
314
|
-
end
|
|
315
318
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
end
|
|
319
|
+
success = parsed[:status] != 'error'
|
|
320
|
+
message = parsed[:status]
|
|
319
321
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
+
Response.new(success, message, parsed,
|
|
323
|
+
:test => test?,
|
|
324
|
+
:authorization => parsed[:rebill_id])
|
|
322
325
|
end
|
|
323
326
|
|
|
324
327
|
def parse(body)
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
fields.has_key?('MASTER_ID') ? begin trans_id = fields['MASTER_ID']; fields.delete('MASTER_ID') end : trans_id = ''
|
|
337
|
-
fields[:avs_result_code] = avs
|
|
338
|
-
fields[:card_code] = cvv2
|
|
339
|
-
fields[:response_code] = status
|
|
340
|
-
fields[:response_reason_code] = ''
|
|
341
|
-
fields[:response_reason_text] = message
|
|
342
|
-
fields[:transaction_id] = trans_id
|
|
343
|
-
return fields
|
|
328
|
+
# The bp20api has max one value per form field.
|
|
329
|
+
response_fields = Hash[CGI::parse(body).map{|k,v| [k.upcase,v.first]}]
|
|
330
|
+
|
|
331
|
+
if response_fields.include? "REBILL_ID"
|
|
332
|
+
return parse_recurring(response_fields)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
parsed = {}
|
|
336
|
+
response_fields.each do |k,v|
|
|
337
|
+
mapped_key = FIELD_MAP.include?(k) ? FIELD_MAP[k] : k
|
|
338
|
+
parsed[mapped_key] = v
|
|
344
339
|
end
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
340
|
+
|
|
341
|
+
# normalize message
|
|
342
|
+
message = message_from(parsed)
|
|
343
|
+
success = parsed[:response_code] == '1'
|
|
344
|
+
Response.new(success, message, parsed,
|
|
345
|
+
:test => test?,
|
|
346
|
+
:authorization => (parsed[:rebid] && parsed[:rebid] != '' ? parsed[:rebid] : parsed[:transaction_id]),
|
|
347
|
+
:fraud_review => FRAUD_REVIEW_STATUSES.include?(parsed[:response_code]),
|
|
348
|
+
:avs_result => { :code => parsed[:avs_result_code] },
|
|
349
|
+
:cvv_result => parsed[:card_code]
|
|
350
|
+
)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def message_from(parsed)
|
|
354
|
+
message = parsed[:message]
|
|
355
|
+
if(parsed[:response_code].to_i == 2)
|
|
356
|
+
if CARD_CODE_ERRORS.include?(parsed[:card_code])
|
|
357
|
+
message = CVVResult.messages[parsed[:card_code]]
|
|
358
|
+
elsif AVS_ERRORS.include?(parsed[:avs_result_code])
|
|
359
|
+
message = AVSResult.messages[ parsed[:avs_result_code] ]
|
|
360
|
+
else
|
|
361
|
+
message = message.chomp('.')
|
|
362
|
+
end
|
|
363
|
+
elsif message == "Missing ACCOUNT_ID"
|
|
364
|
+
message = "The merchant login ID or password is invalid"
|
|
365
|
+
elsif message =~ /Approved/
|
|
366
|
+
message = "This transaction has been approved"
|
|
367
|
+
elsif message =~ /Expired/
|
|
368
|
+
message = "The credit card has expired"
|
|
350
369
|
end
|
|
351
|
-
|
|
370
|
+
message
|
|
352
371
|
end
|
|
353
372
|
|
|
354
373
|
def add_invoice(post, options)
|
|
355
|
-
post[:ORDER_ID] = options[:order_id]
|
|
356
|
-
post[:INVOICE_ID] = options[:invoice]
|
|
357
|
-
post[:invoice_num] = options[:order_id]
|
|
358
|
-
post[:MEMO] = options[:description]
|
|
359
|
-
post[:description] = options[:description]
|
|
374
|
+
post[:ORDER_ID] = options[:order_id]
|
|
375
|
+
post[:INVOICE_ID] = options[:invoice]
|
|
376
|
+
post[:invoice_num] = options[:order_id]
|
|
377
|
+
post[:MEMO] = options[:description]
|
|
378
|
+
post[:description] = options[:description]
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def add_payment_method(post, payment_object)
|
|
382
|
+
post[:MASTER_ID] = ''
|
|
383
|
+
case payment_object
|
|
384
|
+
when String
|
|
385
|
+
post[:MASTER_ID] = payment_object
|
|
386
|
+
when Check
|
|
387
|
+
add_check(post, payment_object)
|
|
388
|
+
else
|
|
389
|
+
add_creditcard(post, payment_object)
|
|
390
|
+
end
|
|
360
391
|
end
|
|
361
392
|
|
|
362
393
|
def add_creditcard(post, creditcard)
|
|
363
394
|
post[:PAYMENT_TYPE] = 'CREDIT'
|
|
364
395
|
post[:PAYMENT_ACCOUNT] = creditcard.number
|
|
365
|
-
post[:CARD_CVV2] = creditcard.verification_value
|
|
366
|
-
creditcard.verification_value?
|
|
396
|
+
post[:CARD_CVV2] = creditcard.verification_value
|
|
367
397
|
post[:CARD_EXPIRE] = expdate(creditcard)
|
|
368
398
|
post[:NAME1] = creditcard.first_name
|
|
369
399
|
post[:NAME2] = creditcard.last_name
|
|
370
400
|
end
|
|
371
401
|
|
|
402
|
+
CHECK_ACCOUNT_TYPES = {
|
|
403
|
+
"checking" => "C",
|
|
404
|
+
"savings" => "S"
|
|
405
|
+
}
|
|
406
|
+
|
|
372
407
|
def add_check(post, check)
|
|
373
408
|
post[:PAYMENT_TYPE] = 'ACH'
|
|
374
|
-
post[:PAYMENT_ACCOUNT] = check.account_type
|
|
409
|
+
post[:PAYMENT_ACCOUNT] = [CHECK_ACCOUNT_TYPES[check.account_type], check.routing_number, check.account_number].join(":")
|
|
375
410
|
post[:NAME1] = check.first_name
|
|
376
411
|
post[:NAME2] = check.last_name
|
|
377
412
|
end
|
|
378
413
|
|
|
379
414
|
def add_customer_data(post, options)
|
|
380
|
-
post[:EMAIL] = options[:email]
|
|
381
|
-
post[:CUSTOM_ID] = options[:customer]
|
|
415
|
+
post[:EMAIL] = options[:email]
|
|
416
|
+
post[:CUSTOM_ID] = options[:customer]
|
|
382
417
|
end
|
|
383
418
|
|
|
384
|
-
def
|
|
385
|
-
|
|
386
|
-
post[:duplicate_window] = duplicate_window
|
|
387
|
-
post[:DUPLICATE_OVERRIDE] = duplicate_window
|
|
388
|
-
end
|
|
419
|
+
def add_duplicate_override(post, options)
|
|
420
|
+
post[:DUPLICATE_OVERRIDE] = options[:duplicate_override]
|
|
389
421
|
end
|
|
390
422
|
|
|
391
423
|
def add_address(post, options)
|
|
392
|
-
if address = options[:billing_address] || options[:address]
|
|
424
|
+
if address = (options[:shipping_address] || options[:billing_address] || options[:address])
|
|
393
425
|
post[:NAME1] = address[:first_name]
|
|
394
426
|
post[:NAME2] = address[:last_name]
|
|
395
427
|
post[:ADDR1] = address[:address1]
|
|
@@ -397,27 +429,23 @@ module ActiveMerchant #:nodoc:
|
|
|
397
429
|
post[:COMPANY_NAME] = address[:company]
|
|
398
430
|
post[:PHONE] = address[:phone]
|
|
399
431
|
post[:CITY] = address[:city]
|
|
400
|
-
post[:STATE] = address[:state].blank?
|
|
432
|
+
post[:STATE] = (address[:state].blank? ? 'n/a' : address[:state])
|
|
401
433
|
post[:ZIP] = address[:zip]
|
|
402
434
|
post[:COUNTRY] = address[:country]
|
|
403
435
|
end
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
post[:CITY] = address[:city]
|
|
413
|
-
post[:COUNTRY] = address[:country]
|
|
414
|
-
post[:STATE] = address[:state].blank? ? 'n/a' : address[:state]
|
|
415
|
-
end
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
def add_rebill(post, options)
|
|
439
|
+
post[:DO_REBILL] = '1'
|
|
440
|
+
post[:REB_AMOUNT] = amount(options[:rebill_amount])
|
|
441
|
+
post[:REB_FIRST_DATE] = options[:rebill_start_date]
|
|
442
|
+
post[:REB_EXPR] = options[:rebill_expression]
|
|
443
|
+
post[:REB_CYCLES] = options[:rebill_cycles]
|
|
416
444
|
end
|
|
417
445
|
|
|
418
446
|
def post_data(action, parameters = {})
|
|
419
447
|
post = {}
|
|
420
|
-
post[:version] = '
|
|
448
|
+
post[:version] = '1'
|
|
421
449
|
post[:login] = ''
|
|
422
450
|
post[:tran_key] = ''
|
|
423
451
|
post[:relay_response] = "FALSE"
|
|
@@ -427,60 +455,48 @@ module ActiveMerchant #:nodoc:
|
|
|
427
455
|
post[:encap_char] = "$"
|
|
428
456
|
post[:card_num] = '4111111111111111'
|
|
429
457
|
post[:exp_date] = '1212'
|
|
430
|
-
post[:solution_ID] = application_id if
|
|
431
|
-
|
|
432
|
-
request
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
def message_from(results)
|
|
436
|
-
if results[:response_code] == 2
|
|
437
|
-
return CVVResult.messages[ results[:card_code] ] if CARD_CODE_ERRORS.include?(results[:card_code])
|
|
438
|
-
if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code])
|
|
439
|
-
return AVSResult.messages[ results[:avs_result_code] ]
|
|
440
|
-
end
|
|
441
|
-
return (results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '')
|
|
442
|
-
end
|
|
443
|
-
if results.has_key?(:response_reason_text)
|
|
444
|
-
return results[:response_reason_text].to_s()
|
|
445
|
-
end
|
|
446
|
-
if !results.has_key?('STATUS')
|
|
447
|
-
return results[RESPONSE_REASON_TEXT] ? results[RESPONSE_REASON_TEXT].chomp('.') : ''
|
|
448
|
-
end
|
|
458
|
+
post[:solution_ID] = application_id if(application_id && application_id != "ActiveMerchant")
|
|
459
|
+
post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
|
449
460
|
end
|
|
450
461
|
|
|
451
462
|
def expdate(creditcard)
|
|
452
|
-
year =
|
|
453
|
-
month =
|
|
463
|
+
year = format(creditcard.year, :two_digits)
|
|
464
|
+
month = format(creditcard.month, :two_digits)
|
|
454
465
|
|
|
455
|
-
"#{month}#{year
|
|
466
|
+
"#{month}#{year}"
|
|
456
467
|
end
|
|
457
468
|
|
|
458
469
|
def calc_tps(amount, post)
|
|
459
|
-
post[:NAME1]
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
470
|
+
post[:NAME1] ||= ''
|
|
471
|
+
Digest::MD5.hexdigest(
|
|
472
|
+
[
|
|
473
|
+
@options[:password],
|
|
474
|
+
@options[:login],
|
|
475
|
+
post[:TRANS_TYPE],
|
|
476
|
+
amount,
|
|
477
|
+
post[:MASTER_ID],
|
|
478
|
+
post[:NAME1],
|
|
479
|
+
post[:PAYMENT_ACCOUNT]
|
|
480
|
+
].join("")
|
|
481
|
+
)
|
|
465
482
|
end
|
|
466
483
|
|
|
467
484
|
def calc_rebill_tps(post)
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
485
|
+
Digest::MD5.hexdigest(
|
|
486
|
+
[
|
|
487
|
+
@options[:password],
|
|
488
|
+
@options[:login],
|
|
489
|
+
post[:TRANS_TYPE],
|
|
490
|
+
post[:REBILL_ID]
|
|
491
|
+
].join("")
|
|
492
|
+
)
|
|
471
493
|
end
|
|
472
494
|
|
|
473
495
|
def handle_response(response)
|
|
474
|
-
if ignore_http_status
|
|
496
|
+
if ignore_http_status || (200...300).include?(response.code.to_i)
|
|
475
497
|
return response.body
|
|
476
|
-
else
|
|
477
|
-
case response.code.to_i
|
|
478
|
-
when 200...300
|
|
479
|
-
response.body
|
|
480
|
-
else
|
|
481
|
-
raise ResponseError.new(response)
|
|
482
|
-
end
|
|
483
498
|
end
|
|
499
|
+
raise ResponseError.new(response)
|
|
484
500
|
end
|
|
485
501
|
end
|
|
486
502
|
end
|
|
@@ -34,7 +34,7 @@ module ActiveMerchant #:nodoc:
|
|
|
34
34
|
money = amount(money)
|
|
35
35
|
case normalize(credit_card_or_reference)
|
|
36
36
|
when /1$/, AUTHORIZATION
|
|
37
|
-
Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
|
|
37
|
+
Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true, :authorization => AUTHORIZATION)
|
|
38
38
|
when /2$/
|
|
39
39
|
Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE },:test => true)
|
|
40
40
|
else
|