koffsite_payments 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +13 -0
  4. data/lib/offsite_payments.rb +48 -0
  5. data/lib/offsite_payments/action_view_helper.rb +72 -0
  6. data/lib/offsite_payments/helper.rb +119 -0
  7. data/lib/offsite_payments/integrations.rb +14 -0
  8. data/lib/offsite_payments/integrations/a1agregator.rb +245 -0
  9. data/lib/offsite_payments/integrations/authorize_net_sim.rb +580 -0
  10. data/lib/offsite_payments/integrations/bit_pay.rb +150 -0
  11. data/lib/offsite_payments/integrations/bogus.rb +32 -0
  12. data/lib/offsite_payments/integrations/chronopay.rb +283 -0
  13. data/lib/offsite_payments/integrations/citrus.rb +227 -0
  14. data/lib/offsite_payments/integrations/coinbase.rb +166 -0
  15. data/lib/offsite_payments/integrations/direc_pay.rb +339 -0
  16. data/lib/offsite_payments/integrations/directebanking.rb +237 -0
  17. data/lib/offsite_payments/integrations/doku.rb +171 -0
  18. data/lib/offsite_payments/integrations/dotpay.rb +166 -0
  19. data/lib/offsite_payments/integrations/dwolla.rb +160 -0
  20. data/lib/offsite_payments/integrations/e_payment_plans.rb +146 -0
  21. data/lib/offsite_payments/integrations/easy_pay.rb +137 -0
  22. data/lib/offsite_payments/integrations/epay.rb +161 -0
  23. data/lib/offsite_payments/integrations/first_data.rb +133 -0
  24. data/lib/offsite_payments/integrations/gestpay.rb +203 -0
  25. data/lib/offsite_payments/integrations/hi_trust.rb +179 -0
  26. data/lib/offsite_payments/integrations/ipay88.rb +251 -0
  27. data/lib/offsite_payments/integrations/klarna.rb +291 -0
  28. data/lib/offsite_payments/integrations/liqpay.rb +216 -0
  29. data/lib/offsite_payments/integrations/maksuturva.rb +231 -0
  30. data/lib/offsite_payments/integrations/mollie_ideal.rb +216 -0
  31. data/lib/offsite_payments/integrations/moneybookers.rb +199 -0
  32. data/lib/offsite_payments/integrations/nochex.rb +228 -0
  33. data/lib/offsite_payments/integrations/pag_seguro.rb +268 -0
  34. data/lib/offsite_payments/integrations/paxum.rb +114 -0
  35. data/lib/offsite_payments/integrations/pay_fast.rb +269 -0
  36. data/lib/offsite_payments/integrations/pay_u_latam.rb +246 -0
  37. data/lib/offsite_payments/integrations/paydollar.rb +142 -0
  38. data/lib/offsite_payments/integrations/payflow_link.rb +194 -0
  39. data/lib/offsite_payments/integrations/paypal.rb +362 -0
  40. data/lib/offsite_payments/integrations/paypal_payments_advanced.rb +23 -0
  41. data/lib/offsite_payments/integrations/paysbuy.rb +71 -0
  42. data/lib/offsite_payments/integrations/payu_in.rb +266 -0
  43. data/lib/offsite_payments/integrations/payu_in_paisa.rb +46 -0
  44. data/lib/offsite_payments/integrations/platron.rb +153 -0
  45. data/lib/offsite_payments/integrations/pxpay.rb +273 -0
  46. data/lib/offsite_payments/integrations/quickpay.rb +232 -0
  47. data/lib/offsite_payments/integrations/rbkmoney.rb +110 -0
  48. data/lib/offsite_payments/integrations/robokassa.rb +154 -0
  49. data/lib/offsite_payments/integrations/sage_pay_form.rb +425 -0
  50. data/lib/offsite_payments/integrations/two_checkout.rb +329 -0
  51. data/lib/offsite_payments/integrations/universal.rb +181 -0
  52. data/lib/offsite_payments/integrations/valitor.rb +200 -0
  53. data/lib/offsite_payments/integrations/verkkomaksut.rb +143 -0
  54. data/lib/offsite_payments/integrations/web_pay.rb +186 -0
  55. data/lib/offsite_payments/integrations/webmoney.rb +119 -0
  56. data/lib/offsite_payments/integrations/wirecard_checkout_page.rb +359 -0
  57. data/lib/offsite_payments/integrations/world_pay.rb +273 -0
  58. data/lib/offsite_payments/notification.rb +71 -0
  59. data/lib/offsite_payments/return.rb +37 -0
  60. data/lib/offsite_payments/version.rb +3 -0
  61. metadata +268 -0
