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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +124 -84
  4. data/app/assets/javascripts/effective_orders/customers.js.coffee +39 -0
  5. data/app/assets/javascripts/effective_orders/providers/{stripe_charges.js.coffee → stripe.js.coffee} +15 -13
  6. data/app/assets/javascripts/effective_orders/subscriptions.js.coffee +73 -0
  7. data/app/assets/stylesheets/effective_orders.scss +2 -1
  8. data/app/assets/stylesheets/effective_orders/_order.scss +16 -8
  9. data/app/assets/stylesheets/effective_orders/_subscriptions.scss +14 -0
  10. data/app/controllers/admin/customers_controller.rb +11 -8
  11. data/app/controllers/admin/order_items_controller.rb +4 -8
  12. data/app/controllers/admin/orders_controller.rb +133 -87
  13. data/app/controllers/effective/carts_controller.rb +18 -8
  14. data/app/controllers/effective/concerns/purchase.rb +39 -0
  15. data/app/controllers/effective/customers_controller.rb +43 -0
  16. data/app/controllers/effective/orders_controller.rb +73 -119
  17. data/app/controllers/effective/providers/app_checkout.rb +3 -1
  18. data/app/controllers/effective/providers/ccbill.rb +4 -6
  19. data/app/controllers/effective/providers/cheque.rb +20 -11
  20. data/app/controllers/effective/providers/free.rb +33 -0
  21. data/app/controllers/effective/providers/mark_as_paid.rb +33 -0
  22. data/app/controllers/effective/providers/moneris.rb +9 -17
  23. data/app/controllers/effective/providers/paypal.rb +4 -6
  24. data/app/controllers/effective/providers/pretend.rb +4 -4
  25. data/app/controllers/effective/providers/refund.rb +39 -0
  26. data/app/controllers/effective/providers/stripe.rb +19 -40
  27. data/app/controllers/effective/providers/stripe_connect.rb +2 -6
  28. data/app/controllers/effective/webhooks_controller.rb +44 -95
  29. data/app/datatables/effective_customers_datatable.rb +21 -29
  30. data/app/datatables/effective_order_items_datatable.rb +77 -79
  31. data/app/datatables/effective_orders_datatable.rb +67 -57
  32. data/app/helpers/effective_carts_helper.rb +17 -14
  33. data/app/helpers/effective_orders_helper.rb +40 -56
  34. data/app/helpers/effective_paypal_helper.rb +3 -3
  35. data/app/helpers/effective_stripe_helper.rb +47 -18
  36. data/app/helpers/effective_subscriptions_helper.rb +79 -0
  37. data/app/mailers/effective/orders_mailer.rb +125 -2
  38. data/app/models/concerns/acts_as_purchasable.rb +23 -33
  39. data/app/models/concerns/acts_as_subscribable.rb +68 -0
  40. data/app/models/concerns/acts_as_subscribable_buyer.rb +22 -0
  41. data/app/models/effective/cart.rb +53 -24
  42. data/app/models/effective/cart_item.rb +6 -12
  43. data/app/models/effective/customer.rb +51 -54
  44. data/app/models/effective/order.rb +160 -147
  45. data/app/models/effective/order_item.rb +18 -21
  46. data/app/models/effective/product.rb +7 -7
  47. data/app/models/effective/providers/ccbill_postback.rb +1 -1
  48. data/app/models/effective/providers/stripe_charge.rb +8 -19
  49. data/app/models/effective/subscripter.rb +230 -0
  50. data/app/models/effective/subscription.rb +27 -76
  51. data/app/models/effective/tax_rate_calculator.rb +10 -7
  52. data/app/views/admin/customers/_actions.html.haml +1 -2
  53. data/app/views/admin/customers/index.html.haml +1 -1
  54. data/app/views/admin/customers/show.html.haml +6 -0
  55. data/app/views/admin/orders/_actions.html.haml +9 -7
  56. data/app/views/admin/orders/_form.html.haml +11 -7
  57. data/app/views/admin/orders/_order_actions.html.haml +2 -1
  58. data/app/views/admin/orders/_order_item_fields.html.haml +1 -1
  59. data/app/views/admin/orders/edit.html.haml +4 -0
  60. data/app/views/admin/orders/index.html.haml +1 -4
  61. data/app/views/admin/orders/new.html.haml +1 -1
  62. data/app/views/admin/orders/show.html.haml +5 -6
  63. data/app/views/effective/carts/_cart.html.haml +2 -2
  64. data/app/views/effective/carts/show.html.haml +2 -2
  65. data/app/views/effective/customers/_customer.html.haml +152 -0
  66. data/app/views/effective/customers/_fields.html.haml +12 -0
  67. data/app/views/effective/customers/_form.html.haml +13 -0
  68. data/app/views/effective/customers/edit.html.haml +3 -0
  69. data/app/views/effective/orders/_checkout_step1.html.haml +8 -15
  70. data/app/views/effective/orders/_checkout_step2.html.haml +34 -21
  71. data/app/views/effective/orders/_order.html.haml +8 -9
  72. data/app/views/effective/orders/_order_actions.html.haml +7 -8
  73. data/app/views/effective/orders/_order_header.html.haml +1 -1
  74. data/app/views/effective/orders/_order_items.html.haml +11 -5
  75. data/app/views/effective/orders/_order_note.html.haml +4 -7
  76. data/app/views/effective/orders/_orders_table.html.haml +26 -26
  77. data/app/views/effective/orders/app_checkout/_form.html.haml +2 -2
  78. data/app/views/effective/orders/ccbill/_form.html.haml +1 -1
  79. data/app/views/effective/orders/cheque/_form.html.haml +3 -1
  80. data/app/views/effective/orders/declined.html.haml +1 -1
  81. data/app/views/effective/orders/{checkout_step1.html.haml → edit.html.haml} +0 -0
  82. data/app/views/effective/orders/free/_form.html.haml +4 -0
  83. data/app/views/effective/orders/index.html.haml +2 -4
  84. data/app/views/effective/orders/mark_as_paid/_form.html.haml +32 -0
  85. data/app/views/effective/orders/moneris/_form.html.haml +6 -6
  86. data/app/views/effective/orders/{checkout_step2.html.haml → new.html.haml} +1 -1
  87. data/app/views/effective/orders/paypal/_form.html.haml +2 -2
  88. data/app/views/effective/orders/pretend/_form.html.haml +2 -2
  89. data/app/views/effective/orders/purchased.html.haml +3 -0
  90. data/app/views/effective/orders/refund/_form.html.haml +32 -0
  91. data/app/views/effective/orders/show.html.haml +4 -1
  92. data/app/views/effective/orders/stripe/_form.html.haml +5 -5
  93. data/app/views/effective/orders_mailer/subscription_canceled.html.haml +9 -0
  94. data/app/views/effective/orders_mailer/subscription_payment_failed.html.haml +9 -0
  95. data/app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml +9 -0
  96. data/app/views/effective/orders_mailer/subscription_trial_expired.html.haml +5 -0
  97. data/app/views/effective/orders_mailer/subscription_trial_expiring.html.haml +7 -0
  98. data/app/views/effective/subscriptions/_fields.html.haml +16 -0
  99. data/app/views/effective/subscriptions/_plan.html.haml +21 -0
  100. data/app/views/layouts/effective_orders_mailer_layout.html.haml +6 -8
  101. data/config/effective_orders.rb +41 -20
  102. data/config/routes.rb +48 -48
  103. data/db/migrate/01_create_effective_orders.rb.erb +19 -5
  104. data/lib/effective_orders.rb +78 -42
  105. data/lib/effective_orders/engine.rb +36 -82
  106. data/lib/effective_orders/version.rb +1 -1
  107. data/lib/generators/effective_orders/install_generator.rb +2 -2
  108. data/lib/generators/templates/effective_orders_mailer_preview.rb +39 -4
  109. data/lib/tasks/effective_orders_tasks.rake +42 -0
  110. data/spec/controllers/carts_controller_spec.rb +1 -1
  111. data/spec/controllers/moneris_orders_controller_spec.rb +4 -4
  112. data/spec/controllers/orders_controller_spec.rb +4 -4
  113. data/spec/controllers/stripe_orders_controller_spec.rb +2 -2
  114. data/spec/controllers/webhooks_controller_spec.rb +1 -1
  115. data/spec/dummy/config/initializers/effective_orders.rb +1 -7
  116. data/spec/dummy/db/schema.rb +1 -0
  117. data/spec/dummy/db/test.sqlite3 +0 -0
  118. data/spec/dummy/log/test.log +3 -0
  119. data/spec/models/acts_as_purchasable_spec.rb +0 -56
  120. data/spec/models/customer_spec.rb +3 -3
  121. data/spec/models/order_spec.rb +2 -2
  122. data/spec/spec_helper.rb +1 -1
  123. data/spec/support/factories.rb +2 -1
  124. metadata +37 -49
  125. data/active_admin/effective_carts.rb +0 -14
  126. data/active_admin/effective_orders.rb +0 -112
  127. data/app/assets/javascripts/effective_orders/providers/stripe_subscriptions.js.coffee +0 -28
  128. data/app/controllers/concerns/acts_as_active_admin_controller.rb +0 -69
  129. data/app/controllers/effective/subscriptions_controller.rb +0 -126
  130. data/app/models/effective/datatables/customers.rb +0 -40
  131. data/app/models/effective/datatables/order_items.rb +0 -101
  132. data/app/models/effective/datatables/orders.rb +0 -91
  133. data/app/models/inputs/price_field.rb +0 -63
  134. data/app/models/inputs/price_form_input.rb +0 -7
  135. data/app/models/inputs/price_formtastic_input.rb +0 -9
  136. data/app/models/inputs/price_input.rb +0 -19
  137. data/app/models/inputs/price_simple_form_input.rb +0 -8
  138. data/app/views/admin/orders/_form_mark_as_paid.html.haml +0 -33
  139. data/app/views/admin/orders/_order_payment_details.html.haml +0 -5
  140. data/app/views/admin/orders/mark_as_paid.html.haml +0 -7
  141. data/app/views/effective/orders/stripe/_subscription_fields.html.haml +0 -7
  142. data/app/views/effective/subscriptions/index.html.haml +0 -22
  143. data/app/views/effective/subscriptions/new.html.haml +0 -9
  144. data/app/views/effective/subscriptions/show.html.haml +0 -49
  145. data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +0 -29
  146. data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +0 -98
  147. data/db/upgrade/upgrade_price_column_on_table.rb.erb +0 -17
  148. data/lib/generators/effective_orders/upgrade_from03x_generator.rb +0 -31
  149. data/lib/generators/effective_orders/upgrade_from1x_generator.rb +0 -27
  150. 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: 7006871350baa02cd389c691d50c31240809e934
4
- data.tar.gz: 2881b82a65e145a785921e7b8dfc65f057a25bf2
3
+ metadata.gz: 2ec2b7db0f986ae5f26513e93e940bbf6daad8fd
4
+ data.tar.gz: e10dd21a55398487ab2460f14b74008a7d54ba20
5
5
  SHA512:
6
- metadata.gz: 22755b105fc451ea5d7f0ee5d0a5392f46a4248a639f8d1df46c188f76408d96b6e1cd80bf0b3f21998334ed6d168dc292c223ceb9e351f807f9804a2164ca1d
7
- data.tar.gz: 3928a9a2fe440a733be0e10bc99b2e021aff7dd8253e72dbf75f9500a45abb4e1be4547cadb467764634b6abe7bed8bcc511469ab9b3c9c4fe5bec3345c66b0d
6
+ metadata.gz: a5e492bd4496e236c506b7b2656a0506100044c10f5c79b7c079da96c6e5a74c2b9b4020c8c66397d61ed94a0c1941f6c980231eca0bb2b41ae07cff3bc396f7
7
+ data.tar.gz: a2d8b2c04e632ddd1b61680e339fdd0a57356a33ff90ca02c17c82222028b0398806f7933b9e1c9d4efd41ba7f82fe45d6b4f209e006d77adcd7793345321de2
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2017 Code and Effect Inc.
1
+ Copyright 2018 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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) and [effective_datatables](https://github.com/code-and-effect/effective_datatables) gems.
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. For us North Americans, think of it as the number of cents.
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
- # this structure do... block is provided by the migrant gem https://github.com/pascalh1011/migrant
134
- structure do
135
- title :string
136
-
137
- price :integer, default: 0
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 the EffectiveOrders price input to enter the price.
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: :price
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: :price
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.price_field :price
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
- after_purchase do |order, order_item| # These are optional, if you don't care about the order or order_item
377
- self.do_something() # self is the newly purchased instance of this Product
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.order_purchased_path` screen where they see a 'Thank You!' message, and the Order receipt.
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, purchased_redirect_url: '/', declined_redirect_url: '/')` to display the Checkout step with custom redirect paths.
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.my_purchases_path
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 ADMIN -> hosted config from the menu
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: 'My Test store'
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.moneris_postback_path value in your application. By default it is /orders/moneris_postback
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 merchange name: true, if you have an SSL cert
727
+ Display merchant name: true, if you have an SSL cert
740
728
 
741
- Cancel Button Text: 'Cancel'
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 Fields
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: false, unchecked
743
+ Perform asynchronous data post: false, unchecked
754
744
 
755
- Async Response URL: leave blank
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
- Referring URL: https://myapp.herokuapp.com/
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: 4242 4242 4242 4242
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, if your order total price is less than $10, the penny amount may be used to raise an error code.
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
- Order totals ending in .00 will be Approved
801
- Order totals ending in .05 will be Declined
792
+ Please refer to:
802
793
 
803
- And there's a whole bunch more. Please refer to:
794
+ https://developer.moneris.com/en/More/Testing/Penny%20Value%20Simulator
804
795
 
805
- https://www.collinsharper.com/downloadable/download/sample/sample_id/5/
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 Dashbaord -> Your Account (dropdown) -> Account Settings -> Apps
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
- Subscriptions and Stripe Connect do not currently work together.
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
- Register an additional Webhook, to accept Stripe subscription creation events from Stripe
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
- root_url/webhooks/stripe
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'
@@ -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. Your card has not been charged. Please refresh the page and try again. #{token.error.message}")
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('input#effective_providers_stripe_charge_token').val('' + token['id'])
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.find("input[type='submit']").prop('disabled', true)
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(obj.data('stripe-publishable-key'), form).open
28
- name: obj.data('site-title')
29
- email: obj.data('user-email')
30
- description: obj.data('description')
31
- amount: obj.data('amount')
32
- closed: ->
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