effective_orders 6.12.4 → 6.13.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d365ebd0599f72ed9c5bbf7e9e9f26284647135153befe60799452b87fc1e0c
4
- data.tar.gz: 913c9fa4e2d528382652c297d6806fb827c79974baebb9890ddd1854449f98d1
3
+ metadata.gz: 4499fc477da7ba7d00a8550057e754772594ca4622fdfc498ec6ff054b19eb30
4
+ data.tar.gz: f8c09cce9f19c1e872ae4e1d27e3928d1be8ee0a29dc42d421c0a058bb8e0840
5
5
  SHA512:
6
- metadata.gz: d5fde239931a219f5e15a29a085dd4f056f12174fb4e6331b5b05369d8798518781e7eddae549edb3d3e8d34a9a8a18896a6a271fa0883a15161f75766cad95b
7
- data.tar.gz: 2b0daaa3d6a0b0111efe48cac3db3d2b0073a3a8ed3b51ec5e9beaeaadaee604ae515cdc5c309b33c8a4ad28598bfcbdd3c6f345aa95052543588f31dcc1a6bc
6
+ metadata.gz: 8bd284864d14aedf394014d9cbea8fca1309a8856564c6f03f5dfe606d3cf123184cbda1d6a61fbfe0b2fdbe0e23be04c9d5979d0d3e371c43e3765e4f614264
7
+ data.tar.gz: df32798cf7ebd2b0614e28befadef7f1ab391ffd0124c0748b74139f579cdcc6b8919c35c0307c47ed5fdade567a48cb54008cf765ebae39680baca5cd1874f2
@@ -104,6 +104,7 @@ module Admin
104
104
  col :delayed_payment, visible: false
105
105
  col :delayed_payment_date
106
106
  col :delayed_payment_intent, visible: false
107
+ col :delayed_payment_total, as: :price, visible: false
107
108
  col :delayed_payment_purchase_ran_at, visible: false
108
109
  col :delayed_payment_purchase_result, visible: false
109
110
  end
@@ -119,13 +119,13 @@ module EffectiveOrdersHelper
119
119
  end
120
120
  end
121
121
 
122
- def render_checkout_step1(order, namespace: nil, purchased_url: nil, declined_url: nil, deferred_url: nil, skip_deferred: false)
123
- locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url, namespace: namespace, skip_deferred: skip_deferred }
122
+ def render_checkout_step1(order, namespace: nil, purchased_url: nil, declined_url: nil, deferred_url: nil, skip_deferred: false, skip_order: false)
123
+ locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url, namespace: namespace, skip_deferred: skip_deferred, skip_order: skip_order }
124
124
  render(partial: 'effective/orders/checkout_step1', locals: locals)
125
125
  end
126
126
 
127
- def render_checkout_step2(order, namespace: nil, purchased_url: nil, declined_url: nil, deferred_url: nil, skip_deferred: false)
128
- locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url, namespace: namespace, skip_deferred: skip_deferred }
127
+ def render_checkout_step2(order, namespace: nil, purchased_url: nil, declined_url: nil, deferred_url: nil, skip_deferred: false, skip_order: false)
128
+ locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url, namespace: namespace, skip_deferred: skip_deferred, skip_order: skip_order }
129
129
  render(partial: 'effective/orders/checkout_step2', locals: locals)
130
130
  end
131
131
 
@@ -110,6 +110,15 @@ module ActsAsPurchasable
110
110
  self[:tax_exempt] || false
111
111
  end
112
112
 
113
+ def purchased_or_deferred?
114
+ purchased_order_id.present? || orders.any? { |order| order.purchased? || order.deferred? }
115
+ end
116
+
117
+ def purchased_or_deferred_at
118
+ order = orders.find { |order| order.purchased? } || orders.find { |order| order.deferred? }
119
+ order&.purchased_at || order&.deferred_at
120
+ end
121
+
113
122
  def purchased?
