authorizenet_blaq 1.9.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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/lib/app/helpers/authorize_net_helper.rb +24 -0
  3. data/lib/authorize_net/addresses/address.rb +29 -0
  4. data/lib/authorize_net/addresses/shipping_address.rb +26 -0
  5. data/lib/authorize_net/aim/response.rb +131 -0
  6. data/lib/authorize_net/aim/transaction.rb +190 -0
  7. data/lib/authorize_net/api/api_transaction.rb +123 -0
  8. data/lib/authorize_net/api/constants.yml +1 -0
  9. data/lib/authorize_net/api/schema.rb +4985 -0
  10. data/lib/authorize_net/api/transaction.rb +258 -0
  11. data/lib/authorize_net/arb/fields.rb +24 -0
  12. data/lib/authorize_net/arb/paging.rb +33 -0
  13. data/lib/authorize_net/arb/response.rb +34 -0
  14. data/lib/authorize_net/arb/sorting.rb +43 -0
  15. data/lib/authorize_net/arb/subscription.rb +72 -0
  16. data/lib/authorize_net/arb/subscription_detail.rb +14 -0
  17. data/lib/authorize_net/arb/subscription_list_response.rb +43 -0
  18. data/lib/authorize_net/arb/transaction.rb +177 -0
  19. data/lib/authorize_net/authorize_net.rb +154 -0
  20. data/lib/authorize_net/cim/customer_profile.rb +19 -0
  21. data/lib/authorize_net/cim/payment_profile.rb +37 -0
  22. data/lib/authorize_net/cim/response.rb +116 -0
  23. data/lib/authorize_net/cim/transaction.rb +727 -0
  24. data/lib/authorize_net/customer.rb +27 -0
  25. data/lib/authorize_net/email_receipt.rb +24 -0
  26. data/lib/authorize_net/fields.rb +779 -0
  27. data/lib/authorize_net/key_value_response.rb +117 -0
  28. data/lib/authorize_net/key_value_transaction.rb +291 -0
  29. data/lib/authorize_net/line_item.rb +25 -0
  30. data/lib/authorize_net/order.rb +42 -0
  31. data/lib/authorize_net/payment_methods/credit_card.rb +62 -0
  32. data/lib/authorize_net/payment_methods/echeck.rb +72 -0
  33. data/lib/authorize_net/reporting/batch.rb +19 -0
  34. data/lib/authorize_net/reporting/batch_statistics.rb +19 -0
  35. data/lib/authorize_net/reporting/fds_filter.rb +11 -0
  36. data/lib/authorize_net/reporting/response.rb +163 -0
  37. data/lib/authorize_net/reporting/returned_item.rb +46 -0
  38. data/lib/authorize_net/reporting/transaction.rb +133 -0
  39. data/lib/authorize_net/reporting/transaction_details.rb +25 -0
  40. data/lib/authorize_net/response.rb +27 -0
  41. data/lib/authorize_net/sim/hosted_payment_form.rb +38 -0
  42. data/lib/authorize_net/sim/hosted_receipt_page.rb +37 -0
  43. data/lib/authorize_net/sim/response.rb +142 -0
  44. data/lib/authorize_net/sim/transaction.rb +138 -0
  45. data/lib/authorize_net/transaction.rb +66 -0
  46. data/lib/authorize_net/xml_response.rb +172 -0
  47. data/lib/authorize_net/xml_transaction.rb +298 -0
  48. data/lib/authorize_net.rb +107 -0
  49. data/lib/authorizenet_blaq.rb +4 -0
  50. data/lib/generators/authorize_net/direct_post/direct_post_generator.rb +53 -0
  51. data/lib/generators/authorize_net/direct_post/templates/README-AuthorizeNet +49 -0
  52. data/lib/generators/authorize_net/direct_post/templates/config.yml.erb +8 -0
  53. data/lib/generators/authorize_net/direct_post/templates/config.yml.rails3.erb +8 -0
  54. data/lib/generators/authorize_net/direct_post/templates/controller.rb.erb +31 -0
  55. data/lib/generators/authorize_net/direct_post/templates/initializer.rb +4 -0
  56. data/lib/generators/authorize_net/direct_post/templates/layout.erb +18 -0
  57. data/lib/generators/authorize_net/direct_post/templates/payment.erb +10 -0
  58. data/lib/generators/authorize_net/direct_post/templates/payment.rails3.erb +10 -0
  59. data/lib/generators/authorize_net/direct_post/templates/receipt.erb +1 -0
  60. data/lib/generators/authorize_net/direct_post/templates/relay_response.erb +1 -0
  61. data/lib/generators/authorize_net/sim/sim_generator.rb +47 -0
  62. data/lib/generators/authorize_net/sim/templates/README-AuthorizeNet +52 -0
  63. data/lib/generators/authorize_net/sim/templates/config.yml.erb +8 -0
  64. data/lib/generators/authorize_net/sim/templates/config.yml.rails3.erb +8 -0
  65. data/lib/generators/authorize_net/sim/templates/controller.rb.erb +21 -0
  66. data/lib/generators/authorize_net/sim/templates/initializer.rb +4 -0
  67. data/lib/generators/authorize_net/sim/templates/layout.erb +18 -0
  68. data/lib/generators/authorize_net/sim/templates/payment.erb +6 -0
  69. data/lib/generators/authorize_net/sim/templates/payment.rails3.erb +6 -0
  70. data/lib/generators/authorize_net/sim/templates/thank_you.erb +1 -0
  71. data/lib/generators/generator_extensions.rb +75 -0
  72. metadata +196 -0
