effective_orders 2.2.4 → 3.0.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/MIT-LICENSE +1 -1
- data/README.md +124 -84
- data/app/assets/javascripts/effective_orders/customers.js.coffee +39 -0
- data/app/assets/javascripts/effective_orders/providers/{stripe_charges.js.coffee → stripe.js.coffee} +15 -13
- data/app/assets/javascripts/effective_orders/subscriptions.js.coffee +73 -0
- data/app/assets/stylesheets/effective_orders.scss +2 -1
- data/app/assets/stylesheets/effective_orders/_order.scss +16 -8
- data/app/assets/stylesheets/effective_orders/_subscriptions.scss +14 -0
- data/app/controllers/admin/customers_controller.rb +11 -8
- data/app/controllers/admin/order_items_controller.rb +4 -8
- data/app/controllers/admin/orders_controller.rb +133 -87
- data/app/controllers/effective/carts_controller.rb +18 -8
- data/app/controllers/effective/concerns/purchase.rb +39 -0
- data/app/controllers/effective/customers_controller.rb +43 -0
- data/app/controllers/effective/orders_controller.rb +73 -119
- data/app/controllers/effective/providers/app_checkout.rb +3 -1
- data/app/controllers/effective/providers/ccbill.rb +4 -6
- data/app/controllers/effective/providers/cheque.rb +20 -11
- data/app/controllers/effective/providers/free.rb +33 -0
- data/app/controllers/effective/providers/mark_as_paid.rb +33 -0
- data/app/controllers/effective/providers/moneris.rb +9 -17
- data/app/controllers/effective/providers/paypal.rb +4 -6
- data/app/controllers/effective/providers/pretend.rb +4 -4
- data/app/controllers/effective/providers/refund.rb +39 -0
- data/app/controllers/effective/providers/stripe.rb +19 -40
- data/app/controllers/effective/providers/stripe_connect.rb +2 -6
- data/app/controllers/effective/webhooks_controller.rb +44 -95
- data/app/datatables/effective_customers_datatable.rb +21 -29
- data/app/datatables/effective_order_items_datatable.rb +77 -79
- data/app/datatables/effective_orders_datatable.rb +67 -57
- data/app/helpers/effective_carts_helper.rb +17 -14
- data/app/helpers/effective_orders_helper.rb +40 -56
- data/app/helpers/effective_paypal_helper.rb +3 -3
- data/app/helpers/effective_stripe_helper.rb +47 -18
- data/app/helpers/effective_subscriptions_helper.rb +79 -0
- data/app/mailers/effective/orders_mailer.rb +125 -2
- data/app/models/concerns/acts_as_purchasable.rb +23 -33
- data/app/models/concerns/acts_as_subscribable.rb +68 -0
- data/app/models/concerns/acts_as_subscribable_buyer.rb +22 -0
- data/app/models/effective/cart.rb +53 -24
- data/app/models/effective/cart_item.rb +6 -12
- data/app/models/effective/customer.rb +51 -54
- data/app/models/effective/order.rb +160 -147
- data/app/models/effective/order_item.rb +18 -21
- data/app/models/effective/product.rb +7 -7
- data/app/models/effective/providers/ccbill_postback.rb +1 -1
- data/app/models/effective/providers/stripe_charge.rb +8 -19
- data/app/models/effective/subscripter.rb +230 -0
- data/app/models/effective/subscription.rb +27 -76
- data/app/models/effective/tax_rate_calculator.rb +10 -7
- data/app/views/admin/customers/_actions.html.haml +1 -2
- data/app/views/admin/customers/index.html.haml +1 -1
- data/app/views/admin/customers/show.html.haml +6 -0
- data/app/views/admin/orders/_actions.html.haml +9 -7
- data/app/views/admin/orders/_form.html.haml +11 -7
- data/app/views/admin/orders/_order_actions.html.haml +2 -1
- data/app/views/admin/orders/_order_item_fields.html.haml +1 -1
- data/app/views/admin/orders/edit.html.haml +4 -0
- data/app/views/admin/orders/index.html.haml +1 -4
- data/app/views/admin/orders/new.html.haml +1 -1
- data/app/views/admin/orders/show.html.haml +5 -6
- data/app/views/effective/carts/_cart.html.haml +2 -2
- data/app/views/effective/carts/show.html.haml +2 -2
- data/app/views/effective/customers/_customer.html.haml +152 -0
- data/app/views/effective/customers/_fields.html.haml +12 -0
- data/app/views/effective/customers/_form.html.haml +13 -0
- data/app/views/effective/customers/edit.html.haml +3 -0
- data/app/views/effective/orders/_checkout_step1.html.haml +8 -15
- data/app/views/effective/orders/_checkout_step2.html.haml +34 -21
- data/app/views/effective/orders/_order.html.haml +8 -9
- data/app/views/effective/orders/_order_actions.html.haml +7 -8
- data/app/views/effective/orders/_order_header.html.haml +1 -1
- data/app/views/effective/orders/_order_items.html.haml +11 -5
- data/app/views/effective/orders/_order_note.html.haml +4 -7
- data/app/views/effective/orders/_orders_table.html.haml +26 -26
- data/app/views/effective/orders/app_checkout/_form.html.haml +2 -2
- data/app/views/effective/orders/ccbill/_form.html.haml +1 -1
- data/app/views/effective/orders/cheque/_form.html.haml +3 -1
- data/app/views/effective/orders/declined.html.haml +1 -1
- data/app/views/effective/orders/{checkout_step1.html.haml → edit.html.haml} +0 -0
- data/app/views/effective/orders/free/_form.html.haml +4 -0
- data/app/views/effective/orders/index.html.haml +2 -4
- data/app/views/effective/orders/mark_as_paid/_form.html.haml +32 -0
- data/app/views/effective/orders/moneris/_form.html.haml +6 -6
- data/app/views/effective/orders/{checkout_step2.html.haml → new.html.haml} +1 -1
- data/app/views/effective/orders/paypal/_form.html.haml +2 -2
- data/app/views/effective/orders/pretend/_form.html.haml +2 -2
- data/app/views/effective/orders/purchased.html.haml +3 -0
- data/app/views/effective/orders/refund/_form.html.haml +32 -0
- data/app/views/effective/orders/show.html.haml +4 -1
- data/app/views/effective/orders/stripe/_form.html.haml +5 -5
- data/app/views/effective/orders_mailer/subscription_canceled.html.haml +9 -0
- data/app/views/effective/orders_mailer/subscription_payment_failed.html.haml +9 -0
- data/app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml +9 -0
- data/app/views/effective/orders_mailer/subscription_trial_expired.html.haml +5 -0
- data/app/views/effective/orders_mailer/subscription_trial_expiring.html.haml +7 -0
- data/app/views/effective/subscriptions/_fields.html.haml +16 -0
- data/app/views/effective/subscriptions/_plan.html.haml +21 -0
- data/app/views/layouts/effective_orders_mailer_layout.html.haml +6 -8
- data/config/effective_orders.rb +41 -20
- data/config/routes.rb +48 -48
- data/db/migrate/01_create_effective_orders.rb.erb +19 -5
- data/lib/effective_orders.rb +78 -42
- data/lib/effective_orders/engine.rb +36 -82
- data/lib/effective_orders/version.rb +1 -1
- data/lib/generators/effective_orders/install_generator.rb +2 -2
- data/lib/generators/templates/effective_orders_mailer_preview.rb +39 -4
- data/lib/tasks/effective_orders_tasks.rake +42 -0
- data/spec/controllers/carts_controller_spec.rb +1 -1
- data/spec/controllers/moneris_orders_controller_spec.rb +4 -4
- data/spec/controllers/orders_controller_spec.rb +4 -4
- data/spec/controllers/stripe_orders_controller_spec.rb +2 -2
- data/spec/controllers/webhooks_controller_spec.rb +1 -1
- data/spec/dummy/config/initializers/effective_orders.rb +1 -7
- data/spec/dummy/db/schema.rb +1 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +3 -0
- data/spec/models/acts_as_purchasable_spec.rb +0 -56
- data/spec/models/customer_spec.rb +3 -3
- data/spec/models/order_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/support/factories.rb +2 -1
- metadata +37 -49
- data/active_admin/effective_carts.rb +0 -14
- data/active_admin/effective_orders.rb +0 -112
- data/app/assets/javascripts/effective_orders/providers/stripe_subscriptions.js.coffee +0 -28
- data/app/controllers/concerns/acts_as_active_admin_controller.rb +0 -69
- data/app/controllers/effective/subscriptions_controller.rb +0 -126
- data/app/models/effective/datatables/customers.rb +0 -40
- data/app/models/effective/datatables/order_items.rb +0 -101
- data/app/models/effective/datatables/orders.rb +0 -91
- data/app/models/inputs/price_field.rb +0 -63
- data/app/models/inputs/price_form_input.rb +0 -7
- data/app/models/inputs/price_formtastic_input.rb +0 -9
- data/app/models/inputs/price_input.rb +0 -19
- data/app/models/inputs/price_simple_form_input.rb +0 -8
- data/app/views/admin/orders/_form_mark_as_paid.html.haml +0 -33
- data/app/views/admin/orders/_order_payment_details.html.haml +0 -5
- data/app/views/admin/orders/mark_as_paid.html.haml +0 -7
- data/app/views/effective/orders/stripe/_subscription_fields.html.haml +0 -7
- data/app/views/effective/subscriptions/index.html.haml +0 -22
- data/app/views/effective/subscriptions/new.html.haml +0 -9
- data/app/views/effective/subscriptions/show.html.haml +0 -49
- data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +0 -29
- data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +0 -98
- data/db/upgrade/upgrade_price_column_on_table.rb.erb +0 -17
- data/lib/generators/effective_orders/upgrade_from03x_generator.rb +0 -31
- data/lib/generators/effective_orders/upgrade_from1x_generator.rb +0 -27
- data/lib/generators/effective_orders/upgrade_price_column_generator.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ec2b7db0f986ae5f26513e93e940bbf6daad8fd
|
4
|
+
data.tar.gz: e10dd21a55398487ab2460f14b74008a7d54ba20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5e492bd4496e236c506b7b2656a0506100044c10f5c79b7c079da96c6e5a74c2b9b4020c8c66397d61ed94a0c1941f6c980231eca0bb2b41ae07cff3bc396f7
|
7
|
+
data.tar.gz: a2d8b2c04e632ddd1b61680e339fdd0a57356a33ff90ca02c17c82222028b0398806f7933b9e1c9d4efd41ba7f82fe45d6b4f209e006d77adcd7793345321de2
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -10,9 +10,18 @@ Sends order receipt emails automatically.
|
|
10
10
|
|
11
11
|
Has Order History, My Purchases, My Sales and Admin screens.
|
12
12
|
|
13
|
+
## Bootstrap3
|
14
|
+
|
15
|
+
This is the `bootstrap3` branch of effective_orders which supports Twitter Bootstrap 3.
|
16
|
+
|
17
|
+
All published effective_orders 3.x gems will support Twitter Bootstrap 3 and SimpleForm.
|
18
|
+
|
19
|
+
For Bootstrap 4 please see the master branch and/or effective_orders 4.x gems.
|
20
|
+
|
21
|
+
|
13
22
|
## Getting Started
|
14
23
|
|
15
|
-
Please first install the [effective_addresses](https://github.com/code-and-effect/effective_addresses)
|
24
|
+
Please first install the [effective_addresses](https://github.com/code-and-effect/effective_addresses), [effective_datatables](https://github.com/code-and-effect/effective_datatables) and [effective_form_inputs](https://github.com/code-and-effect/effective_form_inputs) gems.
|
16
25
|
|
17
26
|
Add to your Gemfile:
|
18
27
|
|
@@ -54,27 +63,6 @@ Require the stylesheet on the asset pipeline by adding the following to your app
|
|
54
63
|
*= require effective_orders
|
55
64
|
```
|
56
65
|
|
57
|
-
### Upgrading to 2.0.x
|
58
|
-
|
59
|
-
The `tax_rate_method` configuration option has been removed and renamed to `order_tax_rate_method`.
|
60
|
-
Changing this in `/config/initializers/effective_orders.rb` is the first step.
|
61
|
-
|
62
|
-
The default implementation assigns the tax rate based on the order's billing_address (see the [Tax section](#tax)):
|
63
|
-
|
64
|
-
```ruby
|
65
|
-
config.order_tax_rate_method = Proc.new { |order| Effective::TaxRateCalculator.new(order: order).tax_rate }
|
66
|
-
```
|
67
|
-
|
68
|
-
There are numerous database changes in the 2.0.0 line of effective_orders.
|
69
|
-
|
70
|
-
if you are running a 1.x version, please upgrade your database with this command:
|
71
|
-
|
72
|
-
```ruby
|
73
|
-
rails generate effective_orders:upgrade_from1x
|
74
|
-
```
|
75
|
-
|
76
|
-
the above command will add `products` table to you DB.
|
77
|
-
|
78
66
|
## High Level Overview
|
79
67
|
|
80
68
|
Your rails app creates and displays a list of `acts_as_purchasable` objects, each with a `link_to_add_to_cart(object)`.
|
@@ -107,7 +95,7 @@ These purchasables could be Products, EventTickets, Memberships or anything else
|
|
107
95
|
|
108
96
|
### Representing Prices
|
109
97
|
|
110
|
-
All prices should be internally represented as Integers.
|
98
|
+
All prices should be internally represented as Integers. For us North Americans, think of it as the number of cents.
|
111
99
|
|
112
100
|
To represent the value of `$10.00` the price method should return `1000`.
|
113
101
|
|
@@ -130,28 +118,14 @@ If someone purchased a Product which is later deleted, the Order History page wi
|
|
130
118
|
class Product < ActiveRecord::Base
|
131
119
|
acts_as_purchasable
|
132
120
|
|
133
|
-
#
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
tax_exempt :boolean, default: false
|
139
|
-
|
140
|
-
archived :boolean, default: false
|
141
|
-
|
142
|
-
timestamps
|
143
|
-
end
|
121
|
+
# Attributes
|
122
|
+
# title :string
|
123
|
+
# price :integer, default: 0
|
124
|
+
# tax_exempt :boolean, default: false
|
125
|
+
# timestamps
|
144
126
|
|
145
127
|
validates_presence_of :title
|
146
128
|
validates_numericality_of :price, greater_than_or_equal_to: 0
|
147
|
-
|
148
|
-
scope :products, -> { where(archived: false) }
|
149
|
-
|
150
|
-
# This archives Products instead of deleting them
|
151
|
-
def destroy
|
152
|
-
update_attributes(archived: true)
|
153
|
-
end
|
154
|
-
|
155
129
|
end
|
156
130
|
```
|
157
131
|
|
@@ -164,7 +138,6 @@ class CreateProducts < ActiveRecord::Migration
|
|
164
138
|
t.string :title
|
165
139
|
t.integer :price, :default=>0
|
166
140
|
t.boolean :tax_exempt, :default=>false
|
167
|
-
t.boolean :archived, :default=>false
|
168
141
|
t.datetime :updated_at
|
169
142
|
t.datetime :created_at
|
170
143
|
end
|
@@ -180,7 +153,7 @@ Once the database has been migrated, it is time to scaffold/build the CRUD Produ
|
|
180
153
|
|
181
154
|
### Products#new/#edit
|
182
155
|
|
183
|
-
Use
|
156
|
+
Use an [effective_form_inputs](https://github.com/code-and-effect/effective_form_inputs#effective-price) effective_price input to enter the price.
|
184
157
|
|
185
158
|
It displays the underlying Integer price as a currency formatted value, ensures that a properly formatted price is entered by the user, and POSTs the appropriate Integer value back to the server.
|
186
159
|
|
@@ -190,7 +163,7 @@ This is available for simple_form, formtastic and Rails default FormBuilder.
|
|
190
163
|
= simple_form_for(@product) do |f|
|
191
164
|
= f.input :title
|
192
165
|
= f.input :tax_exempt
|
193
|
-
= f.input :price, as: :
|
166
|
+
= f.input :price, as: :effective_price
|
194
167
|
= f.button :submit
|
195
168
|
```
|
196
169
|
|
@@ -198,26 +171,14 @@ or
|
|
198
171
|
|
199
172
|
```ruby
|
200
173
|
= semantic_form_for(@product) do |f|
|
201
|
-
= f.input :price, as: :
|
174
|
+
= f.input :price, as: :effective_price
|
202
175
|
```
|
203
176
|
|
204
177
|
or
|
205
178
|
|
206
179
|
```haml
|
207
180
|
= form_for(@product) do |f|
|
208
|
-
= f.
|
209
|
-
```
|
210
|
-
|
211
|
-
The `as: :price` will work interchangeably with SimpleForm or Formtastic, as long as only one of these gems is present in your application
|
212
|
-
|
213
|
-
If you use both SimpleForm and Formtastic, you will need to call price input differently:
|
214
|
-
|
215
|
-
```ruby
|
216
|
-
= simple_form_for(@product) do |f|
|
217
|
-
= f.input :price, as: :price_simple_form
|
218
|
-
|
219
|
-
= semantic_form_for @user do |f|
|
220
|
-
= f.input :price, as: :price_formtastic
|
181
|
+
= f.effective_price :price
|
221
182
|
```
|
222
183
|
|
223
184
|
### Products#show
|
@@ -362,19 +323,40 @@ Or to apply 0% tax:
|
|
362
323
|
config.order_tax_rate_method = Proc.new { |order| 0 }
|
363
324
|
```
|
364
325
|
|
326
|
+
Or, hardcode a country and state code:
|
327
|
+
|
328
|
+
```ruby
|
329
|
+
config.order_tax_rate_method = Proc.new { |order| Effective::TaxRateCalculator.new(country_code: 'CA', state_code: 'AB').tax_rate }
|
330
|
+
```
|
331
|
+
|
365
332
|
Please see the initializer file for more information.
|
366
333
|
|
367
334
|
|
368
335
|
### Callbacks
|
369
336
|
|
337
|
+
There are three interesting callbacks you can define on the purchasable object, `before_purchase`, `after_purchase` and `after_decline`.
|
338
|
+
|
339
|
+
The `before_purchase` callback runs just before the `order` object is saved. This callback lets you do things in the same transaction the order is saved in.
|
340
|
+
|
341
|
+
The `after_purchase` callback runs just after the `order` object is saved. It runs outside and just after the order save transaction.
|
342
|
+
|
343
|
+
All three of these callbacks will re-raise any exceptions when in development mode, and swallow them in production.
|
344
|
+
|
370
345
|
When defined, upon purchase the following callback will be triggered:
|
371
346
|
|
372
347
|
```ruby
|
373
348
|
class Product
|
374
349
|
acts_as_purchasable
|
375
350
|
|
376
|
-
|
377
|
-
|
351
|
+
# Will automatically be saved when order is saved
|
352
|
+
before_purchase do |order, order_item|
|
353
|
+
self.completed_at = Time.zone.now
|
354
|
+
end
|
355
|
+
|
356
|
+
# Won't be automatically saved. You need to call save on your own.
|
357
|
+
after_purchase do |order, order_item|
|
358
|
+
self.completed_at = Time.zone.now
|
359
|
+
save!
|
378
360
|
end
|
379
361
|
|
380
362
|
end
|
@@ -494,7 +476,7 @@ On this final checkout screen, links to all configured payment providers are dis
|
|
494
476
|
|
495
477
|
The payment processor handles collecting the Credit Card number, and through one way or another, the `Effective::Order` `@order.purchase!` method is called.
|
496
478
|
|
497
|
-
Once the order has been marked purchased, the user is redirected to the `effective_orders.
|
479
|
+
Once the order has been marked purchased, the user is redirected to the `effective_orders.purchased_order_path` screen where they see a 'Thank You!' message, and the Order receipt.
|
498
480
|
|
499
481
|
If the configuration option `config.mailer[:send_order_receipt_to_buyer] == true` the order receipt will be emailed to the user.
|
500
482
|
|
@@ -506,7 +488,7 @@ The Order has now been purchased.
|
|
506
488
|
If you are using effective_orders to roll your own custom payment workflow, you should be aware of the following helpers:
|
507
489
|
|
508
490
|
- `render_checkout(order)` to display the standard Checkout step inline.
|
509
|
-
- `render_checkout(order,
|
491
|
+
- `render_checkout(order, purchased_url: '/', declined_url: '/')` to display the Checkout step with custom redirect paths.
|
510
492
|
|
511
493
|
- `render_purchasables(one_or_more_acts_as_purchasable_objects)` to display a list of purchasable items
|
512
494
|
|
@@ -587,7 +569,7 @@ or
|
|
587
569
|
or
|
588
570
|
|
589
571
|
```ruby
|
590
|
-
= link_to 'My Order History', effective_orders.
|
572
|
+
= link_to 'My Order History', effective_orders.my_purchases_orders_path
|
591
573
|
```
|
592
574
|
|
593
575
|
or render it inline on an existing page with
|
@@ -676,23 +658,29 @@ We are also going to use ngrok to give us a public facing URL
|
|
676
658
|
|
677
659
|
Visit https://esqa.moneris.com/mpg/ and login with: demouser / store1 / password
|
678
660
|
|
679
|
-
Select
|
661
|
+
Select Admin -> Hosted Paypage Config from the menu
|
680
662
|
|
681
663
|
Click the 'Generate a New Configuration' button which should bring us to a "Hosted Paypage Configuration"
|
682
664
|
|
683
665
|
### Basic Configuration
|
684
666
|
|
685
|
-
Description:
|
667
|
+
Description: My Test Store
|
686
668
|
|
687
669
|
Transaction Type: Purchase
|
688
670
|
|
671
|
+
Payment Methods: Credit Cards
|
672
|
+
|
689
673
|
Response Method: Sent to your server as a POST
|
690
674
|
|
691
675
|
Approved URL: https://myapp.herokuapp.com/orders/moneris_postback
|
692
676
|
|
693
677
|
Declined URL: https://myapp.herokuapp.com/orders/moneris_postback
|
694
678
|
|
695
|
-
Note: The Approved and Declined URLs must match the effective_orders.
|
679
|
+
Note: The Approved and Declined URLs must match the effective_orders.moneris_postback_orders_path value in your application. By default it is /orders/moneris_postback
|
680
|
+
|
681
|
+
Use 'Enhanced Cancel': false
|
682
|
+
Use 'Enhanced Response Feedback': false
|
683
|
+
|
696
684
|
|
697
685
|
Click 'Save Changes'
|
698
686
|
|
@@ -734,11 +722,11 @@ Display billing address details: true
|
|
734
722
|
|
735
723
|
Display shipping address details: true
|
736
724
|
|
737
|
-
Enable input of Billing, Shipping and extra fields: false
|
725
|
+
Enable input of Billing, Shipping, and extra data fields on the hosted paypage: false
|
738
726
|
|
739
|
-
Display
|
727
|
+
Display merchant name: true, if you have an SSL cert
|
740
728
|
|
741
|
-
Cancel Button Text:
|
729
|
+
Cancel Button Text: Cancel
|
742
730
|
|
743
731
|
Cancel Button URL: https://myapp.herokuapp.com/
|
744
732
|
|
@@ -746,13 +734,15 @@ Click 'Save Appearance Settings'
|
|
746
734
|
|
747
735
|
Click 'Return to main configuration'
|
748
736
|
|
749
|
-
### Response
|
737
|
+
### Response/Receipt Data
|
738
|
+
|
739
|
+
Click 'Configure Response Fields' from the main Hosted Paypage Configuration
|
750
740
|
|
751
741
|
None of the 'Return...' checkboxes are needed. Leave unchecked.
|
752
742
|
|
753
|
-
Perform asynchronous data post:
|
743
|
+
Perform asynchronous data post: false, unchecked
|
754
744
|
|
755
|
-
Async Response URL:
|
745
|
+
Async Response URL: leave blank
|
756
746
|
|
757
747
|
Click 'Save Response Settings'
|
758
748
|
|
@@ -761,7 +751,9 @@ Click 'Return to main configuration'
|
|
761
751
|
|
762
752
|
### Security
|
763
753
|
|
764
|
-
|
754
|
+
Click 'Configure Security' from the main Hosted Paypage Configuration
|
755
|
+
|
756
|
+
Referring URL -> Add URL: https://myapp.herokuapp.com/
|
765
757
|
|
766
758
|
Enable Card Verification: false, unused
|
767
759
|
|
@@ -789,20 +781,20 @@ With this test store set up, you can make a successful purchase with:
|
|
789
781
|
|
790
782
|
Cardholder Name: Any name
|
791
783
|
|
792
|
-
Credit Card Number:
|
784
|
+
Credit Card Number: 4502 2850 7000 0007
|
793
785
|
|
794
786
|
Expiry Date: Any future date
|
795
787
|
|
796
788
|
Some gotchas:
|
797
789
|
|
798
|
-
1. When using a test store,
|
790
|
+
1. When using a test store, there are a whole bunch of ways to simulate failures by posting an order less than $10.00
|
799
791
|
|
800
|
-
|
801
|
-
Order totals ending in .05 will be Declined
|
792
|
+
Please refer to:
|
802
793
|
|
803
|
-
|
794
|
+
https://developer.moneris.com/en/More/Testing/Penny%20Value%20Simulator
|
804
795
|
|
805
|
-
|
796
|
+
The following card will always be approved: 4502 2850 7000 0007
|
797
|
+
The following card will always be declined: 4355 3100 0257 6375
|
806
798
|
|
807
799
|
2. Moneris will not process a duplicate order ID
|
808
800
|
|
@@ -843,7 +835,7 @@ Stripe Connect allows effective_orders to collect payments on behalf of users.
|
|
843
835
|
|
844
836
|
First register your application with Stripe
|
845
837
|
|
846
|
-
Stripe
|
838
|
+
Stripe Dashboard -> Your Account (dropdown) -> Account Settings -> Apps
|
847
839
|
|
848
840
|
Register your application
|
849
841
|
|
@@ -891,11 +883,59 @@ end
|
|
891
883
|
|
892
884
|
### Stripe Subscriptions
|
893
885
|
|
894
|
-
|
886
|
+
To set up stripe subscriptions:
|
887
|
+
|
888
|
+
Define your model
|
889
|
+
|
890
|
+
```ruby
|
891
|
+
acts_as_subscribable
|
892
|
+
```
|
893
|
+
|
894
|
+
and then in your form, to choose a subscription:
|
895
|
+
|
896
|
+
```ruby
|
897
|
+
= effective_subscription_fields(f, item_wrapper_class: 'col-sm-3')
|
898
|
+
```
|
899
|
+
|
900
|
+
and in your controller:
|
901
|
+
|
902
|
+
```ruby
|
903
|
+
@team.save! && @team.subscripter.save!
|
904
|
+
```
|
905
|
+
|
906
|
+
and in your application controller:
|
907
|
+
|
908
|
+
```ruby
|
909
|
+
before_action :set_subscription_notice
|
910
|
+
|
911
|
+
def set_subscription_notice
|
912
|
+
return unless team && team.subscription_active? == false
|
913
|
+
|
914
|
+
if team.trial_expired?
|
915
|
+
flash.now[:warning] = 'Your trial has expired'
|
916
|
+
elsif team.subscription_active? == false
|
917
|
+
flash.now[:warning] = 'Your subscription has become unpaid'
|
918
|
+
end
|
919
|
+
end
|
920
|
+
```
|
921
|
+
|
922
|
+
And you can link to the customer#show page
|
923
|
+
|
924
|
+
```ruby
|
925
|
+
link_to 'Customer', effective_orders.customer_settings_path
|
926
|
+
```
|
927
|
+
|
928
|
+
To set up stripe:
|
929
|
+
|
930
|
+
1.) Set up a stripe account as above.
|
931
|
+
|
932
|
+
2.) Ceate one or more plans. Don't include any trial or trial periods.
|
933
|
+
|
934
|
+
3.) Subscription Settings: 3-days. Then 1-day, 3-days, 3-days, then Cancel subscription
|
895
935
|
|
896
|
-
|
936
|
+
4.) Click API -> Webhooks and add an endpoint `root_url/webhooks/stripe`. You will need something like ngrok to test this.
|
897
937
|
|
898
|
-
|
938
|
+
5.) Record the webhook Signing secret in `config.subscription[:webhook_secret]`
|
899
939
|
|
900
940
|
|
901
941
|
## Paying Via PayPal
|
@@ -0,0 +1,39 @@
|
|
1
|
+
stripeCustomerChangeCardHandler = (key, form) ->
|
2
|
+
StripeCheckout.configure
|
3
|
+
key: key
|
4
|
+
closed: ->
|
5
|
+
form.find("input[type='submit']").removeAttr('disabled')
|
6
|
+
$('input[data-disable-with]').each -> try $.rails.enableFormElement($(this))
|
7
|
+
token: (token, args) ->
|
8
|
+
if token.error
|
9
|
+
form.find("input[type='submit']").removeAttr('disabled')
|
10
|
+
$('input[data-disable-with]').each -> try $.rails.enableFormElement($(this))
|
11
|
+
|
12
|
+
alert("An error ocurred when contacting Stripe. Your card has not been charged. Your subscription has not changed. Please refresh the page and try again. #{token.error.message}")
|
13
|
+
else
|
14
|
+
form.find("input[name$='[stripe_token]']").val('' + token['id'])
|
15
|
+
|
16
|
+
customer = form.find('.effective-orders-customer')
|
17
|
+
customer.find('.active-card').html("**** **** **** #{token.card.last4} #{token.card.brand} #{token.card.exp_month}/#{token.card.exp_year}")
|
18
|
+
|
19
|
+
if customer.data('submit')
|
20
|
+
form.find("input[type='submit']").prop('disabled', true)
|
21
|
+
$('input[data-disable-with]').each -> try $.rails.disableFormElement($(this))
|
22
|
+
form.submit()
|
23
|
+
|
24
|
+
# When we click 'Change credit card', make sure the form collects a credit card
|
25
|
+
$(document).on 'click', '.effective-orders-customer .btn-change-card', (event) ->
|
26
|
+
event.preventDefault()
|
27
|
+
|
28
|
+
$form = $(event.currentTarget).closest('form')
|
29
|
+
stripe = $(event.currentTarget).closest('.effective-orders-customer').data('stripe')
|
30
|
+
|
31
|
+
# Disable the form
|
32
|
+
$form.find("input[type='submit']").prop('disabled', true)
|
33
|
+
$('input[data-disable-with]').each -> try $.rails.disableFormElement($(this))
|
34
|
+
|
35
|
+
stripeCustomerChangeCardHandler(stripe.key, $form).open
|
36
|
+
image: stripe.image
|
37
|
+
name: stripe.name
|
38
|
+
email: stripe.email
|
39
|
+
panelLabel: 'Update Card Details'
|
data/app/assets/javascripts/effective_orders/providers/{stripe_charges.js.coffee → stripe.js.coffee}
RENAMED
@@ -1,34 +1,36 @@
|
|
1
1
|
stripeCheckoutHandler = (key, form) ->
|
2
2
|
StripeCheckout.configure
|
3
3
|
key: key
|
4
|
+
closed: ->
|
5
|
+
form.find("input[type='submit']").removeAttr('disabled')
|
6
|
+
$('input[data-disable-with]').each -> try $.rails.enableFormElement($(this))
|
4
7
|
token: (token, args) ->
|
5
8
|
if token.error
|
6
9
|
form.find("input[type='submit']").removeAttr('disabled')
|
7
10
|
$('input[data-disable-with]').each -> try $.rails.enableFormElement($(this))
|
8
11
|
|
9
|
-
alert("An error ocurred when contacting Stripe.
|
12
|
+
alert("An error ocurred when contacting Stripe. Your card has not been charged. Please refresh the page and try again. #{token.error.message}")
|
10
13
|
else
|
11
|
-
form.find(
|
14
|
+
form.find("input[name$='[stripe_token]']").val('' + token['id'])
|
12
15
|
|
13
16
|
form.find("input[type='submit']").prop('disabled', true)
|
14
17
|
$('input[data-disable-with]').each -> try $.rails.disableFormElement($(this))
|
15
|
-
|
16
18
|
form.submit()
|
17
19
|
|
18
20
|
$(document).on 'click', "#effective-orders-new-charge-form form input[type='submit']", (event) ->
|
19
21
|
event.preventDefault()
|
20
22
|
|
21
23
|
obj = $('#effective-orders-new-charge-form')
|
22
|
-
form = obj.find('form').first()
|
24
|
+
$form = obj.find('form').first()
|
25
|
+
stripe = obj.data('stripe')
|
23
26
|
|
24
|
-
form
|
27
|
+
# Disable the form
|
28
|
+
$form.find("input[type='submit']").prop('disabled', true)
|
25
29
|
$('input[data-disable-with]').each -> try $.rails.disableFormElement($(this))
|
26
30
|
|
27
|
-
stripeCheckoutHandler(
|
28
|
-
|
29
|
-
|
30
|
-
description:
|
31
|
-
|
32
|
-
|
33
|
-
form.find("input[type='submit']").removeAttr('disabled')
|
34
|
-
$('input[data-disable-with]').each -> try $.rails.enableFormElement($(this))
|
31
|
+
stripeCheckoutHandler(stripe.key, $form).open
|
32
|
+
image: stripe.image
|
33
|
+
name: stripe.name
|
34
|
+
description: stripe.description
|
35
|
+
email: stripe.email
|
36
|
+
amount: stripe.amount
|