effective_orders 6.19.1 → 6.19.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe4877e8b611ca4cf5aae18c2f43d0e62a6dc333e76634c74d098efe952199b6
4
- data.tar.gz: 7fdb4b4fda03ea47a941a032ee320fff2a6f432fd452e596bb2cfae40ed04569
3
+ metadata.gz: 73f7c7e5f31c361565954b31a82a278a0c5127829cbd24be06b4c307205c5f74
4
+ data.tar.gz: d7821ca6b2a5e7a9b22c9e5d67c69a6a22f49a6c7211b88961b6cb42a8f7698a
5
5
  SHA512:
6
- metadata.gz: 35d1d862fc154790c9e03ab1e01cd679340ae2c6da181cb26c6206fbaa6d6e3d1788e2b98516ba204e4e575ad98b12331ce81db0c41f5883fab3ca6ce99d1c70
7
- data.tar.gz: 468b756bce436cacd7e9132d126edff379f61991dc984cc1ac140dec93750459caa379aedd184c9c5f846770d2566ecf16639c0f2980baa7557acf8746e72c63
6
+ metadata.gz: '0967f05a59940c88a2b1ea47a8125c3501a9e1a0e1497fd5280fe4542f74b7bea94253fb72fd192adf32f6df958cfbc5179231d5c3d1351f0bf41bbc7ce49b1d'
7
+ data.tar.gz: 950b3b66593162a86e80a69dcea163415a0a7f1d1c0496dd3deeb886d8d1be7d9fb575fd3db334f8ab3e73662a8e9d3c3c2d8ec2d1fafd35fd49946a9dbf88ba
@@ -14,6 +14,7 @@ module Effective
14
14
  attr_accessor :currency
15
15
 
16
16
  attr_accessor :purchase_response
17
+ attr_accessor :read_timeout
17
18
 
18
19
  def initialize(environment: nil, client_id: nil, client_secret: nil, access_token: nil, currency: nil)
19
20
  self.environment = environment || EffectiveOrders.deluxe.fetch(:environment)
@@ -125,52 +126,133 @@ module Effective
125
126
  purchase_response
126
127
  end
127
128
 