114
123
  purchased_order_id.present?
115
124
  end
@@ -122,6 +131,10 @@ module ActsAsPurchasable
122
131
  self[:purchased_at] || purchased_order.try(:purchased_at)
123
132
  end
124
133
 
134
+ def deferred_at
135
+ self[:deferred_at] || orders.find { |order| order.deferred? }.try(:deferred_at)
136
+ end
137
+
125
138
  def purchased_by?(user)
126
139
  purchased_orders.any? { |order| order.purchased_by_id == user.id }
127
140
  end
@@ -65,7 +65,7 @@ module Effective
65
65
  end
66
66
 
67
67
  # After we store a payment intent we can call purchase! immediately or wait till later.
68
- # This calls Authorize Payment and Complete Payment
68
+ # This calls the /payments Create Payment endpoint
69
69
  # Returns true when purchased. Returns false when declined.
70
70
  # The response is stored in api.payment() after this is run
71
71
  def purchase!(order, payment_intent)
@@ -75,18 +75,10 @@ module Effective
75
75
 
76
76
  # Start a purchase. Which is an Authorization and a Completion
77
77
  self.purchase_response = nil
78
-
79
- # Process Authorization
80
- authorization = authorize_payment(order, payment_intent)
81
- self.purchase_response = authorization
82
-
83
- valid = [0].include?(authorization['responseCode'])
84
- return false unless valid
85
-
86
- ## Complete Payment
87
- payment = complete_payment(order, authorization)
78
+ payment = create_payment(order, payment_intent)
88
79
  self.purchase_response = payment
89
80
 
81
+ # Validate
90
82
  valid = [0].include?(payment['responseCode'])
91
83
  return false unless valid
92
84
 
@@ -94,11 +86,35 @@ module Effective
94
86
  true
95
87
  end
96
88
 
89
+ # Create Payment
90
+ def create_payment(order, payment_intent)
91
+ response = post('/payments', params: create_payment_params(order, payment_intent))
92
+
93
+ # Sanity check response
94
+ raise('expected responseCode') unless response.kind_of?(Hash) && response['responseCode'].present?
95
+
96
+ # Sanity check response approved vs authorized
97
+ valid = [0].include?(response['responseCode'])
98
+
99
+ # We might be approved for an amount less than the order total. Not sure what to do here
100
+ if valid && (amountApproved = response['amountApproved']) != (amountAuthorized = order.total_to_f)
101
+ raise("expected complete payment amountApproved #{amountApproved} to be the same as the amountAuthorized #{amountAuthorized} but it was not")
102
+ end
103
+
104
+ # Generate the card info we can store
105
+ card = card_info(payment_intent)
106
+
107
+ # Return the response merged with the card info
108
+ response.reverse_merge(card)
109
+ end
110
+
111
+ # The response from last create payment request
97
112
  def payment
98
113
  raise('expected purchase response to be present') unless purchase_response.kind_of?(Hash)
99
114
  purchase_response
100
115
  end
101
116
 
117
+ # Called by rake task
102
118
  def purchase_delayed_orders!(orders)
103
119
  now = Time.zone.now
104
120
 
@@ -144,51 +160,7 @@ module Effective
144
160
 
145
161
  protected
146
162
 
