effective_orders 6.27.2 → 6.28.0
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/assets/javascripts/effective_orders/providers/helcim.js +4 -1
- data/app/controllers/effective/providers/helcim.rb +8 -2
- data/app/helpers/effective_orders_helper.rb +1 -1
- data/app/models/effective/helcim_api.rb +50 -7
- data/app/models/effective/order.rb +38 -15
- data/app/views/effective/order_emails/_info.html.haml +2 -2
- data/app/views/effective/orders/_checkout_step2.html.haml +5 -0
- data/app/views/effective/orders/_order_items.html.haml +20 -0
- data/app/views/effective/orders/_order_shipping.html.haml +1 -1
- data/app/views/effective/orders/helcim/_form.html.haml +1 -1
- data/lib/effective_orders/engine.rb +0 -1
- data/lib/effective_orders/version.rb +1 -1
- data/lib/effective_orders.rb +4 -0
- 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: 5d9af403d4a78ea5498469fb7c45b0dddad5ff8f72b6e752c059d473442e332d
|
4
|
+
data.tar.gz: 79cfedddb1851a9bb4c7c6b798dbc8cd14ad5a0e77aebe3ce5954d4b8ace116c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fddb18b9e210244dc6c009a4885f97610cf324a10cf9c154373e1bd95a13f61c995bbe262d9d0784fd17d32a3af7a8f237bac4950c599b2c3d6cbad2d168310f
|
7
|
+
data.tar.gz: 4a262a7709a4df828f604bf5f4f02cb9825bcf3a27b1713ea3b0006cc56339be48a23ab87e262b36d2d8b7ae261eb7c8ac2478b3f8fbe6980c27ba2555eb1ef9
|
@@ -20,14 +20,17 @@ function initializeHelcim() {
|
|
20
20
|
|
21
21
|
function helcimPayIframeEvent(event) {
|
22
22
|
if(event.data.eventName.startsWith('helcim-pay-js')) {
|
23
|
-
window.removeEventListener('message', helcimPayIframeEvent, false);
|
24
23
|
|
25
24
|
if(event.data.eventStatus == 'HIDE') {
|
25
|
+
window.removeEventListener('message', helcimPayIframeEvent, false);
|
26
|
+
|
26
27
|
let button = $('.effective-helcim-checkout').find('#helcim-checkout-button').get(0);
|
27
28
|
Rails.enableElement(button)
|
28
29
|
}
|
29
30
|
|
30
31
|
if(event.data.eventStatus == 'SUCCESS') {
|
32
|
+
window.removeEventListener('message', helcimPayIframeEvent, false);
|
33
|
+
|
31
34
|
let payment = btoa(event.data.eventMessage);
|
32
35
|
|
33
36
|
let $form = $('form[data-helcim-checkout]').first();
|
@@ -22,8 +22,14 @@ module Effective
|
|
22
22
|
return order_not_processed(declined_url: helcim_params[:declined_url])
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
26
|
-
payment = api.
|
25
|
+
# Get the trusted payment Hash from Helcim
|
26
|
+
payment = api.get_payment(@order, payment_payload)
|
27
|
+
|
28
|
+
# If fee_saver? we assign any surcharge to the order
|
29
|
+
api.assign_order_charges!(@order, payment)
|
30
|
+
|
31
|
+
# Verify the payment. This will raise a 500 error if the payment is not valid
|
32
|
+
api.verify_payment!(@order, payment)
|
27
33
|
|
28
34
|
# If it's purchased
|
29
35
|
purchased = api.purchased?(payment)
|
@@ -49,7 +49,7 @@ module Effective
|
|
49
49
|
brandColor: (brand_color || '815AF0')
|
50
50
|
},
|
51
51
|
invoiceRequest: {
|
52
|
-
invoiceNumber: '#' + order.
|
52
|
+
invoiceNumber: '#' + order.transaction_id(short: true)
|
53
53
|
},
|
54
54
|
customerRequest: {
|
55
55
|
contactName: order.billing_name,
|
@@ -110,6 +110,22 @@ module Effective
|
|
110
110
|
end
|
111
111
|
|
112
112
|
# Decode the base64 encoded JSON object that was given from the form into a Hash
|
113
|
+
# {"transactionId"=>"38142732",
|
114
|
+
# "dateCreated"=>"2025-08-15 10:10:32",
|
115
|
+
# "cardBatchId"=>"4656307",
|
116
|
+
# "status"=>"APPROVED",
|
117
|
+
# "type"=>"purchase",
|
118
|
+
# "amount"=>"10.97",
|
119
|
+
# "currency"=>"CAD",
|
120
|
+
# "avsResponse"=>"X",
|
121
|
+
# "cvvResponse"=>"",
|
122
|
+
# "approvalCode"=>"T5E3ST",
|
123
|
+
# "cardToken"=>"gv5J-lJAQNqVjZ_HkXyisQ",
|
124
|
+
# "cardNumber"=>"4242424242",
|
125
|
+
# "cardHolderName"=>"Test User",
|
126
|
+
# "customerCode"=>"CST1022",
|
127
|
+
# "invoiceNumber"=>"#30",
|
128
|
+
# "warning"=>""}
|
113
129
|
def decode_payment_payload(payload)
|
114
130
|
return if payload.blank?
|
115
131
|
|
@@ -127,11 +143,15 @@ module Effective
|
|
127
143
|
|
128
144
|
def purchased?(payment)
|
129
145
|
raise('expected a payment Hash') unless payment.kind_of?(Hash)
|
130
|
-
|
146
|
+
|
147
|
+
return true if (payment['status'] == 'APPROVED' && payment['type'] == 'purchase') # CC
|
148
|
+
return true if (payment['bankToken'].present? && payment['type'] == 'WITHDRAWAL') # ACH
|
149
|
+
|
150
|
+
false
|
131
151
|
end
|
132
152
|
|
133
153
|
# Considers the insecure payment_payload, requests the real transaction from Helcim and verifies it vs the order
|
134
|
-
def
|
154
|
+
def get_payment(order, payment_payload)
|
135
155
|
raise('expected a payment_payload Hash') unless payment_payload.kind_of?(Hash)
|
136
156
|
|
137
157
|
transaction_id = payment_payload['transactionId']
|
@@ -145,8 +165,32 @@ module Effective
|
|
145
165
|
raise('expected the payment and payment_payload to have the same transactionId')
|
146
166
|
end
|
147
167
|
|
168
|
+
# Normalize the card info and scrub out the card number
|
169
|
+
payment = payment.merge(card_info(payment)).except('cardNumber')
|
170
|
+
|
171
|
+
payment
|
172
|
+
end
|
173
|
+
|
174
|
+
# Adds the order.surcharge if this is a fee saver order
|
175
|
+
def assign_order_charges!(order, payment)
|
176
|
+
raise('expected an order') unless order.kind_of?(Effective::Order)
|
177
|
+
raise('expected a payment Hash') unless payment.kind_of?(Hash)
|
178
|
+
|
179
|
+
return unless EffectiveOrders.fee_saver?
|
180
|
+
|
181
|
+
# Validate amounts if purchased
|
182
|
+
amount = payment['amount'].to_f
|
183
|
+
amountAuthorized = order.total_to_f
|
184
|
+
|
185
|
+
surcharge = ((amount - amountAuthorized) * 100.0).round(0)
|
186
|
+
raise('expected surcharge to be a positive number') if surcharge < 0
|
187
|
+
|
188
|
+
order.update!(surcharge: surcharge)
|
189
|
+
end
|
190
|
+
|
191
|
+
def verify_payment!(order, payment)
|
148
192
|
# Validate order ids
|
149
|
-
|
193
|
+
unless payment['invoiceNumber'].to_s.start_with?('#' + order.to_param)
|
150
194
|
raise("expected card-transaction invoiceNumber to be the same as the order to_param")
|
151
195
|
end
|
152
196
|
|
@@ -155,9 +199,6 @@ module Effective
|
|
155
199
|
raise("expected card-transaction amount #{amount} to be the same as the amountAuthorized #{amountAuthorized} but it was not")
|
156
200
|
end
|
157
201
|
|
158
|
-
# Normalize the card info and scrub out the card number
|
159
|
-
payment = payment.merge(card_info(payment)).except('cardNumber')
|
160
|
-
|
161
202
|
payment
|
162
203
|
end
|
163
204
|
|
@@ -167,6 +208,8 @@ module Effective
|
|
167
208
|
last4 = payment['cardNumber'].to_s.last(4)
|
168
209
|
card = payment['cardType'].to_s.downcase
|
169
210
|
|
211
|
+
card = 'ACH' if card.blank? && payment['bankToken'].present?
|
212
|
+
|
170
213
|
active_card = "**** **** **** #{last4} #{card}" if last4.present?
|
171
214
|
|
172
215
|
{ 'active_card' => active_card, 'card' => card }.compact
|
@@ -205,6 +205,13 @@ module Effective
|
|
205
205
|
validates :delayed_payment_total, presence: true
|
206
206
|
end
|
207
207
|
|
208
|
+
# helcim fee saver and our own surcharge cannot co-exist
|
209
|
+
validate do
|
210
|
+
if EffectiveOrders.fee_saver? && EffectiveOrders.surcharge?
|
211
|
+
errors.add(:base, "cannot use fee saver and surcharge at the same time")
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
208
215
|
validate do
|
209
216
|
if EffectiveOrders.organization_enabled?
|
210
217
|
errors.add(:base, "must have a User or #{EffectiveOrders.organization_class_name || 'Organization'}") if user_id.blank? && organization_id.blank?
|
@@ -214,6 +221,8 @@ module Effective
|
|
214
221
|
end
|
215
222
|
|
216
223
|
# Price validations
|
224
|
+
validates :surcharge, numericality: { greater_than_or_equal_to: 0, allow_blank: true }, unless: -> { refund? }
|
225
|
+
|
217
226
|
validates :subtotal, presence: true
|
218
227
|
validates :total, presence: true, if: -> { EffectiveOrders.minimum_charge.to_i > 0 }
|
219
228
|
|
@@ -337,7 +346,7 @@ module Effective
|
|
337
346
|
removed.each { |order_item| order_item.mark_for_destruction }
|
338
347
|
|
339
348
|
# Make sure to reset stored aggregates
|
340
|
-
assign_attributes(subtotal: nil, tax_rate: nil, tax: nil, amount_owing: nil, surcharge_percent: nil, surcharge: nil, total: nil)
|
349
|
+
assign_attributes(subtotal: nil, tax_rate: nil, tax: nil, amount_owing: nil, surcharge_percent: nil, surcharge: nil, surcharge_tax: nil, total: nil)
|
341
350
|
|
342
351
|
removed.length == 1 ? removed.first : removed
|
343
352
|
end
|
@@ -381,7 +390,7 @@ module Effective
|
|
381
390
|
end.compact
|
382
391
|
|
383
392
|
# Make sure to reset stored aggregates
|
384
|
-
assign_attributes(subtotal: nil, tax_rate: nil, tax: nil, amount_owing: nil, surcharge_percent: nil, surcharge: nil, total: nil)
|
393
|
+
assign_attributes(subtotal: nil, tax_rate: nil, tax: nil, amount_owing: nil, surcharge_percent: nil, surcharge: nil, surcharge_tax: nil, total: nil)
|
385
394
|
|
386
395
|
retval = cart_items.map do |item|
|
387
396
|
order_items.build(
|
@@ -455,8 +464,12 @@ module Effective
|
|
455
464
|
end
|
456
465
|
|
457
466
|
# For moneris and moneris_checkout. Just a unique value. Must be 50 characters or fewer or will raise moneris error.
|
458
|
-
def transaction_id
|
459
|
-
|
467
|
+
def transaction_id(short: false)
|
468
|
+
if short
|
469
|
+
[to_param, Time.zone.now.to_i].compact.join('-')
|
470
|
+
else
|
471
|
+
[to_param, billing_name.to_s.parameterize.first(20).presence, Time.zone.now.to_i, rand(1000..9999)].compact.join('-')
|
472
|
+
end
|
460
473
|
end
|
461
474
|
|
462
475
|
def billing_first_name
|
@@ -979,10 +992,10 @@ module Effective
|
|
979
992
|
end
|
980
993
|
|
981
994
|
def get_surcharge_percent
|
982
|
-
|
983
|
-
return nil
|
995
|
+
return nil unless EffectiveOrders.surcharge?
|
996
|
+
return nil if purchased_without_credit_card?
|
984
997
|
|
985
|
-
|
998
|
+
percent = EffectiveOrders.credit_card_surcharge_percent.to_f
|
986
999
|
|
987
1000
|
if (percent > 10.0 || percent < 0.5)
|
988
1001
|
raise "expected EffectiveOrders.credit_card_surcharge to return a value between 10.0 (10%) and 0.5 (0.5%) or nil. Received #{percent}. Please return 2.5 for 2.5% surcharge."
|
@@ -992,21 +1005,25 @@ module Effective
|
|
992
1005
|
end
|
993
1006
|
|
994
1007
|
def get_surcharge
|
995
|
-
return
|
1008
|
+
return nil unless EffectiveOrders.surcharge?
|
1009
|
+
return nil unless surcharge_percent.present?
|
1010
|
+
|
996
1011
|
((subtotal + tax) * (surcharge_percent / 100.0)).round(0).to_i
|
997
1012
|
end
|
998
1013
|
|
999
1014
|
def get_surcharge_tax
|
1000
|
-
return
|
1001
|
-
|
1015
|
+
return nil unless EffectiveOrders.surcharge?
|
1016
|
+
return nil unless tax_rate.present?
|
1017
|
+
|
1018
|
+
(surcharge.to_i * (tax_rate / 100.0)).round(0).to_i
|
1002
1019
|
end
|
1003
1020
|
|
1004
1021
|
def get_total
|
1005
|
-
subtotal + tax + surcharge + surcharge_tax
|
1022
|
+
subtotal + tax + surcharge.to_i + surcharge_tax.to_i
|
1006
1023
|
end
|
1007
1024
|
|
1008
1025
|
def get_total_with_surcharge
|
1009
|
-
subtotal + tax + surcharge + surcharge_tax
|
1026
|
+
subtotal + tax + surcharge.to_i + surcharge_tax.to_i
|
1010
1027
|
end
|
1011
1028
|
|
1012
1029
|
def get_total_without_surcharge
|
@@ -1025,6 +1042,7 @@ module Effective
|
|
1025
1042
|
when 'm', 'mc', 'master', 'mastercard' then 'MasterCard'
|
1026
1043
|
when 'a', 'ax', 'american', 'americanexpress' then 'American Express'
|
1027
1044
|
when 'd', 'discover' then 'Discover'
|
1045
|
+
when 'ach' then 'ACH Payment'
|
1028
1046
|
else payment_card.to_s
|
1029
1047
|
end
|
1030
1048
|
|
@@ -1119,10 +1137,15 @@ module Effective
|
|
1119
1137
|
end
|
1120
1138
|
|
1121
1139
|
def assign_order_charges
|
1140
|
+
# We are assigning credit card surcharges ourselves
|
1122
1141
|
# We only apply surcharge for credit card orders. But we have to display and calculate for non purchased orders
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1142
|
+
if EffectiveOrders.surcharge?
|
1143
|
+
raise('surcharge is not supported with fee saver') if EffectiveOrders.fee_saver?
|
1144
|
+
|
1145
|
+
self.surcharge_percent = get_surcharge_percent()
|
1146
|
+
self.surcharge = get_surcharge()
|
1147
|
+
self.surcharge_tax = get_surcharge_tax()
|
1148
|
+
end
|
1126
1149
|
|
1127
1150
|
# Subtotal + Tax + Surcharge + Surcharge Tax
|
1128
1151
|
self.total = get_total()
|
@@ -32,7 +32,7 @@
|
|
32
32
|
|
33
33
|
- elsif order.payment_provider == 'etransfer'
|
34
34
|
%ul
|
35
|
-
%li Please submit your
|
35
|
+
%li Please submit your e-transfer payment within 30 days of the invoice date.
|
36
36
|
%li You have until payment is received or until <strong>#{order.delayed_payment_date.strftime("%A, %B %e, %Y")}</strong>, whichever is first, to make changes and cancellations.
|
37
37
|
%li A receipt will be sent after payment has been received.
|
38
38
|
|
@@ -65,7 +65,7 @@
|
|
65
65
|
%li A receipt will be sent after payment has been received.
|
66
66
|
- elsif order.payment_provider == 'etransfer'
|
67
67
|
%ul
|
68
|
-
%li Please submit your
|
68
|
+
%li Please submit your e-transfer within 30 days of the invoice date.
|
69
69
|
%li A receipt will be sent after payment has been received.
|
70
70
|
- else
|
71
71
|
- providers = EffectiveOrders.deferred_providers.to_sentence(last_word_connector: ', or', two_words_connector: ' or ')
|
@@ -23,6 +23,11 @@
|
|
23
23
|
= render partial: '/effective/orders/refund/form', locals: provider_locals
|
24
24
|
|
25
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 ')}.
|
30
|
+
|
26
31
|
- if EffectiveOrders.pretend?
|
27
32
|
= render partial: '/effective/orders/pretend/form', locals: provider_locals
|
28
33
|
|
@@ -36,6 +36,7 @@
|
|
36
36
|
-# Nothing to do. We can't display Tax, Total or Credit Card Surcharge (which is taxed) yet.
|
37
37
|
|
38
38
|
- elsif order.tax_rate.present? && order.surcharge_percent.to_f > 0.0
|
39
|
+
- # We're adding the surcharge. EffectiveOrders.surcharge? mode
|
39
40
|
%tr
|
40
41
|
%th.tax{colspan: 2} #{EffectiveOrders.tax_label} (#{rate_to_percentage(order.tax_rate)})
|
41
42
|
%td.price.tax-price= price_to_currency(order.tax)
|
@@ -56,7 +57,26 @@
|
|
56
57
|
%th.total{colspan: 2} Total amount charged to credit card
|
57
58
|
%td.price.total-price= price_to_currency(order.total)
|
58
59
|
|
60
|
+
- elsif order.tax_rate.present? && !(order.surcharge_percent.to_f > 0.0) && order.surcharge.to_i > 0
|
61
|
+
- # The surcharge is being added by the payment processor. EffectiveOrders.fee_saver? mode
|
62
|
+
%tr
|
63
|
+
%th.tax{colspan: 2} #{EffectiveOrders.tax_label} (#{rate_to_percentage(order.tax_rate)})
|
64
|
+
%td.price.tax-price= price_to_currency(order.tax)
|
65
|
+
|
66
|
+
%tr.single-line
|
67
|
+
%th.amount-owing{colspan: 2} Total
|
68
|
+
%td.price.amount-owing-price= price_to_currency(order.amount_owing)
|
69
|
+
|
70
|
+
%tr
|
71
|
+
%th.surcharge{colspan: 2} Credit card surcharge
|
72
|
+
%td.price.surcharge-price= price_to_currency(order.surcharge)
|
73
|
+
|
74
|
+
%tr.double-line
|
75
|
+
%th.total{colspan: 2} Credit card sale
|
76
|
+
%td.price.total-price= price_to_currency(order.total)
|
77
|
+
|
59
78
|
- elsif order.tax_rate.present? && !(order.surcharge_percent.to_f > 0.0)
|
79
|
+
- # No surcharges
|
60
80
|
%tr
|
61
81
|
%th.tax{colspan: 2} #{EffectiveOrders.tax_label} (#{rate_to_percentage(order.tax_rate)})
|
62
82
|
%td.price.tax-price= price_to_currency(order.tax)
|
@@ -17,6 +17,6 @@
|
|
17
17
|
.alert.alert-info.mb-4
|
18
18
|
This is the #{Rails.env.upcase} SERVER.
|
19
19
|
%br
|
20
|
-
Use credit card number 4242 4242 4242 4242 with any future
|
20
|
+
Use credit card number 4242 4242 4242 4242 with any future Expiry date and CVV 123
|
21
21
|
|
22
22
|
= render('effective/orders/helcim/element')
|
data/lib/effective_orders.rb
CHANGED
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.28.0
|
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-08-
|
11
|
+
date: 2025-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|