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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a6cc64b4d3c8818b17aef520b1f2df8d2fae53fd356a23d5894173dc8e8a912
4
- data.tar.gz: 7ff8238897bd82324aa3371edf338b3990ce86799b370f8e14bbf3a24b040acd
3
+ metadata.gz: 8f2d362666e0acf723037a83305a0d8abb7390b9450bdb70ca8edb2917023062
4
+ data.tar.gz: a9582919b75d433be885f5bd4f58b7fe45f4b49778627cbd1d66152d346c7a02
5
5
  SHA512:
6
- metadata.gz: d2edd3b449476638442508c6e5bd7866200b0b5af446a7b637359a8e22bf34ff7424c7ac53ba8ce62727fdbd90e80fcf5002ad3d8a409bb403c779c166bf2475
7
- data.tar.gz: 5d00adeedb3939c46283b4cc0335ce4301f587dc44ce9675216cec68b1cffcfef92eebab40b917039e86acac13a65bd018a98ab55344a8a2229ecdde3ffebec4
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
+ };
@@ -9,6 +9,7 @@ module Effective
9
9
  include Providers::DeluxeDelayedPurchase
10
10
  include Providers::Etransfer
11
11
  include Providers::Free
12
+ include Providers::Helcim
12
13
  include Providers::MarkAsPaid
13
14
  include Providers::Moneris
14
15
  include Providers::MonerisCheckout
@@ -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,5 @@
1
+ module EffectiveHelcimHelper
2
+ def helcim_initialize_request(order)
3
+ Effective::HelcimApi.new.initialize_request(order)
4
+ end
5
+ end
@@ -50,6 +50,8 @@ module EffectiveOrdersHelper
50
50
  'Pay by E-transfer'
51
51
  when :free
52
52
  'Checkout Free'
53
+ when :helcim
54
+ 'Pay by Credit Card'
53
55
  when :mark_as_paid
54
56
  'Admin: Mark as Paid'
55
57
  when :moneris
@@ -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,5 @@
1
+ .effective-helcim-checkout.text-center
2
+ #helcim-checkout-loading.text-center
3
+
4
+ #helcimCheckout
5
+ = link_to(order_checkout_label(:helcim), '#', id: 'helcim-checkout-button', class: 'btn btn-primary', 'data-disable-with' => 'Loading...')
@@ -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')
@@ -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
@@ -16,6 +16,7 @@ EffectiveOrders::Engine.routes.draw do
16
16
 
17
17
  post :etransfer
18
18
  post :free
19
+ post :helcim
19
20
  post :mark_as_paid
20
21
  post :moneris_checkout
21
22
  post :phone
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrders
2
- VERSION = '6.26.0'.freeze
2
+ VERSION = '6.27.0'.freeze
3
3
  end
@@ -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.26.0
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-22 00:00:00.000000000 Z
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