effective_orders 2.2.4 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|