effective_orders 6.30.6 → 6.30.7

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: 184e488ae56c8f57964bc8b95c69ac60be438c31ca305ca2e4dfe492eac77e1e
4
- data.tar.gz: 4ecfd86a4e39a48e77f070a1daa97ef70765e28e1a10904f7d63958840fbb8ee
3
+ metadata.gz: b6fbbdbf063fd45bb9a7f23f4abfd06616c2ad91001d24a5533d30deb0874d0b
4
+ data.tar.gz: 2e54c5a696f2dc423d2968ade04b0cc31f4ca022a7f919a1b3ca6999691ec627
5
5
  SHA512:
6
- metadata.gz: 79821bd949e9a20a7b034ae7ac1cc7b9c9f900de93970a7de37086f5f4a312d8a78fb3cc14fffd829c02efed01c1e0f04cde42ff505a252c1d61c7a55d6307a4
7
- data.tar.gz: 54a564990255816fec95ee3d5b92522aa2a2c0d45fb1606ba9a0921c5478a71daf62d799f22c6458b2f0606d4c889b7d02a51fe50ef0b4801b0ca1b035a982d6
6
+ metadata.gz: 0275d8f8cd79cbede5ca656605f6b41dc607fd06e9c40f2603da4b87ac1ebc2edf62280f9275a69be5feb5769750b4a7d3299cb3c775a74782036f87f1f132a6
7
+ data.tar.gz: eb661600355d08984662e37de9f017b9de632b15801a2929a9e7600e9e8a1baf0c54ad35bab8859de50dcedb34523addcfb89df5c0200cb41297824bab2696a8
@@ -30,3 +30,4 @@ function initializeDeluxe() {
30
30
 
31
31
  $(document).ready(function() { initializeDeluxe() });
32
32
  $(document).on('turbolinks:load', function() { initializeDeluxe() });
33
+
@@ -30,3 +30,4 @@ function initializeDeluxeDelayed() {
30
30
 
31
31
  $(document).ready(function() { initializeDeluxeDelayed() });
32
32
  $(document).on('turbolinks:load', function() { initializeDeluxeDelayed() });
33
+
@@ -73,3 +73,4 @@ this.MonerisCheckoutForm ||= class MonerisCheckoutForm
73
73
 
74
74
  $ -> (new MonerisCheckoutForm()).initialize()
75
75
  $(document).on 'turbolinks:load', -> (new MonerisCheckoutForm()).initialize()
76
+
@@ -89,3 +89,4 @@ this.StripeForm ||= class StripeForm
89
89
  $ -> (new StripeForm()).initialize()
90
90
  $(document).on 'turbolinks:load', -> (new StripeForm()).initialize()
91
91
  $(document).on 'turbolinks:before-cache', -> (new StripeForm()).destroy()
92
+
@@ -0,0 +1,3 @@
1
+ function onEffectiveOrdersRecaptchaVerified() {
2
+ document.getElementById('recaptcha-gate-form').submit();
3
+ }
@@ -1,6 +1,7 @@
1
1
  //= require effective_addresses
2
2
 
3
3
  //= require ./effective_orders/customers
4
+ //= require ./effective_orders/recaptcha
4
5
  //= require ./effective_orders/subscriptions
5
6
 
6
7
  //= require_tree ./effective_orders/providers
@@ -14,13 +14,14 @@ module Effective
14
14
 
15
15
  def order_purchased(payment:, provider:, card: 'none', email: true, skip_buyer_validations: false, purchased_url: nil)
16
16
  @order.purchase!(
17
- payment: payment,
18
- provider: provider,
19
- card: card,
20
- email: email,
17
+ payment: payment,
18
+ provider: provider,
19
+ card: card,
20
+ email: email,
21
21
  skip_buyer_validations: skip_buyer_validations
22
22
  )
23
23
 
24
+ session.delete(:recaptcha_verified_order_id)
24
25
  Effective::Cart.where(user: @order.current_user).destroy_all if @order.current_user.present?
25
26
 
26
27
  if flash[:success].blank?
@@ -38,6 +39,7 @@ module Effective
38
39
  def order_deferred(provider:, email: true, deferred_url: nil)
39
40
  @order.defer!(provider: provider, email: email)
40
41
 
42
+ session.delete(:recaptcha_verified_order_id)
41
43
  Effective::Cart.where(user: @order.current_user).destroy_all if @order.current_user.present?
42
44
 
43
45
  if flash[:success].blank?
@@ -55,6 +57,7 @@ module Effective
55
57
  def order_delayed(payment:, payment_intent:, provider:, card: 'none', email: true, deferred_url: nil)
56
58
  @order.delay!(payment: payment, payment_intent: payment_intent, provider: provider, card: card, email: email)
57
59
 
60
+ session.delete(:recaptcha_verified_order_id)
58
61
  Effective::Cart.where(user: @order.current_user).destroy_all if @order.current_user.present?
59
62
 
60
63
  if flash[:success].blank?
@@ -72,6 +75,8 @@ module Effective
72
75
  def order_declined(payment:, provider:, card: 'none', declined_url: nil)
73
76
  @order.decline!(payment: payment, provider: provider, card: card)
74
77
 
78
+ session.delete(:recaptcha_verified_order_id)
79
+
75
80
  if flash[:danger].blank?
76
81
  flash[:danger] = 'Payment was unsuccessful. Your credit card was declined by the payment processor. Please try again.'
77
82
  end
@@ -3,6 +3,7 @@ module Effective
3
3
  include Effective::CrudController
4
4
  include Concerns::Purchase
5
5
 
6
+ # Update the verify_recaptcha_checkout! method if we add another payment provider here
6
7
  include Providers::Cheque
7
8
  include Providers::Deluxe
8
9
  include Providers::DeluxeDelayed
@@ -26,6 +27,10 @@ module Effective
26
27
  before_action :authenticate_user!, except: [:free, :paypal_postback, :moneris_postback, :pretend]
27
28
  before_action :set_page_title, except: [:show, :edit]
28
29
 
30
+ before_action :verify_recaptcha_checkout!, only: [
31
+ :cheque, :deluxe, :deluxe_delayed, :etransfer, :free, :helcim, :mark_as_paid, :moneris_checkout, :phone, :pretend, :refund, :stripe
32
+ ]
33
+
29
34
  # If you want to use the Add to Cart -> Checkout flow
30
35
  # Add one or more items however you do.
31
36
  # redirect_to effective_orders.new_order_path, which is here.
@@ -142,6 +147,24 @@ module Effective
142
147
  end
143
148
  end
144
149
 
150
+ def recaptcha
151
+ raise('recaptcha is not enabled') unless EffectiveOrders.recaptcha?
152
+ raise('recaptcha secret key is not set') unless EffectiveOrders.recaptcha_secret_key.present?
153
+
154
+ @order = Effective::Order.not_purchased.find(params[:id])
155
+ EffectiveResources.authorize!(self, :update, @order)
156
+
157
+ redirect_url = params[:redirect_url].presence || effective_orders.order_path(@order)
158
+
159
+ if verify_recaptcha(secret_key: EffectiveOrders.recaptcha_secret_key)
160
+ session[:recaptcha_verified_order_id] = @order.id
161
+ redirect_to redirect_url
162
+ else
163
+ flash[:danger] = 'Verification failed. Please try again.'
164
+ redirect_to redirect_url
165
+ end
166
+ end
167
+
145
168
  private
146
169
 
147
170
  # StrongParameters
@@ -159,5 +182,14 @@ module Effective
159
182
  end
160
183
  end
161
184
 
185
+ def verify_recaptcha_checkout!
186
+ return unless EffectiveOrders.recaptcha?
187
+
188
+ unless session[:recaptcha_verified_order_id].to_s == params[:id].to_s
189
+ flash[:danger] = 'Please complete the verification to proceed with payment.'
190
+ redirect_back(fallback_location: effective_orders.order_path(params[:id]))
191
+ end
192
+ end
193
+
162
194
  end
163
195
  end
@@ -1,63 +1,77 @@
1
- - # Show this if I'm on the effective orders checkout screen. But not on a rendered order.
2
- - if order.persisted? && order.user == current_user && request.path.to_s.start_with?(effective_orders.order_path(order))
3
- .effective-order-change-items
4
- = link_to 'Change Addresses', effective_orders.edit_order_path(order), rel: :nofollow
1
+ - recaptcha_enabled = EffectiveOrders.recaptcha? && order.user == current_user
2
+ - recaptcha_verified = session[:recaptcha_verified_order_id].to_s == order.id.to_s
5
3
 
6
- - unless local_assigns[:skip_order]
7
- = render('/effective/orders/order', order: order)
4
+ - if recaptcha_enabled && !recaptcha_verified
5
+ .card
6
+ .card-body
7
+ %h2 Checkout
8
+ .effective-order-recaptcha-gate.text-center
9
+ = form_tag(effective_orders.recaptcha_order_path(order), method: :post, id: 'recaptcha-gate-form') do
10
+ = hidden_field_tag :redirect_url, request.path
11
+ .d-flex.justify-content-center
12
+ = recaptcha_tags(site_key: EffectiveOrders.recaptcha_site_key, callback: 'onEffectiveOrdersRecaptchaVerified')
8
13
 
9
- .effective-order-purchase-actions
10
- - provider_locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url }
14
+ - else
15
+ - # Show this if I'm on the effective orders checkout screen. But not on a rendered order.
16
+ - if order.persisted? && order.user == current_user && request.path.to_s.start_with?(effective_orders.order_path(order))
17
+ .effective-order-change-items
18
+ = link_to 'Change Addresses', effective_orders.edit_order_path(order), rel: :nofollow
11
19
 
12
- - if EffectiveOrders.delayed? && order.delayed_payment_date_upcoming?
13
- = render partial: '/effective/orders/delayed/form', locals: provider_locals
20
+ .effective-order-purchase-actions
21
+ - provider_locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url }
14
22
 
