spree_stripe_subscriptions 0.0.1

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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +91 -0
  3. data/.rubocop.yml +26 -0
  4. data/.travis.yml +37 -0
  5. data/Gemfile +12 -0
  6. data/LICENSE +26 -0
  7. data/README.md +72 -0
  8. data/Rakefile +21 -0
  9. data/app/controllers/spree/admin/stripe_configurations_controller.rb +6 -0
  10. data/app/controllers/spree/admin/stripe_customers_controller.rb +6 -0
  11. data/app/controllers/spree/admin/stripe_plans_controller.rb +36 -0
  12. data/app/controllers/spree/admin/stripe_subscription_events_controller.rb +6 -0
  13. data/app/controllers/spree/admin/stripe_subscriptions_controller.rb +6 -0
  14. data/app/controllers/spree/stripe_plans_controller.rb +20 -0
  15. data/app/controllers/spree/stripe_subscriptions_controller.rb +166 -0
  16. data/app/controllers/spree/stripe_webhooks_controller.rb +56 -0
  17. data/app/models/spree/stripe_configuration.rb +28 -0
  18. data/app/models/spree/stripe_customer.rb +30 -0
  19. data/app/models/spree/stripe_invoice.rb +21 -0
  20. data/app/models/spree/stripe_plan.rb +104 -0
  21. data/app/models/spree/stripe_subscription.rb +167 -0
  22. data/app/models/spree/stripe_subscription_event.rb +10 -0
  23. data/app/models/spree_stripe_subscriptions/configuration.rb +15 -0
  24. data/app/models/spree_stripe_subscriptions/user_decorator.rb +50 -0
  25. data/app/overrides/spree/admin/shared/_main_menu.rb +13 -0
  26. data/app/serializers/.gitkeep +0 -0
  27. data/app/services/.gitkeep +0 -0
  28. data/app/views/spree/admin/shared/sub_menu/_stripe_subscriptions.html.erb +8 -0
  29. data/app/views/spree/admin/stripe_configurations/_form.html.erb +42 -0
  30. data/app/views/spree/admin/stripe_configurations/edit.html.erb +17 -0
  31. data/app/views/spree/admin/stripe_configurations/index.html.erb +44 -0
  32. data/app/views/spree/admin/stripe_configurations/new.html.erb +13 -0
  33. data/app/views/spree/admin/stripe_customers/index.html.erb +36 -0
  34. data/app/views/spree/admin/stripe_plans/_form.html.erb +50 -0
  35. data/app/views/spree/admin/stripe_plans/edit.html.erb +15 -0
  36. data/app/views/spree/admin/stripe_plans/index.html.erb +59 -0
  37. data/app/views/spree/admin/stripe_plans/new.html.erb +15 -0
  38. data/app/views/spree/admin/stripe_subscription_events/index.html.erb +36 -0
  39. data/app/views/spree/admin/stripe_subscriptions/index.html.erb +40 -0
  40. data/app/views/spree/stripe_plans/index.html.erb +77 -0
  41. data/bin/rails +8 -0
  42. data/config/initializers/stripe.rb +11 -0
  43. data/config/locales/en.yml +80 -0
  44. data/config/routes.rb +27 -0
  45. data/db/migrate/20221130094411_add_spree_stripe_configuration_model.rb +14 -0
  46. data/db/migrate/20221130095015_add_spree_stripe_plan_model.rb +23 -0
  47. data/db/migrate/20221130100526_add_spree_stripe_customer.rb +11 -0
  48. data/db/migrate/20221130100903_add_spree_stripe_subscription_model.rb +23 -0
  49. data/db/migrate/20221130102650_add_spree_stripe_subscription_events_model.rb +16 -0
  50. data/db/migrate/20221202111450_add_weightage_to_stripe_plan.rb +10 -0
  51. data/db/migrate/20221209065244_add_schedules_to_subscription.rb +6 -0
  52. data/db/migrate/20221209094013_add_stripe_invoices.rb +33 -0
  53. data/db/migrate/20221209131817_add_user_to_invoice.rb +5 -0
  54. data/db/migrate/20221221080141_add_extra_plan_fields.rb +8 -0
  55. data/lib/generators/spree_stripe_subscriptions/install/install_generator.rb +20 -0
  56. data/lib/spree_stripe_subscriptions/engine.rb +24 -0
  57. data/lib/spree_stripe_subscriptions/factories.rb +6 -0
  58. data/lib/spree_stripe_subscriptions/version.rb +11 -0
  59. data/lib/spree_stripe_subscriptions.rb +4 -0
  60. data/spree_stripe_subscriptions.gemspec +34 -0
  61. metadata +207 -0