129
+ def payment_approved?(order)
130
+ payment = search_payment(order)
131
+ return false if payment.blank?
132
+
133
+ payment.dig('payment', 'responseCode').present? && payment.dig('payment', 'authResponse').to_s.downcase.include?('approved')
134
+ end
135
+
136
+ # Search for an existing Payment
137
+ def search_payment(order)
138
+ date = (order.delayed_payment_purchase_ran_at || order.purchased_at || order.created_at || Time.zone.now)
139
+ response = post('/payments/search', params: { orderId: order.to_param, startDate: date.strftime('%m/%d/%Y'), endDate: (date + 1.day).strftime('%m/%d/%Y') })
140
+
141
+ # Sanity check response
142
+ raise('expected valid search') unless response.kind_of?(Hash) && response['isSuccess'] == true
143
+
144
+ # Find the payment for this order
145
+ payment = Array(response.dig('data', 'payments')).find { |payment| payment.dig('payment', 'orderId') == order.to_param }
146
+ return unless payment.present?
147
+
148
+ # Return the payment hash
149
+ payment
150
+ end
151
+
152
+ def purchase_delayed_order!(order)
153
+ raise('expected a delayed order') unless order.delayed?
154
+ raise('expected a deferred order') unless order.deferred?
155
+ raise('expected delayed payment intent') unless order.delayed_payment_intent.present?
156
+ raise('expected a delayed_ready_to_purchase? order') unless order.delayed_ready_to_purchase?
157
+
158
+ order.update_columns(delayed_payment_purchase_ran_at: Time.zone.now, delayed_payment_purchase_result: nil)
159
+
160
+ purchased = if order.total.to_i > 0
161
+ purchase!(order, order.delayed_payment_intent)
162
+ elsif order.free?
163
+ purchase_free!(order)
164
+ else
165
+ raise("Unexpected order amount: #{order.total}")
166
+ end
167
+
168
+ provider = (order.free? ? 'free' : order.payment_provider)
169
+ payment = self.payment()
170
+ card = payment["card"] || payment[:card]
171
+
172
+ if purchased
173
+ order.assign_attributes(delayed_payment_purchase_result: "success")
174
+ order.purchase!(payment: payment, provider: provider, card: card, email: true, skip_buyer_validations: true)
175
+
176
+ puts "Successfully purchased order #{order.id}"
177
+ else
178
+ order.assign_attributes(delayed_payment_purchase_result: "failed: #{Array(payment['responseMessage']).to_sentence.presence || 'none'}")
179
+ order.decline!(payment: payment, provider: provider, card: card, email: true)
180
+
181
+ puts "Failed to purchase order #{order.id} #{order.delayed_payment_purchase_result}"
182
+ end
183
+
184
+ purchased
185
+ end
186
+
187
+ def retry_purchase_delayed_order!(order)
188
+ raise('expected a delayed order') unless order.delayed?
189
+ raise('expected a deferred order') unless order.deferred?
190
+ raise('expected delayed payment intent') unless order.delayed_payment_intent.present?
191
+ raise('expected an order with a positive total') unless order.total.to_i > 0
192
+
193
+ order.update_columns(delayed_payment_purchase_ran_at: Time.zone.now, delayed_payment_purchase_result: nil)
194
+
195
+ # Look up the existing payment on Deluxe API
196
+ existing_payment = search_payment(order)
197
+ existing_purchased = existing_payment.present? && existing_payment.dig('payment', 'responseCode').present? && existing_payment.dig('payment', 'authResponse').to_s.downcase.include?('approved')
198
+
199
+ # If it doesn't exist, purchase it now
200
+ purchased = (existing_purchased || purchase!(order, order.delayed_payment_intent))
201
+
202
+ # Payment
203
+ provider = order.payment_provider
204
+ payment = (existing_payment if existing_purchased) || self.payment()
205
+ card = payment.dig('payment', 'card', 'cardType') || payment.dig('payment', 'card') || payment['card'] || payment[:card]
206
+
207
+ if purchased
208
+ order.assign_attributes(delayed_payment_purchase_result: "success")
209
+ order.purchase!(payment: payment, provider: provider, card: card, email: true, skip_buyer_validations: true)
210
+
211
+ puts "Successfully purchased order #{order.id}"
212
+ else
213
+ order.assign_attributes(delayed_payment_purchase_result: "failed: #{Array(payment['responseMessage']).to_sentence.presence || 'none'}")
214
+ order.decline!(payment: payment, provider: provider, card: card, email: true)
215
+
216
+ puts "Failed to purchase order #{order.id} #{order.delayed_payment_purchase_result}"
217
+ end
218
+
219
+ purchased
220
+ end
221
+
128
222
  # Called by rake task
129
223
  def purchase_delayed_orders!(orders)
130
- now = Time.zone.now
224
+ # Orders that failed to purchase and need to be retried
225
+ retry_orders = []
131
226
 
227
+ # First pass over all the orders
132
228
  Array(orders).each do |order|
133
229
  puts "Trying order #{order.id}"
134
230
 
135
231
  begin
136
- raise('expected a delayed order') unless order.delayed?
137
- raise('expected a deferred order') unless order.deferred?
138
- raise('expected delayed payment intent') unless order.delayed_payment_intent.present?
139
- raise('expected a delayed_ready_to_purchase? order') unless order.delayed_ready_to_purchase?
140
-
141
- order.update_columns(delayed_payment_purchase_ran_at: now, delayed_payment_purchase_result: nil)
142
-
143
- purchased = if order.total.to_i > 0
144
- purchase!(order, order.delayed_payment_intent)
145
- elsif order.free?
146
- purchase_free!(order)
147
- else
148
- raise("Unexpected order amount: #{order.total}")
149
- end
150
-
151
- provider = (order.free? ? 'free' : order.payment_provider)
152
- payment = self.payment()
153
- card = payment["card"] || payment[:card]
232
+ purchase_delayed_order!(order)
233
+ rescue => e
234
+ order.update_columns(delayed_payment_purchase_ran_at: Time.zone.now, delayed_payment_purchase_result: "error: #{e.message}")
235
+ retry_orders << order
154
236
 