15
- - if EffectiveOrders.deferred? && !controller_path.include?('admin/') && !local_assigns[:skip_deferred]
16
- %p.my-4.text-center - or -
17
- = render partial: '/effective/orders/deferred/form', locals: provider_locals
23
+ - if EffectiveOrders.delayed? && order.delayed_payment_date_upcoming?
24
+ = render partial: '/effective/orders/delayed/form', locals: provider_locals
18
25
 
19
- - elsif EffectiveOrders.free? && order.free?
20
- = render partial: '/effective/orders/free/form', locals: provider_locals
26
+ - if EffectiveOrders.deferred? && !controller_path.include?('admin/') && !local_assigns[:skip_deferred]
27
+ %p.my-4.text-center - or -
28
+ = render partial: '/effective/orders/deferred/form', locals: provider_locals
21
29
 
22
- - elsif EffectiveOrders.refund? && order.refund?
23
- = render partial: '/effective/orders/refund/form', locals: provider_locals
30
+ - elsif EffectiveOrders.free? && order.free?
31
+ = render partial: '/effective/orders/free/form', locals: provider_locals
24
32
 
25
- - else
26
- - if EffectiveOrders.fee_saver?
27
- .alert.alert-info.mb-4
28
- All credit card transations are subject to a surcharge.
29
- To avoid this fee you can pay by #{['ACH', ('cheque' if EffectiveOrders.cheque?), ('e-transfer' if EffectiveOrders.etransfer?)].compact.to_sentence(last_word_connector: ' or ')}.
33
+ - elsif EffectiveOrders.refund? && order.refund?
34
+ = render partial: '/effective/orders/refund/form', locals: provider_locals
30
35
 