@@ -0,0 +1,329 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module TwoCheckout
4
+ mattr_accessor :payment_routine
5
+ self.payment_routine = :single_page
6
+
7
+ def self.service_url
8
+ case self.payment_routine
9
+ when :multi_page
10
+ 'https://www.2checkout.com/checkout/purchase'
11
+ when :single_page
12
+ 'https://www.2checkout.com/checkout/spurchase'
13
+ else
14
+ raise StandardError, "Integration payment routine set to an invalid value: #{self.payment_routine}"
15
+ end
16
+ end
17
+
18
+ def self.service_url=(service_url)
19
+ # Note: do not use this method, it is here for backward compatibility
20
+ # Use the payment_routine method to change service_url
21
+ if service_url =~ /spurchase/
22
+ self.payment_routine = :single_page
23
+ else
24
+ self.payment_routine = :multi_page
25
+ end
26
+ end
27
+
28
+ def self.notification(post, options = {})
29
+ Notification.new(post, options)
30
+ end
31
+
32
+ def self.return(query_string, options = {})
33
+ Return.new(query_string, options)
34
+ end
35
+
36
+ class Helper < OffsitePayments::Helper
37
+ def initialize(order, account, options = {})
38
+ super
39
+ if OffsitePayments.mode == :test || options[:test]
40
+ add_field('demo', 'Y')
41
+ end
42
+ end
43
+
44
+ # The 2checkout vendor account number
45
+ mapping :account, 'sid'
46
+
47
+ # The total amount to be billed, in decimal form, without a currency symbol. (8 characters, decimal, 2 characters: Example: 99999999.99)
48
+ # This field is only used with the Third Party Cart parameter set.
49
+ mapping :amount, 'total'
50
+
51
+ # Pass the sale's currency code.
52
+ mapping :currency, 'currency_code'
53
+
54
+ # Pass your order id. (50 characters max)
55
+ mapping :order, 'merchant_order_id'
56
+
57
+ # Pass your cart identifier if you are using Third Part Cart Parameters. (128 characters max)
58
+ # This value is visible to the buyer and will be listed as the sale's lineitem.
59
+ mapping :invoice, 'cart_order_id'
60
+
61
+ mapping :customer,
62
+ :email => 'email',
63
+ :phone => 'phone'
64
+
65
+ mapping :billing_address,
66
+ :city => 'city',
67
+ :address1 => 'street_address',
68
+ :address2 => 'street_address2',
69
+ :state => 'state',
70
+ :zip => 'zip',
71
+ :country => 'country'
72
+
73
+ mapping :shipping_address,
74
+ :name => 'ship_name',
75
+ :city => 'ship_city',
76
+ :address1 => 'ship_street_address',
77
+ :address2 => 'ship_street_address2',
78
+ :state => 'ship_state',
79
+ :zip => 'ship_zip',
80
+ :country => 'ship_country'
81
+
82
+ # Overrides Approved URL for return process redirects
83
+ mapping :return_url, 'x_receipt_link_url'
84
+
85
+ # Allow seller to indicate the step of the checkout page
86
+ # Possible values: ‘review-cart’, ‘shipping-information’, ‘shipping-method’, ‘billing-information’ and ‘payment-method’
87
+ mapping :purchase_step, 'purchase_step'
88
+
89
+ # Allow referral partners to indicate their shopping cart
90
+ mapping :cart_type, '2co_cart_type'
91
+
92
+ def customer(params = {})
93
+ add_field(mappings[:customer][:email], params[:email])
94
+ add_field(mappings[:customer][:phone], params[:phone])
95
+ add_field('card_holder_name', "#{params[:first_name]} #{params[:last_name]}")
96
+ end
97
+
98
+ def shipping_address(params = {})
99
+ super
100
+ add_field(mappings[:shipping_address][:name], "#{params[:first_name]} #{params[:last_name]}")
101
+ end
102
+
103
+ # Uses Third Party Cart parameter set to pass in lineitem details.
104
+ # You must also specify `service.invoice` when using this method.
105
+ def third_party_cart(params = {})
106
+ add_field('id_type', '1')
107
+ (max_existing_line_item_id = form_fields.keys.map do |key|
108
+ i = key.to_s[/^c_prod_(\d+)/, 1]
109
+ (i && i.to_i)
110
+ end.compact.max || 0)
111
+
112
+ line_item_id = max_existing_line_item_id + 1
113
+ params.each do |key, value|
114
+ add_field("c_#{key}_#{line_item_id}", value)
115
+ end
116
+ end
117
+ end
118
+
119
+ class Notification < OffsitePayments::Notification
120
+ # message_type - Indicates type of message
121
+ # message_description - Human readable description of message_type
122
+ # timestamp - Timestamp of event; format YYYY-MM-DD HH:MM:SS ZZZ
123
+ # md5_hash - UPPERCASE(MD5_ENCRYPTED(sale_id + vendor_id + invoice_id + Secret Word))
124
+ # message_id - This number is incremented for each message sent to a given seller.
125
+ # key_count - Indicates the number of parameters sent in message
126
+ # vendor_id - Seller account number
127
+ # sale_id - 2Checkout sale number
128
+ # sale_date_placed - Date of sale; format YYYY-MM-DD
129
+ # vendor_order_id - Custom order id provided by seller, if available.
130
+ # invoice_id - 2Checkout invoice number; Each recurring sale can have several invoices
131
+ # recurring - recurring=1 if any item on the invoice is a recurring item, 0 otherwise
132
+ # payment_type - Buyer’s payment method (credit card, online check, paypal ec, OR paypal pay later)
133
+ # list_currency - 3-Letter ISO code for seller currency
134
+ # cust_currency - 3-Letter ISO code for buyer currency
135
+ # auth_exp - The date credit authorization will expire; format YYYY-MM-DD
136
+ # invoice_status - Status of a transaction (approved, pending, deposited, or declined)
137
+ # fraud_status - Status of 2Checkout fraud review (pass, fail, or wait); This parameter could be empty.
138
+ # invoice_list_amount - Total in seller pricing currency; format as appropriate to currency=
139
+ # invoice_usd_amount - Total in US Dollars; format with 2 decimal places
140
+ # invoice_cust_amount - Total in buyer currency; format as appropriate to currency=
141
+ # customer_first_name - Buyer’s first name (may not be available on older sales)
142
+ # customer_last_name - Buyer’s last name (may not be available on older sales)
143
+ # customer_name - Buyer's full name (name as it appears on credit card)
144
+ # customer_email - Buyer's email address
145
+ # customer_phone - Buyer's phone number; all but digits stripped out
146
+ # customer_ip - Buyer's IP address at time of sale
147
+ # customer_ip_country - Country of record for buyer's IP address at time of sale
148
+ # bill_street_address - Billing street address
149
+ # bill_street_address2 - Billing street address line 2
150
+ # bill_city - Billing address city
151
+ # bill_state - Billing address state or province
152
+ # bill_postal_code - Billing address postal code
153
+ # bill_country - 3-Letter ISO country code of billing address
154
+ # ship_status - not_shipped, shipped, or empty (if intangible / does not need shipped)
155
+ # ship_tracking_number - Tracking Number as entered in Seller Admin
156
+ # ship_name - Shipping Recipient’s name (as it should appears on shipping label)
157
+ # ship_street_address - Shipping street address
158
+ # ship_street_address2 - Shipping street address line 2
159
+ # ship_city - Shipping address city
160
+ # ship_state - Shipping address state or province
161
+ # ship_postal_code - Shipping address postal code
162
+ # ship_country - 3-Letter ISO country code of shipping address
163
+ # item_count - Indicates how many numbered sets of item parameters to expect
164
+ # item_name_# - Product name
165
+ # item_id_# - Seller product id
166
+ # item_list_amount_# - Total in seller pricing currency; format as appropriate to currency
167
+ # item_usd_amount_# - Total in US Dollars; format with 2 decimal places
168
+ # item_cust_amount_# - Total in buyer currency; format as appropriate to currency
169
+ # item_type_# - Indicates if item is a bill or refund; Value will be bill or refund
170
+ # item_duration_# - Product duration, how long it re-bills for Ex. 1 Year
171
+ # item_recurrence_# - Product recurrence, how often it re-bills Ex. 1 Month
172
+ # item_rec_list_amount_# - Product price; format as appropriate to currency
173
+ # item_rec_status_# - Indicates status of recurring subscription: live, canceled, or completed
174
+ # item_rec_date_next_# - Date of next recurring installment; format YYYY-MM-DD
175
+ # item_rec_install_billed_# - The number of successful recurring installments successfully billed
176
+
177
+ # INS message type
178
+ def type
179
+ params['message_type']
180
+ end
181
+
182
+ # Seller currency sale was placed in
183
+ def currency
184
+ params['list_currency']
185
+ end
186
+
187
+ def complete?
188
+ status == 'Completed'
189
+ end
190
+
191
+ # The value passed with 'merchant_order_id' is passed back as 'vendor_order_id'
192
+ def item_id
193
+ params['vendor_order_id'] || params['merchant_order_id']
194
+ end
195
+
196
+ # 2Checkout Sale ID
197
+ def transaction_id
198
+ params['sale_id'] || params['order_number']
199
+ end
200
+
201
+ # 2Checkout Invoice ID
202
+ def invoice_id
203
+ params['invoice_id']
204
+ end
205
+
206
+ def received_at
207
+ params['timestamp']
208
+ end
209
+
210
+ #Customer Email
211
+ def payer_email
212
+ params['customer_email']
213
+ end
214
+
215
+ # The MD5 Hash
216
+ def security_key
217
+ params['md5_hash'] || params['key']
218
+ end
219
+
220
+ # The money amount we received in X.2 decimal.
221
+ # passback || INS gross amount for new orders || default INS gross
222
+ def gross
223
+ params['invoice_list_amount'] || params['total'] || params['item_list_amount_1']
224
+ end
225
+
226
+ # Determine status based on parameter set, if the params include a fraud status we know we're being
227
+ # notified of the finalization of an order (an INS message)
228
+ # If the params include 'credit_card_processed' we know we're being notified of a new order being inbound,
229
+ # which we handle in the deferred demo sale scenario.
230
+ def status
231
+ if params['fraud_status'] == 'pass' || params['credit_card_processed'] == 'Y'
232
+ 'Completed'
233
+ elsif params['fraud_status'] == 'wait'
234
+ 'Pending'
235
+ else
236
+ 'Failed'
237
+ end
238
+ end
239
+
240
+ # Secret Word defined in 2Checkout account
241
+ def secret
242
+ @options[:credential2]
243
+ end
244
+
245
+ # Checks against MD5 Hash
246
+ def acknowledge(authcode = nil)
247
+ return false if security_key.blank?
248
+ if ins_message?
249
+ Digest::MD5.hexdigest("#{ transaction_id }#{ params['vendor_id'] }#{ invoice_id }#{ secret }").upcase == security_key.upcase
250
+ elsif passback?
251
+ order_number = params['demo'] == 'Y' ? 1 : params['order_number']
252
+ Digest::MD5.hexdigest("#{ secret }#{ params['sid'] }#{ order_number }#{ gross }").upcase == params['key'].upcase
253
+ else
254
+ false
255
+ end
256
+ end
257
+
258
+ private
259
+
260
+ # Parses Header Redirect Query String
261
+ def parse(post)
262
+ @raw = post.to_s
263
+ for line in @raw.split('&')
264
+ key, value = *line.scan( %r{^(\w+)\=(.*)$} ).flatten
265
+ params[key] = CGI.unescape(value || '')
266
+ end
267
+ end
268
+
269
+ def ins_message?
270
+ params.include? 'message_type'
271
+ end
272
+
273
+ def passback?
274
+ params.include? 'credit_card_processed'
275
+ end
276
+ end
277
+
278
+ class Return < OffsitePayments::Return
279
+ # card_holder_name - Provides the customer’s name.
280
+ # city - Provides the customer’s city.
281
+ # country - Provides the customer’s country.
282
+ # credit_card_processed - This parameter will always be passed back as Y.
283
+ # demo - Defines if an order was live, or if the order was a demo order. If the order was a demo, the MD5 hash will fail.
284
+ # email - Provides the email address the customer provided when placing the order.
285
+ # fixed - This parameter will only be passed back if it was passed into the purchase routine.
286
+ # ip_country - Provides the customer’s IP location.
287
+ # key - An MD5 hash used to confirm the validity of a sale.
288
+ # lang - Customer language
289
+ # merchant_order_id - The order ID you had assigned to the order.
290
+ # order_number - The 2Checkout order number associated with the order.
291
+ # invoice_id - The 2Checkout invoice number.
292
+ # pay_method - Provides seller with the customer’s payment method. CC for Credit Card, PPI for PayPal.
293
+ # phone - Provides the phone number the customer provided when placing the order.
294
+ # ship_name - Provides the ship to name for the order.
295
+ # ship_street_address - Provides ship to address.
296
+ # ship_street_address2 - Provides more detailed shipping address if this information was provided by the customer.
297
+ # ship_city - Provides ship to city.
298
+ # ship_state - Provides ship to state.
299
+ # ship_zip - Ship Zip
300
+
301
+ # Pass Through Products Only
302
+ # li_#_name - Name of the corresponding lineitem.
303
+ # li_#_quantity - Quantity of the corresponding lineitem.
304
+ # li_#_price - Price of the corresponding lineitem.
305
+ # li_#_tangible - Specifies if the corresponding li_#_type is a tangible or intangible. ‘Y’ OR ‘N’
306
+ # li_#_product_id - ID of the corresponding lineitem.
307
+ # li_#_product_description - Description of the corresponding lineitem.
308
+ # li_#_recurrence - # WEEK | MONTH | YEAR – always singular.
309
+ # li_#_duration - Forever or # WEEK | MONTH | YEAR – always singular, defaults to Forever.
310
+ # li_#_startup_fee - Amount in account pricing currency.
311
+ # li_#_option_#_name - Name of option. 64 characters max – cannot include '<' or '>'.
312
+ # li_#_option_#_value - Name of option. 64 characters max – cannot include '<' or '>'.
313
+ # li_#_option_#_surcharge - Amount in account pricing currency.
314
+
315
+ #Third Party Cart Only
316
+ # cart_order_id - The order ID you had assigned to the order
317
+
318
+ def initialize(query_string, options = {})
319
+ super
320
+ @notification = Notification.new(query_string, options)
321
+ end
322
+
323
+ def success?
324
+ @notification.status != 'Failed'
325
+ end
326
+ end
327
+ end
328
+ end
329
+ end
@@ -0,0 +1,181 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Universal
4
+ def self.notification(post, options = {})
5
+ Notification.new(post, options)
6
+ end
7
+
8
+ def self.return(query_string, options = {})
9
+ Return.new(query_string, options)
10
+ end
11
+
12
+ def self.sign(fields, key)
13
+ Digest::HMAC.hexdigest(fields.sort.join, key, Digest::SHA256)
14
+ end
15
+
16
+ class Helper < OffsitePayments::Helper
17
+ CURRENCY_SPECIAL_MINOR_UNITS = {
18
+ 'BIF' => 0,
19
+ 'BYR' => 0,
20
+ 'CLF' => 0,
21
+ 'CLP' => 0,
22
+ 'CVE' => 0,
23
+ 'DJF' => 0,
24
+ 'GNF' => 0,
25
+ 'HUF' => 0,
26
+ 'ISK' => 0,
27
+ 'JPY' => 0,
28
+ 'KMF' => 0,
29
+ 'KRW' => 0,
30
+ 'PYG' => 0,
31
+ 'RWF' => 0,
32
+ 'UGX' => 0,
33
+ 'UYI' => 0,
34
+ 'VND' => 0,
35
+ 'VUV' => 0,
36
+ 'XAF' => 0,
37
+ 'XOF' => 0,
38
+ 'XPF' => 0,
39
+ 'BHD' => 3,
40
+ 'IQD' => 3,
41
+ 'JOD' => 3,
42
+ 'KWD' => 3,
43
+ 'LYD' => 3,
44
+ 'OMR' => 3,
45
+ 'TND' => 3,
46
+ 'COU' => 4
47
+ }
48
+
49
+ def initialize(order, account, options = {})
50
+ @forward_url = options[:forward_url]
51
+ @key = options[:credential2]
52
+ @currency = options[:currency]
53
+ super
54
+ self.country = options[:country]
55
+ self.account_name = options[:account_name]
56
+ self.transaction_type = options[:transaction_type]
57
+ add_field 'x_test', @test.to_s
58
+ end
59
+
60
+ def credential_based_url
61
+ @forward_url
62
+ end
63
+
64
+ def form_fields
65
+ sign_fields
66
+ end
67
+
68
+ def amount=(amount)
69
+ add_field 'x_amount', format_amount(amount, @currency)
70
+ end
71
+
72
+ def shipping(amount)
73
+ add_field 'x_amount_shipping', format_amount(amount, @currency)
74
+ end
75
+
76
+ def tax(amount)
77
+ add_field 'x_amount_tax', format_amount(amount, @currency)
78
+ end
79
+
80
+ def sign_fields
81
+ @fields.merge!('x_signature' => generate_signature)
82
+ end
83
+
84
+ def generate_signature
85
+ Universal.sign(@fields, @key)
86
+ end
87
+
88
+ mapping :account, 'x_account_id'
89
+ mapping :currency, 'x_currency'
90
+ mapping :order, 'x_reference'
91
+ mapping :country, 'x_shop_country'
92
+ mapping :account_name, 'x_shop_name'
93
+ mapping :transaction_type, 'x_transaction_type'
94
+ mapping :description, 'x_description'
95
+ mapping :invoice, 'x_invoice'
96
+
97
+ mapping :customer, :first_name => 'x_customer_first_name',
98
+ :last_name => 'x_customer_last_name',
99
+ :email => 'x_customer_email',
100
+ :phone => 'x_customer_phone'
101
+
102
+ mapping :shipping_address, :first_name => 'x_customer_shipping_first_name',
103
+ :last_name => 'x_customer_shipping_last_name',
104
+ :city => 'x_customer_shipping_city',
105
+ :company => 'x_customer_shipping_company',
106
+ :address1 => 'x_customer_shipping_address1',
107
+ :address2 => 'x_customer_shipping_address2',
108
+ :state => 'x_customer_shipping_state',
109
+ :zip => 'x_customer_shipping_zip',
110
+ :country => 'x_customer_shipping_country',
111
+ :phone => 'x_customer_shipping_phone'
112
+
113
+ mapping :notify_url, 'x_url_callback'
114
+ mapping :return_url, 'x_url_complete'
115
+ mapping :cancel_return_url, 'x_url_cancel'
116
+
117
+ private
118
+
119
+ def format_amount(amount, currency)
120
+ units = CURRENCY_SPECIAL_MINOR_UNITS[currency] || 2
121
+ sprintf("%.#{units}f", amount)
122
+ end
123
+ end
124
+
125
+ class Notification < OffsitePayments::Notification
126
+ def initialize(post, options = {})
127
+ super
128
+ @key = options[:credential2]
129
+ end
130
+
131
+ def acknowledge(authcode = nil)
132
+ signature = @params['x_signature']
133
+ signature && signature.casecmp(generate_signature) == 0
134
+ end
135
+
136
+ def item_id
137
+ @params['x_reference']
138
+ end
139
+
140
+ def currency
141
+ @params['x_currency']
142
+ end
143
+
144
+ def gross
145
+ @params['x_amount']
146
+ end
147
+
148
+ def transaction_id
149
+ @params['x_gateway_reference']
150
+ end
151
+
152
+ def status
153
+ result = @params['x_result']
154
+ result && result.capitalize
155
+ end
156
+
157
+ def test?
158
+ @params['x_test'] == 'true'
159
+ end
160
+
161
+ private
162
+
163
+ def generate_signature
164
+ signature_params = @params.select { |k| k.start_with? 'x_' }.reject { |k| k == 'x_signature' }
165
+ Universal.sign(signature_params, @key)
166
+ end
167
+ end
168
+
169
+ class Return < OffsitePayments::Return
170
+ def initialize(query_string, options = {})
171
+ super
172
+ @notification = Notification.new(query_string, options)
173
+ end
174
+
175
+ def success?
176
+ @notification.acknowledge
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end