authorizenet 1.8.2 → 1.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/authorize_net.rb +5 -0
- data/lib/authorize_net/api/api_transaction.rb +63 -0
- data/lib/authorize_net/api/schema.rb +3968 -0
- data/lib/authorize_net/api/transaction.rb +34 -0
- data/lib/authorize_net/cim/response.rb +6 -0
- data/lib/authorize_net/cim/transaction.rb +51 -2
- data/lib/authorize_net/fields.rb +16 -5
- data/lib/authorize_net/reporting/transaction.rb +17 -0
- data/lib/authorize_net/xml_transaction.rb +3 -0
- metadata +28 -17
- data/lib/authorize_net.rb~ +0 -95
- data/lib/authorize_net/aim/response.rb~ +0 -131
- data/lib/authorize_net/arb/fields.rb~ +0 -13
- data/lib/authorize_net/arb/paging.rb~ +0 -25
- data/lib/authorize_net/arb/response.rb~ +0 -68
- data/lib/authorize_net/arb/sorting.rb~ +0 -43
- data/lib/authorize_net/arb/subscription_detail.rb~ +0 -56
- data/lib/authorize_net/arb/subscription_list_response.rb~ +0 -45
- data/lib/authorize_net/arb/transaction.rb~ +0 -176
- data/lib/authorize_net/fields.rb~ +0 -767
- data/lib/authorize_net/xml_response.rb~ +0 -173
- data/lib/authorize_net/xml_transaction.rb~ +0 -276
@@ -1,173 +0,0 @@
|
|
1
|
-
module AuthorizeNet
|
2
|
-
|
3
|
-
# The core, xml response class. You shouldn't instantiate this one.
|
4
|
-
# Instead you should use AuthorizeNet::ARB::Response.
|
5
|
-
class XmlResponse < AuthorizeNet::Response
|
6
|
-
|
7
|
-
# DO NOT USE. Instantiate AuthorizeNet::ARB::Response or AuthorizeNet::CIM::Response instead.
|
8
|
-
def initialize(raw_response, transaction)
|
9
|
-
@raw_response = raw_response
|
10
|
-
@transaction = transaction
|
11
|
-
unless connection_failure?
|
12
|
-
begin
|
13
|
-
xml = Nokogiri::XML(@raw_response.body) do |config|
|
14
|
-
# confirm noent is the right flag
|
15
|
-
config.recover.noent.nonet
|
16
|
-
end
|
17
|
-
@root = xml.children[0]
|
18
|
-
@result_code = node_content_unless_nil(@root.at_css('messages resultCode'))
|
19
|
-
@message_code = node_content_unless_nil(@root.at_css('messages message code'))
|
20
|
-
@message_text = node_content_unless_nil(@root.at_css('messages message text'))
|
21
|
-
@reference_id = node_content_unless_nil(@root.at_css('refId'))
|
22
|
-
rescue
|
23
|
-
@raw_response = $!
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Check to see if the response indicated success. Success is defined as a 200 OK response with a resultCode
|
29
|
-
# of 'Ok'.
|
30
|
-
def success?
|
31
|
-
puts "there"
|
32
|
-
!connection_failure? && @result_code == 'Ok'
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns true if we failed to open a connection to the gateway or got back a non-200 OK HTTP response.
|
36
|
-
def connection_failure?
|
37
|
-
!@raw_response.kind_of?(Net::HTTPOK)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Returns the underlying Net::HTTPResponse object. This has the original response body along with
|
41
|
-
# headers and such. Note that if an exception is generated while making the request (which happens
|
42
|
-
# if there is no internet connection for example), you will get the exception object here instead of
|
43
|
-
# a Net::HTTPResponse object.
|
44
|
-
def raw
|
45
|
-
@raw_response
|
46
|
-
end
|
47
|
-
|
48
|
-
# Returns a deep-copy of the XML object received from the payment gateway. Or nil if there was no XML payload.
|
49
|
-
def xml
|
50
|
-
@root.dup unless @root.nil?
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns the resultCode from the XML response. resultCode will be either 'Ok' or 'Error'.
|
54
|
-
def result_code
|
55
|
-
@result_code
|
56
|
-
end
|
57
|
-
|
58
|
-
# Returns the messageCode from the XML response. This is a code indicating the details of an error
|
59
|
-
# or success.
|
60
|
-
def message_code
|
61
|
-
@message_code
|
62
|
-
end
|
63
|
-
|
64
|
-
# Returns the messageText from the XML response. This is a text description of the message_code.
|
65
|
-
def message_text
|
66
|
-
@message_text
|
67
|
-
end
|
68
|
-
|
69
|
-
# Alias for result_code.
|
70
|
-
def response_code
|
71
|
-
result_code
|
72
|
-
end
|
73
|
-
|
74
|
-
# Alias for message_code.
|
75
|
-
def response_reason_code
|
76
|
-
message_code
|
77
|
-
end
|
78
|
-
|
79
|
-
# Alias for message_text.
|
80
|
-
def response_reason_text
|
81
|
-
message_text
|
82
|
-
end
|
83
|
-
|
84
|
-
# Returns the refId from the response if there is one. Otherwise returns nil.
|
85
|
-
def reference_id
|
86
|
-
@reference_id
|
87
|
-
end
|
88
|
-
|
89
|
-
#:enddoc:
|
90
|
-
protected
|
91
|
-
|
92
|
-
def node_content_unless_nil(node)
|
93
|
-
if node.nil?
|
94
|
-
nil
|
95
|
-
else
|
96
|
-
node.content
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def node_child_content_unless_nil(node)
|
101
|
-
if node.nil?
|
102
|
-
nil
|
103
|
-
else
|
104
|
-
if node.children.length > 0
|
105
|
-
node.children.collect(&:content)
|
106
|
-
else
|
107
|
-
nil
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Transforms a block of XML into a model Object defined by entity_desc.
|
113
|
-
def build_entity(xml, entity_desc)
|
114
|
-
args = {}
|
115
|
-
entity_desc.node_structure.each do |node_desc|
|
116
|
-
node_name = (node_desc.keys.reject {|k| k.to_s[0..0] == '_' }).first
|
117
|
-
args.merge!(handle_node_type(xml, node_desc, node_name, args, ''))
|
118
|
-
end
|
119
|
-
|
120
|
-
if args.length == 0
|
121
|
-
return nil
|
122
|
-
end
|
123
|
-
|
124
|
-
if entity_desc.arg_mapping.nil?
|
125
|
-
return entity_desc.entity_class.new(args)
|
126
|
-
else
|
127
|
-
args_list = []
|
128
|
-
entity_desc.arg_mapping.each do |arg|
|
129
|
-
args_list <<= args[arg]
|
130
|
-
args.delete(arg)
|
131
|
-
end
|
132
|
-
args_list <<= args
|
133
|
-
return entity_desc.entity_class.new(*args_list)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Parses an XML fragment into an internal representation.
|
138
|
-
def handle_node_type(xml, node_desc, node_name, args, base_name)
|
139
|
-
case node_desc[node_name]
|
140
|
-
when Symbol
|
141
|
-
node = xml.at_css(base_name + node_name.to_s)
|
142
|
-
unless node.nil?
|
143
|
-
content = node.content
|
144
|
-
case node_desc[:_converter]
|
145
|
-
when Method, Proc
|
146
|
-
content = node_desc[:_converter].call(content)
|
147
|
-
when Symbol
|
148
|
-
content = self.send(node_desc[:_converter], content)
|
149
|
-
end
|
150
|
-
args[node_desc[node_name]] = content unless content.nil?
|
151
|
-
end
|
152
|
-
when AuthorizeNet::EntityDescription
|
153
|
-
unless node_desc[:_multivalue].nil?
|
154
|
-
xml.css(base_name + node_name.to_s).each do |node|
|
155
|
-
entity = build_entity(node, node_desc[node_name])
|
156
|
-
args[node_desc[:_multivalue]] = args[node_desc[:_multivalue]].to_a + entity.to_a unless entity.nil?
|
157
|
-
end
|
158
|
-
else
|
159
|
-
entity = build_entity(xml.css(base_name + node_name.to_s), node_desc[node_name])
|
160
|
-
args[node_desc[:_value]] = entity unless entity.nil?
|
161
|
-
end
|
162
|
-
when Array
|
163
|
-
node_desc[node_name].each do |inner_node|
|
164
|
-
inner_node_name = (inner_node.keys.reject {|k| k.to_s[0..0] == '_' }).first
|
165
|
-
args.merge!(handle_node_type(xml, inner_node, inner_node_name, args, node_name.to_s + ' '))
|
166
|
-
end
|
167
|
-
end
|
168
|
-
return args
|
169
|
-
end
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
end
|
@@ -1,276 +0,0 @@
|
|
1
|
-
module AuthorizeNet
|
2
|
-
|
3
|
-
# The ARB transaction class.
|
4
|
-
class XmlTransaction < AuthorizeNet::Transaction
|
5
|
-
|
6
|
-
# The XML namespace used by the ARB API.
|
7
|
-
XML_NAMESPACE = 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'
|
8
|
-
|
9
|
-
# Constants for both the various Authorize.Net subscription gateways are defined here.
|
10
|
-
module Gateway
|
11
|
-
LIVE = 'https://api.authorize.net/xml/v1/request.api'
|
12
|
-
TEST = 'https://apitest.authorize.net/xml/v1/request.api'
|
13
|
-
end
|
14
|
-
|
15
|
-
# Constants for both the various Authorize.Net transaction types are defined here.
|
16
|
-
module Type
|
17
|
-
ARB_CREATE = "ARBCreateSubscriptionRequest"
|
18
|
-
ARB_UPDATE = "ARBUpdateSubscriptionRequest"
|
19
|
-
ARB_GET_STATUS = "ARBGetSubscriptionStatusRequest"
|
20
|
-
ARB_CANCEL = "ARBCancelSubscriptionRequest"
|
21
|
-
ARB_GET_SUBSCRIPTION_LIST = "ARBGetSubscriptionListRequest"
|
22
|
-
CIM_CREATE_PROFILE = "createCustomerProfileRequest"
|
23
|
-
CIM_CREATE_PAYMENT = "createCustomerPaymentProfileRequest"
|
24
|
-
CIM_CREATE_ADDRESS = "createCustomerShippingAddressRequest"
|
25
|
-
CIM_CREATE_TRANSACTION = "createCustomerProfileTransactionRequest"
|
26
|
-
CIM_DELETE_PROFILE = "deleteCustomerProfileRequest"
|
27
|
-
CIM_DELETE_PAYMENT = "deleteCustomerPaymentProfileRequest"
|
28
|
-
CIM_DELETE_ADDRESS = "deleteCustomerShippingAddressRequest"
|
29
|
-
CIM_GET_PROFILE_IDS = "getCustomerProfileIdsRequest"
|
30
|
-
CIM_GET_PROFILE = "getCustomerProfileRequest"
|
31
|
-
CIM_GET_PAYMENT = "getCustomerPaymentProfileRequest"
|
32
|
-
CIM_GET_ADDRESS = "getCustomerShippingAddressRequest"
|
33
|
-
CIM_UPDATE_PROFILE = "updateCustomerProfileRequest"
|
34
|
-
CIM_UPDATE_PAYMENT = "updateCustomerPaymentProfileRequest"
|
35
|
-
CIM_UPDATE_ADDRESS = "updateCustomerShippingAddressRequest"
|
36
|
-
CIM_UPDATE_SPLIT = "updateSplitTenderGroupRequest"
|
37
|
-
CIM_VALIDATE_PAYMENT = "validateCustomerPaymentProfileRequest"
|
38
|
-
REPORT_GET_BATCH_LIST = "getSettledBatchListRequest"
|
39
|
-
REPORT_GET_TRANSACTION_LIST = "getTransactionListRequest"
|
40
|
-
REPORT_GET_TRANSACTION_DETAILS = "getTransactionDetailsRequest"
|
41
|
-
end
|
42
|
-
|
43
|
-
# Fields to convert to/from booleans.
|
44
|
-
@@boolean_fields = []
|
45
|
-
|
46
|
-
# Fields to convert to/from BigDecimal.
|
47
|
-
@@decimal_fields = []
|
48
|
-
|
49
|
-
# Fields to convert to/from Date.
|
50
|
-
@@date_fields = []
|
51
|
-
|
52
|
-
# Fields to convert to/from DateTime.
|
53
|
-
@@datetime_fields = []
|
54
|
-
|
55
|
-
# The class to wrap our response in.
|
56
|
-
@response_class = AuthorizeNet::XmlResponse
|
57
|
-
|
58
|
-
# The default options for the constructor.
|
59
|
-
@@option_defaults = {
|
60
|
-
:gateway => :production,
|
61
|
-
:verify_ssl => false,
|
62
|
-
:reference_id => nil
|
63
|
-
}
|
64
|
-
|
65
|
-
# DO NOT USE. Instantiate AuthorizeNet::ARB::Transaction or AuthorizeNet::CIM::Transaction instead.
|
66
|
-
def initialize(api_login_id, api_transaction_key, options = {})
|
67
|
-
super()
|
68
|
-
@api_login_id = api_login_id
|
69
|
-
@api_transaction_key = api_transaction_key
|
70
|
-
|
71
|
-
@response ||= nil
|
72
|
-
@type ||= nil
|
73
|
-
|
74
|
-
options = @@option_defaults.merge(options)
|
75
|
-
@verify_ssl = options[:verify_ssl]
|
76
|
-
@reference_id = options[:reference_id]
|
77
|
-
case options[:gateway]
|
78
|
-
when :sandbox, :test
|
79
|
-
@gateway = Gateway::TEST
|
80
|
-
when :production, :live
|
81
|
-
@gateway = Gateway::LIVE
|
82
|
-
else
|
83
|
-
@gateway = options[:gateway]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Checks if the transaction has been configured for the sandbox or not. Return FALSE if the
|
88
|
-
# transaction is running against the production, TRUE otherwise.
|
89
|
-
def test?
|
90
|
-
@gateway != Gateway::LIVE
|
91
|
-
end
|
92
|
-
|
93
|
-
# Checks to see if the transaction has a response (meaning it has been submitted to the gateway).
|
94
|
-
# Returns TRUE if a response is present, FALSE otherwise.
|
95
|
-
def has_response?
|
96
|
-
!@response.nil?
|
97
|
-
end
|
98
|
-
|
99
|
-
# Retrieve the response object (or Nil if transaction hasn't been sent to the gateway).
|
100
|
-
def response
|
101
|
-
@response
|
102
|
-
end
|
103
|
-
|
104
|
-
# Submits the transaction to the gateway for processing. Returns a response object. If the transaction
|
105
|
-
# has already been run, it will return nil.
|
106
|
-
def run
|
107
|
-
make_request
|
108
|
-
end
|
109
|
-
|
110
|
-
# Returns a deep-copy of the XML object sent to the payment gateway. Or nil if there was no XML payload.
|
111
|
-
def xml
|
112
|
-
@xml
|
113
|
-
end
|
114
|
-
|
115
|
-
#:enddoc:
|
116
|
-
protected
|
117
|
-
|
118
|
-
# Takes a list of nodes (a Hash is a node, and Array is a list) and returns True if any nodes
|
119
|
-
# would be built by build_nodes. False if no new nodes would be generated.
|
120
|
-
def has_content(nodeList, data)
|
121
|
-
nodeList.each do |node|
|
122
|
-
nodeName = (node.keys.reject {|k| nodeName.to_s[0..0] == '_' }).first
|
123
|
-
multivalue = node[:_multivalue]
|
124
|
-
conditional = node[:_conditional]
|
125
|
-
value = node[nodeName]
|
126
|
-
unless conditional.nil?
|
127
|
-
value = self.send(conditional, nodeName)
|
128
|
-
end
|
129
|
-
case value
|
130
|
-
when Array
|
131
|
-
if multivalue.nil?
|
132
|
-
if has_content(value, data)
|
133
|
-
return true
|
134
|
-
end
|
135
|
-
else
|
136
|
-
data[multivalue].each do |v|
|
137
|
-
if has_content(value, v)
|
138
|
-
return true
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
when Symbol
|
143
|
-
converted = convert_field(value, data[value])
|
144
|
-
return true unless converted.nil?
|
145
|
-
else
|
146
|
-
return true
|
147
|
-
end
|
148
|
-
end
|
149
|
-
false
|
150
|
-
end
|
151
|
-
|
152
|
-
# Takes a list of nodes (a Hash is a node, and Array is a list) and recursively builds the XML by pulling
|
153
|
-
# values as needed from data.
|
154
|
-
def build_nodes(builder, nodeList, data)
|
155
|
-
nodeList.each do |node|
|
156
|
-
# TODO - ADD COMMENTS HERE
|
157
|
-
nodeName = (node.keys.reject {|k| k.to_s[0..0] == '_' }).first
|
158
|
-
multivalue = node[:_multivalue]
|
159
|
-
conditional = node[:_conditional]
|
160
|
-
value = node[nodeName]
|
161
|
-
|
162
|
-
unless conditional.nil?
|
163
|
-
value = self.send(conditional, nodeName)
|
164
|
-
end
|
165
|
-
case value
|
166
|
-
when Array # node containing other nodes
|
167
|
-
if multivalue.nil?
|
168
|
-
proc = Proc.new { build_nodes(builder, value, data) }
|
169
|
-
builder.send(nodeName, &proc) if has_content(value, data)
|
170
|
-
else
|
171
|
-
data[multivalue].to_a.each do |v|
|
172
|
-
proc = Proc.new { build_nodes(builder, value, v) }
|
173
|
-
builder.send(nodeName, &proc) if has_content(value, v)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
when Symbol # node containing actual data
|
177
|
-
if data[value].kind_of?(Array)
|
178
|
-
data[value].each do |v|
|
179
|
-
converted = convert_field(value, v)
|
180
|
-
builder.send(nodeName, converted) unless converted.nil?
|
181
|
-
end
|
182
|
-
else
|
183
|
-
converted = convert_field(value, data[value])
|
184
|
-
builder.send(nodeName, converted) unless converted.nil?
|
185
|
-
end
|
186
|
-
else
|
187
|
-
builder.send(nodeName, value)
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
def convert_field(field, value)
|
193
|
-
if @@boolean_fields.include?(field) and !value.nil?
|
194
|
-
return boolean_to_value(value)
|
195
|
-
elsif @@decimal_fields.include?(field) and !value.nil?
|
196
|
-
return decimal_to_value(value)
|
197
|
-
elsif @@date_fields.include?(field) and !value.nil?
|
198
|
-
return date_to_value(value)
|
199
|
-
elsif @@datetime_fields.include?(field) and !value.nil?
|
200
|
-
return datetime_to_value(value)
|
201
|
-
elsif field == :extra_options
|
202
|
-
# handle converting extra options
|
203
|
-
options = []
|
204
|
-
unless value.nil?
|
205
|
-
value.each_pair{|k,v| options <<= self.to_param(k, v)}
|
206
|
-
end
|
207
|
-
unless @custom_fields.nil?
|
208
|
-
# special sort to maintain compatibility with AIM custom field ordering
|
209
|
-
# FIXME - This should be DRY'd up.
|
210
|
-
custom_field_keys = @custom_fields.keys.collect(&:to_s).sort.collect(&:to_sym)
|
211
|
-
for key in custom_field_keys
|
212
|
-
options <<= self.to_param(key, @custom_fields[key.to_sym], '')
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
if options.length > 0
|
217
|
-
return options.join('&')
|
218
|
-
else
|
219
|
-
return nil
|
220
|
-
end
|
221
|
-
elsif field == :exp_date
|
222
|
-
# convert MMYY expiration dates into the XML equivalent
|
223
|
-
unless value.nil?
|
224
|
-
begin
|
225
|
-
return value.to_s.downcase == 'xxxx' ? 'XXXX' : Date.strptime(value.to_s, '%m%y').strftime('%Y-%m')
|
226
|
-
rescue
|
227
|
-
# If we didn't get the exp_date in MMYY format, try our best to convert it
|
228
|
-
return Date.parse(value.to_s).strftime('%Y-%m')
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
value
|
234
|
-
end
|
235
|
-
|
236
|
-
# An internal method that builds the POST body, submits it to the gateway, and constructs a Response object with the response.
|
237
|
-
def make_request
|
238
|
-
if has_response?
|
239
|
-
return nil
|
240
|
-
end
|
241
|
-
|
242
|
-
fields = @fields
|
243
|
-
|
244
|
-
builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |x|
|
245
|
-
x.send(@type.to_sym, :xmlns => XML_NAMESPACE) {
|
246
|
-
x.merchantAuthentication {
|
247
|
-
x.name @api_login_id
|
248
|
-
x.transactionKey @api_transaction_key
|
249
|
-
}
|
250
|
-
build_nodes(x, self.class.const_get(:FIELDS)[@type], fields)
|
251
|
-
}
|
252
|
-
end
|
253
|
-
@xml = builder.to_xml
|
254
|
-
url = URI.parse(@gateway)
|
255
|
-
|
256
|
-
request = Net::HTTP::Post.new(url.path)
|
257
|
-
request.content_type = 'text/xml'
|
258
|
-
request.body = @xml
|
259
|
-
connection = Net::HTTP.new(url.host, url.port)
|
260
|
-
connection.use_ssl = true
|
261
|
-
if @verify_ssl
|
262
|
-
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
263
|
-
else
|
264
|
-
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
265
|
-
end
|
266
|
-
|
267
|
-
# Use our Class's @response_class variable to find the Response class we are supposed to use.
|
268
|
-
begin
|
269
|
-
@response = self.class.instance_variable_get(:@response_class).new((connection.start {|http| http.request(request)}), self)
|
270
|
-
rescue
|
271
|
-
@response = self.class.instance_variable_get(:@response_class).new($!, self)
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
end
|
276
|
-
end
|