155
- if purchased
156
- order.assign_attributes(delayed_payment_purchase_result: "success")
157
- order.purchase!(payment: payment, provider: provider, card: card, email: true, skip_buyer_validations: true)
237
+ puts "Error purchasing #{order.id}: #{e.message}"
238
+ end
239
+ end
158
240
 
159
- puts "Successfully purchased order #{order.id}"
160
- else
161
- order.assign_attributes(delayed_payment_purchase_result: "failed with message: #{Array(payment['responseMessage']).to_sentence.presence || 'none'}")
162
- order.decline!(payment: payment, provider: provider, card: card, email: true)
241
+ # Second pass over all the orders that raised an error on call to purchase
242
+ orders = Effective::Order.where(id: retry_orders.map(&:id))
163
243
 
164
- puts "Failed to purchase order #{order.id} #{order.delayed_payment_purchase_result}"
165
- end
244
+ Array(orders).each do |order|
245
+ puts "Retrying order #{order.id}"
166
246
 
247
+ begin
248
+ retry_purchase_delayed_order!(order)
167
249
  rescue => e
168
- order.update_columns(delayed_payment_purchase_ran_at: now, delayed_payment_purchase_result: "error: #{e.message}")
250
+ order.update_columns(delayed_payment_purchase_ran_at: Time.zone.now, delayed_payment_purchase_result: "error: #{e.message}")
169
251
 
170
252
  EffectiveLogger.error(e.message, associated: order) if defined?(EffectiveLogger)
171
253
  ExceptionNotifier.notify_exception(e, data: { order_id: order.id }) if defined?(ExceptionNotifier)
172
254
 
173
- puts "Error purchasing #{order.id}: #{e.message}"
255
+ puts "Error retry purchasing #{order.id}: #{e.message}"
174
256
 
175
257
  raise(e) if Rails.env.development? || Rails.env.test?
176
258
  end
@@ -260,7 +342,7 @@ module Effective
260
342
 
261
343
  orderData = {
262
344
  autoGenerateOrderId: true,
263
- orderID: order.to_param,
345
+ orderId: order.to_param,
264
346
  orderIdIsUnique: true
265
347
  }
266
348
 
@@ -282,7 +364,7 @@ module Effective
282
364
  uri = URI.parse(api_url + endpoint + query.to_s)
283
365
 
284
366
  http = Net::HTTP.new(uri.host, uri.port)
285
- http.read_timeout = 10
367
+ http.read_timeout = (read_timeout || 30)
286
368
  http.use_ssl = true
287
369
 
288
370
  result = with_retries do
@@ -301,19 +383,15 @@ module Effective
301
383
  uri = URI.parse(api_url + endpoint)
302
384
 
303
385
  http = Net::HTTP.new(uri.host, uri.port)
304
- http.read_timeout = 10
386
+ http.read_timeout = (read_timeout || 30)
305
387
  http.use_ssl = true
306
388
 
307
- result = with_retries do
308
- puts "[POST] #{uri} #{params}" if Rails.env.development?
389
+ puts "[POST] #{uri} #{params}" if Rails.env.development?
309
390
 
310
- response = http.post(uri.path, params.to_json, headers)
311
- raise Exception.new("#{response.code} #{response.body}") unless response.code == '200'
391
+ response = http.post(uri.path, params.to_json, headers)
392
+ raise Exception.new("#{response.code} #{response.body}") unless response.code == '200'
312
393
 
313
- response
314
- end
315
-
316
- JSON.parse(result.body)
394
+ JSON.parse(response.body)
317
395
  end
318
396
 
319
397
  private
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrders
2
- VERSION = '6.19.1'.freeze
2
+ VERSION = '6.19.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_orders
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.19.1
4
+ version: 6.19.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-20 00:00:00.000000000 Z
11
+ date: 2025-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails