effective_orders 6.26.0 → 6.27.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 +41 -0
- data/app/controllers/effective/orders_controller.rb +1 -0
- data/app/controllers/effective/providers/helcim.rb +58 -0
- data/app/helpers/effective_helcim_helper.rb +5 -0
- data/app/helpers/effective_orders_helper.rb +2 -0
- data/app/models/effective/helcim_api.rb +277 -0
- data/app/models/effective/order.rb +6 -2
- data/app/models/effective/order_item.rb +12 -0
- data/app/views/effective/orders/_checkout_step2.html.haml +3 -0
- data/app/views/effective/orders/helcim/_element.html.haml +5 -0
- data/app/views/effective/orders/helcim/_form.html.haml +22 -0
- data/config/effective_orders.rb +10 -0
- data/config/routes.rb +1 -0
- data/lib/effective_orders/version.rb +1 -1
- data/lib/effective_orders.rb +16 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f2d362666e0acf723037a83305a0d8abb7390b9450bdb70ca8edb2917023062
|
4
|
+
data.tar.gz: a9582919b75d433be885f5bd4f58b7fe45f4b49778627cbd1d66152d346c7a02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de9920886821096194b4ee8b07ee2a643994e3daa4c726173cb354de7a0b044b74ca28d51deda550857e52f9166fb539cd6484f0eb5b3149c5d353a3f6fb76ca
|
7
|
+
data.tar.gz: 302f8062e198841746e462b589946f8fbd4b1bc52744e1f493402889db788739069708d9cc5729513a12cbfeae6c3c2551e945f470b3ce5c3942b6b88bc2d67a
|
@@ -0,0 +1,41 @@
|
|
1
|
+
// https://devdocs.helcim.com/docs/render-helcimpayjs
|
2
|
+
|
3
|
+
$(document).on('click', 'form[data-helcim-checkout] a', function(event) {
|
4
|
+
event.preventDefault();
|
5
|
+
initializeHelcim();
|
6
|
+
});
|
7
|
+
|
8
|
+
function initializeHelcim() {
|
9
|
+
let $helcim = $('form[data-helcim-checkout]');
|
10
|
+
if($helcim.length == 0) return;
|
11
|
+
|
12
|
+
let token = $helcim.data('helcim-checkout');
|
13
|
+
|
14
|
+
// From HelcimPay.js
|
15
|
+
appendHelcimPayIframe(token)
|
16
|
+
|
17
|
+
// Add our event listener
|
18
|
+
window.addEventListener('message', helcimPayIframeEvent, false);
|
19
|
+
};
|
20
|
+
|
21
|
+
function helcimPayIframeEvent(event) {
|
22
|
+
if(event.data.eventName.startsWith('helcim-pay-js')) {
|
23
|
+
window.removeEventListener('message', helcimPayIframeEvent, false);
|
24
|
+
|
25
|
+
if(event.data.eventStatus == 'HIDE') {
|
26
|
+
let button = $('.effective-helcim-checkout').find('#helcim-checkout-button').get(0);
|
27
|
+
Rails.enableElement(button)
|
28
|
+
}
|
29
|
+
|
30
|
+
if(event.data.eventStatus == 'SUCCESS') {
|
31
|
+
let payment = btoa(event.data.eventMessage);
|
32
|
+
|
33
|
+
let $form = $('form[data-helcim-checkout]').first();
|
34
|
+
$form.find('input[name="helcim[payment]"]').val(payment);
|
35
|
+
$form.submit();
|
36
|
+
|
37
|
+
$('#helcimCheckout').fadeOut('slow');
|
38
|
+
$('#helcim-checkout-loading').text('Thank you! Processing payment information. Please wait...');
|
39
|
+
}
|
40
|
+
}
|
41
|
+
};
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Effective
|
2
|
+
module Providers
|
3
|
+
module Helcim
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def helcim
|
7
|
+
raise('helcim provider is not available') unless EffectiveOrders.helcim?
|
8
|
+
|
9
|
+
@order = Effective::Order.deep.find(params[:id])
|
10
|
+
@order.current_user = current_user unless admin_checkout?(helcim_params)
|
11
|
+
|
12
|
+
EffectiveResources.authorize!(self, :update, @order)
|
13
|
+
|
14
|
+
# Process and Verify Payment
|
15
|
+
api = Effective::HelcimApi.new
|
16
|
+
|
17
|
+
# Decode the payment payload
|
18
|
+
payment_payload = api.decode_payment_payload(helcim_params[:payment])
|
19
|
+
|
20
|
+
if payment_payload.blank?
|
21
|
+
flash[:danger] = 'Unable to process helcim order without payment. please try again.'
|
22
|
+
return order_not_processed(declined_url: helcim_params[:declined_url])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Verify the payment
|
26
|
+
payment = api.verify_payment(@order, payment_payload)
|
27
|
+
|
28
|
+
# If it's purchased
|
29
|
+
purchased = api.purchased?(payment)
|
30
|
+
|
31
|
+
if purchased == false
|
32
|
+
flash[:danger] = "Payment was unsuccessful. The credit card payment failed with message: #{payment['status'] || 'none'}. Please try again."
|
33
|
+
return order_declined(
|
34
|
+
payment: payment,
|
35
|
+
provider: 'helcim',
|
36
|
+
card: payment['card'],
|
37
|
+
declined_url: helcim_params[:declined_url]
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Valid Authorized and Completed Payment
|
42
|
+
order_purchased(
|
43
|
+
payment: payment,
|
44
|
+
provider: 'helcim',
|
45
|
+
card: payment['card'],
|
46
|
+
purchased_url: helcim_params[:purchased_url]
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def helcim_params
|
53
|
+
params.require(:helcim).permit(:payment, :purchased_url, :declined_url)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,277 @@
|
|
1
|
+
# https://devdocs.helcim.com/docs/overview-of-helcimpayjs
|
2
|
+
# Effective::HelcimApi.new.health_check
|
3
|
+
module Effective
|
4
|
+
class HelcimApi
|
5
|
+
# All required
|
6
|
+
attr_accessor :environment
|
7
|
+
attr_accessor :api_token
|
8
|
+
attr_accessor :currency
|
9
|
+
attr_accessor :brand_color
|
10
|
+
|
11
|
+
attr_accessor :read_timeout
|
12
|
+
|
13
|
+
def initialize(environment: nil, api_token: nil, currency: nil, brand_color: nil)
|
14
|
+
self.environment = environment || EffectiveOrders.helcim.fetch(:environment)
|
15
|
+
self.api_token = api_token || EffectiveOrders.helcim.fetch(:api_token)
|
16
|
+
self.currency = currency || EffectiveOrders.helcim.fetch(:currency)
|
17
|
+
self.brand_color = brand_color || EffectiveOrders.helcim.fetch(:brand_color)
|
18
|
+
end
|
19
|
+
|
20
|
+
def health_check
|
21
|
+
get('/connection-test')
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_transaction(id)
|
25
|
+
get("/card-transactions/#{id}")
|
26
|
+
end
|
27
|
+
|
28
|
+
# Make the Preload Request
|
29
|
+
# https://devdocs.helcim.com/reference/checkout-init
|
30
|
+
def initialize_request(order)
|
31
|
+
params = {
|
32
|
+
amount: ('%.2f' % order.total_to_f),
|
33
|
+
currency: currency,
|
34
|
+
paymentMethod: 'cc',
|
35
|
+
paymentType: 'purchase', # purchase, preauth, verify
|
36
|
+
allowPartial: 0,
|
37
|
+
hasConvenienceFee: 0,
|
38
|
+
taxAmount: ('%.2f' % order.tax_to_f if order.tax.to_i > 0),
|
39
|
+
hideExistingPaymentDetails: 0,
|
40
|
+
setAsDefaultPaymentMethod: 1,
|
41
|
+
confirmationScreen: false,
|
42
|
+
displayContactFields: 0,
|
43
|
+
customStyling: {
|
44
|
+
brandColor: (brand_color || '815AF0')
|
45
|
+
},
|
46
|
+
invoiceRequest: {
|
47
|
+
invoiceNumber: '#' + order.to_param
|
48
|
+
},
|
49
|
+
customerRequest: {
|
50
|
+
contactName: order.billing_name,
|
51
|
+
businessName: order.organization.to_s.presence,
|
52
|
+
}.compact,
|
53
|
+
}.compact
|
54
|
+
|
55
|
+
params[:invoiceRequest][:lineItems] = order.order_items.map do |item|
|
56
|
+
{
|
57
|
+
description: item.name,
|
58
|
+
quantity: item.quantity,
|
59
|
+
price: ('%.2f' % item.price_to_f),
|
60
|
+
total: ('%.2f' % item.subtotal_to_f),
|
61
|
+
taxAmount: ('%.2f' % item.tax_to_f),
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
address = order.billing_address
|
66
|
+
country = helcim_country(address&.country_code)
|
67
|
+
|
68
|
+
if address.present? && country.to_s.length == 3
|
69
|
+
params[:customerRequest][:billingAddress] = {
|
70
|
+
name: order.billing_name,
|
71
|
+
street1: address.address1,
|
72
|
+
street2: address.address2,
|
73
|
+
city: address.city,
|
74
|
+
province: address.state_code,
|
75
|
+
country: country,
|
76
|
+
postalCode: address.postal_code,
|
77
|
+
email: order.email,
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
address = order.shipping_address
|
82
|
+
country = helcim_country(address&.country_code)
|
83
|
+
|
84
|
+
if address.present? && country.to_s.length == 3
|
85
|
+
params[:customerRequest][:shippingAddress] = {
|
86
|
+
name: order.billing_name,
|
87
|
+
street1: address.address1,
|
88
|
+
street2: address.address2,
|
89
|
+
city: address.city,
|
90
|
+
province: address.state_code,
|
91
|
+
country: country,
|
92
|
+
postalCode: address.postal_code,
|
93
|
+
email: order.email,
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
response = post('/helcim-pay/initialize', params: params)
|
98
|
+
raise("expected response to be a Hash") unless response.kind_of?(Hash)
|
99
|
+
|
100
|
+
token = response['checkoutToken']
|
101
|
+
raise("expected response to include a checkoutToken") unless token.present?
|
102
|
+
|
103
|
+
# Return the token to the front end form
|
104
|
+
token
|
105
|
+
end
|
106
|
+
|
107
|
+
# Decode the base64 encoded JSON object that was given from the form into a Hash
|
108
|
+
def decode_payment_payload(payload)
|
109
|
+
return if payload.blank?
|
110
|
+
|
111
|
+
raise('expected a string') unless payload.kind_of?(String)
|
112
|
+
|
113
|
+
payment = (JSON.parse(Base64.decode64(payload)) rescue nil)
|
114
|
+
raise('expected payment to be a Hash') unless payment.kind_of?(Hash)
|
115
|
+
|
116
|
+
payment = payment.dig('data', 'data')
|
117
|
+
raise('expected payment data') unless payment.kind_of?(Hash)
|
118
|
+
raise('expected payment data with a transactionId') unless payment['transactionId'].present?
|
119
|
+
|
120
|
+
payment
|
121
|
+
end
|
122
|
+
|
123
|
+
def purchased?(payment)
|
124
|
+
raise('expected a payment Hash') unless payment.kind_of?(Hash)
|
125
|
+
(payment['status'] == 'APPROVED' && payment['type'] == 'purchase')
|
126
|
+
end
|
127
|
+
|
128
|
+
# Considers the insecure payment_payload, requests the real transaction from Helcim and verifies it vs the order
|
129
|
+
def verify_payment(order, payment_payload)
|
130
|
+
raise('expected a payment_payload Hash') unless payment_payload.kind_of?(Hash)
|
131
|
+
|
132
|
+
transaction_id = payment_payload['transactionId']
|
133
|
+
raise('expected a payment_payload with a transactionId') unless transaction_id.present?
|
134
|
+
|
135
|
+
payment = get_transaction(transaction_id)
|
136
|
+
raise('expected an existing card-transaction payment') unless payment.kind_of?(Hash)
|
137
|
+
|
138
|
+
# Compare the payment (trusted truth) and the payment_payload (untrusted)
|
139
|
+
if payment['transactionId'].to_s != payment_payload['transactionId'].to_s
|
140
|
+
raise('expected the payment and payment_payload to have the same transactionId')
|
141
|
+
end
|
142
|
+
|
143
|
+
# Validate order ids
|
144
|
+
if payment['invoiceNumber'].to_s != '#' + order.to_param
|
145
|
+
raise("expected card-transaction invoiceNumber to be the same as the order to_param")
|
146
|
+
end
|
147
|
+
|
148
|
+
# Validate amounts if purchased
|
149
|
+
if purchased?(payment) && (amount = payment['amount'].to_f) != (amountAuthorized = order.total_to_f)
|
150
|
+
raise("expected card-transaction amount #{amount} to be the same as the amountAuthorized #{amountAuthorized} but it was not")
|
151
|
+
end
|
152
|
+
|
153
|
+
# Normalize the card info and scrub out the card number
|
154
|
+
payment = payment.merge(card_info(payment)).except('cardNumber')
|
155
|
+
|
156
|
+
payment
|
157
|
+
end
|
158
|
+
|
159
|
+
# Takes a payment_intent and returns the card info we can store
|
160
|
+
def card_info(payment)
|
161
|
+
# Return the authorization params merged with the card info
|
162
|
+
last4 = payment['cardNumber'].to_s.last(4)
|
163
|
+
card = payment['cardType'].to_s.downcase
|
164
|
+
|
165
|
+
active_card = "**** **** **** #{last4} #{card}" if last4.present?
|
166
|
+
|
167
|
+
{ 'active_card' => active_card, 'card' => card }.compact
|
168
|
+
end
|
169
|
+
|
170
|
+
def get(endpoint, params: nil)
|
171
|
+
query = ('?' + params.compact.map { |k, v| "$#{k}=#{v}" }.join('&')) if params.present?
|
172
|
+
|
173
|
+
uri = URI.parse(api_url + endpoint + query.to_s)
|
174
|
+
|
175
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
176
|
+
http.read_timeout = (read_timeout || 30)
|
177
|
+
http.use_ssl = true
|
178
|
+
|
179
|
+
result = with_retries do
|
180
|
+
puts "[GET] #{uri}" if Rails.env.development?
|
181
|
+
|
182
|
+
response = http.get(uri, headers)
|
183
|
+
raise Exception.new("#{response.code} #{response.body}") unless response.code == '200'
|
184
|
+
|
185
|
+
response
|
186
|
+
end
|
187
|
+
|
188
|
+
JSON.parse(result.body)
|
189
|
+
end
|
190
|
+
|
191
|
+
def post(endpoint, params:)
|
192
|
+
uri = URI.parse(api_url + endpoint)
|
193
|
+
|
194
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
195
|
+
http.read_timeout = (read_timeout || 30)
|
196
|
+
http.use_ssl = true
|
197
|
+
|
198
|
+
puts "[POST] #{uri} #{params}" if Rails.env.development?
|
199
|
+
|
200
|
+
response = http.post(uri.path, params.to_json, headers)
|
201
|
+
raise Exception.new("#{response.code} #{response.body}") unless response.code == '200'
|
202
|
+
|
203
|
+
JSON.parse(response.body)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Effective::HelcimApi.new.set_logo!
|
207
|
+
# Put your file in the apps/tenant/app/assets/images/tenant/helcim-logo.png
|
208
|
+
# Run this once to set the logo
|
209
|
+
def set_logo!(path: nil)
|
210
|
+
path ||= Rails.root.join("apps/#{Tenant.current}/app/assets/images/#{Tenant.current}/helcim-logo.png")
|
211
|
+
raise("Expected #{path} to exist") unless File.exist?(path)
|
212
|
+
|
213
|
+
url = URI.parse(api_url + '/branding/logo')
|
214
|
+
boundary = "AaB03x"
|
215
|
+
|
216
|
+
# Build multipart form data
|
217
|
+
body = [
|
218
|
+
"--#{boundary}",
|
219
|
+
"Content-Disposition: form-data; name=\"logo\"; filename=\"#{File.basename(path)}\"",
|
220
|
+
"Content-Type: image/#{File.extname(path).downcase.delete('.')}",
|
221
|
+
"",
|
222
|
+
File.binread(path),
|
223
|
+
"--#{boundary}--"
|
224
|
+
].join("\r\n")
|
225
|
+
|
226
|
+
# Set up HTTP request
|
227
|
+
http = Net::HTTP.new(url.host, url.port)
|
228
|
+
http.use_ssl = true
|
229
|
+
|
230
|
+
# Create POST request
|
231
|
+
request = Net::HTTP::Post.new(url.path)
|
232
|
+
request.body = body
|
233
|
+
|
234
|
+
request.initialize_http_header(headers.merge({
|
235
|
+
'Content-Type' => "multipart/form-data; boundary=#{boundary}",
|
236
|
+
'Content-Length' => request.body.length.to_s,
|
237
|
+
}))
|
238
|
+
|
239
|
+
# Send request
|
240
|
+
response = http.request(request)
|
241
|
+
raise Exception.new("#{response.code} #{response.body}") unless response.code == '200'
|
242
|
+
|
243
|
+
JSON.parse(response.body)
|
244
|
+
end
|
245
|
+
|
246
|
+
private
|
247
|
+
|
248
|
+
def headers
|
249
|
+
{ "Accept": "application/json", "Content-Type": "application/json", 'api-token': api_token }
|
250
|
+
end
|
251
|
+
|
252
|
+
def api_url
|
253
|
+
'https://api.helcim.com/v2' # No trailing /
|
254
|
+
end
|
255
|
+
|
256
|
+
def helcim_country(country_code)
|
257
|
+
return 'CAN' if country_code == 'CA' || country_code == 'CAD'
|
258
|
+
return 'USA' if country_code == 'US'
|
259
|
+
country_code
|
260
|
+
end
|
261
|
+
|
262
|
+
def with_retries(retries: (Rails.env.development? ? 0 : 3), wait: 2, &block)
|
263
|
+
raise('expected a block') unless block_given?
|
264
|
+
|
265
|
+
begin
|
266
|
+
return yield
|
267
|
+
rescue Exception => e
|
268
|
+
if (retries -= 1) > 0
|
269
|
+
sleep(wait); retry
|
270
|
+
else
|
271
|
+
raise
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
end
|
@@ -539,6 +539,10 @@ module Effective
|
|
539
539
|
((total || 0) / 100.0).to_f
|
540
540
|
end
|
541
541
|
|
542
|
+
def tax_to_f
|
543
|
+
((tax || 0) / 100.0).to_f
|
544
|
+
end
|
545
|
+
|
542
546
|
def total_with_surcharge
|
543
547
|
get_total_with_surcharge()
|
544
548
|
end
|
@@ -1017,7 +1021,7 @@ module Effective
|
|
1017
1021
|
# Normalize payment card
|
1018
1022
|
card = case payment_card.to_s.downcase.gsub(' ', '').strip
|
1019
1023
|
when '' then nil
|
1020
|
-
when 'v', 'visa' then 'Visa'
|
1024
|
+
when 'v', 'visa', 'vi' then 'Visa'
|
1021
1025
|
when 'm', 'mc', 'master', 'mastercard' then 'MasterCard'
|
1022
1026
|
when 'a', 'ax', 'american', 'americanexpress' then 'American Express'
|
1023
1027
|
when 'd', 'discover' then 'Discover'
|
@@ -1028,7 +1032,7 @@ module Effective
|
|
1028
1032
|
if card == 'none' && payment['card_type'].present?
|
1029
1033
|
card = case payment['card_type'].to_s.downcase.gsub(' ', '').strip
|
1030
1034
|
when '' then nil
|
1031
|
-
when 'v', 'visa' then 'Visa'
|
1035
|
+
when 'v', 'visa', 'vi' then 'Visa'
|
1032
1036
|
when 'm', 'mc', 'master', 'mastercard' then 'MasterCard'
|
1033
1037
|
when 'a', 'ax', 'american', 'americanexpress' then 'American Express'
|
1034
1038
|
when 'd', 'discover' then 'Discover'
|
@@ -58,10 +58,18 @@ module Effective
|
|
58
58
|
purchasable&.purchased_download_url
|
59
59
|
end
|
60
60
|
|
61
|
+
def price_to_f
|
62
|
+
((price|| 0) / 100.0).to_f
|
63
|
+
end
|
64
|
+
|
61
65
|
def subtotal
|
62
66
|
price * quantity
|
63
67
|
end
|
64
68
|
|
69
|
+
def subtotal_to_f
|
70
|
+
((subtotal || 0) / 100.0).to_f
|
71
|
+
end
|
72
|
+
|
65
73
|
def quantity
|
66
74
|
self[:quantity] || 1
|
67
75
|
end
|
@@ -72,6 +80,10 @@ module Effective
|
|
72
80
|
(subtotal * order.tax_rate / 100.0).round(0).to_i
|
73
81
|
end
|
74
82
|
|
83
|
+
def tax_to_f
|
84
|
+
((tax || 0) / 100.0).to_f
|
85
|
+
end
|
86
|
+
|
75
87
|
def amount_owing
|
76
88
|
total
|
77
89
|
end
|
@@ -29,6 +29,9 @@
|
|
29
29
|
- if EffectiveOrders.deluxe?
|
30
30
|
= render partial: '/effective/orders/deluxe/form', locals: provider_locals
|
31
31
|
|
32
|
+
- if EffectiveOrders.helcim?
|
33
|
+
= render partial: '/effective/orders/helcim/form', locals: provider_locals
|
34
|
+
|
32
35
|
- if EffectiveOrders.moneris?
|
33
36
|
= render partial: '/effective/orders/moneris/form', locals: provider_locals
|
34
37
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
- token = helcim_initialize_request(order)
|
2
|
+
|
3
|
+
.card
|
4
|
+
.card-body
|
5
|
+
%h2 Checkout
|
6
|
+
|
7
|
+
.mt-4
|
8
|
+
|
9
|
+
= effective_form_with(scope: :helcim, url: effective_orders.helcim_order_path(order), data: { 'helcim-checkout': token }) do |f|
|
10
|
+
= f.hidden_field :purchased_url, value: purchased_url
|
11
|
+
= f.hidden_field :declined_url, value: declined_url
|
12
|
+
|
13
|
+
-# This is set by the helcim.js javascript
|
14
|
+
= f.hidden_field :payment
|
15
|
+
|
16
|
+
- if EffectiveOrders.helcim[:environment] == 'sandbox'
|
17
|
+
.alert.alert-info.mb-4
|
18
|
+
This is the #{Rails.env.upcase} SERVER.
|
19
|
+
%br
|
20
|
+
Use credit card number 4242 4242 4242 4242 with any future expiry and cvv 123
|
21
|
+
|
22
|
+
= render('effective/orders/helcim/element')
|
data/config/effective_orders.rb
CHANGED
@@ -166,6 +166,16 @@ EffectiveOrders.setup do |config|
|
|
166
166
|
# success: 'Thank you! You have indicated that this order will be purchased by e-transfer. Please send us an e-transfer to "payments@example.com" with password "example" at your earliest convenience'
|
167
167
|
# }
|
168
168
|
|
169
|
+
# Helcim
|
170
|
+
config.helcim = false
|
171
|
+
|
172
|
+
# config.helcim = {
|
173
|
+
# environment: (Rails.env.production? ? 'production' : 'sandbox'),
|
174
|
+
# api_token: '',
|
175
|
+
# currency: 'CAD',
|
176
|
+
# brand_color: '815AF0' # 6-digit hex color without any # sign
|
177
|
+
# }
|
178
|
+
|
169
179
|
# Moneris
|
170
180
|
config.moneris = false
|
171
181
|
|
data/config/routes.rb
CHANGED
data/lib/effective_orders.rb
CHANGED
@@ -49,7 +49,7 @@ module EffectiveOrders
|
|
49
49
|
:free_enabled, :mark_as_paid_enabled, :pretend_enabled, :pretend_message, :buyer_purchases_refund,
|
50
50
|
|
51
51
|
# Payment processors. false or Hash
|
52
|
-
:cheque, :deluxe, :deluxe_delayed, :etransfer, :moneris, :moneris_checkout, :paypal, :phone, :refund, :stripe, :subscriptions, :trial
|
52
|
+
:cheque, :deluxe, :deluxe_delayed, :etransfer, :helcim, :moneris, :moneris_checkout, :paypal, :phone, :refund, :stripe, :subscriptions, :trial
|
53
53
|
]
|
54
54
|
end
|
55
55
|
|
@@ -104,6 +104,10 @@ module EffectiveOrders
|
|
104
104
|
delayed_providers.present?
|
105
105
|
end
|
106
106
|
|
107
|
+
def self.helcim?
|
108
|
+
helcim.kind_of?(Hash)
|
109
|
+
end
|
110
|
+
|
107
111
|
def self.mark_as_paid?
|
108
112
|
mark_as_paid_enabled == true
|
109
113
|
end
|
@@ -164,6 +168,7 @@ module EffectiveOrders
|
|
164
168
|
('deluxe' if deluxe?),
|
165
169
|
('etransfer' if etransfer?),
|
166
170
|
('free' if free?),
|
171
|
+
('helcim' if helcim?),
|
167
172
|
('moneris' if moneris?),
|
168
173
|
('moneris_checkout' if moneris_checkout?),
|
169
174
|
('paypal' if paypal?),
|
@@ -183,6 +188,7 @@ module EffectiveOrders
|
|
183
188
|
('credit card' if mark_as_paid?),
|
184
189
|
('deluxe' if deluxe?),
|
185
190
|
('etransfer' if etransfer?),
|
191
|
+
('helcim' if helcim?),
|
186
192
|
#('free' if free?),
|
187
193
|
('moneris' if moneris?),
|
188
194
|
('moneris_checkout' if moneris_checkout?),
|
@@ -206,7 +212,7 @@ module EffectiveOrders
|
|
206
212
|
end
|
207
213
|
|
208
214
|
def self.credit_card_payment_providers
|
209
|
-
['credit card', 'deluxe', 'moneris', 'moneris_checkout', 'paypal', 'stripe']
|
215
|
+
['credit card', 'deluxe', 'helcim', 'moneris', 'moneris_checkout', 'paypal', 'stripe']
|
210
216
|
end
|
211
217
|
|
212
218
|
def self.qb_sync?
|
@@ -330,6 +336,10 @@ module EffectiveOrders
|
|
330
336
|
end
|
331
337
|
end
|
332
338
|
|
339
|
+
def self.helcim_script_url
|
340
|
+
"https://secure.helcim.app/helcim-pay/services/start.js"
|
341
|
+
end
|
342
|
+
|
333
343
|
def self.moneris_checkout_script_url
|
334
344
|
case EffectiveOrders.moneris_checkout.fetch(:environment)
|
335
345
|
when 'prod' then 'https://gateway.moneris.com/chktv2/js/chkt_v2.00.js'
|
@@ -346,6 +356,10 @@ module EffectiveOrders
|
|
346
356
|
end
|
347
357
|
end
|
348
358
|
|
359
|
+
def self.stripe_script_url
|
360
|
+
"https://js.stripe.com/v3/"
|
361
|
+
end
|
362
|
+
|
349
363
|
class SoldOutException < Exception; end
|
350
364
|
|
351
365
|
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.
|
4
|
+
version: 6.27.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-07-
|
11
|
+
date: 2025-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -195,6 +195,7 @@ files:
|
|
195
195
|
- app/assets/javascripts/effective_orders/customers.js.coffee
|
196
196
|
- app/assets/javascripts/effective_orders/providers/deluxe.js
|
197
197
|
- app/assets/javascripts/effective_orders/providers/deluxe_delayed.js
|
198
|
+
- app/assets/javascripts/effective_orders/providers/helcim.js
|
198
199
|
- app/assets/javascripts/effective_orders/providers/moneris_checkout.js.coffee
|
199
200
|
- app/assets/javascripts/effective_orders/providers/stripe.js.coffee
|
200
201
|
- app/assets/javascripts/effective_orders/subscriptions.js.coffee
|
@@ -216,6 +217,7 @@ files:
|
|
216
217
|
- app/controllers/effective/providers/deluxe_delayed_purchase.rb
|
217
218
|
- app/controllers/effective/providers/etransfer.rb
|
218
219
|
- app/controllers/effective/providers/free.rb
|
220
|
+
- app/controllers/effective/providers/helcim.rb
|
219
221
|
- app/controllers/effective/providers/mark_as_paid.rb
|
220
222
|
- app/controllers/effective/providers/moneris.rb
|
221
223
|
- app/controllers/effective/providers/moneris_checkout.rb
|
@@ -239,6 +241,7 @@ files:
|
|
239
241
|
- app/helpers/effective_carts_helper.rb
|
240
242
|
- app/helpers/effective_deluxe_delayed_helper.rb
|
241
243
|
- app/helpers/effective_deluxe_helper.rb
|
244
|
+
- app/helpers/effective_helcim_helper.rb
|
242
245
|
- app/helpers/effective_moneris_checkout_helper.rb
|
243
246
|
- app/helpers/effective_orders_helper.rb
|
244
247
|
- app/helpers/effective_paypal_helper.rb
|
@@ -253,6 +256,7 @@ files:
|
|
253
256
|
- app/models/effective/cart_item.rb
|
254
257
|
- app/models/effective/customer.rb
|
255
258
|
- app/models/effective/deluxe_api.rb
|
259
|
+
- app/models/effective/helcim_api.rb
|
256
260
|
- app/models/effective/item_name.rb
|
257
261
|
- app/models/effective/order.rb
|
258
262
|
- app/models/effective/order_email.rb
|
@@ -326,6 +330,8 @@ files:
|
|
326
330
|
- app/views/effective/orders/edit.html.haml
|
327
331
|
- app/views/effective/orders/etransfer/_form.html.haml
|
328
332
|
- app/views/effective/orders/free/_form.html.haml
|
333
|
+
- app/views/effective/orders/helcim/_element.html.haml
|
334
|
+
- app/views/effective/orders/helcim/_form.html.haml
|
329
335
|
- app/views/effective/orders/index.html.haml
|
330
336
|
- app/views/effective/orders/mark_as_paid/_form.html.haml
|
331
337
|
- app/views/effective/orders/moneris/_form.html.haml
|