31
- - if EffectiveOrders.pretend?
32
- = render partial: '/effective/orders/pretend/form', locals: provider_locals
36
+ - else
37
+ - if EffectiveOrders.fee_saver?
38
+ .alert.alert-info.mb-4
39
+ All credit card transations are subject to a surcharge.
40
+ To avoid this fee you can pay by #{['ACH', ('cheque' if EffectiveOrders.cheque?), ('e-transfer' if EffectiveOrders.etransfer?)].compact.to_sentence(last_word_connector: ' or ')}.
33
41
 
34
- - if EffectiveOrders.deluxe?
35
- = render partial: '/effective/orders/deluxe/form', locals: provider_locals
42
+ - if EffectiveOrders.pretend?
43
+ = render partial: '/effective/orders/pretend/form', locals: provider_locals
36
44
 
37
- - if EffectiveOrders.helcim?
38
- = render partial: '/effective/orders/helcim/form', locals: provider_locals
45
+ - if EffectiveOrders.deluxe?
46
+ = render partial: '/effective/orders/deluxe/form', locals: provider_locals
39
47
 
40
- - if EffectiveOrders.moneris?
41
- = render partial: '/effective/orders/moneris/form', locals: provider_locals
48
+ - if EffectiveOrders.helcim?
49
+ = render partial: '/effective/orders/helcim/form', locals: provider_locals
42
50
 
