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.
- checksums.yaml +7 -0
- data/lib/app/helpers/authorize_net_helper.rb +24 -0
- data/lib/authorize_net/addresses/address.rb +29 -0
- data/lib/authorize_net/addresses/shipping_address.rb +26 -0
- data/lib/authorize_net/aim/response.rb +131 -0
- data/lib/authorize_net/aim/transaction.rb +190 -0
- data/lib/authorize_net/api/api_transaction.rb +123 -0
- data/lib/authorize_net/api/constants.yml +1 -0
- data/lib/authorize_net/api/schema.rb +4985 -0
- data/lib/authorize_net/api/transaction.rb +258 -0
- data/lib/authorize_net/arb/fields.rb +24 -0
- data/lib/authorize_net/arb/paging.rb +33 -0
- data/lib/authorize_net/arb/response.rb +34 -0
- data/lib/authorize_net/arb/sorting.rb +43 -0
- data/lib/authorize_net/arb/subscription.rb +72 -0
- data/lib/authorize_net/arb/subscription_detail.rb +14 -0
- data/lib/authorize_net/arb/subscription_list_response.rb +43 -0
- data/lib/authorize_net/arb/transaction.rb +177 -0
- data/lib/authorize_net/authorize_net.rb +154 -0
- data/lib/authorize_net/cim/customer_profile.rb +19 -0
- data/lib/authorize_net/cim/payment_profile.rb +37 -0
- data/lib/authorize_net/cim/response.rb +116 -0
- data/lib/authorize_net/cim/transaction.rb +727 -0
- data/lib/authorize_net/customer.rb +27 -0
- data/lib/authorize_net/email_receipt.rb +24 -0
- data/lib/authorize_net/fields.rb +779 -0
- data/lib/authorize_net/key_value_response.rb +117 -0
- data/lib/authorize_net/key_value_transaction.rb +291 -0
- data/lib/authorize_net/line_item.rb +25 -0
- data/lib/authorize_net/order.rb +42 -0
- data/lib/authorize_net/payment_methods/credit_card.rb +62 -0
- data/lib/authorize_net/payment_methods/echeck.rb +72 -0
- data/lib/authorize_net/reporting/batch.rb +19 -0
- data/lib/authorize_net/reporting/batch_statistics.rb +19 -0
- data/lib/authorize_net/reporting/fds_filter.rb +11 -0
- data/lib/authorize_net/reporting/response.rb +163 -0
- data/lib/authorize_net/reporting/returned_item.rb +46 -0
- data/lib/authorize_net/reporting/transaction.rb +133 -0
- data/lib/authorize_net/reporting/transaction_details.rb +25 -0
- data/lib/authorize_net/response.rb +27 -0
- data/lib/authorize_net/sim/hosted_payment_form.rb +38 -0
- data/lib/authorize_net/sim/hosted_receipt_page.rb +37 -0
- data/lib/authorize_net/sim/response.rb +142 -0
- data/lib/authorize_net/sim/transaction.rb +138 -0
- data/lib/authorize_net/transaction.rb +66 -0
- data/lib/authorize_net/xml_response.rb +172 -0
- data/lib/authorize_net/xml_transaction.rb +298 -0
- data/lib/authorize_net.rb +107 -0
- data/lib/authorizenet_blaq.rb +4 -0
- data/lib/generators/authorize_net/direct_post/direct_post_generator.rb +53 -0
- data/lib/generators/authorize_net/direct_post/templates/README-AuthorizeNet +49 -0
- data/lib/generators/authorize_net/direct_post/templates/config.yml.erb +8 -0
- data/lib/generators/authorize_net/direct_post/templates/config.yml.rails3.erb +8 -0
- data/lib/generators/authorize_net/direct_post/templates/controller.rb.erb +31 -0
- data/lib/generators/authorize_net/direct_post/templates/initializer.rb +4 -0
- data/lib/generators/authorize_net/direct_post/templates/layout.erb +18 -0
- data/lib/generators/authorize_net/direct_post/templates/payment.erb +10 -0
- data/lib/generators/authorize_net/direct_post/templates/payment.rails3.erb +10 -0
- data/lib/generators/authorize_net/direct_post/templates/receipt.erb +1 -0
- data/lib/generators/authorize_net/direct_post/templates/relay_response.erb +1 -0
- data/lib/generators/authorize_net/sim/sim_generator.rb +47 -0
- data/lib/generators/authorize_net/sim/templates/README-AuthorizeNet +52 -0
- data/lib/generators/authorize_net/sim/templates/config.yml.erb +8 -0
- data/lib/generators/authorize_net/sim/templates/config.yml.rails3.erb +8 -0
- data/lib/generators/authorize_net/sim/templates/controller.rb.erb +21 -0
- data/lib/generators/authorize_net/sim/templates/initializer.rb +4 -0
- data/lib/generators/authorize_net/sim/templates/layout.erb +18 -0
- data/lib/generators/authorize_net/sim/templates/payment.erb +6 -0
- data/lib/generators/authorize_net/sim/templates/payment.rails3.erb +6 -0
- data/lib/generators/authorize_net/sim/templates/thank_you.erb +1 -0
- data/lib/generators/generator_extensions.rb +75 -0
- 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('&', '&').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
|