pay_me 0.5.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 +7 -0
- data/README.md +111 -0
- data/Rakefile +33 -0
- data/app/controllers/pay_me/api/v1/invoices_controller.rb +30 -0
- data/app/controllers/pay_me/api/v1/stripe_plans_controller.rb +35 -0
- data/app/controllers/pay_me/application_controller.rb +10 -0
- data/app/helpers/pay_me/application_helper.rb +4 -0
- data/app/subscribers/pay_me/customer_subscriber.rb +42 -0
- data/app/subscribers/pay_me/plan_subscriber.rb +38 -0
- data/app/subscribers/pay_me/subscription_subscriber.rb +50 -0
- data/app/subscribers/pay_me/webhook_event_subscriber.rb +11 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20160725204454_create_pay_me_subscriptions.rb +16 -0
- data/db/migrate/20161011170659_create_pay_me_plans.rb +8 -0
- data/db/migrate/20171030174731_add_quantity_to_pay_me_subscription.rb +6 -0
- data/db/migrate/20171130192525_create_pay_me_customers.rb +11 -0
- data/db/migrate/20180116193943_remove_customerable_from_subscriptions.rb +11 -0
- data/db/migrate/20180215235017_add_past_due_to_subscriptions.rb +5 -0
- data/lib/generators/pay_me/controllers/controllers_generator.rb +11 -0
- data/lib/generators/pay_me/controllers/templates/subscriptions_controller.rb +12 -0
- data/lib/generators/pay_me/install_generator.rb +39 -0
- data/lib/generators/pay_me/migrate_to_customer_model/USAGE +8 -0
- data/lib/generators/pay_me/migrate_to_customer_model/migrate_to_customer_model_generator.rb +9 -0
- data/lib/generators/pay_me/migrate_to_customer_model/templates/migration.rb.erb +64 -0
- data/lib/generators/pay_me/models/models_generator.rb +13 -0
- data/lib/generators/pay_me/models/templates/customer.rb +14 -0
- data/lib/generators/pay_me/models/templates/plan.rb +14 -0
- data/lib/generators/pay_me/models/templates/subscription.rb +14 -0
- data/lib/generators/pay_me/policies/policies_generator.rb +11 -0
- data/lib/generators/pay_me/policies/templates/subscription_policy.rb +34 -0
- data/lib/generators/pay_me/templates/pay_me_initializer.rb +17 -0
- data/lib/pay_me.rb +28 -0
- data/lib/pay_me/active_record.rb +6 -0
- data/lib/pay_me/concerns/controllers/customerable.rb +116 -0
- data/lib/pay_me/concerns/models/customerable.rb +54 -0
- data/lib/pay_me/concerns/models/stripe_customerable.rb +24 -0
- data/lib/pay_me/concerns/models/stripe_plannable.rb +31 -0
- data/lib/pay_me/concerns/models/stripe_subscribable.rb +43 -0
- data/lib/pay_me/configuration.rb +27 -0
- data/lib/pay_me/engine.rb +8 -0
- data/lib/pay_me/models.rb +4 -0
- data/lib/pay_me/railtie.rb +2 -0
- data/lib/pay_me/route_helpers.rb +21 -0
- data/lib/pay_me/services/customer.rb +141 -0
- data/lib/pay_me/version.rb +3 -0
- data/lib/pay_me/view_models/charge.rb +48 -0
- data/lib/tasks/pay_me_tasks.rake +4 -0
- data/lib/tasks/stripe.rake +22 -0
- data/test/controllers/pay_me/api/v1/invoices_controller_test.rb +82 -0
- data/test/controllers/pay_me/api/v1/plans_controller_test.rb +62 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/api/v1/users_controller.rb +10 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/pay_me/api/v1/subscriptions_controller.rb +12 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/pay_me/customer.rb +5 -0
- data/test/dummy/app/models/pay_me/plan.rb +5 -0
- data/test/dummy/app/models/pay_me/subscription.rb +5 -0
- data/test/dummy/app/models/user.rb +8 -0
- data/test/dummy/app/policies/pay_me/subscription_policy.rb +34 -0
- data/test/dummy/app/serializers/pay_me/subscription_serializer.rb +3 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +25 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/pay_me.rb +17 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +10 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/db/migrate/20160630181300_create_pay_me_users.rb +12 -0
- data/test/dummy/db/migrate/20180118001940_api_me_migrate_to_customer_model.rb +9 -0
- data/test/dummy/db/schema.rb +53 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/integration/customer_test.rb +395 -0
- data/test/lib/generators/pay_me/pay_me/migrate_to_customer_model_generator_test.rb +16 -0
- data/test/models/pay_me/customer_test.rb +9 -0
- data/test/models/pay_me/subscription_test.rb +9 -0
- data/test/models/pay_me/user_test.rb +6 -0
- data/test/pay_me_test.rb +7 -0
- data/test/support/concerns/api_test_helper.rb +15 -0
- data/test/support/concerns/stripe_helpers.rb +25 -0
- data/test/test_helper.rb +52 -0
- data/test/unit/concerns/customerable.rb +21 -0
- data/test/unit/models/customerable_test.rb +18 -0
- data/test/unit/services/customer_test.rb +75 -0
- data/test/unit/stubs/customerable.rb +28 -0
- data/test/unit/stubs/customerable_test.rb +16 -0
- data/test/webhooks/customer_webhook_test.rb +74 -0
- data/test/webhooks/plan_webhook_test.rb +74 -0
- metadata +288 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e18795d8af901a878f1d13c1a86de08fa1f2d50f73376813e46fc438311bd36e
|
|
4
|
+
data.tar.gz: adfdcca8ec3e7060f0076a5de4192161e47b775b91d556e59f539052e38ce505
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7acc778c322a0a4af83d521ba81e797f9ba8c283e658e346c358f52e0e63fa29b444582d9eb6b29288b927ea8c65631efdb1431caefb15ef577c1f19cc7de3fc
|
|
7
|
+
data.tar.gz: 9da7a3ffdfdc90bba5e8203e47e99e32d02c68ba09a639409de79c10186b929e2c859eadb08fd741f397e328621f9e621a8a3299875283503dc32e4d42ceebab
|
data/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
PayMe
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
## This gem is currently a work in progress, follows semver, and may change significantly until version 1.0
|
|
5
|
+
|
|
6
|
+
### A gem for attaching a payment system to business login in Rails
|
|
7
|
+
TODO...
|
|
8
|
+
|
|
9
|
+
### Details
|
|
10
|
+
TODO...
|
|
11
|
+
|
|
12
|
+
### Testing
|
|
13
|
+
Ensure you have `STRIPE_TEST_SECRET_KEY` as an ENV variable.
|
|
14
|
+
This progect uses [dotenv](https://github.com/bkeepers/dotenv) so you can create a `.env` file.
|
|
15
|
+
You can run the tests using `rake test`.
|
|
16
|
+
|
|
17
|
+
### Installation
|
|
18
|
+
Add the gem to your Gemfile: `gem 'pay_me'`.
|
|
19
|
+
|
|
20
|
+
Run `bundle install` to install it.
|
|
21
|
+
|
|
22
|
+
Run `rails g pay_me:install`
|
|
23
|
+
|
|
24
|
+
Add the following to your routes
|
|
25
|
+
```ruby
|
|
26
|
+
...
|
|
27
|
+
pay_me_customerable_for :users
|
|
28
|
+
...
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Add the following to your customer model controller
|
|
32
|
+
```ruby
|
|
33
|
+
require 'pay_me/concerns/controllers/customerable'
|
|
34
|
+
...
|
|
35
|
+
class UsersController < BaseController
|
|
36
|
+
include PayMe::Concerns::Controllers::Customerable
|
|
37
|
+
...
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Add the following to your customer model
|
|
41
|
+
```ruby
|
|
42
|
+
require 'pay_me/concerns/models/customerable'
|
|
43
|
+
...
|
|
44
|
+
class User < ActiveRecord::Base
|
|
45
|
+
include PayMe::Concerns::Models::Customerable
|
|
46
|
+
...
|
|
47
|
+
```
|
|
48
|
+
The model will also need a `receipt_email` attribute and `customer_id`.
|
|
49
|
+
|
|
50
|
+
The installer will automatically add the following to your `secrets.yml` for `development` `test` and `production`.
|
|
51
|
+
`secrets.yml`
|
|
52
|
+
```yml
|
|
53
|
+
development:
|
|
54
|
+
###
|
|
55
|
+
# Other configs
|
|
56
|
+
###
|
|
57
|
+
stripe_publishable_key: <%= ENV['STRIPE_PUBLISHABLE_KEY'] %>
|
|
58
|
+
stripe_secret_key: <%= ENV['STRIPE_SECRET_KEY'] %>
|
|
59
|
+
stripe_webhook_secret: <%= ENV['STRIPE_WEBHOOK_SECRET'] %>
|
|
60
|
+
stripe_signing_secret: <%= ENV['STRIPE_SIGNING_SECRET'] %>
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
or using inheritance:
|
|
65
|
+
`secrets.yml`
|
|
66
|
+
```yml
|
|
67
|
+
stripe: &stripe
|
|
68
|
+
stripe_publishable_key: <%= ENV['STRIPE_PUBLISHABLE_KEY'] %>
|
|
69
|
+
stripe_secret_key: <%= ENV['STRIPE_SECRET_KEY'] %>
|
|
70
|
+
stripe_webhook_secret: <%= ENV['STRIPE_WEBHOOK_SECRET'] %>
|
|
71
|
+
stripe_signing_secret: <%= ENV['STRIPE_SIGNING_SECRET'] %>
|
|
72
|
+
|
|
73
|
+
development:
|
|
74
|
+
<<: *stripe
|
|
75
|
+
...
|
|
76
|
+
|
|
77
|
+
test:
|
|
78
|
+
<<: *stripe
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
production:
|
|
82
|
+
<<: *stripe
|
|
83
|
+
...
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
You will need to add the stripe keys to your `ENV`.
|
|
87
|
+
- `STRIPE_PUBLISHABLE_KEY` is your stripe publishable key.
|
|
88
|
+
- `STRIPE_SECRET_KEY` is your stripe secret key.
|
|
89
|
+
- `STRIPE_WEBHOOK_SECRET` is a secret that is used for stripe as a password for basic authentication to the webhook. You can use `rake secret` to generate a suitable secret. This is also used when configuring the stripe webhook in stripe: `https://stripe:STRIPE_WEBHOOK_SECRET@myapplication.com/pay_me-stripe_webhooks`
|
|
90
|
+
- `STRIPE_SIGNING_SECRET` is used by stripe to sign webhooks. It can be found in your stripe webhook settings.
|
|
91
|
+
|
|
92
|
+
PayMe adds to rake task for caching Stripe plans locally to reduce calls to stripe.
|
|
93
|
+
They are:
|
|
94
|
+
- `pay_me:stripe:add_stripe_plans` This will add missing Stripe plans, but not delete local ones that no longer exist on stripe.
|
|
95
|
+
- `pay_me:stripe:sync_stripe_plans` This will add missing Stripe plans and delete local ones that don't exist on stripe.
|
|
96
|
+
|
|
97
|
+
You are now setup!
|
|
98
|
+
|
|
99
|
+
### Stripe Configuration Checklist
|
|
100
|
+
- [ ] Get API keys and add to `ENV`
|
|
101
|
+
- [ ] Add webhook URL and webhook secret to `ENV`
|
|
102
|
+
- [ ] Get webhook signing secret and add to `ENV`
|
|
103
|
+
- [ ] Add plan(s) to Stripe.
|
|
104
|
+
TODO...
|
|
105
|
+
|
|
106
|
+
### Usage
|
|
107
|
+
#### Todo:
|
|
108
|
+
- [ ] TODO...
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
Copyright (c) 2015, Pay Me is developed and maintained by Wildland
|
data/Rakefile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require 'rdoc/task'
|
|
8
|
+
|
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
11
|
+
rdoc.title = 'PayMe'
|
|
12
|
+
rdoc.options << '--line-numbers'
|
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
|
|
18
|
+
load 'rails/tasks/engine.rake'
|
|
19
|
+
|
|
20
|
+
load 'rails/tasks/statistics.rake'
|
|
21
|
+
|
|
22
|
+
Bundler::GemHelper.install_tasks
|
|
23
|
+
|
|
24
|
+
require 'rake/testtask'
|
|
25
|
+
|
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
|
27
|
+
t.libs << 'lib'
|
|
28
|
+
t.libs << 'test'
|
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
|
30
|
+
t.verbose = false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
task default: :test
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_dependency 'pay_me/application_controller'
|
|
2
|
+
module PayMe
|
|
3
|
+
module Api
|
|
4
|
+
module V1
|
|
5
|
+
class InvoicesController < ApplicationController # TODO ApiMe Integration
|
|
6
|
+
def index
|
|
7
|
+
invoices = PayMe.configuration.stripe_invoice_class.list
|
|
8
|
+
|
|
9
|
+
render status: 200, json: {
|
|
10
|
+
invoices: invoices.map do |invoice|
|
|
11
|
+
invoice.as_json.tap do |i|
|
|
12
|
+
i.store('stripe_id', i.delete('id'))
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def show
|
|
19
|
+
invoice = PayMe.configuration.stripe_invoice_class.retrieve(params[:id])
|
|
20
|
+
|
|
21
|
+
render status: 200, json: {
|
|
22
|
+
invoice: invoice.as_json.tap do |i|
|
|
23
|
+
i.store('stripe_id', i.delete('id'))
|
|
24
|
+
end
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_dependency 'pay_me/application_controller'
|
|
2
|
+
|
|
3
|
+
module PayMe
|
|
4
|
+
module Api
|
|
5
|
+
module V1
|
|
6
|
+
class StripePlansController < ApplicationController # TODO ApiMe Integration
|
|
7
|
+
def index
|
|
8
|
+
plans = Stripe::Plan.list
|
|
9
|
+
|
|
10
|
+
pay_me_plans = PayMe::Plan.all.pluck(:plan_id)
|
|
11
|
+
|
|
12
|
+
plans = plans.to_a.select{ |p| pay_me_plans.include?(p['id']) }
|
|
13
|
+
|
|
14
|
+
render status: 200, json: {
|
|
15
|
+
stripePlans: plans.map do |plan|
|
|
16
|
+
plan.as_json.tap do |p|
|
|
17
|
+
p.store('stripe_id', p.delete('id'))
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def show
|
|
24
|
+
plan = Stripe::Plan.retrieve(params[:id])
|
|
25
|
+
|
|
26
|
+
render status: 200, json: {
|
|
27
|
+
stripePlans: plan.as_json.tap do |p|
|
|
28
|
+
p.store('stripe_id', p.delete('id'))
|
|
29
|
+
end
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module PayMe
|
|
2
|
+
class ApplicationController < ActionController::Base
|
|
3
|
+
protect_from_forgery with: :exception
|
|
4
|
+
|
|
5
|
+
rescue_from Stripe::StripeError do |e|
|
|
6
|
+
logger.error { e.to_s }
|
|
7
|
+
render status: e.http_status, json: { reason: e.message, errors: [e.message] }
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module PayMe
|
|
2
|
+
class CustomerSubscriber < WebhookEventSubscriber
|
|
3
|
+
def call(event)
|
|
4
|
+
case event.type
|
|
5
|
+
when 'customer.created'
|
|
6
|
+
customer_created(event.data.object)
|
|
7
|
+
when 'customer.deleted'
|
|
8
|
+
customer_deleted(event.data.object)
|
|
9
|
+
when 'customer.updated'
|
|
10
|
+
customer_updated(event.data.object)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def customer_created(stripe_customer)
|
|
15
|
+
ActiveRecord::Base.transaction do
|
|
16
|
+
PayMe::Customer.created_webhook!(stripe_customer)
|
|
17
|
+
unless PayMe::Customer.exists?(customer_id: stripe_customer.id)
|
|
18
|
+
@logger.warn "[STRIPE] Stripe customer stripe_ID:#{stripe_customer.id} created through stripe interface."
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def customer_deleted(stripe_customer)
|
|
24
|
+
ActiveRecord::Base.transaction do
|
|
25
|
+
PayMe::Customer.deleted_webhook!(stripe_customer)
|
|
26
|
+
if PayMe::Customer.exists?(customer_id: stripe_customer.id)
|
|
27
|
+
@logger.warn "[STRIPE] Stripe customer stripe_ID:#{stripe_customer.id} deleted through stripe interface."
|
|
28
|
+
PayMe::Customer.find_by!(customer_id: stripe_customer.id).destroy
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def customer_updated(stripe_customer)
|
|
34
|
+
ActiveRecord::Base.transaction do
|
|
35
|
+
PayMe::Customer.updated_webhook!(stripe_customer)
|
|
36
|
+
unless PayMe::Customer.exists?(customer_id: stripe_customer.id)
|
|
37
|
+
@logger.warn "[STRIPE] Unable to find stripe customer stripe_ID:#{stripe_customer.id} on update."
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module PayMe
|
|
2
|
+
class PlanSubscriber < WebhookEventSubscriber
|
|
3
|
+
def call(event)
|
|
4
|
+
case event.type
|
|
5
|
+
when 'plan.created'
|
|
6
|
+
plan_created(event.data.object)
|
|
7
|
+
when 'plan.deleted'
|
|
8
|
+
plan_deleted(event.data.object)
|
|
9
|
+
when 'plan.updated'
|
|
10
|
+
plan_updated(event.data.object)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def plan_created(stripe_plan)
|
|
15
|
+
ActiveRecord::Base.transaction do
|
|
16
|
+
PayMe::Plan.created_webhook!(stripe_plan)
|
|
17
|
+
unless PayMe::Plan.exists?(plan_id: stripe_plan.id)
|
|
18
|
+
PayMe::Plan.create!(plan_id: stripe_plan.id)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def plan_deleted(stripe_plan)
|
|
24
|
+
ActiveRecord::Base.transaction do
|
|
25
|
+
PayMe::Plan.deleted_webhook!(stripe_plan)
|
|
26
|
+
if PayMe::Plan.exists?(plan_id: stripe_plan.id)
|
|
27
|
+
PayMe::Plan.find_by!(plan_id: stripe_plan.id).destroy
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def plan_updated(stripe_plan)
|
|
33
|
+
ActiveRecord::Base.transaction do
|
|
34
|
+
PayMe::Plan.updated_webhook!(stripe_plan)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module PayMe
|
|
2
|
+
class SubscriptionSubscriber < WebhookEventSubscriber
|
|
3
|
+
def call(event)
|
|
4
|
+
case event.type
|
|
5
|
+
when 'customer.subscription.created'
|
|
6
|
+
subscription_created(event.data.object)
|
|
7
|
+
when 'customer.subscription.deleted'
|
|
8
|
+
subscription_deleted(event.data.object)
|
|
9
|
+
when 'customer.subscription.updated'
|
|
10
|
+
subscription_updated(event.data.object)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def subscription_created(stripe_subscription)
|
|
15
|
+
ActiveRecord::Base.transaction do
|
|
16
|
+
PayMe::Subscription.created_webhook!(stripe_subscription)
|
|
17
|
+
unless PayMe::Subscription.exists?(subscription_id: stripe_subscription.id)
|
|
18
|
+
@logger.warn "[STRIPE] Stripe subscription stripe_ID:#{stripe_subscription.id} created in stripe interface."
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def subscription_deleted(stripe_subscription)
|
|
24
|
+
ActiveRecord::Base.transaction do
|
|
25
|
+
PayMe::Subscription.deleted_webhook!(stripe_subscription)
|
|
26
|
+
if PayMe::Subscription.exists?(subscription_id: stripe_subscription.id)
|
|
27
|
+
@logger.warn "[STRIPE] Stripe subscription stripe_ID:#{stripe_subscription.id} delete in stripe interface."
|
|
28
|
+
PayMe::Subscription.destroy(subscription_id: stripe_subscription.id)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def subscription_updated(stripe_subscription)
|
|
34
|
+
ActiveRecord::Base.transaction do
|
|
35
|
+
PayMe::Subscription.updated_webhook!(stripe_subscription)
|
|
36
|
+
@subscription = PayMe::Subscription.find_by!(subscription_id: stripe_subscription.id)
|
|
37
|
+
case stripe_subscription.status
|
|
38
|
+
when 'trialing', 'active'
|
|
39
|
+
@subscription.update!(is_active: true, past_due: false)
|
|
40
|
+
when 'past_due'
|
|
41
|
+
@subscription.update!(is_active: true, past_due: true)
|
|
42
|
+
when 'canceled', 'unpaid'
|
|
43
|
+
@subscription.update!(is_active: false, past_due: false)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
rescue ActiveRecord::RecordNotFound => e
|
|
47
|
+
@logger.warn "[STRIPE] Unable to find stripe subscription stripe_ID:#{stripe_subscription.id}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
PayMe::Engine.routes.draw do
|
|
2
|
+
namespace :api do
|
|
3
|
+
namespace :v1 do
|
|
4
|
+
resources :invoices, only: [:index, :show]
|
|
5
|
+
resources :stripe_plans, only: [:index, :show]
|
|
6
|
+
resources :plans, only: [:index, :show]
|
|
7
|
+
resources :subscriptions, only: [:index, :show]
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
mount StripeEvent::Engine, at: '/stripe_webhooks'
|
|
11
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class CreatePayMeSubscriptions < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :pay_me_subscriptions do |t|
|
|
4
|
+
t.string :subscription_id, null: false
|
|
5
|
+
t.boolean :is_active, null: false
|
|
6
|
+
t.references :customerable, polymorphic: true, null: false
|
|
7
|
+
|
|
8
|
+
t.timestamps null: false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
add_index :pay_me_subscriptions, :subscription_id, unique: true
|
|
12
|
+
add_index :pay_me_subscriptions,
|
|
13
|
+
[:customerable_id, :customerable_type],
|
|
14
|
+
unique: true, name: 'subscription_customerable_index'
|
|
15
|
+
end
|
|
16
|
+
end
|