@@ -0,0 +1,59 @@
1
+ <% content_for :page_title do %>
2
+ <%= link_to I18n.t('spree_stripe_subscriptions.admin.stripe_configurations'), spree.admin_stripe_configurations_url %> /
3
+ <%= link_to @stripe_configuration.name, spree.edit_admin_stripe_configuration_url(@stripe_configuration) %> /
4
+ <%= I18n.t('spree_stripe_subscriptions.admin.stripe_plans') %>
5
+ <% end %>
6
+
7
+ <% content_for :page_actions do %>
8
+ <%= button_link_to I18n.t('spree_stripe_subscriptions.admin.new_stripe_plan'), new_object_url, class: "btn-success", icon: 'add.svg' %>
9
+ <% end if can? :create, Spree::StripePlan %>
10
+
11
+ <% if @stripe_plans.any? %>
12
+ <div class="table-responsive">
13
+ <table class="table sortable" data-hook
14
+ data-sortable-link="<%= update_positions_admin_stripe_configuration_stripe_plans_url(@stripe_configuration) %>">
15
+ <thead>
16
+ <tr>
17
+ <th title="<%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.weightage_title') %>"><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.weightage') %></th>
18
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.stripe_plan_id') %></th>
19
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.name') %></th>
20
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.currency') %></th>
21
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.amount') %></th>
22
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.interval') %></th>
23
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.interval_count') %></th>
24
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.trial_period_days') %></th>
25
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_plans.active') %></th>
26
+ <th></th>
27
+ </tr>
28
+ </thead>
29
+ <tbody>
30
+ <% @stripe_plans.each do |stripe_plan| %>
31
+ <tr id="<%= spree_dom_id stripe_plan %>">
32
+ <td class="move-handle text-center">
33
+ <%= svg_icon name: "sort.svg", width: '18', height: '18' %>
34
+ </td>
35
+ <td><%= stripe_plan.stripe_plan_id %></td>
36
+ <td><%= stripe_plan.name %></td>
37
+ <td><%= stripe_plan.currency.upcase %></td>
38
+ <td><%= stripe_plan.amount %></td>
39
+ <td><%= stripe_plan.interval.capitalize %></td>
40
+ <td><%= stripe_plan.interval_count %></td>
41
+ <td><%= stripe_plan.trial_period_days %></td>
42
+ <td><%= active_badge(stripe_plan.active) %></td>
43
+ <td class="actions">
44
+ <span class="d-flex justify-content-end">
45
+ <%= link_to_with_icon('edit.svg', I18n.t('spree_stripe_subscriptions.admin.edit'), spree.edit_admin_stripe_configuration_stripe_plan_url(@stripe_configuration, stripe_plan), class: 'btn btn-primary btn-sm', no_text: true, data: { action: 'edit' }) if can? :edit, stripe_plan %>
46
+ <%= link_to_delete(stripe_plan, { url: spree.admin_stripe_configuration_stripe_plan_url(@stripe_configuration, stripe_plan), no_text: true }) if can? :delete, stripe_plan %>
47
+ </span>
48
+ </tr>
49
+ <% end %>
50
+ </tbody>
51
+ </table>
52
+ </div>
53
+ <% else %>
54
+ <div class="alert alert-info no-objects-found">
55
+ <%= I18n.t('spree_stripe_subscriptions.admin.no_resource_found',
56
+ resource: I18n.t('spree_stripe_subscriptions.admin.stripe_plans')) %>,
57
+ <%= link_to(I18n.t('spree_stripe_subscriptions.admin.add_one'), new_object_url) if can? :create, Spree::StripePlan %>
58
+ </div>
59
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <% content_for :page_title do %>
2
+ <%= link_to I18n.t('spree_stripe_subscriptions.admin.stripe_configurations'), spree.admin_stripe_configurations_url %> /
3
+ <%= link_to @stripe_configuration.name, spree.edit_admin_stripe_configuration_url(@stripe_configuration) %> /
4
+ <%= link_to I18n.t('spree_stripe_subscriptions.admin.stripe_plans'), spree.admin_stripe_configuration_stripe_plans_url(@stripe_configuration) %> /
5
+ <%= I18n.t('spree_stripe_subscriptions.admin.new_stripe_plan') %>
6
+ <% end %>
7
+
8
+ <%= render partial: 'spree/admin/shared/error_messages', locals: { target: @stripe_plan } %>
9
+
10
+ <%= form_for [:admin, @stripe_configuration, @stripe_plan] do |f| %>
11
+ <fieldset>
12
+ <%= render partial: 'form', locals: { f: f } %>
13
+ <%= render partial: 'spree/admin/shared/new_resource_links' %>
14
+ </fieldset>
15
+ <% end %>
@@ -0,0 +1,36 @@
1
+ <% content_for :page_title do %>
2
+ <%= I18n.t('spree_stripe_subscriptions.admin.stripe_subscription_events') %>
3
+ <% end %>
4
+
5
+ <% if @stripe_subscription_events.any? %>
6
+ <div class="table-responsive">
7
+ <table class="table">
8
+ <thead>
9
+ <tr>
10
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscription_events.event_id') %></th>
11
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscription_events.event_type') %></th>
12
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscription_events.stripe_subscription_id') %></th>
13
+ <th></th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% @stripe_subscription_events.each do |stripe_subscription_event| %>
18
+ <tr id="<%= spree_dom_id stripe_subscription_event %>">
19
+ <td><%= stripe_subscription_event.event_id %></td>
20
+ <td><%= stripe_subscription_event.event_type %></td>
21
+ <td><%= stripe_subscription_event.subscription.stripe_subscription_id %></td>
22
+ <td class="actions">
23
+ <span class="d-flex justify-content-end">
24
+ <%#= link_to_edit(stripe_subscription_event, no_text: true) if can? :edit, stripe_subscription_event %>
25
+ <%#= link_to_delete(stripe_subscription_event, no_text: true) if can? :delete, stripe_subscription_event %>
26
+ </span>
27
+ </tr>
28
+ <% end %>
29
+ </tbody>
30
+ </table>
31
+ </div>
32
+ <% else %>
33
+ <div class="alert alert-info no-objects-found">
34
+ <%= I18n.t('spree_stripe_subscriptions.admin.no_resource_found', resource: I18n.t('spree_stripe_subscriptions.admin.stripe_subscription_events')) %>
35
+ </div>
36
+ <% end %>
@@ -0,0 +1,40 @@
1
+ <% content_for :page_title do %>
2
+ <%= I18n.t('spree_stripe_subscriptions.admin.stripe_subscriptions') %>
3
+ <% end %>
4
+
5
+ <% if @stripe_subscriptions.any? %>
6
+ <div class="table-responsive">
7
+ <table class="table">
8
+ <thead>
9
+ <tr>
10
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscriptions.stripe_subscription_id') %></th>
11
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscriptions.plan') %></th>
12
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscriptions.user') %></th>
13
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscriptions.customer') %></th>
14
+ <th><%= I18n.t('spree_stripe_subscriptions.models.stripe_subscriptions.status') %></th>
15
+ <th></th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <% @stripe_subscriptions.each do |stripe_subscription| %>
20
+ <tr id="<%= spree_dom_id stripe_subscription %>">
21
+ <td><%= stripe_subscription.stripe_subscription_id %></td>
22
+ <td><%= stripe_subscription.plan.name %></td>
23
+ <td><%= stripe_subscription.user.email %></td>
24
+ <td><%= stripe_subscription.customer.stripe_customer_id %></td>
25
+ <td><%= stripe_subscription.status.capitalize %></td>
26
+ <td class="actions">
27
+ <span class="d-flex justify-content-end">
28
+ <%#= link_to_edit(stripe_subscription, no_text: true) if can? :edit, stripe_subscription %>
29
+ <%#= link_to_delete(stripe_subscription, no_text: true) if can? :delete, stripe_subscription %>
30
+ </span>
31
+ </tr>
32
+ <% end %>
33
+ </tbody>
34
+ </table>
35
+ </div>
36
+ <% else %>
37
+ <div class="alert alert-info no-objects-found">
38
+ <%= I18n.t('spree_stripe_subscriptions.admin.no_resource_found', resource: I18n.t('spree_stripe_subscriptions.admin.stripe_subscriptions')) %>
39
+ </div>
40
+ <% end %>
@@ -0,0 +1,77 @@
1
+ <div class="container">
2
+ <div class="row my-5">
3
+ <div class="col-12 text-center">
4
+ <h2><%= I18n.t('spree_stripe_subscriptions.plans') %></h2>
5
+ </div>
6
+ </div>
7
+ <hr/>
8
+ <div class="row my-5">
9
+ <% @stripe_plans.each do |plan| %>
10
+ <div class="col-sm-12 py-4">
11
+ <div class="card text-center">
12
+ <div class="card-body">
13
+ <h5 class="card-title"><%= plan.name %></h5>
14
+ <p class="card-text">
15
+ <%= number_to_currency(plan.amount, precision: 2) %> /
16
+ <%= plan.interval_count %> <%= plan.interval.pluralize(plan.interval_count) %> <br/>
17
+ <%= plan.trial_period_days %> <%= 'day'.pluralize(plan.trial_period_days) %> trial
18
+ </p>
19
+ <% if spree_current_user %>
20
+ <% if @active_subscription.present? && @active_subscription.plan_id == plan.id %>
21
+ <% if @active_subscription.cancel_at_period_end %>
22
+ <p class="card-text">
23
+ Your subscription ends on <%= @active_subscription.cancel_at %>
24
+ </p>
25
+ <% else %>
26
+ <%= button_link_to I18n.t('spree_stripe_subscriptions.cancel_renewal'),
27
+ stripe_plan_stripe_subscription_url(plan, @active_subscription),
28
+ method: :patch, class: 'btn btn-primary btn-danger',
29
+ confirm: "Do you want to cancel renewal?" %>
30
+ <br/>
31
+ <% end %>
32
+ <%= button_link_to I18n.t('spree_stripe_subscriptions.unsubscribe'),
33
+ stripe_plan_stripe_subscription_url(plan, @active_subscription),
34
+ method: :delete, class: 'btn btn-primary btn-danger',
35
+ confirm: "Do you want to unsubscribe?" %>
36
+ <br/>
37
+ <%= button_link_to I18n.t('spree_stripe_subscriptions.update_payment_method'),
38
+ change_payment_details_stripe_plan_stripe_subscription_url(plan, @active_subscription),
39
+ method: :post, class: 'btn btn-primary btn-danger' %>
40
+ <% elsif @active_subscription.present? && @active_subscription.next_plan_id == plan.id %>
41
+ <p class="card-text">
42
+ Your next subscription starts on <%= @active_subscription.current_period_end %>
43
+ </p>
44
+ <% else %>
45
+ <% if @active_subscription.present? %>
46
+ <%
47
+ action_type = if @active_subscription.plan.weightage < plan.weightage
48
+ :upgrade
49
+ else
50
+ :downgrade
51
+ end
52
+ action_url = if action_type == :upgrade
53
+ stripe_plan_stripe_subscriptions_url(plan)
54
+ else
55
+ downgrade_stripe_plan_stripe_subscription_url(plan, @active_subscription)
56
+ end
57
+ %>
58
+ <%= button_link_to I18n.t("spree_stripe_subscriptions.#{action_type}"),
59
+ action_url,
60
+ method: :post,
61
+ class: 'btn btn-primary btn-default' %>
62
+ <% else %>
63
+ <%= button_link_to I18n.t('spree_stripe_subscriptions.subscribe'),
64
+ stripe_plan_stripe_subscriptions_url(plan),
65
+ method: :post,
66
+ class: 'btn btn-primary btn-default' %>
67
+ <% end %>
68
+ <% end %>
69
+ <% end %>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ <% end %>
74
+ </div>
75
+ </div>
76
+
77
+
data/bin/rails ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" from the root of your extension
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/spree_stripe_subscriptions/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
@@ -0,0 +1,11 @@
1
+ require 'stripe'
2
+ require 'stripe_tester' if Rails.env.development? || Rails.env.test?
3
+
4
+ Stripe.api_version = '2020-03-02'
5
+
6
+ begin
7
+ Stripe.api_key = Spree::StripeConfiguration.active.last&.preferred_secret_key
8
+ rescue ActiveRecord::StatementInvalid => e
9
+ Rails.logger.error e
10
+ # Ignored
11
+ end
@@ -0,0 +1,80 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ spree_stripe_subscriptions:
6
+ admin:
7
+ stripe_configurations: Stripe Configurations
8
+ new_stripe_configuration: New Stripe Configuration
9
+ stripe_plans: Stripe Plans
10
+ new_stripe_plan: Stripe Plan
11
+ stripe_customers: Stripe Customers
12
+ stripe_subscriptions: Stripe Subscriptions
13
+ stripe_subscription_events: Stripe Subscription Events
14
+ manage_plans: Manage Plans
15
+ no_resource_found: No %{resource} found
16
+ add_one: Add one
17
+ edit: Edit
18
+ messages:
19
+ success:
20
+ successfully_subscribed: Successfully subscribed
21
+ successfully_unsubscribed: Successfully unsubscribed
22
+ successfully_canceled_renewal: Successfully canceled renewal
23
+ successfully_upgraded: Successfully Upgraded
24
+ successfully_downgraded: Successfully Downgraded
25
+ successfully_updated: Successfully Updated
26
+ errors:
27
+ no_active_subscription: You don't have any active subscription
28
+ already_subscribed: You already have active subscription
29
+ stripe_configuration_doesnt_exist: Stripe configurations not found
30
+ cannot_process_request: Please contact us to proceed
31
+ models:
32
+ stripe_configuration:
33
+ name: Name
34
+ description: Description
35
+ active: Active
36
+ deleted_at: Deleted At
37
+ billing_address_collection: Billing Address Collection
38
+ automatic_tax: Automatic Tax
39
+ tax_id_collection: Tax ID Collection
40
+ stripe_customers:
41
+ name: Name
42
+ email: Email
43
+ stripe_customer_id: Stripe Customer ID
44
+ deleted_at: Deleted At
45
+ stripe_plans:
46
+ name: Name
47
+ description: Description
48
+ currency: Currency
49
+ amount: Amount
50
+ interval: Interval
51
+ interval_count: Interval Count
52
+ trial_period_days: Trial Period Days
53
+ configuration_id: Configuration ID
54
+ stripe_plan_id: Stripe Plan ID
55
+ active: Active
56
+ deleted_at: Deleted At
57
+ weightage: Plan Weightage
58
+ weightage_title: Move plans to update weightage, it'll be helpful in setting up upgrades/downgrades
59
+ tax_behavior: Tax Behavior
60
+ stripe_subscription_events:
61
+ event_id: Event ID
62
+ event_type: Event Type
63
+ stripe_subscription_id: Stripe Subscription ID
64
+ stripe_subscriptions:
65
+ stripe_subscription_id: Stripe Subscription ID
66
+ plan: Plan
67
+ user: User
68
+ customer: Customer
69
+ status: Status
70
+ plans: Plans
71
+ spree:
72
+ public_key: Public Key
73
+ secret_key: Secret Key
74
+ webhook_secret: Webhook Secret Key
75
+ subscribe: Subscribe
76
+ unsubscribe: Unsubscribe
77
+ cancel_renewal: Cancel Renewal
78
+ upgrade: Upgrade
79
+ downgrade: Downgrade
80
+ update_payment_method: Update Payment Method
data/config/routes.rb ADDED
@@ -0,0 +1,27 @@
1
+ Spree::Core::Engine.add_routes do
2
+ namespace :admin, path: Spree.admin_path do
3
+ resources :stripe_configurations, except: :show do
4
+ resources :stripe_plans, except: :show do
5
+ collection do
6
+ post :update_positions
7
+ end
8
+ end
9
+ end
10
+
11
+ resources :stripe_customers, only: :index
12
+ resources :stripe_subscriptions, only: :index
13
+ resources :stripe_subscription_events, only: :index
14
+ end
15
+
16
+ resources :stripe_plans, only: :index, path: SpreeStripeSubscriptions::Config.stripe_plans_path do
17
+ resources :stripe_subscriptions, only: %i[create update destroy] do
18
+ post :downgrade, on: :member
19
+ post :change_payment_details, on: :member
20
+ get :update_payment_details, on: :member
21
+ end
22
+ end
23
+
24
+ resources :stripe_webhooks, only: :none, path: SpreeStripeSubscriptions::Config.stripe_webhooks_path do
25
+ post :handler, on: :collection
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ class AddSpreeStripeConfigurationModel < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :spree_stripe_configurations, if_not_exists: true do |t|
4
+ t.string :name
5
+ t.text :description
6
+
7
+ t.boolean :active
8
+ t.text :preferences
9
+
10
+ t.datetime :deleted_at
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ class AddSpreeStripePlanModel < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :spree_stripe_plans, if_not_exists: true do |t|
4
+ t.string :name
5
+ t.text :description
6
+
7
+ t.string :currency
8
+ t.decimal :amount, precision: 8, scale: 2, null: false, default: 0.0
9
+
10
+ t.string :interval
11
+ t.integer :interval_count, default: 1
12
+ t.integer :trial_period_days, default: 0
13
+
14
+ t.references :configuration
15
+ t.string :stripe_plan_id, null: false
16
+
17
+ t.boolean :active, default: false
18
+
19
+ t.datetime :deleted_at
20
+ t.timestamps
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ class AddSpreeStripeCustomer < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :spree_stripe_customers, if_not_exists: true do |t|
4
+ t.references :user
5
+ t.string :stripe_customer_id
6
+
7
+ t.datetime :deleted_at
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ class AddSpreeStripeSubscriptionModel < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :spree_stripe_subscriptions, if_not_exists: true do |t|
4
+ t.references :plan
5
+ t.references :customer
6
+ t.references :user
7
+
8
+ t.string :stripe_subscription_id
9
+
10
+ t.string :status
11
+ t.datetime :current_period_start
12
+ t.datetime :current_period_end
13
+ t.datetime :billing_cycle_anchor
14
+ t.boolean :cancel_at_period_end, default: false
15
+ t.datetime :cancel_at
16
+ t.datetime :canceled_at
17
+ t.datetime :ended_at
18
+
19
+ t.datetime :deleted_at
20
+ t.timestamps
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ class AddSpreeStripeSubscriptionEventsModel < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :spree_stripe_subscription_events, if_not_exists: true do |t|
4
+ t.string :event_id
5
+ t.string :event_type
6
+
7
+ t.references :subscription
8
+ t.references :user
9
+
10
+ t.text :response
11
+
12
+ t.datetime :deleted_at
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ class AddWeightageToStripePlan < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :spree_stripe_plans, :weightage, :integer, if_not_exists: true
4
+
5
+ # Migrate existing stripe plans
6
+ Spree::StripePlan.with_deleted.order(:updated_at).each.with_index(1) do |stripe_plan, index|
7
+ stripe_plan.update_column :weightage, index
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ class AddSchedulesToSubscription < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :spree_stripe_subscriptions, :schedule, :string, if_not_exists: true
4
+ add_column :spree_stripe_subscriptions, :next_plan_id, :bigint, if_not_exists: true
5
+ end
6
+ end
@@ -0,0 +1,33 @@
1
+ class AddStripeInvoices < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :spree_stripe_invoices, if_not_exists: true do |t|
4
+ t.references :customer
5
+ t.references :subscription
6
+
7
+ t.string :stripe_invoice_id
8
+
9
+ t.string :status
10
+ t.boolean :paid, default: false
11
+ t.string :currency
12
+
13
+ t.decimal :amount_paid, precision: 8, scale: 2, null: false, default: 0.0
14
+ t.decimal :subtotal, precision: 8, scale: 2, null: false, default: 0.0
15
+ t.decimal :subtotal_excluding_tax, precision: 8, scale: 2, null: false, default: 0.0
16
+ t.decimal :tax, precision: 8, scale: 2, null: false, default: 0.0
17
+ t.decimal :total, precision: 8, scale: 2, null: false, default: 0.0
18
+ t.decimal :total_excluding_tax, precision: 8, scale: 2, null: false, default: 0.0
19
+
20
+ t.string :customer_name
21
+ t.string :billing_reason
22
+ t.string :invoice_pdf
23
+
24
+ t.datetime :period_start
25
+ t.datetime :period_end
26
+
27
+ t.text :raw_data
28
+
29
+ t.datetime :deleted_at
30
+ t.timestamps
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ class AddUserToInvoice < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :spree_stripe_invoices, :user_id, :bigint, if_not_exists: true
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ class AddExtraPlanFields < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :spree_stripe_plans, :tax_behavior, :string, default: 'unspecified'
4
+ add_column :spree_stripe_configurations, :automatic_tax, :boolean, default: true
5
+ add_column :spree_stripe_configurations, :billing_address_collection, :string
6
+ add_column :spree_stripe_configurations, :tax_id_collection, :boolean, default: true
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ module SpreeStripeSubscriptions
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ class_option :migrate, type: :boolean, default: true
5
+
6
+ def add_migrations
7
+ run 'bundle exec rake railties:install:migrations FROM=spree_stripe_subscriptions'
8
+ end
9
+
10
+ def run_migrations
11
+ run_migrations = options[:migrate] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
12
+ if run_migrations
13
+ run 'bundle exec rails db:migrate'
14
+ else
15
+ puts 'Skipping rails db:migrate, don\'t forget to run it!'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ module SpreeStripeSubscriptions
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_stripe_subscriptions'
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ initializer 'spree_stripe_subscriptions.environment', before: :load_config_initializers do |_app|
13
+ SpreeStripeSubscriptions::Config = SpreeStripeSubscriptions::Configuration.new
14
+ end
15
+
16
+ def self.activate
17
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')).sort.each do |c|
18
+ Rails.configuration.cache_classes ? require(c) : load(c)
19
+ end
20
+ end
21
+
22
+ config.to_prepare(&method(:activate).to_proc)
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
+ #
4
+ # Example adding this to your spec_helper will load these Factories for use:
5
+ # require 'spree_stripe_subscriptions/factories'
6
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeStripeSubscriptions
2
+ VERSION = '0.0.1'.freeze
3
+
4
+ module_function
5
+
6
+ # Returns the version of the currently loaded SpreeStripeSubscriptions as a
7
+ # <tt>Gem::Version</tt>.
8
+ def version
9
+ Gem::Version.new VERSION
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ require 'spree_core'
2
+ require 'spree_extension'
3
+ require 'spree_stripe_subscriptions/engine'
4
+ require 'spree_stripe_subscriptions/version'
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'spree_stripe_subscriptions/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.platform = Gem::Platform::RUBY
9
+ s.name = 'spree_stripe_subscriptions'
10
+ s.version = SpreeStripeSubscriptions.version
11
+ s.summary = 'Spree extension to manage stripe subscriptions using Stripe Checkout Session.'
12
+ s.description = s.summary
13
+ s.required_ruby_version = '>= 2.5'
14
+
15
+ s.author = 'Satyakam Pandya'
16
+ s.email = 'satyakampandya@gmail.com'
17
+ s.homepage = 'https://github.com/satyakampandya/spree_stripe_subscriptions'
18
+ s.license = 'BSD-3-Clause'
19
+
20
+ s.files = `git ls-files`.split("\n").reject { |f| f.match(/^spec/) && !f.match(/^spec\/fixtures/) }
21
+ s.require_path = 'lib'
22
+ s.requirements << 'none'
23
+
24
+ s.add_dependency 'spree', '>= 4.3.0'
25
+ s.add_dependency 'spree_backend'
26
+ s.add_dependency 'spree_extension'
27
+
28
+ s.add_dependency 'stripe', '>= 3.3.2', '< 8.0.0'
29
+ s.add_dependency 'stripe_tester'
30
+
31
+ s.add_dependency 'deface', '~> 1.0'
32
+
33
+ s.add_development_dependency 'spree_dev_tools'
34
+ end