authorize-net 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/License.pdf +0 -0
  2. data/README.rdoc +124 -0
  3. data/Rakefile +74 -0
  4. data/generators/authorize_net_direct_post/USAGE +20 -0
  5. data/generators/authorize_net_direct_post/authorize_net_direct_post_generator.rb +21 -0
  6. data/generators/authorize_net_direct_post/templates/README-AuthorizeNet +49 -0
  7. data/generators/authorize_net_direct_post/templates/config.yml.erb +8 -0
  8. data/generators/authorize_net_direct_post/templates/config.yml.rails3.erb +8 -0
  9. data/generators/authorize_net_direct_post/templates/controller.rb.erb +31 -0
  10. data/generators/authorize_net_direct_post/templates/initializer.rb +4 -0
  11. data/generators/authorize_net_direct_post/templates/layout.erb +18 -0
  12. data/generators/authorize_net_direct_post/templates/payment.erb +10 -0
  13. data/generators/authorize_net_direct_post/templates/payment.rails3.erb +10 -0
  14. data/generators/authorize_net_direct_post/templates/receipt.erb +1 -0
  15. data/generators/authorize_net_direct_post/templates/relay_response.erb +1 -0
  16. data/generators/authorize_net_sim/USAGE +20 -0
  17. data/generators/authorize_net_sim/authorize_net_sim_generator.rb +19 -0
  18. data/generators/authorize_net_sim/templates/README-AuthorizeNet +52 -0
  19. data/generators/authorize_net_sim/templates/config.yml.erb +8 -0
  20. data/generators/authorize_net_sim/templates/config.yml.rails3.erb +8 -0
  21. data/generators/authorize_net_sim/templates/controller.rb.erb +21 -0
  22. data/generators/authorize_net_sim/templates/initializer.rb +4 -0
  23. data/generators/authorize_net_sim/templates/layout.erb +18 -0
  24. data/generators/authorize_net_sim/templates/payment.erb +6 -0
  25. data/generators/authorize_net_sim/templates/payment.rails3.erb +6 -0
  26. data/generators/authorize_net_sim/templates/thank_you.erb +1 -0
  27. data/generators/generator_extensions.rb +75 -0
  28. data/init.rb +2 -0
  29. data/install.rb +1 -0
  30. data/lib/app/helpers/authorize_net_helper.rb +24 -0
  31. data/lib/authorize-net.rb +4 -0
  32. data/lib/authorize_net.rb +92 -0
  33. data/lib/authorize_net/addresses/address.rb +29 -0
  34. data/lib/authorize_net/addresses/shipping_address.rb +26 -0
  35. data/lib/authorize_net/aim/response.rb +131 -0
  36. data/lib/authorize_net/aim/transaction.rb +184 -0
  37. data/lib/authorize_net/arb/response.rb +34 -0
  38. data/lib/authorize_net/arb/subscription.rb +72 -0
  39. data/lib/authorize_net/arb/transaction.rb +146 -0
  40. data/lib/authorize_net/authorize_net.rb +154 -0
  41. data/lib/authorize_net/cim/customer_profile.rb +19 -0
  42. data/lib/authorize_net/cim/payment_profile.rb +37 -0
  43. data/lib/authorize_net/cim/response.rb +110 -0
  44. data/lib/authorize_net/cim/transaction.rb +678 -0
  45. data/lib/authorize_net/customer.rb +27 -0
  46. data/lib/authorize_net/email_receipt.rb +24 -0
  47. data/lib/authorize_net/fields.rb +736 -0
  48. data/lib/authorize_net/key_value_response.rb +117 -0
  49. data/lib/authorize_net/key_value_transaction.rb +291 -0
  50. data/lib/authorize_net/line_item.rb +25 -0
  51. data/lib/authorize_net/order.rb +42 -0
  52. data/lib/authorize_net/payment_methods/credit_card.rb +74 -0
  53. data/lib/authorize_net/payment_methods/echeck.rb +72 -0
  54. data/lib/authorize_net/reporting/batch.rb +19 -0
  55. data/lib/authorize_net/reporting/batch_statistics.rb +19 -0
  56. data/lib/authorize_net/reporting/fds_filter.rb +11 -0
  57. data/lib/authorize_net/reporting/response.rb +127 -0
  58. data/lib/authorize_net/reporting/transaction.rb +116 -0
  59. data/lib/authorize_net/reporting/transaction_details.rb +25 -0
  60. data/lib/authorize_net/response.rb +27 -0
  61. data/lib/authorize_net/sim/hosted_payment_form.rb +38 -0
  62. data/lib/authorize_net/sim/hosted_receipt_page.rb +37 -0
  63. data/lib/authorize_net/sim/response.rb +142 -0
  64. data/lib/authorize_net/sim/transaction.rb +138 -0
  65. data/lib/authorize_net/transaction.rb +66 -0
  66. data/lib/authorize_net/xml_response.rb +172 -0
  67. data/lib/authorize_net/xml_transaction.rb +275 -0
  68. data/lib/generators/authorize_net/direct_post_generator.rb +51 -0
  69. data/lib/generators/authorize_net/sim_generator.rb +47 -0
  70. data/spec/aim_spec.rb +310 -0
  71. data/spec/arb_spec.rb +191 -0
  72. data/spec/authorize_net_spec.rb +200 -0
  73. data/spec/cim_spec.rb +450 -0
  74. data/spec/reporting_spec.rb +431 -0
  75. data/spec/sim_spec.rb +97 -0
  76. data/spec/spec.opts +5 -0
  77. data/spec/spec_helper.rb +2 -0
  78. data/uninstall.rb +1 -0
  79. metadata +223 -0
