slack-ruby-bot-server-stripe 0.1.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/.gitignore +10 -0
- data/.rspec +3 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +29 -0
- data/.travis.yml +29 -0
- data/CHANGELOG.md +5 -0
- data/CONTRIBUTING.md +125 -0
- data/Dangerfile +1 -0
- data/Gemfile +42 -0
- data/LICENSE +21 -0
- data/README.md +278 -0
- data/RELEASING.md +61 -0
- data/Rakefile +14 -0
- data/lib/slack-ruby-bot-server-stripe.rb +15 -0
- data/lib/slack-ruby-bot-server-stripe/api.rb +1 -0
- data/lib/slack-ruby-bot-server-stripe/api/endpoints.rb +1 -0
- data/lib/slack-ruby-bot-server-stripe/api/endpoints/subscriptions_endpoint.rb +44 -0
- data/lib/slack-ruby-bot-server-stripe/commands.rb +2 -0
- data/lib/slack-ruby-bot-server-stripe/commands/subscription.rb +14 -0
- data/lib/slack-ruby-bot-server-stripe/commands/unsubscribe.rb +34 -0
- data/lib/slack-ruby-bot-server-stripe/config.rb +41 -0
- data/lib/slack-ruby-bot-server-stripe/errors.rb +10 -0
- data/lib/slack-ruby-bot-server-stripe/lifecycle.rb +17 -0
- data/lib/slack-ruby-bot-server-stripe/models.rb +2 -0
- data/lib/slack-ruby-bot-server-stripe/models/activerecord.rb +18 -0
- data/lib/slack-ruby-bot-server-stripe/models/methods.rb +317 -0
- data/lib/slack-ruby-bot-server-stripe/models/mongoid.rb +27 -0
- data/lib/slack-ruby-bot-server-stripe/public/img/icon.png +0 -0
- data/lib/slack-ruby-bot-server-stripe/public/img/stripe.png +0 -0
- data/lib/slack-ruby-bot-server-stripe/public/subscribe.html.erb +99 -0
- data/lib/slack-ruby-bot-server-stripe/version.rb +5 -0
- data/lib/slack-ruby-bot-server/api.rb +2 -0
- data/lib/slack-ruby-bot-server/api/endpoints.rb +9 -0
- data/lib/slack-ruby-bot-server/api/presenters.rb +2 -0
- data/lib/slack-ruby-bot-server/api/presenters/root_presenter.rb +11 -0
- data/lib/slack-ruby-bot-server/api/presenters/team_presenter.rb +10 -0
- data/slack-ruby-bot-server-stripe.gemspec +19 -0
- metadata +107 -0
data/RELEASING.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Releasing Slack-Ruby-Bot-Server-Stripe
|
2
|
+
|
3
|
+
There're no hard rules about when to release slack-ruby-bot-server-stripe. Release bug fixes frequently, features not so frequently and breaking API changes rarely.
|
4
|
+
|
5
|
+
### Release
|
6
|
+
|
7
|
+
Run tests, check that all tests succeed locally.
|
8
|
+
|
9
|
+
```
|
10
|
+
bundle install
|
11
|
+
rake
|
12
|
+
```
|
13
|
+
|
14
|
+
Check that the last build succeeded in [Travis CI](https://travis-ci.org/slack-ruby/slack-ruby-bot-server-stripe) for all supported platforms.
|
15
|
+
|
16
|
+
Change "Next" in [CHANGELOG.md](CHANGELOG.md) to the current date.
|
17
|
+
|
18
|
+
```
|
19
|
+
### 0.2.2 (7/10/2015)
|
20
|
+
```
|
21
|
+
|
22
|
+
Remove the line with "Your contribution here.", since there will be no more contributions to this release.
|
23
|
+
|
24
|
+
Commit your changes.
|
25
|
+
|
26
|
+
```
|
27
|
+
git add CHANGELOG.md
|
28
|
+
git commit -m "Preparing for release, 0.2.2."
|
29
|
+
git push origin master
|
30
|
+
```
|
31
|
+
|
32
|
+
Release.
|
33
|
+
|
34
|
+
```
|
35
|
+
$ rake release
|
36
|
+
|
37
|
+
slack-ruby-bot-server-stripe 0.2.2 built to pkg/slack-ruby-bot-server-stripe-0.2.2.gem.
|
38
|
+
Tagged v0.2.2.
|
39
|
+
Pushed git commits and tags.
|
40
|
+
Pushed slack-ruby-bot-server-stripe 0.2.2 to rubygems.org.
|
41
|
+
```
|
42
|
+
|
43
|
+
### Prepare for the Next Version
|
44
|
+
|
45
|
+
Add the next release to [CHANGELOG.md](CHANGELOG.md).
|
46
|
+
|
47
|
+
```
|
48
|
+
### 0.2.3 (Next)
|
49
|
+
|
50
|
+
* Your contribution here.
|
51
|
+
```
|
52
|
+
|
53
|
+
Increment the third version number in [lib/slack-ruby-bot-server-stripe/version.rb](lib/slack-ruby-bot-server-stripe/version.rb).
|
54
|
+
|
55
|
+
Commit your changes.
|
56
|
+
|
57
|
+
```
|
58
|
+
git add CHANGELOG.md lib/slack-ruby-bot-server-stripe/version.rb
|
59
|
+
git commit -m "Preparing for next development iteration, 0.2.3."
|
60
|
+
git push origin master
|
61
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
require 'rspec/core'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
+
spec.pattern = FileList['spec/**/*_spec.rb'].exclude(%r{ext\/(?!#{ENV['DATABASE_ADAPTER']})})
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'rubocop/rake_task'
|
12
|
+
RuboCop::RakeTask.new
|
13
|
+
|
14
|
+
task default: %i[rubocop spec]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'stripe'
|
2
|
+
|
3
|
+
require 'slack-ruby-bot-server'
|
4
|
+
|
5
|
+
require_relative 'slack-ruby-bot-server-stripe/version'
|
6
|
+
require_relative 'slack-ruby-bot-server-stripe/config'
|
7
|
+
require_relative 'slack-ruby-bot-server-stripe/errors'
|
8
|
+
require_relative 'slack-ruby-bot-server-stripe/models'
|
9
|
+
require_relative 'slack-ruby-bot-server-stripe/lifecycle'
|
10
|
+
require_relative 'slack-ruby-bot-server-stripe/api'
|
11
|
+
require_relative 'slack-ruby-bot-server-stripe/commands'
|
12
|
+
|
13
|
+
SlackRubyBotServer::Config.view_paths << File.expand_path(File.join(__dir__, 'slack-ruby-bot-server-stripe/public'))
|
14
|
+
|
15
|
+
require_relative 'slack-ruby-bot-server/api'
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'api/endpoints'
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'endpoints/subscriptions_endpoint'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SlackRubyBotServer
|
2
|
+
module Stripe
|
3
|
+
module Api
|
4
|
+
module Endpoints
|
5
|
+
class SubscriptionsEndpoint < Grape::API
|
6
|
+
format :json
|
7
|
+
|
8
|
+
namespace :subscriptions do
|
9
|
+
desc 'Create or update a subscription.'
|
10
|
+
params do
|
11
|
+
requires :stripe_token, type: String
|
12
|
+
optional :stripe_token_type, type: String
|
13
|
+
optional :stripe_email, type: String
|
14
|
+
requires :team_id, type: String
|
15
|
+
end
|
16
|
+
post do
|
17
|
+
begin
|
18
|
+
team = Team.where(team_id: params[:team_id]).first || error!('Team Not Found', 404)
|
19
|
+
if team.subscribed?
|
20
|
+
SlackRubyBotServer::Api::Middleware.logger.info "Updating a subscription for team #{team}."
|
21
|
+
stripe_customer = team.update_subscription!(params)
|
22
|
+
SlackRubyBotServer::Api::Middleware.logger.info "Updated subscription for team #{team}, stripe_customer_id=#{stripe_customer['id']}."
|
23
|
+
else
|
24
|
+
SlackRubyBotServer::Api::Middleware.logger.info "Creating a subscription for team #{team}."
|
25
|
+
stripe_customer = team.subscribe!(params)
|
26
|
+
SlackRubyBotServer::Api::Middleware.logger.info "Subscription for team #{team} created, stripe_customer_id=#{stripe_customer['id']}."
|
27
|
+
end
|
28
|
+
present team, with: SlackRubyBotServer::Api::Presenters::TeamPresenter
|
29
|
+
rescue Errors::AlreadySubscribedError
|
30
|
+
error! 'Already Subscribed', 400
|
31
|
+
rescue Errors::StripeCustomerExistsError
|
32
|
+
error! 'Customer Already Registered', 400
|
33
|
+
rescue Errors::NotSubscribedError
|
34
|
+
error! 'Not a Subscriber', 400
|
35
|
+
rescue Errors::MissingStripeCustomerError
|
36
|
+
error! 'Missing Stripe Customer', 400
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SlackRubyBotServer
|
2
|
+
module Stripe
|
3
|
+
module Commands
|
4
|
+
class Subscription < SlackRubyBot::Commands::Base
|
5
|
+
command 'subscription' do |client, data, _match|
|
6
|
+
team = ::Team.find(client.owner.id)
|
7
|
+
include_admin_info = (data.user == team.activated_user_id)
|
8
|
+
client.say(channel: data.channel, text: team.subscription_text(include_admin_info: include_admin_info))
|
9
|
+
logger.info "SUBSCRIPTION: #{client.owner} - #{data.user}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SlackRubyBotServer
|
2
|
+
module Stripe
|
3
|
+
module Commands
|
4
|
+
class Unsubscribe < SlackRubyBot::Commands::Base
|
5
|
+
command 'unsubscribe' do |client, data, match|
|
6
|
+
team = ::Team.find(client.owner.id)
|
7
|
+
if !team.active_stripe_subscription?
|
8
|
+
client.say(channel: data.channel, text: "You don't have a paid subscription, all set.")
|
9
|
+
logger.info "UNSUBSCRIBE: #{client.owner} - #{data.user} unsubscribe failed, no subscription"
|
10
|
+
elsif data.user == team.activated_user_id
|
11
|
+
subscription_info = []
|
12
|
+
subscription_id = match['expression']
|
13
|
+
active_subscription = team.active_stripe_subscription
|
14
|
+
if active_subscription && active_subscription.id == subscription_id
|
15
|
+
team.unsubscribe!
|
16
|
+
amount = ActiveSupport::NumberHelper.number_to_currency(active_subscription.plan.amount.to_f / 100)
|
17
|
+
subscription_info << "Successfully canceled auto-renew for #{active_subscription.plan.name} (#{amount})."
|
18
|
+
logger.info "UNSUBSCRIBE: #{client.owner} - #{data.user}, canceled #{subscription_id}"
|
19
|
+
elsif subscription_id
|
20
|
+
subscription_info << "Sorry, I cannot find a subscription with \"#{subscription_id}\"."
|
21
|
+
else
|
22
|
+
subscription_info << "Send \"unsubscribe #{active_subscription.id}\" to confirm."
|
23
|
+
end
|
24
|
+
client.say(channel: data.channel, text: subscription_info.compact.join("\n"))
|
25
|
+
logger.info "UNSUBSCRIBE: #{client.owner} - #{data.user}"
|
26
|
+
else
|
27
|
+
client.say(channel: data.channel, text: "Sorry, only <@#{team.activated_user_id}> can do that.")
|
28
|
+
logger.info "UNSUBSCRIBE: #{client.owner} - #{data.user} unsubscribe failed, not admin"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SlackRubyBotServer
|
2
|
+
module Stripe
|
3
|
+
module Config
|
4
|
+
extend self
|
5
|
+
|
6
|
+
attr_reader :stripe_api_key
|
7
|
+
|
8
|
+
def stripe_api_key=(value)
|
9
|
+
@stripe_api_key = value
|
10
|
+
::Stripe.api_key = value
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :stripe_api_publishable_key
|
14
|
+
attr_accessor :subscription_plan_id
|
15
|
+
attr_accessor :subscription_plan_amount
|
16
|
+
attr_accessor :trial_duration
|
17
|
+
attr_accessor :root_url
|
18
|
+
|
19
|
+
def reset!
|
20
|
+
self.stripe_api_publishable_key = ENV['STRIPE_API_PUBLISHABLE_KEY']
|
21
|
+
self.stripe_api_key = ENV['STRIPE_API_KEY']
|
22
|
+
self.subscription_plan_id = ENV['STRIPE_SUBSCRIPTION_PLAN_ID']
|
23
|
+
self.subscription_plan_amount = -1
|
24
|
+
self.root_url = ENV['URL']
|
25
|
+
self.trial_duration = 2.weeks
|
26
|
+
end
|
27
|
+
|
28
|
+
reset!
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def configure
|
33
|
+
block_given? ? yield(Config) : Config
|
34
|
+
end
|
35
|
+
|
36
|
+
def config
|
37
|
+
Config
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module SlackRubyBotServer
|
2
|
+
module Stripe
|
3
|
+
module Errors
|
4
|
+
class StripeCustomerExistsError < StandardError; end
|
5
|
+
class MissingStripeCustomerError < StandardError; end
|
6
|
+
class AlreadySubscribedError < StandardError; end
|
7
|
+
class NotSubscribedError < StandardError; end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
SlackRubyBotServer::Config.service_class.instance.on :starting do |team|
|
2
|
+
begin
|
3
|
+
team.check_stripe!
|
4
|
+
rescue StandardError => e
|
5
|
+
SlackRubyBotServer::Service.logger.error e
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
SlackRubyBotServer::Config.service_class.instance.every :day do
|
10
|
+
Team.each do |team|
|
11
|
+
begin
|
12
|
+
team.check_stripe!
|
13
|
+
rescue StandardError => e
|
14
|
+
SlackRubyBotServer::Service.logger.error e
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'methods'
|
2
|
+
|
3
|
+
module SlackRubyBotServer
|
4
|
+
module Stripe
|
5
|
+
module Models
|
6
|
+
module ActiveRecord
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include Methods
|
9
|
+
|
10
|
+
included do
|
11
|
+
# TODO
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Team.include SlackRubyBotServer::Stripe::Models::ActiveRecord
|
@@ -0,0 +1,317 @@
|
|
1
|
+
module SlackRubyBotServer
|
2
|
+
module Stripe
|
3
|
+
module Models
|
4
|
+
module Methods
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
extend ActiveModel::Callbacks
|
7
|
+
|
8
|
+
included do
|
9
|
+
define_model_callbacks :trial_expiring, :subscription_expired, :subscription_past_due, :unsubscribed
|
10
|
+
define_model_callbacks :subscribed, only: [:after]
|
11
|
+
before_validation :update_subscribed_at
|
12
|
+
before_validation :update_subscription_expired_at
|
13
|
+
after_update :subscribed!
|
14
|
+
end
|
15
|
+
|
16
|
+
# supports https://github.com/slack-ruby/slack-ruby-bot-server-mailchimp
|
17
|
+
def tags
|
18
|
+
[
|
19
|
+
subscribed? ? 'subscribed' : 'trial',
|
20
|
+
stripe_customer_id? ? 'paid' : nil
|
21
|
+
].compact
|
22
|
+
end
|
23
|
+
|
24
|
+
def subscription_expired?
|
25
|
+
return false if subscribed?
|
26
|
+
return true if subscription_expired_at
|
27
|
+
|
28
|
+
time_limit = Time.now - trial_duration
|
29
|
+
created_at < time_limit
|
30
|
+
end
|
31
|
+
|
32
|
+
def trial_expired?
|
33
|
+
remaining_trial_days <= 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def subscription_text(options = { include_admin_info: false })
|
37
|
+
subscription_text = []
|
38
|
+
if active_stripe_subscription?
|
39
|
+
subscription_text << stripe_customer_text
|
40
|
+
subscription_text.concat(stripe_customer_subscriptions_info)
|
41
|
+
if options[:include_admin_info]
|
42
|
+
subscription_text.concat(stripe_customer_invoices_info)
|
43
|
+
subscription_text.concat(stripe_customer_sources_info)
|
44
|
+
subscription_text << update_cc_text
|
45
|
+
end
|
46
|
+
elsif subscribed && subscribed_at
|
47
|
+
subscription_text << subscriber_text
|
48
|
+
else
|
49
|
+
subscription_text << trial_text
|
50
|
+
end
|
51
|
+
subscription_text.compact.join("\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
# params:
|
55
|
+
# - stripe_token
|
56
|
+
# - stripe_email
|
57
|
+
# - subscription_plan_id
|
58
|
+
def subscribe!(params)
|
59
|
+
raise Errors::AlreadySubscribedError if subscribed?
|
60
|
+
raise Errors::StripeCustomerExistsError if stripe_customer_id
|
61
|
+
|
62
|
+
customer = ::Stripe::Customer.create(
|
63
|
+
source: params[:stripe_token],
|
64
|
+
plan: params[:subscription_plan_id] || SlackRubyBotServer::Stripe.config.subscription_plan_id,
|
65
|
+
email: params[:stripe_email],
|
66
|
+
metadata: {
|
67
|
+
id: id,
|
68
|
+
team_id: team_id,
|
69
|
+
name: name,
|
70
|
+
domain: domain
|
71
|
+
}
|
72
|
+
)
|
73
|
+
|
74
|
+
update_attributes!(
|
75
|
+
subscribed: true,
|
76
|
+
subscribed_at: Time.now.utc,
|
77
|
+
stripe_customer_id: customer['id'],
|
78
|
+
subscription_expired_at: nil,
|
79
|
+
subscription_past_due_at: nil,
|
80
|
+
subscription_past_due_informed_at: nil
|
81
|
+
)
|
82
|
+
|
83
|
+
customer
|
84
|
+
end
|
85
|
+
|
86
|
+
# params:
|
87
|
+
# - stripe_token
|
88
|
+
def update_subscription!(params)
|
89
|
+
raise Errors::NotSubscribedError unless subscribed?
|
90
|
+
raise Errors::MissingStripeCustomerError unless active_stripe_subscription?
|
91
|
+
|
92
|
+
stripe_customer.source = params[:stripe_token]
|
93
|
+
stripe_customer.save
|
94
|
+
|
95
|
+
stripe_customer
|
96
|
+
end
|
97
|
+
|
98
|
+
def unsubscribe!
|
99
|
+
raise Errors::NotSubscribedError unless subscribed?
|
100
|
+
raise Errors::MissingStripeCustomerError unless active_stripe_subscription?
|
101
|
+
|
102
|
+
run_callbacks :unsubscribed do
|
103
|
+
active_stripe_subscription.delete(at_period_end: true)
|
104
|
+
update_attributes!(subscribed: false, stripe_customer_id: nil)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def active_stripe_subscription?
|
109
|
+
!active_stripe_subscription.nil?
|
110
|
+
end
|
111
|
+
|
112
|
+
def active_stripe_subscription
|
113
|
+
return unless stripe_customer
|
114
|
+
|
115
|
+
stripe_customer.subscriptions.detect do |subscription|
|
116
|
+
subscription.status == 'active' && !subscription.cancel_at_period_end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def trial_ends_at
|
121
|
+
raise Errors::AlreadySubscribedError if subscribed?
|
122
|
+
|
123
|
+
created_at + trial_duration
|
124
|
+
end
|
125
|
+
|
126
|
+
def remaining_trial_days
|
127
|
+
raise Errors::AlreadySubscribedError if subscribed?
|
128
|
+
|
129
|
+
[0, (trial_ends_at.to_date - Time.now.utc.to_date).to_i].max
|
130
|
+
end
|
131
|
+
|
132
|
+
def trial_text
|
133
|
+
raise Errors::AlreadySubscribedError if subscribed?
|
134
|
+
|
135
|
+
[
|
136
|
+
remaining_trial_days.zero? ?
|
137
|
+
'Your trial subscription has expired.' :
|
138
|
+
"Your trial subscription expires in #{remaining_trial_days} day#{remaining_trial_days == 1 ? '' : 's'}.",
|
139
|
+
subscribe_text
|
140
|
+
].join(' ')
|
141
|
+
end
|
142
|
+
|
143
|
+
def unsubscribed_text
|
144
|
+
[
|
145
|
+
'Your team has been unsubscribed.',
|
146
|
+
subscribe_text
|
147
|
+
].join(' ')
|
148
|
+
end
|
149
|
+
|
150
|
+
def subscribed_text
|
151
|
+
'Your team has been subscribed.'
|
152
|
+
end
|
153
|
+
|
154
|
+
def subscription_expired_text
|
155
|
+
[
|
156
|
+
'Your subscription has expired.',
|
157
|
+
subscribe_text
|
158
|
+
].join(' ')
|
159
|
+
end
|
160
|
+
|
161
|
+
def subscription_past_due_text
|
162
|
+
[
|
163
|
+
'Your subscription is past due.',
|
164
|
+
update_cc_text
|
165
|
+
].join(' ')
|
166
|
+
end
|
167
|
+
|
168
|
+
def check_trial!
|
169
|
+
raise Errors::AlreadySubscribedError if subscribed?
|
170
|
+
return if remaining_trial_days > 3
|
171
|
+
|
172
|
+
trial_expiring!
|
173
|
+
end
|
174
|
+
|
175
|
+
def check_subscription!
|
176
|
+
raise Errors::NotSubscribedError unless subscribed?
|
177
|
+
raise Errors::MissingStripeCustomerError unless stripe_customer
|
178
|
+
|
179
|
+
stripe_customer.subscriptions.each do |subscription|
|
180
|
+
case subscription.status
|
181
|
+
when 'past_due'
|
182
|
+
subscription_past_due!
|
183
|
+
when 'canceled', 'unpaid'
|
184
|
+
subscription_expired!
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def check_stripe!
|
190
|
+
if subscribed? && active_stripe_subscription?
|
191
|
+
check_subscription!
|
192
|
+
elsif !subscribed?
|
193
|
+
check_trial!
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
private
|
198
|
+
|
199
|
+
def subscription_past_due!
|
200
|
+
return unless subscribed?
|
201
|
+
return if subscription_past_due_at && (Time.now.utc < subscription_past_due_informed_at + 3.days)
|
202
|
+
|
203
|
+
run_callbacks :subscription_past_due do
|
204
|
+
# use subscription_past_due_text to tell users to update their cc
|
205
|
+
update_attributes!(
|
206
|
+
subscription_past_due_at: subscription_past_due_at || Time.now.utc,
|
207
|
+
subscription_past_due_informed_at: Time.now.utc
|
208
|
+
)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def subscription_expired!
|
213
|
+
return if subscription_expired_at
|
214
|
+
|
215
|
+
run_callbacks :subscription_expired do
|
216
|
+
# use subscribe_text to tell users to (re)subscribe
|
217
|
+
update_attributes!(
|
218
|
+
subscribed: false,
|
219
|
+
subscription_expired_at: Time.now.utc
|
220
|
+
)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def update_cc_text
|
225
|
+
"Update your credit card info at #{root_url}/subscribe?team_id=#{team_id}."
|
226
|
+
end
|
227
|
+
|
228
|
+
def trial_expiring!
|
229
|
+
return false if subscribed? || subscription_expired?
|
230
|
+
return false if trial_informed_at && (Time.now.utc < trial_informed_at + 7.days)
|
231
|
+
|
232
|
+
run_callbacks :trial_expiring do
|
233
|
+
# use trial_text to inform users
|
234
|
+
update_attributes!(trial_informed_at: Time.now.utc)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def stripe_customer
|
239
|
+
return unless stripe_customer_id
|
240
|
+
|
241
|
+
@stripe_customer ||= ::Stripe::Customer.retrieve(stripe_customer_id)
|
242
|
+
end
|
243
|
+
|
244
|
+
def stripe_customer_text
|
245
|
+
"Customer since #{Time.at(stripe_customer.created).strftime('%B %d, %Y')}."
|
246
|
+
end
|
247
|
+
|
248
|
+
def subscriber_text
|
249
|
+
return unless subscribed_at
|
250
|
+
|
251
|
+
"Subscriber since #{subscribed_at.strftime('%B %d, %Y')}."
|
252
|
+
end
|
253
|
+
|
254
|
+
unless respond_to?(:subscribe_text)
|
255
|
+
def subscribe_text
|
256
|
+
"Subscribe your team at #{root_url}/subscribe?team_id=#{team_id}."
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def trial_duration
|
261
|
+
SlackRubyBotServer::Stripe.config.trial_duration
|
262
|
+
end
|
263
|
+
|
264
|
+
def root_url
|
265
|
+
SlackRubyBotServer::Stripe.config.root_url
|
266
|
+
end
|
267
|
+
|
268
|
+
def stripe_customer_subscriptions_info
|
269
|
+
stripe_customer.subscriptions.map do |subscription|
|
270
|
+
amount = ActiveSupport::NumberHelper.number_to_currency(subscription.plan.amount.to_f / 100)
|
271
|
+
current_period_end = Time.at(subscription.current_period_end).strftime('%B %d, %Y')
|
272
|
+
"Subscribed to #{subscription.plan.name} (#{amount}), will#{subscription.cancel_at_period_end ? ' not' : ''} auto-renew on #{current_period_end}."
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def stripe_auto_renew?
|
277
|
+
stripe_customer.subscriptions.any? do |subscription|
|
278
|
+
!subscription.cancel_at_period_end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def stripe_customer_invoices_info
|
283
|
+
stripe_customer.invoices.map do |invoice|
|
284
|
+
amount = ActiveSupport::NumberHelper.number_to_currency(invoice.amount_due.to_f / 100)
|
285
|
+
"Invoice for #{amount} on #{Time.at(invoice.date).strftime('%B %d, %Y')}, #{invoice.paid ? 'paid' : 'unpaid'}."
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def stripe_customer_sources_info
|
290
|
+
stripe_customer.sources.map do |source|
|
291
|
+
"On file #{source.brand} #{source.object}, #{source.name} ending with #{source.last4}, expires #{source.exp_month}/#{source.exp_year}."
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def subscribed!
|
296
|
+
return unless subscribed? && subscribed_changed?
|
297
|
+
|
298
|
+
run_callbacks :subscribed do
|
299
|
+
# use subscribed_text to inform users
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def update_subscribed_at
|
304
|
+
return unless subscribed? && subscribed_changed?
|
305
|
+
|
306
|
+
self.subscribed_at = subscribed? ? DateTime.now.utc : nil
|
307
|
+
end
|
308
|
+
|
309
|
+
def update_subscription_expired_at
|
310
|
+
return unless subscribed? && subscription_expired_at?
|
311
|
+
|
312
|
+
self.subscription_expired_at = nil
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|