147
- # Authorize Payment
148
- def authorize_payment(order, payment_intent)
149
- response = post('/payments/authorize', params: authorize_payment_params(order, payment_intent))
150
-
151
- # Sanity check response
152
- raise('expected responseCode') unless response.kind_of?(Hash) && response['responseCode'].present?
153
-
154
- # Sanity check response approved vs authorized
155
- valid = [0].include?(response['responseCode'])
156
-
157
- # We might be approved for an amount less than the order total. Not sure what to do here
158
- if valid && (amountApproved = response['amountApproved']) != (amountAuthorized = order.total_to_f)
159
- raise("expected authorize payment amountApproved #{amountApproved} to be the same as the amountAuthorized #{amountAuthorized} but it was not")
160
- end
161
-
162
- # Generate the card info we can store
163
- card = card_info(payment_intent)
164
-
165
- # Return the authorization params merged with the card info
166
- response.reverse_merge(card)
167
- end
168
-
169
- # Complete Payment
170
- def complete_payment(order, authorization)
171
- response = post('/payments/complete', params: complete_payment_params(order, authorization))
172
-
173
- # Sanity check response
174
- raise('expected responseCode') unless response.kind_of?(Hash) && response['responseCode'].present?
175
-
176
- # Sanity check response approved vs authorized
177
- valid = [0].include?(response['responseCode'])
178
-
179
- # We might be approved for an amount less than the order total. Not sure what to do here
180
- if valid && (amountApproved = response['amountApproved']) != (amountAuthorized = order.total_to_f)
181
- raise("expected complete payment amountApproved #{amountApproved} to be the same as the amountAuthorized #{amountAuthorized} but it was not")
182
- end
183
-
184
- # The authorization information
185
- authorization = { 'paymentId' => authorization } if authorization.kind_of?(String)
186
-
187
- # Return the complete params merged with the authorization params
188
- response.reverse_merge(authorization)
189
- end
190
-
191
- def authorize_payment_params(order, payment_intent)
163
+ def create_payment_params(order, payment_intent)
192
164
  raise('expected an Effective::Order') unless order.kind_of?(Effective::Order)
193
165
 
194
166
  token = extract_token(payment_intent)
@@ -232,28 +204,24 @@ module Effective
232
204
  ({ name: 'organization_id', value: order.organization_id.to_s } if order.organization_id.present?)
233
205
  ].compact
234
206
 