@@ -0,0 +1,163 @@
1
+ module AuthorizeNet::Reporting
2
+
3
+ # The CIM response class.
4
+ class Response < AuthorizeNet::XmlResponse
5
+
6
+ include AuthorizeNet::CIM::Fields
7
+
8
+ # Constructs a new response object from raw_response in the context of transaction.
9
+ # You don‘t typically construct this object yourself, as AuthorizeNet::Reeporting::Transaction
10
+ # will build one for you when it makes the request to the gateway.
11
+ def initialize(raw_response, transaction)
12
+ super
13
+ unless connection_failure?
14
+ begin
15
+ @batch_list = @root.at_css('batchList')
16
+ @transactions = @root.at_css('transactions')
17
+ @transaction = @root.at_css('transaction')
18
+ rescue
19
+ @raw_response = $!
20
+ end
21
+ end
22
+ end
23
+
24
+
25
+ # Returns an Array of Batch objects built from the entities returned in the response. Returns nil if no batchList was returned.
26
+ def batch_list
27
+ unless @batch_list.nil?
28
+ batches = []
29
+ @batch_list.element_children.each do |child|
30
+ batches <<= build_entity(child, Fields::BATCH_ENTITY_DESCRIPTION) unless child.nil?
31
+ end
32
+ return batches unless batches.length == 0
33
+ end
34
+ end
35
+
36
+ # Returns an Array of TransactionDetail objects built from the entities returned in the response. Returns nil if no transactions were returned.
37
+ def transactions
38
+ unless @transactions.nil?
39
+ transactions = []
40
+ @transactions.element_children.each do |child|
41
+ unless child.nil?
42
+ transaction = build_entity(child, Fields::TRANSACTION_DETAILS_ENTITY_DESCRIPTION)
43
+
44
+ # handle some stuff thats too tricky for EntityDecription to handle
45
+ first_name = node_content_unless_nil(child.at_css('firstName'))
46
+ last_name = node_content_unless_nil(child.at_css('lastName'))
47
+ unless first_name.nil? && last_name.nil?
48
+ address = AuthorizeNet::Address.new(:first_name => first_name, :last_name => last_name)
49
+ transaction.customer = AuthorizeNet::Customer.new(:address => address)
50
+ end
51
+ invoice_number = node_content_unless_nil(child.at_css('invoiceNumber'))
52
+ unless invoice_number.nil?
53
+ transaction.order = AuthorizeNet::Order.new(:invoice_num => invoice_number)
54
+ end
55
+ subscription = child.at_css('subscription')
56
+ unless subscription.nil?
57
+ subscription_id = node_content_unless_nil(child.at_css('subscription').at_css('id'))
58
+ transaction.subscription_id = subscription_id unless subscription_id.nil?
59
+
60
+ pay_num = node_content_unless_nil(child.at_css('subscription').at_css('payNum'))
61
+ transaction.subscription_paynum = pay_num unless pay_num.nil?
62
+ end
63
+
64
+
65
+ transactions <<= transaction
66
+ end
67
+ end
68
+ return transactions unless transactions.length == 0
69
+ end
70
+ end
71
+
72
+ # Builds and returns a TransactionDetail entity built from the response. If no transaction was found, returns nil.
73
+ def transaction
74
+ unless @transaction.nil?
75
+ transaction = build_entity(@transaction, Fields::TRANSACTION_DETAILS_ENTITY_DESCRIPTION)
76
+
77
+ ip = node_content_unless_nil(@transaction.at_css('customerIP'))
78
+ unless ip.nil?
79
+ transaction.customer ||= AuthorizeNet::CIM::CustomerProfile.new()
80
+ transaction.customer.ip = ip
81
+ end
82
+
83
+ tax_exempt = node_content_unless_nil(@transaction.at_css('taxExempt'))
84
+ unless tax_exempt.nil?
85
+ transaction.order ||= AuthorizeNet::Order.new()
86
+ transaction.order.tax_exempt = value_to_boolean(tax_exempt)
87
+ end
88
+
89
+ tax = @transaction.at_css('tax')
90
+ unless tax.nil?
91
+ transaction.order ||= AuthorizeNet::Order.new()
92
+ tax_amount = node_content_unless_nil(tax.at_css('amount'))
93
+ transaction.order.tax_amount = value_to_decimal(tax_amount) unless tax_amount.nil?
94
+ transaction.order.tax_name = node_content_unless_nil(tax.at_css('name'))
95
+ transaction.order.tax_description = node_content_unless_nil(tax.at_css('description'))
96
+ end
97
+
98
+ shipping = @transaction.at_css('shipping')
99
+ unless shipping.nil?
100
+ transaction.order ||= AuthorizeNet::Order.new()
101
+ shipping_amount = node_content_unless_nil(shipping.at_css('amount'))
102
+ transaction.order.shipping_amount = value_to_decimal(shipping_amount) unless shipping_amount.nil?
103
+ transaction.order.shipping_name = node_content_unless_nil(shipping.at_css('name'))
104
+ transaction.order.shipping_description = node_content_unless_nil(shipping.at_css('description'))
105
+ end
106
+
107
+ duty = @transaction.at_css('duty')
108
+ unless duty.nil?
109
+ transaction.order ||= AuthorizeNet::Order.new()
110
+ duty_amount = node_content_unless_nil(duty.at_css('amount'))
111
+ transaction.order.duty_amount = value_to_decimal(duty_amount) unless duty_amount.nil?
112
+ transaction.order.duty_name = node_content_unless_nil(duty.at_css('name'))
113
+ transaction.order.duty_description = node_content_unless_nil(duty.at_css('description'))
114
+ end
115
+
116
+ line_items = @transaction.at_css('lineItems')
117
+ unless line_items.nil?
118
+ transaction.order ||= AuthorizeNet::Order.new()
119
+ line_items.element_children.each do |child|
120
+ line_item = build_entity(child, Fields::LINE_ITEM_ENTITY_DESCRIPTION)
121
+ transaction.order.add_line_item(line_item)
122
+ end
123
+ end
124
+
125
+ # Really not sure what to do with customer type here. It should go on a payment
126
+ customer_type = node_content_unless_nil(@transaction.at_css('customer type'))
127
+ unless customer_type.nil?
128
+ transaction.customer ||= AuthorizeNet::CIM::CustomerProfile.new()
129
+ transaction.customer.payment_profiles = [AuthorizeNet::CIM::PaymentProfile.new(:cust_type => customer_type)]
130
+ end
131
+
132
+ subscription = @transaction.at_css('subscription')
133
+ unless subscription.nil?
134
+ subscription_id = node_content_unless_nil(@transaction.at_css('subscription').at_css('id'))
135
+ transaction.subscription_id = value_to_decimal(subscription_id) unless subscription_id.nil?
136
+
137
+ pay_num = node_content_unless_nil(@transaction.at_css('subscription').at_css('payNum'))
138
+ transaction.subscription_paynum = value_to_decimal(pay_num) unless pay_num.nil?
139
+ end
140
+
141
+ solution = @transaction.at_css('solution')
142
+ unless solution.nil?
143
+ solution_id = node_content_unless_nil(@transaction.at_css('solution').at_css('id'))
144
+ transaction.solution_id = value_to_decimal(solution_id) unless solution_id.nil?
145
+
146
+ transaction.solution_name = node_content_unless_nil(@transaction.at_css('solution').at_css('name'))
147
+ end
148
+
149
+ returned_items = @transaction.at_css('returnedItems')
150
+ unless returned_items.nil?
151
+ transaction.returns ||= AuthorizeNet::Reporting::ReturnedItem.new
152
+ returned_items.element_children.each do |child|
153
+ returned_item = build_entity(child, Fields::RETURNED_ITEM_ENTITY_DESCRIPTION)
154
+ transaction.returns.add_returned_item(returned_item)
155
+ end
156
+ end
157
+
158
+ return transaction
159
+ end
160
+ end
161
+
162
+ end
163
+ end
@@ -0,0 +1,46 @@
1
+ module AuthorizeNet::Reporting
2
+
3
+ class ReturnedItem
4
+ include AuthorizeNet::Model
5
+
6
+ attr_accessor :id, :date_utc, :date_local, :code, :description, :returned_items
7
+
8
+ def date_utc=(time)
9
+ if time.kind_of?(DateTime)
10
+ @date_utc = time
11
+ else
12
+ @date_utc = DateTime.parse(time.to_s)
13
+ end
14
+ end
15
+
16
+ def date_local=(time)
17
+ if time.kind_of?(DateTime)
18
+ @date_local = time
19
+ else
20
+ @date_local = DateTime.parse(time.to_s)
21
+ end
22
+ end
23
+
24
+ def add_returned_item(id = nil, date_utc = nil, date_local = nil, code = nil, description = nil)
25
+ if id.kind_of?(AuthorizeNet::Reporting::ReturnedItem)
26
+ returned_item = id
27
+ else
28
+ returned_item = AuthorizeNet::Reporting::ReturnedItem.new({:return_item_id => id, :return_item_date_utc => date_utc, :return_item_date_local => date_local, :return_item_code => code, :line_item_description => description})
29
+ end
30
+ @returned_items = @returned_items.to_a << returned_item
31
+ end
32
+
33
+ def to_hash
34
+ hash = {
35
+ :id => @id,
36
+ :date_utc => @date_utc,
37
+ :date_local => @date_local,
38
+ :code => @code,
39
+ :description => @description,
40
+ :returned_items => handle_multivalue_hashing(@returned_items)
41
+ }
42
+ hash.delete_if { |k, v| v.nil? }
43
+ hash
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,133 @@
1
+ module AuthorizeNet::Reporting
2
+
3
+ # The Reporting API transaction class.
4
+ class Transaction < AuthorizeNet::XmlTransaction
5
+
6
+ include AuthorizeNet::Reporting::Fields
7
+
8
+ # The class to wrap our response in.
9
+ @response_class = AuthorizeNet::Reporting::Response
10
+
11
+ # Fields to convert to/from Date.
12
+ @@datetime_fields = [:first_settlement_date, :last_settlement_date]
13
+
14
+ # Constructs a Reporting transaction. You can use the new Reporting transaction object
15
+ # to issue a request to the payment gateway and parse the response into a new
16
+ # AuthorizeNet::Reporting::Response object.
17
+ #
18
+ # +api_login_id+:: Your API login ID, as a string.
19
+ # +api_transaction_key+:: Your API transaction key, as a string.
20
+ # +options+:: A hash of options. See below for values.
21
+ #
22
+ # Options
23
+ # +gateway+:: The gateway to submit the transaction to. Can be a URL string, an AuthorizeNet::Reporting::Transaction::Gateway constant, or one of the convenience symbols :sandbox, :test, :production, or :live (:test is an alias for :sandbox, and :live is an alias for :production).
24
+ # +verify_ssl+:: A boolean indicating if the SSL certificate of the +gateway+ should be verified. Defaults to true.
25
+ # +reference_id+:: A string that can be used to identify a particular transaction with its response. Will be echo'd in the response, only if it was provided in the transaction. Defaults to nil.
26
+ #
27
+ def initialize(api_login_id, api_transaction_key, options = {})
28
+ super
29
+ end
30
+
31
+ # Sets up and submits a getSettledBatchListRequest transaction. If this transaction has already been
32
+ # run, this method will return nil. Otherwise it will return an AuthorizeNet::Reporting::Response object. The
33
+ # response object will have an array of Batch objects available via its batch_list method if
34
+ # the request was successful.
35
+ #
36
+ #
37
+ # +from_date+:: Takes either a DateTime or a String representing a date and time. Only settled batches >= this value will be returned. Defaults to nil (which returns >= 24hrs ago). A to_date must be specified if a from_date is.
38
+ # +to_date+:: Takes either a DateTime or a String representing a date and time. Only settled batches <= this value will be returned. Defaults to nil. The maximum date range is 31 days, and a from_date must be supplied if a to_date is.
39
+ # +include_stats+:: Takes a Boolean. Determines if BatchStatistics should be returned with the Batch objects. Defaults to false.
40
+ #
41
+ # Typical usage:
42
+ #
43
+ # response = transaction.get_settled_batch_list(DateTime.now() - (1 * 3600 * 48), DateTime.now(), true)
44
+ # batches = response.batch_list if response.success?
45
+ #
46
+ def get_settled_batch_list(from_date = nil, to_date = nil, include_stats = false)
47
+ @type = Type::REPORT_GET_BATCH_LIST
48
+ set_fields({:first_settlement_date => from_date, :last_settlement_date => to_date, :include_statistics => include_stats})
49
+ make_request
50
+ end
51
+
52
+ # Sets up and submits a getTransactionListRequest transaction. If this transaction has already been
53
+ # run, this method will return nil. Otherwise it will return an AuthorizeNet::Reporting::Response object. The
54
+ # response object will have an array of TransactionDetail objects available via its transactions method if
55
+ # the request was successful. These TransactionDetail objects will not be fully populated. Use get_transaction_details
56
+ # to get all the details.
57
+ #
58
+ #
59
+ # +batch_id+:: Takes either a Batch object with its id attribute populated, or a String representing the ID of the batch to retrieve the transaction list from.
60
+ #
61
+ # Typical usage:
62
+ #
63
+ # response = transaction.get_transaction_list('123456')
64
+ # transactions = response.transactions if response.success?
65
+ #
66
+ def get_transaction_list(batch_id)
67
+ @type = Type::REPORT_GET_TRANSACTION_LIST
68
+ handle_batch_id(batch_id)
69
+ make_request
70
+ end
71
+
72
+ # Sets up and submits a getUnsettledTransactionListRequest transaction. If this transaction has already been
73
+ # run, this method will return nil. Otherwise it will return an AuthorizeNet::Reporting::Response object. The
74
+ # response object will have an array of TransactionDetail objects available via its transactions method if
75
+ # the request was successful. These TransactionDetail objects will not be fully populated. Use get_transaction_details
76
+ # to get all the details.
77
+ #
78
+ #
79
+ # Typical usage:
80
+ #
81
+ # response = transaction.get_unsettled_transaction_list
82
+ # transactions = response.transactions if response.success?
83
+ #
84
+ def get_unsettled_transaction_list
85
+ @type = Type::REPORT_GET_UNSETTLED_TRANSACTION_LIST
86
+ make_request
87
+ end
88
+
89
+ # Sets up and submits a getTransactionDetailsRequest transaction. If this transaction has already been
90
+ # run, this method will return nil. Otherwise it will return an AuthorizeNet::Reporting::Response object. The
91
+ # response object will have a TransactionDetail object available via its transactions method if
92
+ # the request was successful. This TransactionDetail object will have more data than the limited version
93
+ # returned by get_transaction_list.
94
+ #
95
+ #
96
+ # +transaction_id+:: Takes either a TransactionDetail object with its id attribute populated, or a String representing the ID of the transaction to retrieve the details from.
97
+ #
98
+ # Typical usage:
99
+ #
100
+ # response = transaction.get_transaction_details('123456789')
101
+ # transactions = response.transactions if response.success?
102
+ #
103
+ def get_transaction_details(transaction_id)
104
+ @type = Type::REPORT_GET_TRANSACTION_DETAILS
105
+ handle_transaction_id(transaction_id)
106
+ make_request
107
+ end
108
+
109
+ #:enddoc:
110
+ protected
111
+
112
+ # Handles batch id type massaging.
113
+ def handle_batch_id(id)
114
+ case id
115
+ when Batch
116
+ set_fields(:batch_id => id.id.to_s)
117
+ else
118
+ set_fields(:batch_id => id.to_s)
119
+ end
120
+ end
121
+
122
+ # Handles transaction id type massaging.
123
+ def handle_transaction_id(id)
124
+ case id
125
+ when TransactionDetails
126
+ set_fields(:transaction_id => id.id.to_s)
127
+ else
128
+ set_fields(:transaction_id => id.to_s)
129
+ end
130
+ end
131
+ end
132
+
133
+ end
@@ -0,0 +1,25 @@
1
+ module AuthorizeNet::Reporting
2
+
3
+ # Models the details of a transaction.
4
+ class TransactionDetails
5
+
6
+ include AuthorizeNet::Model
7
+
8
+ attr_accessor :id, :submitted_at, :status, :order, :customer, :account_type,
9
+ :account_number, :settle_amount, :reference_id, :split_tender_id,
10
+ :type, :response_code, :response_reason_code, :response_reason_description,
11
+ :auth_code, :avs_response, :card_code_response, :cavv_response,
12
+ :fds_filter_action, :fds_filters, :batch, :prepaid_balance_remaining,
13
+ :payment_method, :recurring_billing, :bill_to, :ship_to, :auth_amount,
14
+ :subscription_id, :subscription_paynum, :solution_id, :solution_name, :returns
15
+
16
+ def submitted_at=(time)
17
+ if time.kind_of?(DateTime)
18
+ @submitted_at = time
19
+ else
20
+ @submitted_at = DateTime.parse(time.to_s)
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ module AuthorizeNet
2
+
3
+ # The core, API agnostic response class. You shouldn't instantiate this one.
4
+ # Instead you should use AuthorizeNet::AIM::Response, AuthorizeNet::ARB::Response or AuthorizeNet::SIM::Response.
5
+ class Response
6
+
7
+ include AuthorizeNet::TypeConversions
8
+
9
+ # Fields to convert to/from booleans.
10
+ @@boolean_fields = []
11
+
12
+ # Fields to convert to/from BigDecimal.
13
+ @@decimal_fields = []
14
+
15
+ # DO NOT USE. Instantiate AuthorizeNet::AIM::Response or AuthorizeNet::SIM::Response instead.
16
+ def initialize()
17
+ raise "#{self.class.to_s} should not be instantiated directly."
18
+ end
19
+
20
+ # Check to see if the response indicated success.
21
+ def success?
22
+ false
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,38 @@
1
+ module AuthorizeNet::SIM
2
+
3
+ # Models a hosted payment form.
4
+ class HostedPaymentForm
5
+
6
+ include AuthorizeNet::Model
7
+
8
+ attr_accessor :header_html, :footer_html, :color_background, :color_link, :color_text, :logo_url, :background_url, :rename
9
+
10
+ # Convenience method for adding field rename requests to the transaction. This renames a field shown on
11
+ # the hosted payment form.
12
+ def add_rename(field, name)
13
+ rename = "#{field},#{name}"
14
+ unless @rename.nil?
15
+ @rename = @rename.to_a << rename
16
+ else
17
+ @rename = [rename]
18
+ end
19
+ end
20
+
21
+ def to_hash
22
+ hash = {
23
+ :header_html_payment_form => @header_html,
24
+ :footer_html_payment_form => @footer_html,
25
+ :color_background => @color_background,
26
+ :color_link => @color_link,
27
+ :color_text => @color_text,
28
+ :logo_url => @logo_url,
29
+ :background_url => @background_url,
30
+ :rename => @rename
31
+ }
32
+ hash.delete_if {|k, v| v.nil?}
33
+ hash
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,37 @@
1
+ module AuthorizeNet::SIM
2
+
3
+ # Models a hosted receipt page.
4
+ class HostedReceiptPage
5
+
6
+ # Defines constants for each of the link methods used by the hosted receipt page.
7
+ module LinkMethod
8
+ LINK = 'LINK'
9
+ POST = 'POST'
10
+ GET = 'GET'
11
+ end
12
+
13
+ include AuthorizeNet::Model
14
+
15
+ attr_accessor :header_html, :footer_html, :color_background, :color_link, :color_text, :logo_url, :background_url, :link_method, :link_text, :link_url
16
+
17
+
18
+ def to_hash
19
+ hash = {
20
+ :header_html_receipt => @header_html,
21
+ :footer_html_receipt => @footer_html,
22
+ :color_background => @color_background,
23
+ :color_link => @color_link,
24
+ :color_text => @color_text,
25
+ :logo_url => @logo_url,
26
+ :background_url => @background_url,
27
+ :receipt_link_method => @link_method,
28
+ :receipt_link_text => @link_text,
29
+ :receipt_link_url => @link_url
30
+ }
31
+ hash.delete_if {|k, v| v.nil?}
32
+ hash
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,142 @@
1
+ module AuthorizeNet::SIM
2
+
3
+ # The SIM response class. Handles parsing the response from the gateway. Also
4
+ # provides a few relay response helpers used to implement Direct Post Method.
5
+ class Response < AuthorizeNet::KeyValueResponse
6
+
7
+ # Our MD5 digest generator.
8
+ @@digest = OpenSSL::Digest.new('md5')
9
+
10
+ include AuthorizeNet::SIM::Fields
11
+
12
+ # Constructs a new response object from a +raw_response+. Provides utility methods
13
+ # for validating the response as authentic, and for handling the Direct Post Method
14
+ # relay response.
15
+ #
16
+ # +raw_response+:: The raw response, either a string in POST body or GET query string format, or a hash of key/value pairs.
17
+ #
18
+ # Typical usage:
19
+ # response = AuthorizeNet::SIM::Response("x_first_name=John&x_last_name=Doe")
20
+ def initialize(raw_response)
21
+ @raw_response = raw_response
22
+ @custom_fields = {}
23
+ @fields = {}
24
+ parse_response(@raw_response)
25
+ end
26
+
27
+
28
+ # Returns True if the MD5 hash found in the response payload validates using
29
+ # the supplied api_login and secret merchant_value (THIS IS NOT YOUR API KEY).
30
+ def valid_md5?(api_login, merchant_value)
31
+ if @fields[:MD5_Hash].nil?
32
+ return false
33
+ end
34
+ @@digest.hexdigest("#{merchant_value}#{api_login}#{@fields[:trans_id]}#{@fields[:amount]}").downcase == @fields[:MD5_Hash].downcase
35
+ end
36
+
37
+ # Returns an HTML string that can be returned to the gateway during the Relay Response,
38
+ # and will send the user on to URL you specify. Takes a hash of options, currently the
39
+ # only option is :include, which can be True to include all fields returned in the response
40
+ # as query string parameters, or it can be an array of fields to include.
41
+ def direct_post_reply(url, options = {})
42
+ url = direct_post_url(url, options[:include]) if options.has_key?(:include)
43
+ js_url = url.gsub("'", '\'')
44
+ html_url = url.gsub('&', '&amp;').gsub('"', "\"")
45
+ html = <<-HTML
46
+ <html><head><script type="text/javascript" charset="utf-8">window.location='#{js_url}';</script><noscript><meta http-equiv="refresh" content="1;url=#{html_url}"></noscript></head><body></body></html>
47
+ HTML
48
+ end
49
+
50
+ # Returns an URL with the fields found in the response and specified in include_fields attached as
51
+ # part of the URL's query string. If you pass true instead of an array of fields, all fields will be
52
+ # attached.
53
+ def direct_post_url(base_url, include_fields = true)
54
+ url = base_url
55
+ if include_fields
56
+ fields = []
57
+ case include_fields
58
+ when TrueClass
59
+ fields = FIELDS.collect do |k|
60
+ k_str = k.to_s
61
+ k_str[2..k_str.length].to_sym
62
+ end
63
+ when Array
64
+ fields = include_fields
65
+ else
66
+ fields = include_fields.to_a
67
+ end
68
+ parsed_url = URI.parse(url)
69
+ if parsed_url.query.nil?
70
+ parsed_url.query = ''
71
+ elsif parsed_url.query.length != 0
72
+ parsed_url.query = parsed_url.query.chomp('&') + '&'
73
+ end
74
+ parsed_url.query += ((fields.select { |k| @fields.has_key?(k) }).collect { |k| self.to_param(k, @fields[k]) }).join('&')
75
+ parsed_url.query.chomp('&')
76
+ url = parsed_url.to_s
77
+ end
78
+ url
79
+ end
80
+
81
+ # Check to see if the response indicated success. Success is defined as a valid MD5 hash
82
+ # and an response code of AuthorizeNet::Response::ResponseCode::APPROVED.
83
+ def success?(api_login, merchant_value)
84
+ valid_md5?(api_login, merchant_value) && approved?
85
+ end
86
+
87
+ # Returns the transaction's authorization code. This should be shown to the
88
+ # end user.
89
+ def authorization_code
90
+ @fields[:auth_code]
91
+ end
92
+
93
+ # Returns the transaction's authorization id. You will need this for future void, refund
94
+ # and prior authorization capture requests.
95
+ def transaction_id
96
+ @fields[:trans_id]
97
+ end
98
+
99
+ # Returns the customer id from the response.
100
+ def customer_id
101
+ @fields[:cust_id]
102
+ end
103
+
104
+ # Returns a response code (from AVSResponseCode) indicating the result of any Address Verification
105
+ # Service checks.
106
+ def avs_response
107
+ @fields[:avs_code]
108
+ end
109
+
110
+ #:enddoc:
111
+ protected
112
+
113
+ # Internal helper to parse the raw response object. It handles both raw POST bodies and
114
+ # hashes.
115
+ def parse_response(raw_response)
116
+ case raw_response
117
+ when Hash
118
+ raw_response.each do |k, v|
119
+ k = k.to_sym
120
+ if FIELDS.include?(k)
121
+ @fields[to_internal_field(k)] = v # remove x_ from sym and stick in @fields
122
+ else
123
+ @custom_fields[k] = v
124
+ end
125
+ end
126
+ when String
127
+ # convert to hash and re-parse
128
+ hash = CGI::parse(raw_response)
129
+ hash.each do |k, v|
130
+ if v.kind_of?(Array) && v.length == 1
131
+ hash[k] = v[0]
132
+ end
133
+ end
134
+ parse_response(hash)
135
+ else
136
+ parse_response(@raw_response.to_s)
137
+ end
138
+ end
139
+
140
+ end
141
+
142
+ end