@@ -0,0 +1,172 @@
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
+ !connection_failure? && @result_code == 'Ok'
32
+ end
33
+
34
+ # Returns true if we failed to open a connection to the gateway or got back a non-200 OK HTTP response.
35
+ def connection_failure?
36
+ !@raw_response.kind_of?(Net::HTTPOK)
37
+ end
38
+
39
+ # Returns the underlying Net::HTTPResponse object. This has the original response body along with
40
+ # headers and such. Note that if an exception is generated while making the request (which happens
41
+ # if there is no internet connection for example), you will get the exception object here instead of
42
+ # a Net::HTTPResponse object.
43
+ def raw
44
+ @raw_response
45
+ end
46
+
47
+ # Returns a deep-copy of the XML object received from the payment gateway. Or nil if there was no XML payload.
48
+ def xml
49
+ @root.dup unless @root.nil?
50
+ end
51
+
52
+ # Returns the resultCode from the XML response. resultCode will be either 'Ok' or 'Error'.
53
+ def result_code
54
+ @result_code
55
+ end
56
+
57
+ # Returns the messageCode from the XML response. This is a code indicating the details of an error
58
+ # or success.
59
+ def message_code
60
+ @message_code
61
+ end
62
+
63
+ # Returns the messageText from the XML response. This is a text description of the message_code.
64
+ def message_text
65
+ @message_text
66
+ end
67
+
68
+ # Alias for result_code.
69
+ def response_code
70
+ result_code
71
+ end
72
+
73
+ # Alias for message_code.
74
+ def response_reason_code
75
+ message_code
76
+ end
77
+
78
+ # Alias for message_text.
79
+ def response_reason_text
80
+ message_text
81
+ end
82
+
83
+ # Returns the refId from the response if there is one. Otherwise returns nil.
84
+ def reference_id
85
+ @reference_id
86
+ end
87
+
88
+ #:enddoc:
89
+ protected
90
+
91
+ def node_content_unless_nil(node)
92
+ if node.nil?
93
+ nil
94
+ else
95
+ node.content
96
+ end
97
+ end
98
+
99
+ def node_child_content_unless_nil(node)
100
+ if node.nil?
101
+ nil
102
+ else
103
+ if node.children.length > 0
104
+ node.children.collect(&:content)
105
+ else
106
+ nil
107
+ end
108
+ end
109
+ end
110
+
111
+ # Transforms a block of XML into a model Object defined by entity_desc.
112
+ def build_entity(xml, entity_desc)
113
+ args = {}
114
+ entity_desc.node_structure.each do |node_desc|
115
+ node_name = (node_desc.keys.reject {|k| k.to_s[0..0] == '_' }).first
116
+ args.merge!(handle_node_type(xml, node_desc, node_name, args, ''))
117
+ end
118
+
119
+ if args.length == 0
120
+ return nil
121
+ end
122
+
123
+ if entity_desc.arg_mapping.nil?
124
+ return entity_desc.entity_class.new(args)
125
+ else
126
+ args_list = []
127
+ entity_desc.arg_mapping.each do |arg|
128
+ args_list <<= args[arg]
129
+ args.delete(arg)
130
+ end
131
+ args_list <<= args
132
+ return entity_desc.entity_class.new(*args_list)
133
+ end
134
+ end
135
+
136
+ # Parses an XML fragment into an internal representation.
137
+ def handle_node_type(xml, node_desc, node_name, args, base_name)
138
+ case node_desc[node_name]
139
+ when Symbol
140
+ node = xml.at_css(base_name + node_name.to_s)
141
+ unless node.nil?
142
+ content = node.content
143
+ case node_desc[:_converter]
144
+ when Method, Proc
145
+ content = node_desc[:_converter].call(content)
146
+ when Symbol
147
+ content = self.send(node_desc[:_converter], content)
148
+ end
149
+ args[node_desc[node_name]] = content unless content.nil?
150
+ end
151
+ when AuthorizeNet::EntityDescription
152
+ unless node_desc[:_multivalue].nil?
153
+ xml.css(base_name + node_name.to_s).each do |node|
154
+ entity = build_entity(node, node_desc[node_name])
155
+ args[node_desc[:_multivalue]] = args[node_desc[:_multivalue]].to_a + entity.to_a unless entity.nil?
156
+ end
157
+ else
158
+ entity = build_entity(xml.css(base_name + node_name.to_s), node_desc[node_name])
159
+ args[node_desc[:_value]] = entity unless entity.nil?
160
+ end
161
+ when Array
162
+ node_desc[node_name].each do |inner_node|
163
+ inner_node_name = (inner_node.keys.reject {|k| k.to_s[0..0] == '_' }).first
164
+ args.merge!(handle_node_type(xml, inner_node, inner_node_name, args, node_name.to_s + ' '))
165
+ end
166
+ end
167
+ return args
168
+ end
169
+
170
+ end
171
+
172
+ end
@@ -0,0 +1,275 @@
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
+ CIM_CREATE_PROFILE = "createCustomerProfileRequest"
22
+ CIM_CREATE_PAYMENT = "createCustomerPaymentProfileRequest"
23
+ CIM_CREATE_ADDRESS = "createCustomerShippingAddressRequest"
24
+ CIM_CREATE_TRANSACTION = "createCustomerProfileTransactionRequest"
25
+ CIM_DELETE_PROFILE = "deleteCustomerProfileRequest"
26
+ CIM_DELETE_PAYMENT = "deleteCustomerPaymentProfileRequest"
27
+ CIM_DELETE_ADDRESS = "deleteCustomerShippingAddressRequest"
28
+ CIM_GET_PROFILE_IDS = "getCustomerProfileIdsRequest"
29
+ CIM_GET_PROFILE = "getCustomerProfileRequest"
30
+ CIM_GET_PAYMENT = "getCustomerPaymentProfileRequest"
31
+ CIM_GET_ADDRESS = "getCustomerShippingAddressRequest"
32
+ CIM_UPDATE_PROFILE = "updateCustomerProfileRequest"
33
+ CIM_UPDATE_PAYMENT = "updateCustomerPaymentProfileRequest"
34
+ CIM_UPDATE_ADDRESS = "updateCustomerShippingAddressRequest"
35
+ CIM_UPDATE_SPLIT = "updateSplitTenderGroupRequest"
36
+ CIM_VALIDATE_PAYMENT = "validateCustomerPaymentProfileRequest"
37
+ REPORT_GET_BATCH_LIST = "getSettledBatchListRequest"
38
+ REPORT_GET_TRANSACTION_LIST = "getTransactionListRequest"
39
+ REPORT_GET_TRANSACTION_DETAILS = "getTransactionDetailsRequest"
40
+ end
41
+
42
+ # Fields to convert to/from booleans.
43
+ @@boolean_fields = []
44
+
45
+ # Fields to convert to/from BigDecimal.
46
+ @@decimal_fields = []
47
+
48
+ # Fields to convert to/from Date.
49
+ @@date_fields = []
50
+
51
+ # Fields to convert to/from DateTime.
52
+ @@datetime_fields = []
53
+
54
+ # The class to wrap our response in.
55
+ @response_class = AuthorizeNet::XmlResponse
56
+
57
+ # The default options for the constructor.
58
+ @@option_defaults = {
59
+ :gateway => :production,
60
+ :verify_ssl => false,
61
+ :reference_id => nil
62
+ }
63
+
64
+ # DO NOT USE. Instantiate AuthorizeNet::ARB::Transaction or AuthorizeNet::CIM::Transaction instead.
65
+ def initialize(api_login_id, api_transaction_key, options = {})
66
+ super()
67
+ @api_login_id = api_login_id
68
+ @api_transaction_key = api_transaction_key
69
+
70
+ @response ||= nil
71
+ @type ||= nil
72
+
73
+ options = @@option_defaults.merge(options)
74
+ @verify_ssl = options[:verify_ssl]
75
+ @reference_id = options[:reference_id]
76
+ case options[:gateway]
77
+ when :sandbox, :test
78
+ @gateway = Gateway::TEST
79
+ when :production, :live
80
+ @gateway = Gateway::LIVE
81
+ else
82
+ @gateway = options[:gateway]
83
+ end
84
+ end
85
+
86
+ # Checks if the transaction has been configured for the sandbox or not. Return FALSE if the
87
+ # transaction is running against the production, TRUE otherwise.
88
+ def test?
89
+ @gateway != Gateway::LIVE
90
+ end
91
+
92
+ # Checks to see if the transaction has a response (meaning it has been submitted to the gateway).
93
+ # Returns TRUE if a response is present, FALSE otherwise.
94
+ def has_response?
95
+ !@response.nil?
96
+ end
97
+
98
+ # Retrieve the response object (or Nil if transaction hasn't been sent to the gateway).
99
+ def response
100
+ @response
101
+ end
102
+
103
+ # Submits the transaction to the gateway for processing. Returns a response object. If the transaction
104
+ # has already been run, it will return nil.
105
+ def run
106
+ make_request
107
+ end
108
+
109
+ # Returns a deep-copy of the XML object sent to the payment gateway. Or nil if there was no XML payload.
110
+ def xml
111
+ @xml
112
+ end
113
+
114
+ #:enddoc:
115
+ protected
116
+
117
+ # Takes a list of nodes (a Hash is a node, and Array is a list) and returns True if any nodes
118
+ # would be built by build_nodes. False if no new nodes would be generated.
119
+ def has_content(nodeList, data)
120
+ nodeList.each do |node|
121
+ nodeName = (node.keys.reject {|k| nodeName.to_s[0..0] == '_' }).first
122
+ multivalue = node[:_multivalue]
123
+ conditional = node[:_conditional]
124
+ value = node[nodeName]
125
+ unless conditional.nil?
126
+ value = self.send(conditional, nodeName)
127
+ end
128
+ case value
129
+ when Array
130
+ if multivalue.nil?
131
+ if has_content(value, data)
132
+ return true
133
+ end
134
+ else
135
+ data[multivalue].each do |v|
136
+ if has_content(value, v)
137
+ return true
138
+ end
139
+ end
140
+ end
141
+ when Symbol
142
+ converted = convert_field(value, data[value])
143
+ return true unless converted.nil?
144
+ else
145
+ return true
146
+ end
147
+ end
148
+ false
149
+ end
150
+
151
+ # Takes a list of nodes (a Hash is a node, and Array is a list) and recursively builds the XML by pulling
152
+ # values as needed from data.
153
+ def build_nodes(builder, nodeList, data)
154
+ nodeList.each do |node|
155
+ # TODO - ADD COMMENTS HERE
156
+ nodeName = (node.keys.reject {|k| k.to_s[0..0] == '_' }).first
157
+ multivalue = node[:_multivalue]
158
+ conditional = node[:_conditional]
159
+ value = node[nodeName]
160
+ unless conditional.nil?
161
+ value = self.send(conditional, nodeName)
162
+ end
163
+ case value
164
+ when Array # node containing other nodes
165
+ if multivalue.nil?
166
+ proc = Proc.new { build_nodes(builder, value, data) }
167
+ builder.send(nodeName, &proc) if has_content(value, data)
168
+ else
169
+ data[multivalue].to_a.each do |v|
170
+ proc = Proc.new { build_nodes(builder, value, v) }
171
+ builder.send(nodeName, &proc) if has_content(value, v)
172
+ end
173
+ end
174
+ when Symbol # node containing actual data
175
+ if data[value].kind_of?(Array)
176
+ data[value].each do |v|
177
+ converted = convert_field(value, v)
178
+ builder.send(nodeName, converted) unless converted.nil?
179
+ end
180
+ else
181
+ converted = convert_field(value, data[value])
182
+ builder.send(nodeName, converted) unless converted.nil?
183
+ end
184
+ else
185
+ builder.send(nodeName, value)
186
+ end
187
+ end
188
+ end
189
+
190
+ def convert_field(field, value)
191
+ if @@boolean_fields.include?(field) and !value.nil?
192
+ return boolean_to_value(value)
193
+ elsif @@decimal_fields.include?(field) and !value.nil?
194
+ return decimal_to_value(value)
195
+ elsif @@date_fields.include?(field) and !value.nil?
196
+ return date_to_value(value)
197
+ elsif @@datetime_fields.include?(field) and !value.nil?
198
+ return datetime_to_value(value)
199
+ elsif field == :extra_options
200
+ # handle converting extra options
201
+ options = []
202
+ unless value.nil?
203
+ value.each_pair{|k,v| options <<= self.to_param(k, v)}
204
+ end
205
+ unless @custom_fields.nil?
206
+ # special sort to maintain compatibility with AIM custom field ordering
207
+ # FIXME - This should be DRY'd up.
208
+ custom_field_keys = @custom_fields.keys.collect(&:to_s).sort.collect(&:to_sym)
209
+ for key in custom_field_keys
210
+ options <<= self.to_param(key, @custom_fields[key.to_sym], '')
211
+ end
212
+ end
213
+
214
+ if options.length > 0
215
+ return options.join('&')
216
+ else
217
+ return nil
218
+ end
219
+ elsif field == :exp_date
220
+ # convert MMYY expiration dates into the XML equivalent
221
+ unless value.nil?
222
+ begin
223
+ return Date.strptime(value.to_s, '%m%y').strftime('%Y-%m')
224
+ rescue
225
+ # If we didn't get the exp_date in MMYY format, try our best to convert it
226
+ return Date.parse(value.to_s).strftime('%Y-%m')
227
+ end
228
+ end
229
+ end
230
+
231
+ value
232
+ end
233
+
234
+ # An internal method that builds the POST body, submits it to the gateway, and constructs a Response object with the response.
235
+ def make_request
236
+ if has_response?
237
+ return nil
238
+ end
239
+
240
+ fields = @fields
241
+
242
+ builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |x|
243
+ x.send(@type.to_sym, :xmlns => XML_NAMESPACE) {
244
+ x.merchantAuthentication {
245
+ x.name @api_login_id
246
+ x.transactionKey @api_transaction_key
247
+ }
248
+ build_nodes(x, self.class.const_get(:FIELDS)[@type], fields)
249
+ }
250
+ end
251
+ @xml = builder.to_xml
252
+
253
+ url = URI.parse(@gateway)
254
+
255
+ request = Net::HTTP::Post.new(url.path)
256
+ request.content_type = 'text/xml'
257
+ request.body = @xml
258
+ connection = Net::HTTP.new(url.host, url.port)
259
+ connection.use_ssl = true
260
+ if @verify_ssl
261
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
262
+ else
263
+ connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
264
+ end
265
+
266
+ # Use our Class's @response_class variable to find the Response class we are supposed to use.
267
+ begin
268
+ @response = self.class.instance_variable_get(:@response_class).new((connection.start {|http| http.request(request)}), self)
269
+ rescue
270
+ @response = self.class.instance_variable_get(:@response_class).new($!, self)
271
+ end
272
+ end
273
+
274
+ end
275
+ end
@@ -0,0 +1,51 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/named_base'
3
+
4
+ module AuthorizeNet
5
+ module Generators
6
+ class DirectPostGenerator < Rails::Generators::NamedBase
7
+ source_root File.expand_path("../../../../generators/authorize_net_direct_post/templates", __FILE__)
8
+ argument :api_login_id, :type => :string, :desc => 'Your Authorize.Net API login ID.', :optional => true
9
+ argument :api_transaction_key, :type => :string, :desc => 'Your Authorize.Net API transaction key.', :optional => true
10
+ argument :merchant_hash_value, :type => :string, :desc => 'Your Authorize.Net merchant hash value.', :optional => true
11
+ desc <<-DESC
12
+ Description
13
+ Generates a simple implementation of Authorize.Net's Direct Post Method integration method.
14
+
15
+ Example:
16
+ rails generate authorize_net:direct_post payments API_LOGIN_ID API_TRANSACTION_KEY MERCHANT_HASH_VALUE
17
+
18
+ This will create:
19
+ create README-AuthorizeNet
20
+ create app/views/payments
21
+ create app/views/payments/payment.erb
22
+ create app/views/payments/receipt.erb
23
+ create app/views/payments/relay_response.erb
24
+ create app/views/layouts/authorize_net.erb
25
+ create config/authorize_net.yml
26
+ create config/initializers/authorize_net.rb
27
+ create app/controllers/payments_controller.rb
28
+ route match '/payments/receipt', :to => 'payments#receipt', :as => 'payments_receipt', :via => [:get]
29
+ route match '/payments/relay_response', :to => 'payments#relay_response', :as => 'payments_relay_response', :via => [:post]
30
+ route match '/payments/payment', :to => 'payments#payment', :as => 'paymentspayment', :via => [:get]
31
+
32
+ DESC
33
+
34
+ def manifest
35
+ copy_file "README-AuthorizeNet", "README-AuthorizeNet"
36
+ empty_directory "app/views/#{file_name}"
37
+ copy_file "payment.rails3.erb", "app/views/#{file_name}/payment.erb"
38
+ copy_file "receipt.erb", "app/views/#{file_name}/receipt.erb"
39
+ copy_file "relay_response.erb", "app/views/#{file_name}/relay_response.erb"
40
+ copy_file "layout.erb", "app/views/layouts/authorize_net.erb"
41
+ template "config.yml.rails3.erb", "config/authorize_net.yml"
42
+ copy_file "initializer.rb", "config/initializers/authorize_net.rb"
43
+ template "controller.rb.erb", "app/controllers/#{file_name}_controller.rb"
44
+ route "match '/#{plural_name}/receipt', :to => '#{file_name}#receipt', :as => '#{singular_name}_receipt', :via => [:get]"
45
+ route "match '/#{plural_name}/relay_response', :to => '#{file_name}#relay_response', :as => '#{singular_name}_relay_response', :via => [:post]"
46
+ route "match '/#{plural_name}/payment', :to => '#{file_name}#payment', :as => '#{singular_name}payment', :via => [:get]"
47
+ end
48
+
49
+ end
50
+ end
51
+ end