235
- # Params passed into Authorize Payment
236
- {
207
+ orderData = {
208
+ autoGenerateOrderId: true,
209
+ orderID: order.to_param,
210
+ orderIdIsUnique: true
211
+ }
212
+
213
+ # Params passed into Create Payment
214
+ params = {
215
+ paymentType: "Sale",
237
216
  amount: amount,
238
217
  paymentMethod: paymentMethod,
239
218
  shippingAddress: shippingAddress,
240
219
  customData: customData,
220
+ merchantCategory: "E-Commerce",
221
+ orderData: orderData
241
222
  }.compact
242
223
  end
243
224
 
244
- def complete_payment_params(order, payment_intent)
245
- raise('expected an Effective::Order') unless order.kind_of?(Effective::Order)
246
-
247
- payment_id = extract_payment_id(payment_intent)
248
- amount = { amount: order.total_to_f, currency: currency }
249
-
250
- # Params passed into Complete Payment
251
- {
252
- paymentId: payment_id,
253
- amount: amount
254
- }
255
- end
256
-
257
225
  def get(endpoint, params: nil)
258
226
  query = ('?' + params.compact.map { |k, v| "$#{k}=#{v}" }.join('&')) if params.present?
259
227
 
@@ -100,10 +100,11 @@ module Effective
100
100
  delayed_payment :boolean
101
101
  delayed_payment_date :date
102
102
 
103
- # When the order goes to checkout we require the delayed_payment_intent
104
- # This stores the user's card information in a secure way
103
+ # When the order goes to checkout we require the delayed_payment_intent and total
104
+ # This stores the user's card information
105
105
  # This is required for the order to become deferred?
106
106
  delayed_payment_intent :text
107
+ delayed_payment_total :integer # Only for reference, not really used. This is the order total we showed them when they last save card info'd
107
108
 
108
109
  # Set by the rake task that runs 1/day and processes any delayed orders before or on that day
109
110
  delayed_payment_purchase_ran_at :datetime
@@ -192,7 +193,11 @@ module Effective
192
193
  # Delayed Payment Validations
193
194
  validates :delayed_payment_date, presence: true, if: -> { delayed_payment? }
194
195
  validates :delayed_payment_date, absence: true, unless: -> { delayed_payment? }
195
- validates :delayed_payment_intent, presence: { message: 'please provide your card information' }, if: -> { delayed? && deferred? }
196
+
197
+ with_options(if: -> { delayed? && deferred? }) do
198
+ validates :delayed_payment_intent, presence: { message: 'please provide your card information' }
199
+ validates :delayed_payment_total, presence: true
200
+ end
196
201
 
197
202
  validate do
198
203
  if EffectiveOrders.organization_enabled?
@@ -558,7 +563,7 @@ module Effective
558
563
  return unless delayed? && deferred?
559
564
  return unless delayed_payment_date_upcoming?
560
565
 
561
- "Your #{delayed_payment_method} will be charged on #{delayed_payment_date.strftime('%F')} for the full amount of $#{'%0.2f' % total_to_f}"
566
+ "Your #{delayed_payment_method} will be charged $#{'%0.2f' % total_to_f} on #{delayed_payment_date.strftime('%F')}"
562
567
  end
563
568
 
564
569
  def delayed_payment_date_upcoming?
@@ -659,6 +664,12 @@ module Effective
659
664
  present_order_items.each { |oi| oi.update_purchasable_attributes }
660
665
  end
661
666
 
667
+ def update_purchasable_attributes!
668
+ raise('cannot update purchasable attributes of a purchased order') if purchased?
669
+ update_purchasable_attributes
670
+ save!
671
+ end
672
+
662
673
  # Call this as a way to skip over non consequential orders
663
674
  # And mark some purchasables purchased
664
675
  # This is different than the Mark as Paid payment processor
@@ -744,6 +755,7 @@ module Effective
744
755
 
745
756
  assign_attributes(
746
757
  delayed_payment_intent: payment_intent,
758
+ delayed_payment_total: total(),
747
759
 
748
760
  payment: payment_to_h(payment),
749
761
  payment_card: (card.presence || 'none')
@@ -3,20 +3,21 @@
3
3
  .effective-order-change-items
4
4
  = link_to 'Change Addresses', effective_orders.edit_order_path(order), rel: :nofollow
5
5
 
6
- = render('/effective/orders/order', order: order, no_order_actions: true)
6
+ - unless local_assigns[:skip_order]
7
+ = render('/effective/orders/order', order: order, no_order_actions: true)
7
8
 
8
9
  .effective-order-purchase-actions
9
10
  - provider_locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url }
10
11
 
11
- - if EffectiveOrders.free? && order.free?
12
+ - if EffectiveOrders.delayed? && order.delayed?
13
+ = render partial: '/effective/orders/delayed/form', locals: provider_locals
14
+
15
+ - elsif EffectiveOrders.free? && order.free?
12
16
  = render partial: '/effective/orders/free/form', locals: provider_locals
13
17
 
14
18
  - elsif EffectiveOrders.refund? && order.refund?
15
19
  = render partial: '/effective/orders/refund/form', locals: provider_locals
16
20
 
17
- - elsif EffectiveOrders.delayed? && order.delayed?
18
- = render partial: '/effective/orders/delayed/form', locals: provider_locals
19
-
20
21
  - else
21
22
  - if EffectiveOrders.pretend?
22
23
  = render partial: '/effective/orders/pretend/form', locals: provider_locals
@@ -43,6 +43,7 @@ class CreateEffectiveOrders < ActiveRecord::Migration[6.0]
43
43
  t.boolean :delayed_payment, default: false
44
44
  t.date :delayed_payment_date
45
45
  t.text :delayed_payment_intent
46
+ t.integer :delayed_payment_total
46
47
  t.datetime :delayed_payment_purchase_ran_at
47
48
  t.text :delayed_payment_purchase_result
48
49
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrders
2
- VERSION = '6.12.4'.freeze
2
+ VERSION = '6.13.1'.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.12.4
4
+ version: 6.13.1
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: 2024-06-04 00:00:00.000000000 Z
11
+ date: 2024-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails