effective_orders 5.0.1 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +67 -1
- data/app/assets/config/effective_orders_manifest.js +3 -0
- data/app/assets/images/effective_orders/logo.png +0 -0
- data/app/assets/javascripts/effective_orders.js +1 -1
- data/app/assets/javascripts/effective_orders/providers/moneris_checkout.js.coffee +71 -0
- data/app/assets/stylesheets/effective_orders/_order.scss +4 -0
- data/app/controllers/effective/concerns/purchase.rb +14 -21
- data/app/controllers/effective/orders_controller.rb +2 -2
- data/app/controllers/effective/providers/free.rb +0 -1
- data/app/controllers/effective/providers/mark_as_paid.rb +1 -2
- data/app/controllers/effective/providers/moneris_checkout.rb +59 -0
- data/app/controllers/effective/providers/pretend.rb +1 -2
- data/app/controllers/effective/providers/refund.rb +1 -2
- data/app/controllers/effective/providers/stripe.rb +1 -2
- data/app/datatables/admin/effective_orders_datatable.rb +5 -8
- data/app/datatables/effective_orders_datatable.rb +3 -7
- data/app/helpers/effective_moneris_checkout_helper.rb +65 -0
- data/app/helpers/effective_orders_helper.rb +3 -26
- data/app/mailers/effective/orders_mailer.rb +6 -4
- data/app/models/concerns/acts_as_purchasable.rb +2 -0
- data/app/models/concerns/acts_as_subscribable.rb +1 -0
- data/app/models/concerns/acts_as_subscribable_buyer.rb +2 -1
- data/app/models/effective/order.rb +56 -35
- data/app/models/effective/order_item.rb +10 -0
- data/app/models/effective/product.rb +2 -0
- data/app/views/effective/orders/_checkout_step2.html.haml +3 -0
- data/app/views/effective/orders/_order.html.haml +1 -1
- data/app/views/effective/orders/_order_actions.html.haml +1 -1
- data/app/views/effective/orders/_order_footer.html.haml +3 -1
- data/app/views/effective/orders/_order_header.html.haml +4 -20
- data/app/views/effective/orders/_order_payment.html.haml +7 -18
- data/app/views/effective/orders/declined.html.haml +2 -4
- data/app/views/effective/orders/deferred.html.haml +2 -4
- data/app/views/effective/orders/moneris_checkout/_element.html.haml +4 -0
- data/app/views/effective/orders/moneris_checkout/_form.html.haml +23 -0
- data/app/views/effective/orders/purchased.html.haml +2 -4
- data/app/views/effective/orders/show.html.haml +5 -2
- data/config/effective_orders.rb +19 -0
- data/config/routes.rb +1 -0
- data/lib/effective_orders.rb +23 -2
- data/lib/effective_orders/engine.rb +2 -2
- data/lib/effective_orders/version.rb +1 -1
- data/lib/generators/templates/effective_orders_mailer_preview.rb +6 -0
- metadata +69 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31540d5d07a5c2afc891284cd037d88d25ea6aba9db57073a53b5dd60c952a11
|
4
|
+
data.tar.gz: 502ad51ce45452ff307292de9d2f16c934a7e1a0aca7c62376272b1f3ede07b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7541296d5ee6f6d52dc2edf94938f28734bf8da046612c46b0de23ee51fcd70c2eb80a32dd53534d16ffd3a9de72a923de9fffa709c4b96651ccf49fe7779b9b
|
7
|
+
data.tar.gz: 7be888605850e6dda6b952bf6ba9cceb575577b3d18ded8c118c8028890715bf41c8d8ded387de1bd5378c38207329af61709d071f2a80eec528ce6c7e701164
|
data/README.md
CHANGED
@@ -594,8 +594,74 @@ You will need an external IP address to work with these sandboxes.
|
|
594
594
|
|
595
595
|
We suggest the free application `https://ngrok.com/` for this ability.
|
596
596
|
|
597
|
+
## Paying with Moneris Checkout
|
597
598
|
|
598
|
-
|
599
|
+
Use the following instructions to set up a Moneris Checkout store.
|
600
|
+
|
601
|
+
This is the javascript / pay in place form implementation.
|
602
|
+
|
603
|
+
We do not use or implement tokenization of credentials with Moneris Checkout.
|
604
|
+
|
605
|
+
We are also going to use ngrok to give us a public facing URL
|
606
|
+
|
607
|
+
### Create Test / Development Store
|
608
|
+
|
609
|
+
Visit https://esqa.moneris.com/mpg/ and login with: demouser / store1 / password
|
610
|
+
|
611
|
+
- Select Admin -> Moneris Checkout Config from the menu
|
612
|
+
- Click Create Profile
|
613
|
+
|
614
|
+
Checkout Type: I have my custom order form and want to use Moneris simply for payment processing
|
615
|
+
|
616
|
+
Multi-Currency: None
|
617
|
+
|
618
|
+
Payment:
|
619
|
+
|
620
|
+
- Google Pay: No
|
621
|
+
- Card Logos: Yes
|
622
|
+
- Payment Security: CVV
|
623
|
+
- Transaction Type: Purchase
|
624
|
+
- Transaction Limits: None
|
625
|
+
|
626
|
+
Branding & Design
|
627
|
+
|
628
|
+
- Logo Url: None
|
629
|
+
- Colors: Default
|
630
|
+
|
631
|
+
Customizations
|
632
|
+
|
633
|
+
- Enable Fullscreen: No false (important)
|
634
|
+
- Card Borders/Shadows: Yes
|
635
|
+
|
636
|
+
Order Confirmation
|
637
|
+
|
638
|
+
- Order Confirmation Processing: Use Moneris
|
639
|
+
- Confirmation Page Content: Check all
|
640
|
+
|
641
|
+
Email Communications
|
642
|
+
|
643
|
+
- None
|
644
|
+
- Customer Emails: None
|
645
|
+
|
646
|
+
|
647
|
+
Now copy the Checkout id, something like `chktJF76Btore1` into the config/initializers/effective_orders.rb file.
|
648
|
+
|
649
|
+
For the store_id and api_token values, you can use
|
650
|
+
|
651
|
+
```
|
652
|
+
config.moneris_checkout = {
|
653
|
+
environment: 'qa',
|
654
|
+
store_id: 'store1',
|
655
|
+
api_token: 'yesguy1',
|
656
|
+
checkout_id: '', # You need to generate this one
|
657
|
+
}
|
658
|
+
```
|
659
|
+
|
660
|
+
[Testing a Solution](https://developer.moneris.com/en/More/Testing/Testing%20a%20Solution)
|
661
|
+
|
662
|
+
|
663
|
+
|
664
|
+
## Paying via Moneris (hosted pay page - old)
|
599
665
|
|
600
666
|
Use the following instructions to set up a Moneris TEST store.
|
601
667
|
|
Binary file
|
@@ -0,0 +1,71 @@
|
|
1
|
+
this.MonerisCheckoutForm ||= class MonerisCheckoutForm
|
2
|
+
constructor: ->
|
3
|
+
@form = null
|
4
|
+
@data = null
|
5
|
+
@moneris = null
|
6
|
+
|
7
|
+
initialize: ->
|
8
|
+
@form = $('form[data-moneris-checkout-form]:not(.initialized)').first()
|
9
|
+
return false unless @form.length > 0
|
10
|
+
|
11
|
+
@data = @form.data('moneris-checkout-form')
|
12
|
+
@moneris = new monerisCheckout()
|
13
|
+
|
14
|
+
@mount()
|
15
|
+
@form.addClass('initialized')
|
16
|
+
|
17
|
+
mount: ->
|
18
|
+
@moneris.setCheckoutDiv('monerisCheckout')
|
19
|
+
|
20
|
+
@moneris.setCallback('page_loaded', @pageLoaded)
|
21
|
+
@moneris.setCallback('cancel_transaction', @cancelTransaction)
|
22
|
+
@moneris.setCallback('error_event', @errorEvent)
|
23
|
+
@moneris.setCallback('payment_receipt', @paymentReceipt)
|
24
|
+
@moneris.setCallback('payment_complete', @paymentComplete)
|
25
|
+
|
26
|
+
@moneris.setMode(@data.environment)
|
27
|
+
@moneris.startCheckout(@data.ticket)
|
28
|
+
|
29
|
+
success: (payload) ->
|
30
|
+
@moneris.closeCheckout()
|
31
|
+
|
32
|
+
payment = JSON.parse(payload)
|
33
|
+
@form.find('#moneris-checkout-success').html("Transaction complete! Please wait a moment...")
|
34
|
+
@form.find("input[name$='[ticket]']").first().val(payment['ticket'])
|
35
|
+
@form.submit()
|
36
|
+
|
37
|
+
error: (text) ->
|
38
|
+
@moneris.closeCheckout()
|
39
|
+
|
40
|
+
text = "<p>" + text + "<p>Please <a href='#', onclick='window.location.reload();' class='alert-link'>reload the page</a> and try again.</p>"
|
41
|
+
@form.find('#moneris-checkout-error').addClass('alert').html(text)
|
42
|
+
EffectiveForm.invalidate(@form)
|
43
|
+
|
44
|
+
# Moneris iframe has loaded
|
45
|
+
pageLoaded: (payload) =>
|
46
|
+
preload = JSON.parse(payload)
|
47
|
+
|
48
|
+
switch preload['response_code']
|
49
|
+
when '001'
|
50
|
+
true # Success. Nothing to do.
|
51
|
+
when '902'
|
52
|
+
@error('3-D secure failed on response')
|
53
|
+
when '2001'
|
54
|
+
@error('Invalid ticket/ticket re-use')
|
55
|
+
else
|
56
|
+
@error('Unknown payment gateway preload status')
|
57
|
+
|
58
|
+
# Cancel Button
|
59
|
+
cancelTransaction: (payload) => false
|
60
|
+
|
61
|
+
# Any kind of error
|
62
|
+
errorEvent: (payload) =>
|
63
|
+
error = JSON.parse(payload)
|
64
|
+
@error("A payment gateway error #{error['response_code']} has occurred. Your card has not been charged.")
|
65
|
+
|
66
|
+
# Payment is all done
|
67
|
+
paymentReceipt: (payload) => @success(payload)
|
68
|
+
paymentComplete: (payload) => @success(payload)
|
69
|
+
|
70
|
+
$ -> (new MonerisCheckoutForm()).initialize()
|
71
|
+
$(document).on 'turbolinks:load', -> (new MonerisCheckoutForm()).initialize()
|
@@ -5,28 +5,21 @@ module Effective
|
|
5
5
|
|
6
6
|
protected
|
7
7
|
|
8
|
-
def order_purchased(payment:, provider:, card: 'none', email: true, skip_buyer_validations: false, purchased_url: nil
|
9
|
-
|
10
|
-
@order.purchase!(payment: payment, provider: provider, card: card, email: email, skip_buyer_validations: skip_buyer_validations)
|
11
|
-
|
12
|
-
Effective::Cart.where(user: @order.user).destroy_all
|
13
|
-
|
14
|
-
if flash[:success].blank?
|
15
|
-
if EffectiveOrders.mailer[:send_order_receipt_to_buyer] && email
|
16
|
-
flash[:success] = "Payment successful! A receipt has been sent to #{@order.emails_send_to}"
|
17
|
-
else
|
18
|
-
flash[:success] = "Payment successful! An email receipt has not been sent."
|
19
|
-
end
|
20
|
-
end
|
8
|
+
def order_purchased(payment:, provider:, card: 'none', email: true, skip_buyer_validations: false, purchased_url: nil)
|
9
|
+
@order.purchase!(payment: payment, provider: provider, card: card, email: email, skip_buyer_validations: skip_buyer_validations)
|
21
10
|
|
22
|
-
|
23
|
-
redirect_to purchased_url.gsub(':id', @order.to_param.to_s)
|
24
|
-
rescue => e
|
25
|
-
flash[:danger] = "An error occurred while processing your payment: #{e.message}. Please try again."
|
11
|
+
Effective::Cart.where(user: @order.user).destroy_all
|
26
12
|
|
27
|
-
|
28
|
-
|
13
|
+
if flash[:success].blank?
|
14
|
+
if email && EffectiveOrders.mailer[:send_order_receipt_to_buyer]
|
15
|
+
flash[:success] = "Payment successful! A receipt has been sent to #{@order.emails_send_to}"
|
16
|
+
else
|
17
|
+
flash[:success] = "Payment successful! An email receipt has not been sent."
|
18
|
+
end
|
29
19
|
end
|
20
|
+
|
21
|
+
purchased_url = effective_orders.purchased_order_path(':id') if purchased_url.blank?
|
22
|
+
redirect_to purchased_url.gsub(':id', @order.to_param.to_s)
|
30
23
|
end
|
31
24
|
|
32
25
|
def order_deferred(provider:, email: true, deferred_url: nil)
|
@@ -42,7 +35,7 @@ module Effective
|
|
42
35
|
end
|
43
36
|
end
|
44
37
|
|
45
|
-
deferred_url
|
38
|
+
deferred_url = effective_orders.deferred_order_path(':id') if deferred_url.blank?
|
46
39
|
redirect_to deferred_url.gsub(':id', @order.to_param.to_s)
|
47
40
|
end
|
48
41
|
|
@@ -53,7 +46,7 @@ module Effective
|
|
53
46
|
flash[:danger] = 'Payment was unsuccessful. Your credit card was declined by the payment processor. Please try again.'
|
54
47
|
end
|
55
48
|
|
56
|
-
declined_url
|
49
|
+
declined_url = effective_orders.declined_order_path(':id') if declined_url.blank?
|
57
50
|
redirect_to declined_url.gsub(':id', @order.to_param.to_s)
|
58
51
|
end
|
59
52
|
|
@@ -1,19 +1,19 @@
|
|
1
1
|
module Effective
|
2
2
|
class OrdersController < ApplicationController
|
3
|
+
include Effective::CrudController
|
3
4
|
include Concerns::Purchase
|
4
5
|
|
5
6
|
include Providers::Cheque
|
6
7
|
include Providers::Free
|
7
8
|
include Providers::MarkAsPaid
|
8
9
|
include Providers::Moneris
|
10
|
+
include Providers::MonerisCheckout
|
9
11
|
include Providers::Paypal
|
10
12
|
include Providers::Phone
|
11
13
|
include Providers::Pretend
|
12
14
|
include Providers::Refund
|
13
15
|
include Providers::Stripe
|
14
16
|
|
15
|
-
include Effective::CrudController
|
16
|
-
|
17
17
|
if (config = EffectiveOrders.layout)
|
18
18
|
layout(config.kind_of?(Hash) ? (config[:orders] || config[:application]) : config)
|
19
19
|
end
|
@@ -19,8 +19,7 @@ module Effective
|
|
19
19
|
card: mark_as_paid_params[:payment_card],
|
20
20
|
email: @order.send_mark_as_paid_email_to_buyer?,
|
21
21
|
skip_buyer_validations: true,
|
22
|
-
purchased_url: effective_orders.admin_order_path(@order)
|
23
|
-
declined_url: effective_orders.admin_order_path(@order)
|
22
|
+
purchased_url: effective_orders.admin_order_path(@order)
|
24
23
|
)
|
25
24
|
end
|
26
25
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Effective
|
2
|
+
module Providers
|
3
|
+
module MonerisCheckout
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def moneris_checkout
|
7
|
+
raise('moneris_checkout provider is not available') unless EffectiveOrders.moneris_checkout?
|
8
|
+
|
9
|
+
@order = Order.find(params[:id])
|
10
|
+
(EffectiveResources.authorize!(self, :update, @order) rescue false)
|
11
|
+
|
12
|
+
payment = moneris_checkout_receipt_request(moneris_checkout_params[:ticket])
|
13
|
+
purchased = (1..49).include?(payment['response_code'].to_i) # Must be > 0 and < 50 to be valid. Sometimes we get the string 'null'
|
14
|
+
|
15
|
+
if purchased == false
|
16
|
+
return order_declined(
|
17
|
+
payment: payment,
|
18
|
+
provider: 'moneris_checkout',
|
19
|
+
declined_url: moneris_checkout_params[:declined_url]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
order_purchased(
|
24
|
+
payment: payment,
|
25
|
+
provider: 'moneris_checkout',
|
26
|
+
card: payment['card_type'],
|
27
|
+
purchased_url: moneris_checkout_params[:purchased_url]
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def moneris_checkout_params
|
34
|
+
params.require(:moneris_checkout).permit(:ticket, :purchased_url, :declined_url)
|
35
|
+
end
|
36
|
+
|
37
|
+
def moneris_checkout_receipt_request(ticket)
|
38
|
+
params = {
|
39
|
+
environment: EffectiveOrders.moneris_checkout.fetch(:environment),
|
40
|
+
|
41
|
+
api_token: EffectiveOrders.moneris_checkout.fetch(:api_token),
|
42
|
+
store_id: EffectiveOrders.moneris_checkout.fetch(:store_id),
|
43
|
+
checkout_id: EffectiveOrders.moneris_checkout.fetch(:checkout_id),
|
44
|
+
|
45
|
+
action: :receipt,
|
46
|
+
ticket: ticket
|
47
|
+
}
|
48
|
+
|
49
|
+
response = Effective::Http.post(EffectiveOrders.moneris_request_url, params: params)
|
50
|
+
response = response['response'] if response
|
51
|
+
|
52
|
+
raise("moneris receipt error #{response}") unless response && response['success'].to_s == 'true'
|
53
|
+
|
54
|
+
response.dig('receipt', 'cc') || response.dig('receipt', 'gift') || response
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -21,8 +21,7 @@ module Effective
|
|
21
21
|
order_purchased(
|
22
22
|
payment: 'refund. no payment required.',
|
23
23
|
provider: 'refund',
|
24
|
-
purchased_url: refund_params[:purchased_url]
|
25
|
-
declined_url: refund_params[:declined_url]
|
24
|
+
purchased_url: refund_params[:purchased_url]
|
26
25
|
)
|
27
26
|
end
|
28
27
|
|
@@ -14,12 +14,12 @@ class Admin::EffectiveOrdersDatatable < Effective::Datatable
|
|
14
14
|
end
|
15
15
|
|
16
16
|
filters do
|
17
|
-
|
18
|
-
scope :
|
17
|
+
unless attributes[:skip_filters]
|
18
|
+
scope :all
|
19
|
+
scope :purchased
|
19
20
|
scope :deferred
|
20
21
|
scope :refunds
|
21
22
|
scope :not_purchased
|
22
|
-
scope :all
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -84,13 +84,14 @@ class Admin::EffectiveOrdersDatatable < Effective::Datatable
|
|
84
84
|
end
|
85
85
|
|
86
86
|
collection do
|
87
|
-
scope = Effective::Order.all.
|
87
|
+
scope = Effective::Order.all.deep
|
88
88
|
|
89
89
|
if EffectiveOrders.orders_collection_scope.respond_to?(:call)
|
90
90
|
scope = EffectiveOrders.orders_collection_scope.call(scope)
|
91
91
|
end
|
92
92
|
|
93
93
|
if attributes[:user_id].present?
|
94
|
+
user = current_user.class.find(attributes[:user_id])
|
94
95
|
scope = scope.where(user: user)
|
95
96
|
end
|
96
97
|
|
@@ -101,8 +102,4 @@ class Admin::EffectiveOrdersDatatable < Effective::Datatable
|
|
101
102
|
scope
|
102
103
|
end
|
103
104
|
|
104
|
-
def user
|
105
|
-
@user ||= current_user.class.find(attributes[:user_id])
|
106
|
-
end
|
107
|
-
|
108
105
|
end
|
@@ -6,8 +6,6 @@ class EffectiveOrdersDatatable < Effective::Datatable
|
|
6
6
|
scope :purchased, default: true
|
7
7
|
scope :deferred
|
8
8
|
scope :refunds
|
9
|
-
scope :not_purchased
|
10
|
-
scope :all
|
11
9
|
end
|
12
10
|
end
|
13
11
|
|
@@ -61,7 +59,9 @@ class EffectiveOrdersDatatable < Effective::Datatable
|
|
61
59
|
end
|
62
60
|
|
63
61
|
collection do
|
64
|
-
|
62
|
+
user = current_user.class.find(attributes[:user_id])
|
63
|
+
|
64
|
+
scope = Effective::Order.all.deep.where(user: user)
|
65
65
|
|
66
66
|
if EffectiveOrders.orders_collection_scope.respond_to?(:call)
|
67
67
|
scope = EffectiveOrders.orders_collection_scope.call(scope)
|
@@ -78,8 +78,4 @@ class EffectiveOrdersDatatable < Effective::Datatable
|
|
78
78
|
scope
|
79
79
|
end
|
80
80
|
|
81
|
-
def user
|
82
|
-
@user ||= current_user.class.find(attributes[:user_id])
|
83
|
-
end
|
84
|
-
|
85
81
|
end
|