activemerchant 1.44.1 → 1.45.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 +4 -4
- checksums.yaml.gz.sig +1 -3
- data.tar.gz.sig +0 -0
- data/CHANGELOG +48 -0
- data/CONTRIBUTORS +12 -0
- data/README.md +15 -5
- data/lib/active_merchant/billing.rb +2 -0
- data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
- data/lib/active_merchant/billing/gateway.rb +36 -4
- data/lib/active_merchant/billing/gateways/adyen.rb +6 -2
- data/lib/active_merchant/billing/gateways/authorize_net.rb +332 -255
- data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +9 -9
- data/lib/active_merchant/billing/gateways/borgun.rb +0 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +8 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +17 -10
- data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +1 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +1 -1
- data/lib/active_merchant/billing/gateways/elavon.rb +3 -3
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +114 -13
- data/lib/active_merchant/billing/gateways/finansbank.rb +1 -1
- data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
- data/lib/active_merchant/billing/gateways/hps.rb +27 -20
- data/lib/active_merchant/billing/gateways/iats_payments.rb +68 -35
- data/lib/active_merchant/billing/gateways/litle.rb +36 -1
- data/lib/active_merchant/billing/gateways/merchant_one.rb +0 -1
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +8 -4
- data/lib/active_merchant/billing/gateways/mercury.rb +17 -10
- data/lib/active_merchant/billing/gateways/moneris.rb +11 -6
- data/lib/active_merchant/billing/gateways/moneris_us.rb +126 -33
- data/lib/active_merchant/billing/gateways/money_movers.rb +0 -1
- data/lib/active_merchant/billing/gateways/net_registry.rb +6 -1
- data/lib/active_merchant/billing/gateways/network_merchants.rb +5 -5
- data/lib/active_merchant/billing/gateways/nmi.rb +241 -5
- data/lib/active_merchant/billing/gateways/openpay.rb +1 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +6 -4
- data/lib/active_merchant/billing/gateways/pay_junction.rb +9 -5
- data/lib/active_merchant/billing/gateways/payex.rb +19 -9
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +2 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
- data/lib/active_merchant/billing/gateways/payscout.rb +0 -2
- data/lib/active_merchant/billing/gateways/pin.rb +1 -1
- data/lib/active_merchant/billing/gateways/psigate.rb +1 -2
- data/lib/active_merchant/billing/gateways/redsys.rb +37 -40
- data/lib/active_merchant/billing/gateways/secure_pay.rb +181 -9
- data/lib/active_merchant/billing/gateways/stripe.rb +106 -31
- data/lib/active_merchant/billing/gateways/tns.rb +227 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +38 -10
- data/lib/active_merchant/billing/gateways/webpay.rb +14 -0
- data/lib/active_merchant/billing/payment_token.rb +21 -0
- data/lib/active_merchant/billing/response.rb +2 -1
- data/lib/active_merchant/country.rb +6 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +8 -3
- metadata.gz.sig +0 -0
- data/lib/active_merchant/billing/gateways/samurai.rb +0 -130
@@ -18,10 +18,22 @@ module ActiveMerchant #:nodoc:
|
|
18
18
|
self.homepage_url = 'http://www.monerisusa.com/'
|
19
19
|
self.display_name = 'Moneris (US)'
|
20
20
|
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# Initialize the Gateway
|
22
|
+
#
|
23
|
+
# The gateway requires that a valid login and password be passed
|
24
|
+
# in the +options+ hash.
|
25
|
+
#
|
26
|
+
# ==== Options
|
27
|
+
#
|
28
|
+
# * <tt>:login</tt> -- Your Store ID
|
29
|
+
# * <tt>:password</tt> -- Your API Token
|
30
|
+
# * <tt>:cvv_enabled</tt> -- Specify that you would like the CVV passed to the gateway.
|
31
|
+
# Only particular account types at Moneris will allow this.
|
32
|
+
# Defaults to false. (optional)
|
23
33
|
def initialize(options = {})
|
24
34
|
requires!(options, :login, :password)
|
35
|
+
@cvv_enabled = options[:cvv_enabled]
|
36
|
+
@avs_enabled = options[:avs_enabled]
|
25
37
|
options = { :crypt_type => 7 }.merge(options)
|
26
38
|
super
|
27
39
|
end
|
@@ -31,16 +43,32 @@ module ActiveMerchant #:nodoc:
|
|
31
43
|
# captured at a later date.
|
32
44
|
#
|
33
45
|
# Pass in +order_id+ and optionally a +customer+ parameter.
|
34
|
-
def authorize(money,
|
35
|
-
|
46
|
+
def authorize(money, creditcard_or_datakey, options = {})
|
47
|
+
requires!(options, :order_id)
|
48
|
+
post = {}
|
49
|
+
add_payment_source(post, creditcard_or_datakey, options)
|
50
|
+
post[:amount] = amount(money)
|
51
|
+
post[:order_id] = options[:order_id]
|
52
|
+
post[:address] = options[:billing_address] || options[:address]
|
53
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
54
|
+
action = (post[:data_key].blank?) ? 'us_preauth' : 'us_res_preauth_cc'
|
55
|
+
commit(action, post)
|
36
56
|
end
|
37
57
|
|
38
|
-
# This action verifies funding on a customer's card
|
58
|
+
# This action verifies funding on a customer's card and readies them for
|
39
59
|
# deposit in a merchant's account.
|
40
60
|
#
|
41
61
|
# Pass in <tt>order_id</tt> and optionally a <tt>customer</tt> parameter
|
42
|
-
def purchase(money,
|
43
|
-
|
62
|
+
def purchase(money, creditcard_or_datakey, options = {})
|
63
|
+
requires!(options, :order_id)
|
64
|
+
post = {}
|
65
|
+
add_payment_source(post, creditcard_or_datakey, options)
|
66
|
+
post[:amount] = amount(money)
|
67
|
+
post[:order_id] = options[:order_id]
|
68
|
+
post[:address] = options[:billing_address] || options[:address]
|
69
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
70
|
+
action = (post[:data_key].blank?) ? 'us_purchase' : 'us_res_purchase_cc'
|
71
|
+
commit(action, post)
|
44
72
|
end
|
45
73
|
|
46
74
|
# This method retrieves locked funds from a customer's account (from a
|
@@ -79,27 +107,45 @@ module ActiveMerchant #:nodoc:
|
|
79
107
|
commit 'us_refund', crediting_params(authorization, :amount => amount(money))
|
80
108
|
end
|
81
109
|
|
110
|
+
def store(credit_card, options = {})
|
111
|
+
post = {}
|
112
|
+
post[:pan] = credit_card.number
|
113
|
+
post[:expdate] = expdate(credit_card)
|
114
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
115
|
+
commit('us_res_add_cc', post)
|
116
|
+
end
|
117
|
+
|
118
|
+
def unstore(data_key, options = {})
|
119
|
+
post = {}
|
120
|
+
post[:data_key] = data_key
|
121
|
+
commit('us_res_delete', post)
|
122
|
+
end
|
123
|
+
|
124
|
+
def update(data_key, credit_card, options = {})
|
125
|
+
post = {}
|
126
|
+
post[:pan] = credit_card.number
|
127
|
+
post[:expdate] = expdate(credit_card)
|
128
|
+
post[:data_key] = data_key
|
129
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
130
|
+
commit('us_res_update_cc', post)
|
131
|
+
end
|
132
|
+
|
82
133
|
private # :nodoc: all
|
83
134
|
|
84
135
|
def expdate(creditcard)
|
85
136
|
sprintf("%.4i", creditcard.year)[-2..-1] + sprintf("%.2i", creditcard.month)
|
86
137
|
end
|
87
138
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
:
|
97
|
-
|
98
|
-
:amount => amount(money),
|
99
|
-
:pan => creditcard.number,
|
100
|
-
:expdate => expdate(creditcard),
|
101
|
-
:crypt_type => options[:crypt_type] || @options[:crypt_type]
|
102
|
-
}
|
139
|
+
def add_payment_source(post, source, options)
|
140
|
+
if source.is_a?(String)
|
141
|
+
post[:data_key] = source
|
142
|
+
post[:cust_id] = options[:customer]
|
143
|
+
else
|
144
|
+
post[:pan] = source.number
|
145
|
+
post[:expdate] = expdate(source)
|
146
|
+
post[:cvd_value] = source.verification_value if source.verification_value?
|
147
|
+
post[:cust_id] = options[:customer] || source.name
|
148
|
+
end
|
103
149
|
end
|
104
150
|
|
105
151
|
# Common params used amongst the +credit+, +void+ and +capture+ methods
|
@@ -122,10 +168,15 @@ module ActiveMerchant #:nodoc:
|
|
122
168
|
end
|
123
169
|
|
124
170
|
def commit(action, parameters = {})
|
125
|
-
|
171
|
+
data = post_data(action, parameters)
|
172
|
+
url = test? ? self.test_url : self.live_url
|
173
|
+
raw = ssl_post(url, data)
|
174
|
+
response = parse(raw)
|
126
175
|
|
127
176
|
Response.new(successful?(response), message_from(response[:message]), response,
|
128
177
|
:test => test?,
|
178
|
+
:avs_result => { :code => response[:avs_result_code] },
|
179
|
+
:cvv_result => response[:cvd_result_code] && response[:cvd_result_code][-1,1],
|
129
180
|
:authorization => authorization_from(response)
|
130
181
|
)
|
131
182
|
end
|
@@ -163,14 +214,49 @@ module ActiveMerchant #:nodoc:
|
|
163
214
|
root = xml.add_element("request")
|
164
215
|
root.add_element("store_id").text = options[:login]
|
165
216
|
root.add_element("api_token").text = options[:password]
|
166
|
-
|
217
|
+
root.add_element(transaction_element(action, parameters))
|
218
|
+
|
219
|
+
xml.to_s
|
220
|
+
end
|
221
|
+
|
222
|
+
def transaction_element(action, parameters)
|
223
|
+
transaction = REXML::Element.new(action)
|
167
224
|
|
168
225
|
# Must add the elements in the correct order
|
169
226
|
actions[action].each do |key|
|
170
|
-
|
227
|
+
case key
|
228
|
+
when :avs_info
|
229
|
+
transaction.add_element(avs_element(parameters[:address])) if @avs_enabled && parameters[:address]
|
230
|
+
when :cvd_info
|
231
|
+
transaction.add_element(cvd_element(parameters[:cvd_value])) if @cvv_enabled
|
232
|
+
else
|
233
|
+
transaction.add_element(key.to_s).text = parameters[key] unless parameters[key].blank?
|
234
|
+
end
|
171
235
|
end
|
172
236
|
|
173
|
-
|
237
|
+
transaction
|
238
|
+
end
|
239
|
+
|
240
|
+
def avs_element(address)
|
241
|
+
full_address = "#{address[:address1]} #{address[:address2]}"
|
242
|
+
tokens = full_address.split(/\s+/)
|
243
|
+
|
244
|
+
element = REXML::Element.new('avs_info')
|
245
|
+
element.add_element('avs_street_number').text = tokens.select{|x| x =~ /\d/}.join(' ')
|
246
|
+
element.add_element('avs_street_name').text = tokens.reject{|x| x =~ /\d/}.join(' ')
|
247
|
+
element.add_element('avs_zipcode').text = address[:zip]
|
248
|
+
element
|
249
|
+
end
|
250
|
+
|
251
|
+
def cvd_element(cvd_value)
|
252
|
+
element = REXML::Element.new('cvd_info')
|
253
|
+
if cvd_value
|
254
|
+
element.add_element('cvd_indicator').text = "1"
|
255
|
+
element.add_element('cvd_value').text = cvd_value
|
256
|
+
else
|
257
|
+
element.add_element('cvd_indicator').text = "0"
|
258
|
+
end
|
259
|
+
element
|
174
260
|
end
|
175
261
|
|
176
262
|
def message_from(message)
|
@@ -180,17 +266,24 @@ module ActiveMerchant #:nodoc:
|
|
180
266
|
|
181
267
|
def actions
|
182
268
|
{
|
183
|
-
"us_purchase" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
184
|
-
"us_preauth" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
269
|
+
"us_purchase" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info],
|
270
|
+
"us_preauth" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info],
|
271
|
+
"us_command" => [:order_id],
|
185
272
|
"us_refund" => [:order_id, :amount, :txn_number, :crypt_type],
|
186
|
-
"
|
273
|
+
"us_indrefund" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
187
274
|
"us_completion" => [:order_id, :comp_amount, :txn_number, :crypt_type],
|
188
275
|
"us_purchasecorrection" => [:order_id, :txn_number, :crypt_type],
|
189
|
-
"
|
190
|
-
"
|
191
|
-
"
|
276
|
+
"us_cavvpurcha" => [:order_id, :cust_id, :amount, :pan, :expdate, :cav],
|
277
|
+
"us_cavvpreaut" => [:order_id, :cust_id, :amount, :pan, :expdate, :cavv],
|
278
|
+
"us_transact" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
279
|
+
"us_Batchcloseall" => [],
|
192
280
|
"us_opentotals" => [:ecr_number],
|
193
|
-
"us_batchclose" => [:ecr_number]
|
281
|
+
"us_batchclose" => [:ecr_number],
|
282
|
+
"us_res_add_cc" => [:pan, :expdate, :crypt_type],
|
283
|
+
"us_res_delete" => [:data_key],
|
284
|
+
"us_res_update_cc" => [:data_key, :pan, :expdate, :crypt_type],
|
285
|
+
"us_res_purchase_cc" => [:data_key, :order_id, :cust_id, :amount, :crypt_type],
|
286
|
+
"us_res_preauth_cc" => [:data_key, :order_id, :cust_id, :amount, :crypt_type]
|
194
287
|
}
|
195
288
|
end
|
196
289
|
end
|
@@ -9,7 +9,6 @@ module ActiveMerchant #:nodoc:
|
|
9
9
|
self.display_name = 'MoneyMovers'
|
10
10
|
self.supported_countries = ['US']
|
11
11
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
12
|
-
self.ssl_version = :SSLv3
|
13
12
|
|
14
13
|
def initialize(options = {})
|
15
14
|
requires!(options, :login, :password)
|
@@ -151,7 +151,12 @@ module ActiveMerchant
|
|
151
151
|
def post_data(action, params)
|
152
152
|
params['COMMAND'] = TRANSACTIONS[action]
|
153
153
|
params['LOGIN'] = "#{@options[:login]}/#{@options[:password]}"
|
154
|
-
|
154
|
+
escape_uri(params.map{|k,v| "#{k}=#{v}"}.join('&'))
|
155
|
+
end
|
156
|
+
|
157
|
+
# The upstream is picky and so we can't use CGI.escape like we want to
|
158
|
+
def escape_uri(uri)
|
159
|
+
URI::DEFAULT_PARSER.escape(uri)
|
155
160
|
end
|
156
161
|
|
157
162
|
def parse(response)
|
@@ -60,7 +60,7 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
add_address(post, options)
|
61
61
|
add_shipping_address(post, options)
|
62
62
|
add_payment_method(post, creditcard_or_vault_id, options)
|
63
|
-
add_amount(post, money)
|
63
|
+
add_amount(post, money, options)
|
64
64
|
post
|
65
65
|
end
|
66
66
|
|
@@ -68,10 +68,10 @@ module ActiveMerchant #:nodoc:
|
|
68
68
|
build_auth_post(money, creditcard, options)
|
69
69
|
end
|
70
70
|
|
71
|
-
def build_capture_post(money, authorization,
|
71
|
+
def build_capture_post(money, authorization, options)
|
72
72
|
post = {}
|
73
73
|
post[:transactionid] = authorization
|
74
|
-
add_amount(post, money)
|
74
|
+
add_amount(post, money, options)
|
75
75
|
post
|
76
76
|
end
|
77
77
|
|
@@ -84,7 +84,7 @@ module ActiveMerchant #:nodoc:
|
|
84
84
|
def build_refund_post(money, authorization, options)
|
85
85
|
post = {}
|
86
86
|
post[:transactionid] = authorization
|
87
|
-
add_amount(post, money)
|
87
|
+
add_amount(post, money, options)
|
88
88
|
post
|
89
89
|
end
|
90
90
|
|
@@ -184,7 +184,7 @@ module ActiveMerchant #:nodoc:
|
|
184
184
|
post[:password] = @options[:password]
|
185
185
|
end
|
186
186
|
|
187
|
-
def add_amount(post, money)
|
187
|
+
def add_amount(post, money, options)
|
188
188
|
post[:currency] = options[:currency] || currency(money)
|
189
189
|
post[:amount] = amount(money)
|
190
190
|
end
|
@@ -1,20 +1,256 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
|
-
class NmiGateway <
|
3
|
+
class NmiGateway < Gateway
|
4
|
+
API_VERSION = '3.1'
|
5
|
+
|
4
6
|
self.test_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
|
5
7
|
self.live_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
|
6
|
-
|
7
|
-
|
8
|
+
|
9
|
+
class_attribute :duplicate_window
|
10
|
+
|
11
|
+
APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
|
12
|
+
|
13
|
+
RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT, AUTHORIZATION_CODE = 0, 2, 3, 4
|
14
|
+
AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE, CARDHOLDER_AUTH_CODE = 5, 6, 38, 39
|
15
|
+
|
16
|
+
self.default_currency = 'USD'
|
17
|
+
|
8
18
|
self.supported_countries = ['US']
|
9
19
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
20
|
+
self.homepage_url = 'http://nmi.com/'
|
21
|
+
self.display_name = 'NMI'
|
22
|
+
|
23
|
+
CARD_CODE_ERRORS = %w( N S )
|
24
|
+
AVS_ERRORS = %w( A E N R W Z )
|
25
|
+
AVS_REASON_CODES = %w(27 45)
|
26
|
+
TRANSACTION_ALREADY_ACTIONED = %w(310 311)
|
27
|
+
|
28
|
+
def initialize(options = {})
|
29
|
+
requires!(options, :login, :password)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def authorize(money, paysource, options = {})
|
34
|
+
post = {}
|
35
|
+
add_currency_code(post, money, options)
|
36
|
+
add_invoice(post, options)
|
37
|
+
add_payment_source(post, paysource, options)
|
38
|
+
add_address(post, options)
|
39
|
+
add_customer_data(post, options)
|
40
|
+
add_duplicate_window(post)
|
41
|
+
|
42
|
+
commit('AUTH_ONLY', money, post)
|
43
|
+
end
|
44
|
+
|
45
|
+
def purchase(money, paysource, options = {})
|
46
|
+
post = {}
|
47
|
+
add_currency_code(post, money, options)
|
48
|
+
add_invoice(post, options)
|
49
|
+
add_payment_source(post, paysource, options)
|
50
|
+
add_address(post, options)
|
51
|
+
add_customer_data(post, options)
|
52
|
+
add_duplicate_window(post)
|
53
|
+
|
54
|
+
commit('AUTH_CAPTURE', money, post)
|
55
|
+
end
|
56
|
+
|
57
|
+
def capture(money, authorization, options = {})
|
58
|
+
post = {:trans_id => authorization}
|
59
|
+
add_customer_data(post, options)
|
60
|
+
add_invoice(post, options)
|
61
|
+
commit('PRIOR_AUTH_CAPTURE', money, post)
|
62
|
+
end
|
63
|
+
|
64
|
+
def void(authorization, options = {})
|
65
|
+
post = {:trans_id => authorization}
|
66
|
+
add_duplicate_window(post)
|
67
|
+
commit('VOID', nil, post)
|
68
|
+
end
|
69
|
+
|
70
|
+
def refund(money, identification, options = {})
|
71
|
+
requires!(options, :card_number)
|
72
|
+
|
73
|
+
post = { :trans_id => identification,
|
74
|
+
:card_num => options[:card_number]
|
75
|
+
}
|
76
|
+
|
77
|
+
post[:first_name] = options[:first_name] if options[:first_name]
|
78
|
+
post[:last_name] = options[:last_name] if options[:last_name]
|
79
|
+
post[:zip] = options[:zip] if options[:zip]
|
80
|
+
|
81
|
+
add_invoice(post, options)
|
82
|
+
add_duplicate_window(post)
|
83
|
+
|
84
|
+
commit('CREDIT', money, post)
|
85
|
+
end
|
86
|
+
|
87
|
+
def credit(money, identification, options = {})
|
88
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
89
|
+
refund(money, identification, options)
|
90
|
+
end
|
91
|
+
|
92
|
+
def verify(credit_card, options = {})
|
93
|
+
MultiResponse.run(:use_first_response) do |r|
|
94
|
+
r.process { authorize(100, credit_card, options) }
|
95
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
96
|
+
end
|
97
|
+
end
|
10
98
|
|
11
99
|
private
|
100
|
+
|
101
|
+
def commit(action, money, parameters)
|
102
|
+
parameters[:amount] = amount(money) unless action == 'VOID'
|
103
|
+
|
104
|
+
url = test? ? self.test_url : self.live_url
|
105
|
+
data = ssl_post(url, post_data(action, parameters))
|
106
|
+
|
107
|
+
response = parse(data)
|
108
|
+
response[:action] = action
|
109
|
+
|
110
|
+
message = message_from(response)
|
111
|
+
|
112
|
+
Response.new(success?(response), message, response,
|
113
|
+
:test => test?,
|
114
|
+
:authorization => response[:transaction_id],
|
115
|
+
:fraud_review => fraud_review?(response),
|
116
|
+
:avs_result => { :code => response[:avs_result_code] },
|
117
|
+
:cvv_result => response[:card_code]
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
def success?(response)
|
122
|
+
response[:response_code] == APPROVED && TRANSACTION_ALREADY_ACTIONED.exclude?(response[:response_reason_code])
|
123
|
+
end
|
124
|
+
|
125
|
+
def fraud_review?(response)
|
126
|
+
response[:response_code] == FRAUD_REVIEW
|
127
|
+
end
|
128
|
+
|
129
|
+
def parse(body)
|
130
|
+
fields = split(body)
|
131
|
+
|
132
|
+
results = {
|
133
|
+
:response_code => fields[RESPONSE_CODE].to_i,
|
134
|
+
:response_reason_code => fields[RESPONSE_REASON_CODE],
|
135
|
+
:response_reason_text => fields[RESPONSE_REASON_TEXT],
|
136
|
+
:avs_result_code => fields[AVS_RESULT_CODE],
|
137
|
+
:transaction_id => fields[TRANSACTION_ID],
|
138
|
+
:card_code => fields[CARD_CODE_RESPONSE_CODE],
|
139
|
+
:authorization_code => fields[AUTHORIZATION_CODE],
|
140
|
+
:cardholder_authentication_code => fields[CARDHOLDER_AUTH_CODE]
|
141
|
+
}
|
142
|
+
results
|
143
|
+
end
|
144
|
+
|
145
|
+
def post_data(action, parameters = {})
|
146
|
+
post = {}
|
147
|
+
|
148
|
+
post[:version] = API_VERSION
|
149
|
+
post[:login] = @options[:login]
|
150
|
+
post[:tran_key] = @options[:password]
|
151
|
+
post[:relay_response] = "FALSE"
|
152
|
+
post[:type] = action
|
153
|
+
post[:delim_data] = "TRUE"
|
154
|
+
post[:delim_char] = ","
|
155
|
+
post[:encap_char] = "$"
|
156
|
+
post[:solution_ID] = application_id if application_id.present? && application_id != "ActiveMerchant"
|
157
|
+
|
158
|
+
request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
159
|
+
request
|
160
|
+
end
|
161
|
+
|
162
|
+
def add_currency_code(post, money, options)
|
163
|
+
post[:currency_code] = options[:currency] || currency(money)
|
164
|
+
end
|
165
|
+
|
166
|
+
def add_invoice(post, options)
|
167
|
+
post[:invoice_num] = options[:order_id]
|
168
|
+
post[:description] = options[:description]
|
169
|
+
end
|
170
|
+
|
12
171
|
def add_creditcard(post, creditcard, options={})
|
13
|
-
|
172
|
+
post[:card_num] = creditcard.number
|
173
|
+
post[:card_code] = creditcard.verification_value if creditcard.verification_value?
|
174
|
+
post[:exp_date] = expdate(creditcard)
|
175
|
+
post[:first_name] = creditcard.first_name
|
176
|
+
post[:last_name] = creditcard.last_name
|
177
|
+
|
14
178
|
post[:recurring_billing] = "TRUE" if options[:recurring]
|
15
179
|
end
|
16
|
-
end
|
17
180
|
|
181
|
+
def add_payment_source(params, source, options={})
|
182
|
+
add_creditcard(params, source, options)
|
183
|
+
end
|
184
|
+
|
185
|
+
def add_customer_data(post, options)
|
186
|
+
if options.has_key? :email
|
187
|
+
post[:email] = options[:email]
|
188
|
+
post[:email_customer] = false
|
189
|
+
end
|
190
|
+
|
191
|
+
if options.has_key? :customer
|
192
|
+
post[:cust_id] = options[:customer] if Float(options[:customer]) rescue nil
|
193
|
+
end
|
194
|
+
|
195
|
+
if options.has_key? :ip
|
196
|
+
post[:customer_ip] = options[:ip]
|
197
|
+
end
|
198
|
+
|
199
|
+
if options.has_key? :cardholder_authentication_value
|
200
|
+
post[:cardholder_authentication_value] = options[:cardholder_authentication_value]
|
201
|
+
end
|
202
|
+
|
203
|
+
if options.has_key? :authentication_indicator
|
204
|
+
post[:authentication_indicator] = options[:authentication_indicator]
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
def add_duplicate_window(post)
|
210
|
+
unless duplicate_window.nil?
|
211
|
+
post[:duplicate_window] = duplicate_window
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def add_address(post, options)
|
216
|
+
if address = options[:billing_address] || options[:address]
|
217
|
+
post[:address] = address[:address1].to_s
|
218
|
+
post[:company] = address[:company].to_s
|
219
|
+
post[:phone] = address[:phone].to_s
|
220
|
+
post[:zip] = address[:zip].to_s
|
221
|
+
post[:city] = address[:city].to_s
|
222
|
+
post[:country] = address[:country].to_s
|
223
|
+
post[:state] = address[:state].blank? ? 'n/a' : address[:state]
|
224
|
+
end
|
225
|
+
|
226
|
+
if address = options[:shipping_address]
|
227
|
+
post[:ship_to_first_name] = address[:first_name].to_s
|
228
|
+
post[:ship_to_last_name] = address[:last_name].to_s
|
229
|
+
post[:ship_to_address] = address[:address1].to_s
|
230
|
+
post[:ship_to_company] = address[:company].to_s
|
231
|
+
post[:ship_to_phone] = address[:phone].to_s
|
232
|
+
post[:ship_to_zip] = address[:zip].to_s
|
233
|
+
post[:ship_to_city] = address[:city].to_s
|
234
|
+
post[:ship_to_country] = address[:country].to_s
|
235
|
+
post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state]
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def message_from(results)
|
240
|
+
if results[:response_code] == DECLINED
|
241
|
+
return CVVResult.messages[ results[:card_code] ] if CARD_CODE_ERRORS.include?(results[:card_code])
|
242
|
+
if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code])
|
243
|
+
return AVSResult.messages[ results[:avs_result_code] ]
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
(results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '')
|
248
|
+
end
|
249
|
+
|
250
|
+
def split(response)
|
251
|
+
response[1..-2].split(/\$,\$/)
|
252
|
+
end
|
253
|
+
end
|
18
254
|
end
|
19
255
|
end
|
20
256
|
|