43
- - if EffectiveOrders.moneris_checkout?
44
- = render partial: '/effective/orders/moneris_checkout/form', locals: provider_locals
51
+ - if EffectiveOrders.moneris?
52
+ = render partial: '/effective/orders/moneris/form', locals: provider_locals
45
53
 
46
- - if EffectiveOrders.paypal?
47
- = render partial: '/effective/orders/paypal/form', locals: provider_locals
54
+ - if EffectiveOrders.moneris_checkout?
55
+ = render partial: '/effective/orders/moneris_checkout/form', locals: provider_locals
48
56
 
49
- - if EffectiveOrders.stripe?
50
- = render partial: '/effective/orders/stripe/form', locals: provider_locals
57
+ - if EffectiveOrders.paypal?
58
+ = render partial: '/effective/orders/paypal/form', locals: provider_locals
51
59
 
52
- - if EffectiveOrders.deferred? && !controller_path.include?('admin/') && !local_assigns[:skip_deferred]
53
- %p.my-4.text-center - or -
54
- = render partial: '/effective/orders/deferred/form', locals: provider_locals
60
+ - if EffectiveOrders.stripe?
61
+ = render partial: '/effective/orders/stripe/form', locals: provider_locals
55
62
 
56
- - if EffectiveResources.authorized?(controller, :admin, :effective_orders) && controller_path.include?('admin/')
57
- - if EffectiveOrders.delayed? && order.delayed? && order.deferred? && order.delayed_payment_provider?
58
- .effective-order-admin-purchase-actions
59
- = render partial: '/effective/orders/delayed/form_purchase', locals: provider_locals
63
+ - if EffectiveOrders.deferred? && !controller_path.include?('admin/') && !local_assigns[:skip_deferred]
64
+ %p.my-4.text-center - or -
65
+ = render partial: '/effective/orders/deferred/form', locals: provider_locals
60
66
 
