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 +4 -4
- data/app/datatables/admin/effective_orders_datatable.rb +1 -0
- data/app/helpers/effective_orders_helper.rb +4 -4
- data/app/models/concerns/acts_as_purchasable.rb +13 -0
- data/app/models/effective/deluxe_api.rb +39 -71
- data/app/models/effective/order.rb +16 -4
- data/app/views/effective/orders/_checkout_step2.html.haml +6 -5
- data/db/migrate/101_create_effective_orders.rb +1 -0
- data/lib/effective_orders/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4499fc477da7ba7d00a8550057e754772594ca4622fdfc498ec6ff054b19eb30
|
4
|
+
data.tar.gz: f8c09cce9f19c1e872ae4e1d27e3928d1be8ee0a29dc42d421c0a058bb8e0840
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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')}
|
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
|
-
|
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.
|
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
|
|
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.
|
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-
|
11
|
+
date: 2024-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|