activemerchant 1.13.0 → 1.14.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.tar.gz.sig +0 -0
- data/CHANGELOG +19 -0
- data/CONTRIBUTORS +14 -2
- data/README.rdoc +2 -0
- data/lib/active_merchant/billing/credit_card.rb +4 -4
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +10 -5
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +133 -11
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +1 -1
- data/lib/active_merchant/billing/gateways/beanstream.rb +39 -2
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +64 -26
- data/lib/active_merchant/billing/gateways/bogus.rb +21 -3
- data/lib/active_merchant/billing/gateways/cyber_source.rb +5 -1
- data/lib/active_merchant/billing/gateways/data_cash.rb +1 -1
- data/lib/active_merchant/billing/gateways/efsnet.rb +1 -1
- data/lib/active_merchant/billing/gateways/epay.rb +5 -1
- data/lib/active_merchant/billing/gateways/eway.rb +4 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +231 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -7
- data/lib/active_merchant/billing/gateways/first_pay.rb +7 -2
- data/lib/active_merchant/billing/gateways/iridium.rb +1 -1
- data/lib/active_merchant/billing/gateways/jetpay.rb +5 -2
- data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -1
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +6 -4
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +1 -1
- data/lib/active_merchant/billing/gateways/moneris.rb +1 -1
- data/lib/active_merchant/billing/gateways/netaxept.rb +6 -1
- data/lib/active_merchant/billing/gateways/ogone.rb +1 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +317 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +1 -1
- data/lib/active_merchant/billing/gateways/payflow.rb +1 -1
- data/lib/active_merchant/billing/gateways/payflow_express.rb +6 -1
- data/lib/active_merchant/billing/gateways/payment_express.rb +6 -1
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +7 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +11 -7
- data/lib/active_merchant/billing/gateways/plugnpay.rb +1 -1
- data/lib/active_merchant/billing/gateways/psigate.rb +1 -1
- data/lib/active_merchant/billing/gateways/qbms.rb +1 -1
- data/lib/active_merchant/billing/gateways/quantum.rb +6 -1
- data/lib/active_merchant/billing/gateways/quickpay.rb +6 -1
- data/lib/active_merchant/billing/gateways/realex.rb +196 -72
- data/lib/active_merchant/billing/gateways/sage_pay.rb +7 -2
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +38 -2
- data/lib/active_merchant/billing/gateways/smart_ps.rb +2 -2
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +7 -2
- data/lib/active_merchant/billing/gateways/verifi.rb +1 -1
- data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +0 -1
- data/lib/active_merchant/billing/integrations/return.rb +6 -1
- data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +6 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +5 -1
- data/lib/active_merchant/common/connection.rb +15 -0
- data/lib/active_merchant/common/posts_data.rb +2 -0
- data/lib/active_merchant/common/utils.rb +4 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +8 -4
- metadata.gz.sig +0 -0
@@ -57,16 +57,18 @@ module ActiveMerchant #:nodoc:
|
|
57
57
|
commit('X', nil, post)
|
58
58
|
end
|
59
59
|
|
60
|
+
def refund(money, identification, options = {})
|
61
|
+
commit('U', money, options.merge(:transaction_id => identification))
|
62
|
+
end
|
63
|
+
|
60
64
|
def credit(money, creditcard_or_card_id, options = {})
|
61
|
-
post ={}
|
65
|
+
post = {}
|
62
66
|
add_payment_source(post, creditcard_or_card_id, options)
|
63
67
|
commit('C', money, post)
|
64
68
|
end
|
65
69
|
|
66
70
|
def void(transaction_id, options = {})
|
67
|
-
|
68
|
-
post[:transaction_id] = transaction_id
|
69
|
-
commit('V', nil, post)
|
71
|
+
commit('V', nil, options.merge(:transaction_id => transaction_id))
|
70
72
|
end
|
71
73
|
|
72
74
|
private
|
@@ -98,7 +98,7 @@ module ActiveMerchant #:nodoc:
|
|
98
98
|
# * <tt>:order_id</tt> - A unique reference for this order (required when performing a non-referenced credit)
|
99
99
|
def credit(money, identification, options = {})
|
100
100
|
if identification.is_a?(String)
|
101
|
-
|
101
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
102
102
|
refund(money, identification, options)
|
103
103
|
else
|
104
104
|
perform_credit(money, identification, options)
|
@@ -71,7 +71,7 @@ module ActiveMerchant #:nodoc:
|
|
71
71
|
# Moneris interface consistent with other gateways. (See +capture+ for
|
72
72
|
# details.)
|
73
73
|
def credit(money, authorization, options = {})
|
74
|
-
|
74
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
75
75
|
refund(money, authorization, options)
|
76
76
|
end
|
77
77
|
|
@@ -57,13 +57,18 @@ module ActiveMerchant #:nodoc:
|
|
57
57
|
commit('Capture', post, false)
|
58
58
|
end
|
59
59
|
|
60
|
-
def
|
60
|
+
def refund(money, authorization, options = {})
|
61
61
|
post = {}
|
62
62
|
add_credentials(post, options)
|
63
63
|
add_authorization(post, authorization, money)
|
64
64
|
commit('Credit', post, false)
|
65
65
|
end
|
66
66
|
|
67
|
+
def credit(money, authorization, options = {})
|
68
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
69
|
+
refund(money, authorization, options)
|
70
|
+
end
|
71
|
+
|
67
72
|
def void(authorization, options = {})
|
68
73
|
post = {}
|
69
74
|
add_credentials(post, options)
|
@@ -126,7 +126,7 @@ module ActiveMerchant #:nodoc:
|
|
126
126
|
# Credit the specified account by a specific amount.
|
127
127
|
def credit(money, identification_or_credit_card, options = {})
|
128
128
|
if reference_transaction?(identification_or_credit_card)
|
129
|
-
|
129
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
130
130
|
# Referenced credit: refund of a settled transaction
|
131
131
|
refund(money, identification_or_credit_card, options)
|
132
132
|
else # must be a credit card or card reference
|
@@ -0,0 +1,317 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/orbital/orbital_soft_descriptors.rb'
|
2
|
+
require "rexml/document"
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
# For more information on Orbital, visit the {integration center}[http://download.chasepaymentech.com]
|
7
|
+
#
|
8
|
+
# ==== Authentication Options
|
9
|
+
#
|
10
|
+
# The Orbital Gateway supports two methods of authenticating incoming requests:
|
11
|
+
# Source IP authentication and Connection Username/Password authentication
|
12
|
+
#
|
13
|
+
# In addition, these IP addresses/Connection Usernames must be affiliated with the Merchant IDs
|
14
|
+
# for which the client should be submitting transactions.
|
15
|
+
#
|
16
|
+
# This does allow Third Party Hosting service organizations presenting on behalf of other
|
17
|
+
# merchants to submit transactions. However, each time a new customer is added, the
|
18
|
+
# merchant or Third-Party hosting organization needs to ensure that the new Merchant IDs
|
19
|
+
# or Chain IDs are affiliated with the hosting companies IPs or Connection Usernames.
|
20
|
+
#
|
21
|
+
# If the merchant expects to have more than one merchant account with the Orbital
|
22
|
+
# Gateway, it should have its IP addresses/Connection Usernames affiliated at the Chain
|
23
|
+
# level hierarchy within the Orbital Gateway. Each time a new merchant ID is added, as
|
24
|
+
# long as it is placed within the same Chain, it will simply work. Otherwise, the additional
|
25
|
+
# MIDs will need to be affiliated with the merchant IPs or Connection Usernames respectively.
|
26
|
+
# For example, we generally affiliate all Salem accounts [BIN 000001] with
|
27
|
+
# their Company Number [formerly called MA #] number so all MIDs or Divisions under that
|
28
|
+
# Company will automatically be affiliated.
|
29
|
+
|
30
|
+
class OrbitalGateway < Gateway
|
31
|
+
API_VERSION = "4.6"
|
32
|
+
|
33
|
+
POST_HEADERS = {
|
34
|
+
"MIME-Version" => "1.0",
|
35
|
+
"Content-Type" => "Application/PTI46",
|
36
|
+
"Content-transfer-encoding" => "text",
|
37
|
+
"Request-number" => '1',
|
38
|
+
"Document-type" => "Request",
|
39
|
+
"Interface-Version" => "Ruby|ActiveMerchant|Proprietary Gateway"
|
40
|
+
}
|
41
|
+
|
42
|
+
SUCCESS, APPROVED = '0', '00'
|
43
|
+
|
44
|
+
class_inheritable_accessor :primary_test_url, :secondary_test_url, :primary_live_url, :secondary_live_url
|
45
|
+
|
46
|
+
self.primary_test_url = "https://orbitalvar1.paymentech.net/authorize"
|
47
|
+
self.secondary_test_url = "https://orbitalvar2.paymentech.net/authorize"
|
48
|
+
|
49
|
+
self.primary_live_url = "https://orbital1.paymentech.net/authorize"
|
50
|
+
self.secondary_live_url = "https://orbital2.paymentech.net/authorize"
|
51
|
+
|
52
|
+
self.supported_countries = ["US", "CA"]
|
53
|
+
self.default_currency = "CAD"
|
54
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
|
55
|
+
|
56
|
+
self.display_name = 'Orbital Paymentech'
|
57
|
+
self.homepage_url = 'http://chasepaymentech.com/'
|
58
|
+
|
59
|
+
self.money_format = :cents
|
60
|
+
|
61
|
+
CURRENCY_CODES = {
|
62
|
+
"AUD" => '036',
|
63
|
+
"CAD" => '124',
|
64
|
+
"CZK" => '203',
|
65
|
+
"DKK" => '208',
|
66
|
+
"HKD" => '344',
|
67
|
+
"ICK" => '352',
|
68
|
+
"JPY" => '392',
|
69
|
+
"MXN" => '484',
|
70
|
+
"NZD" => '554',
|
71
|
+
"NOK" => '578',
|
72
|
+
"SGD" => '702',
|
73
|
+
"SEK" => '752',
|
74
|
+
"CHF" => '756',
|
75
|
+
"GBP" => '826',
|
76
|
+
"USD" => '840',
|
77
|
+
"EUR" => '978'
|
78
|
+
}
|
79
|
+
|
80
|
+
def initialize(options = {})
|
81
|
+
unless options[:ip_authentication] == true
|
82
|
+
requires!(options, :login, :password, :merchant_id)
|
83
|
+
@options = options
|
84
|
+
end
|
85
|
+
super
|
86
|
+
end
|
87
|
+
|
88
|
+
# A – Authorization request
|
89
|
+
def authorize(money, creditcard, options = {})
|
90
|
+
order = build_new_order_xml('A', money, options) do |xml|
|
91
|
+
add_creditcard(xml, creditcard, options[:currency])
|
92
|
+
add_address(xml, creditcard, options)
|
93
|
+
end
|
94
|
+
commit(order)
|
95
|
+
end
|
96
|
+
|
97
|
+
# AC – Authorization and Capture
|
98
|
+
def purchase(money, creditcard, options = {})
|
99
|
+
order = build_new_order_xml('AC', money, options) do |xml|
|
100
|
+
add_creditcard(xml, creditcard, options[:currency])
|
101
|
+
add_address(xml, creditcard, options)
|
102
|
+
end
|
103
|
+
commit(order)
|
104
|
+
end
|
105
|
+
|
106
|
+
# MFC - Mark For Capture
|
107
|
+
def capture(money, authorization, options = {})
|
108
|
+
commit(build_mark_for_capture_xml(money, authorization, options))
|
109
|
+
end
|
110
|
+
|
111
|
+
# R – Refund request
|
112
|
+
def refund(money, authorization, options = {})
|
113
|
+
order = build_new_order_xml('R', money, options.merge(:authorization => authorization)) do |xml|
|
114
|
+
add_refund(xml, options[:currency])
|
115
|
+
end
|
116
|
+
commit(order)
|
117
|
+
end
|
118
|
+
|
119
|
+
def credit(money, authorization, options= {})
|
120
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
121
|
+
refund(money, authorization, options)
|
122
|
+
end
|
123
|
+
|
124
|
+
# setting money to nil will perform a full void
|
125
|
+
def void(money, authorization, options = {})
|
126
|
+
order = build_void_request_xml(money, authorization, options)
|
127
|
+
commit(order)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def add_customer_data(xml, options)
|
133
|
+
if options[:customer_ref_num]
|
134
|
+
xml.tag! :CustomerProfileFromOrderInd, 'S'
|
135
|
+
xml.tag! :CustomerRefNum, options[:customer_ref_num]
|
136
|
+
else
|
137
|
+
xml.tag! :CustomerProfileFromOrderInd, 'A'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def add_soft_descriptors(xml, soft_desc)
|
142
|
+
xml.tag! :SDMerchantName, soft_desc.merchant_name
|
143
|
+
xml.tag! :SDProductDescription, soft_desc.product_description
|
144
|
+
xml.tag! :SDMerchantCity, soft_desc.merchant_city
|
145
|
+
xml.tag! :SDMerchantPhone, soft_desc.merchant_phone
|
146
|
+
xml.tag! :SDMerchantURL, soft_desc.merchant_url
|
147
|
+
xml.tag! :SDMerchantEmail, soft_desc.merchant_email
|
148
|
+
end
|
149
|
+
|
150
|
+
def add_address(xml, creditcard, options)
|
151
|
+
if address = options[:billing_address] || options[:address]
|
152
|
+
xml.tag! :AVSzip, address[:zip]
|
153
|
+
xml.tag! :AVSaddress1, address[:address1]
|
154
|
+
xml.tag! :AVSaddress2, address[:address2]
|
155
|
+
xml.tag! :AVScity, address[:city]
|
156
|
+
xml.tag! :AVSstate, address[:state]
|
157
|
+
xml.tag! :AVSphoneNum, address[:phone] ? address[:phone].scan(/\d/).to_s : nil
|
158
|
+
xml.tag! :AVSname, creditcard.name
|
159
|
+
xml.tag! :AVScountryCode, address[:country]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def add_creditcard(xml, creditcard, currency=nil)
|
164
|
+
xml.tag! :AccountNum, creditcard.number
|
165
|
+
xml.tag! :Exp, creditcard.expiry_date.expiration.strftime("%m%y")
|
166
|
+
|
167
|
+
xml.tag! :CurrencyCode, currency_code(currency)
|
168
|
+
xml.tag! :CurrencyExponent, '2' # Will need updating to support currencies such as the Yen.
|
169
|
+
|
170
|
+
xml.tag! :CardSecVal, creditcard.verification_value if creditcard.verification_value?
|
171
|
+
end
|
172
|
+
|
173
|
+
def add_refund(xml, currency=nil)
|
174
|
+
xml.tag! :AccountNum, nil
|
175
|
+
|
176
|
+
xml.tag! :CurrencyCode, currency_code(currency)
|
177
|
+
xml.tag! :CurrencyExponent, '2' # Will need updating to support currencies such as the Yen.
|
178
|
+
end
|
179
|
+
|
180
|
+
def parse(body)
|
181
|
+
response = {}
|
182
|
+
xml = REXML::Document.new(body)
|
183
|
+
root = REXML::XPath.first(xml, "//Response") ||
|
184
|
+
REXML::XPath.first(xml, "//ErrorResponse")
|
185
|
+
if root
|
186
|
+
root.elements.to_a.each do |node|
|
187
|
+
recurring_parse_element(response, node)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
response
|
191
|
+
end
|
192
|
+
|
193
|
+
def recurring_parse_element(response, node)
|
194
|
+
if node.has_elements?
|
195
|
+
node.elements.each{|e| recurring_parse_element(response, e) }
|
196
|
+
else
|
197
|
+
response[node.name.underscore.to_sym] = node.text
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def commit(order)
|
202
|
+
headers = POST_HEADERS.merge("Content-length" => order.size.to_s)
|
203
|
+
request = lambda {return parse(ssl_post(remote_url, order, headers))}
|
204
|
+
|
205
|
+
# Failover URL will be used in the event of a connection error
|
206
|
+
begin response = request.call; rescue ConnectionError; retry end
|
207
|
+
|
208
|
+
Response.new(success?(response), message_from(response), response,
|
209
|
+
{:authorization => "#{response[:tx_ref_num]};#{response[:order_id]}",
|
210
|
+
:test => self.test?,
|
211
|
+
:avs_result => {:code => response[:avs_resp_code]},
|
212
|
+
:cvv_result => response[:cvv2_resp_code]
|
213
|
+
}
|
214
|
+
)
|
215
|
+
end
|
216
|
+
|
217
|
+
def remote_url
|
218
|
+
unless $!.class == ActiveMerchant::ConnectionError
|
219
|
+
self.test? ? self.primary_test_url : self.primary_live_url
|
220
|
+
else
|
221
|
+
self.test? ? self.secondary_test_url : self.secondary_live_url
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def success?(response)
|
226
|
+
if response[:message_type] == "R"
|
227
|
+
response[:proc_status] == SUCCESS
|
228
|
+
else
|
229
|
+
response[:proc_status] == SUCCESS &&
|
230
|
+
response[:resp_code] == APPROVED
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def message_from(response)
|
235
|
+
success?(response) ? 'APPROVED' : response[:resp_msg] || response[:status_msg]
|
236
|
+
end
|
237
|
+
|
238
|
+
def ip_authentication?
|
239
|
+
@options[:ip_authentication] == true
|
240
|
+
end
|
241
|
+
|
242
|
+
def build_new_order_xml(action, money, parameters = {})
|
243
|
+
requires!(parameters, :order_id)
|
244
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
245
|
+
xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
|
246
|
+
xml.tag! :Request do
|
247
|
+
xml.tag! :NewOrder do
|
248
|
+
xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
|
249
|
+
xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
|
250
|
+
xml.tag! :IndustryType, "EC" # E-Commerce transaction
|
251
|
+
xml.tag! :MessageType, action
|
252
|
+
xml.tag! :BIN, '000002' # PNS Tampa
|
253
|
+
xml.tag! :MerchantID, @options[:merchant_id]
|
254
|
+
xml.tag! :TerminalID, parameters[:terminal_id] || '001'
|
255
|
+
|
256
|
+
yield xml if block_given?
|
257
|
+
|
258
|
+
xml.tag! :Comments, parameters[:comments] if parameters[:comments]
|
259
|
+
xml.tag! :OrderID, parameters[:order_id].to_s[0...22]
|
260
|
+
xml.tag! :Amount, amount(money)
|
261
|
+
|
262
|
+
# Append Transaction Reference Number at the end for Refund transactions
|
263
|
+
if action == "R"
|
264
|
+
tx_ref_num, _ = parameters[:authorization].split(';')
|
265
|
+
xml.tag! :TxRefNum, tx_ref_num
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
xml.target!
|
270
|
+
end
|
271
|
+
|
272
|
+
def build_mark_for_capture_xml(money, authorization, parameters = {})
|
273
|
+
tx_ref_num, order_id = authorization.split(';')
|
274
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
275
|
+
xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
|
276
|
+
xml.tag! :Request do
|
277
|
+
xml.tag! :MarkForCapture do
|
278
|
+
xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
|
279
|
+
xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
|
280
|
+
xml.tag! :OrderID, order_id
|
281
|
+
xml.tag! :Amount, amount(money)
|
282
|
+
xml.tag! :BIN, '000002' # PNS Tampa
|
283
|
+
xml.tag! :MerchantID, @options[:merchant_id]
|
284
|
+
xml.tag! :TerminalID, parameters[:terminal_id] || '001'
|
285
|
+
xml.tag! :TxRefNum, tx_ref_num
|
286
|
+
end
|
287
|
+
end
|
288
|
+
xml.target!
|
289
|
+
end
|
290
|
+
|
291
|
+
def build_void_request_xml(money, authorization, parameters = {})
|
292
|
+
requires!(parameters, :transaction_index)
|
293
|
+
tx_ref_num, order_id = authorization.split(';')
|
294
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
295
|
+
xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
|
296
|
+
xml.tag! :Request do
|
297
|
+
xml.tag! :Reversal do
|
298
|
+
xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
|
299
|
+
xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
|
300
|
+
xml.tag! :TxRefNum, tx_ref_num
|
301
|
+
xml.tag! :TxRefIdx, parameters[:transaction_index]
|
302
|
+
xml.tag! :AdjustedAmt, amount(money)
|
303
|
+
xml.tag! :OrderID, order_id
|
304
|
+
xml.tag! :BIN, '000002' # PNS Tampa
|
305
|
+
xml.tag! :MerchantID, @options[:merchant_id]
|
306
|
+
xml.tag! :TerminalID, parameters[:terminal_id] || '001'
|
307
|
+
end
|
308
|
+
end
|
309
|
+
xml.target!
|
310
|
+
end
|
311
|
+
|
312
|
+
def currency_code(currency)
|
313
|
+
CURRENCY_CODES[(currency || self.default_currency)].to_s
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class OrbitalSoftDescriptors
|
4
|
+
include Validateable
|
5
|
+
|
6
|
+
PHONE_FORMAT_1 = /\A\d{3}-\d{3}-\d{4}\z/
|
7
|
+
PHONE_FORMAT_2 = /\A\d{3}-\w{7}\z/
|
8
|
+
|
9
|
+
# ==== Tampa PNS Soft Descriptors
|
10
|
+
# The support for Soft Descriptors via the PNS Host is only for customers processing through Chase
|
11
|
+
# Paymentech Canada.
|
12
|
+
|
13
|
+
# Unlike Salem, the only value that gets passed on the cardholder statement is the Merchant Name field.
|
14
|
+
# And for these customers, it is a maximum of 25 bytes of data.
|
15
|
+
#
|
16
|
+
# All other Soft Descriptor fields can optionally be sent, but will not be submitted to the settlement host
|
17
|
+
# and will not display on the cardholder statement.
|
18
|
+
|
19
|
+
attr_accessor :merchant_name, :product_description, :merchant_city, :merchant_phone, :merchant_url, :merchant_email
|
20
|
+
|
21
|
+
def initialize(options = {})
|
22
|
+
self.merchant_name = options[:merchant_name]
|
23
|
+
self.merchant_city = options[:merchant_city]
|
24
|
+
self.merchant_phone = options[:merchant_phone]
|
25
|
+
self.merchant_url = options[:merchant_url]
|
26
|
+
self.merchant_email = options[:merchant_email]
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate
|
30
|
+
errors.add(:merchant_name, "is required") if self.merchant_name.blank?
|
31
|
+
errors.add(:merchant_name, "is required to be 25 bytes or less") if self.merchant_name.bytesize > 25
|
32
|
+
|
33
|
+
unless self.merchant_phone.blank? || self.merchant_phone.match(PHONE_FORMAT_1) || self.merchant_phone.match(PHONE_FORMAT_2)
|
34
|
+
errors.add(:merchant_phone, "is required to follow \"NNN-NNN-NNNN\" or \"NNN-AAAAAAA\" format")
|
35
|
+
end
|
36
|
+
|
37
|
+
[:merchant_email, :merchant_url].each do |attr|
|
38
|
+
unless self.send(attr).blank?
|
39
|
+
errors.add(attr, "is required to be 13 bytes or less") if self.send(attr).bytesize > 13
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -27,7 +27,7 @@ module ActiveMerchant #:nodoc:
|
|
27
27
|
|
28
28
|
def credit(money, identification_or_credit_card, options = {})
|
29
29
|
if identification_or_credit_card.is_a?(String)
|
30
|
-
|
30
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
31
31
|
# Perform referenced credit
|
32
32
|
refund(money, identification_or_credit_card, options)
|
33
33
|
else
|