61
- - if EffectiveOrders.mark_as_paid?
62
- .effective-order-admin-purchase-actions
63
- = render partial: '/effective/orders/mark_as_paid/form', locals: provider_locals
67
+ - if EffectiveResources.authorized?(controller, :admin, :effective_orders) && controller_path.include?('admin/')
68
+ - if EffectiveOrders.delayed? && order.delayed? && order.deferred? && order.delayed_payment_provider?
69
+ .effective-order-admin-purchase-actions
70
+ = render partial: '/effective/orders/delayed/form_purchase', locals: provider_locals
71
+
72
+ - if EffectiveOrders.mark_as_paid?
73
+ .effective-order-admin-purchase-actions
74
+ = render partial: '/effective/orders/mark_as_paid/form', locals: provider_locals
75
+
76
+ - unless local_assigns[:skip_order]
77
+ = render('/effective/orders/order', order: order)
@@ -90,6 +90,12 @@ EffectiveOrders.setup do |config|
90
90
  config.pretend_enabled = !Rails.env.production?
91
91
  config.pretend_message = '* payment information is not required to process this order at this time.'
92
92
 
93
+ # reCAPTCHA v2 Checkbox — gate checkout with verification
94
+ # Requires the recaptcha gem and Google reCAPTCHA v2 Checkbox keys
95
+ config.recaptcha = false
96
+ # config.recaptcha = true # Use global Recaptcha.configure keys
97
+ # config.recaptcha = { site_key: '', secret_key: '' } # Use separate invisible keys
98
+
93
99
  # Mailer Settings
94
100
  # Please see config/initializers/effective_resources.rb for default effective_* gem mailer settings
95
101
  #
data/config/routes.rb CHANGED
@@ -7,6 +7,7 @@ EffectiveOrders::Engine.routes.draw do
7
7
  get :purchased
8
8
  get :deferred
9
9
  get :declined
10
+ post :recaptcha
10
11
  post :send_order_email
11
12
 
12
13
  post :cheque
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrders
2
- VERSION = '6.30.6'.freeze
2
+ VERSION = '6.30.7'.freeze
3
3
  end
@@ -48,6 +48,9 @@ module EffectiveOrders
48
48
  # Quickbooks Online Error Emails
49
49
  :send_qb_online_sync_error, :qb_online_sync_error_recipients,
50
50
 
51
+ # reCAPTCHA. Hash|true|false
52
+ :recaptcha,
53
+
51
54
  # Features
52
55
  :free_enabled, :mark_as_paid_enabled, :pretend_enabled, :pretend_message, :buyer_purchases_refund,
53
56
 
@@ -254,6 +257,26 @@ module EffectiveOrders
254
257
  helcim? && helcim[:fee_saver] == true
255
258
  end
256
259
 
260
+ def self.recaptcha?
261
+ (recaptcha.kind_of?(Hash) || recaptcha == true) && defined?(::Recaptcha)
262
+ end
263
+
264
+ def self.recaptcha_site_key
265
+ if recaptcha.kind_of?(Hash)
266
+ recaptcha[:site_key]
267
+ elsif recaptcha == true
268
+ ::Recaptcha.configuration.site_key!
269
+ end
270
+ end
271
+
272
+ def self.recaptcha_secret_key
273
+ if recaptcha.kind_of?(Hash)
274
+ recaptcha[:secret_key]
275
+ elsif recaptcha == true
276
+ ::Recaptcha.configuration.secret_key!
277
+ end
278
+ end
279
+
257
280
  def self.mailer_class
258
281
  mailer&.constantize || Effective::OrdersMailer
259
282
  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.30.6
4
+ version: 6.30.7
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: 2026-01-26 00:00:00.000000000 Z
11
+ date: 2026-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -198,6 +198,7 @@ files:
198
198
  - app/assets/javascripts/effective_orders/providers/helcim.js
199
199
  - app/assets/javascripts/effective_orders/providers/moneris_checkout.js.coffee
200
200
  - app/assets/javascripts/effective_orders/providers/stripe.js.coffee
201
+ - app/assets/javascripts/effective_orders/recaptcha.js
201
202
  - app/assets/javascripts/effective_orders/subscriptions.js.coffee
202
203
  - app/assets/stylesheets/effective_orders.scss
203
204
  - app/assets/stylesheets/effective_orders/_cart.scss