reji 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +73 -0
- data/.rubocop_todo.yml +31 -0
- data/Appraisals +2 -0
- data/Gemfile +1 -1
- data/README.md +41 -17
- data/Rakefile +8 -2
- data/app/controllers/reji/payment_controller.rb +4 -4
- data/app/controllers/reji/webhook_controller.rb +51 -62
- data/app/views/payment.html.erb +4 -4
- data/app/views/receipt.html.erb +16 -16
- data/config/routes.rb +2 -0
- data/gemfiles/rails_5.0.gemfile +9 -9
- data/gemfiles/rails_5.1.gemfile +7 -9
- data/gemfiles/rails_5.2.gemfile +7 -9
- data/gemfiles/rails_6.0.gemfile +7 -9
- data/lib/generators/reji/install/install_generator.rb +20 -24
- data/lib/generators/reji/install/templates/reji.rb +2 -2
- data/lib/reji.rb +12 -8
- data/lib/reji/concerns/manages_customer.rb +25 -29
- data/lib/reji/concerns/manages_invoices.rb +37 -44
- data/lib/reji/concerns/manages_payment_methods.rb +45 -62
- data/lib/reji/concerns/manages_subscriptions.rb +13 -13
- data/lib/reji/concerns/performs_charges.rb +7 -7
- data/lib/reji/concerns/prorates.rb +1 -1
- data/lib/reji/configuration.rb +2 -2
- data/lib/reji/engine.rb +2 -0
- data/lib/reji/errors.rb +9 -9
- data/lib/reji/invoice.rb +57 -56
- data/lib/reji/invoice_line_item.rb +21 -23
- data/lib/reji/payment.rb +9 -5
- data/lib/reji/payment_method.rb +8 -4
- data/lib/reji/subscription.rb +165 -183
- data/lib/reji/subscription_builder.rb +41 -49
- data/lib/reji/subscription_item.rb +26 -26
- data/lib/reji/tax.rb +8 -10
- data/lib/reji/version.rb +1 -1
- data/reji.gemspec +5 -4
- data/spec/dummy/app/models/user.rb +3 -7
- data/spec/dummy/application.rb +3 -7
- data/spec/dummy/db/schema.rb +3 -4
- data/spec/feature/charges_spec.rb +1 -1
- data/spec/feature/customer_spec.rb +1 -1
- data/spec/feature/invoices_spec.rb +6 -6
- data/spec/feature/multiplan_subscriptions_spec.rb +51 -53
- data/spec/feature/payment_methods_spec.rb +25 -25
- data/spec/feature/pending_updates_spec.rb +26 -26
- data/spec/feature/subscriptions_spec.rb +78 -78
- data/spec/feature/webhooks_spec.rb +72 -72
- data/spec/spec_helper.rb +2 -2
- data/spec/support/feature_helpers.rb +6 -12
- data/spec/unit/customer_spec.rb +13 -13
- data/spec/unit/invoice_line_item_spec.rb +12 -14
- data/spec/unit/invoice_spec.rb +7 -9
- data/spec/unit/payment_spec.rb +3 -3
- data/spec/unit/subscription_spec.rb +29 -30
- metadata +26 -11
- data/Gemfile.lock +0 -133
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0fd54bad11be59354691fc0b267467a58817b3a45a1d1ff8a24ae373166bdb4
|
4
|
+
data.tar.gz: a42de1cba650a26285bd724cecb7eb45a8e8b26d9f0348e0c196714458df7abc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a9a5fa9844145bce066224e36ec817cea037a347816a1c87912b00ac75f32e8a19b186b5eb51cecfcf1673637fb8ce6d9a9a09102498b120fdea300f91dab86
|
7
|
+
data.tar.gz: ab820509b28366cf40545d2bc0ede969fef9f301e82e03fc49ec8c0c98e8b5014ab9bb2c254ecd01720e73c75f03969ee9e997c34dbbbff41ead1799c1d837e0
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
require: rubocop-rails
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
DisplayCopNames: true
|
7
|
+
TargetRubyVersion: 2.4
|
8
|
+
|
9
|
+
Layout/CaseIndentation:
|
10
|
+
EnforcedStyle: end
|
11
|
+
IndentOneStep: true
|
12
|
+
|
13
|
+
Layout/EmptyComment:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Layout/FirstArrayElementIndentation:
|
17
|
+
EnforcedStyle: consistent
|
18
|
+
|
19
|
+
Layout/FirstHashElementIndentation:
|
20
|
+
EnforcedStyle: consistent
|
21
|
+
|
22
|
+
Layout/LineLength:
|
23
|
+
Exclude:
|
24
|
+
- "spec/**/*.rb"
|
25
|
+
|
26
|
+
Layout/MultilineMethodCallIndentation:
|
27
|
+
EnforcedStyle: indented
|
28
|
+
|
29
|
+
Metrics/BlockLength:
|
30
|
+
Max: 40
|
31
|
+
Exclude:
|
32
|
+
# `context` in tests are blocks and get quite large, so exclude the test
|
33
|
+
# directory from having to adhere to this rule.
|
34
|
+
- "spec/**/*.rb"
|
35
|
+
|
36
|
+
Metrics/ClassLength:
|
37
|
+
Exclude:
|
38
|
+
# Test classes get quite large, so exclude the test directory from having
|
39
|
+
# to adhere to this rule.
|
40
|
+
- "spec/**/*.rb"
|
41
|
+
|
42
|
+
Metrics/MethodLength:
|
43
|
+
Max: 24
|
44
|
+
|
45
|
+
Metrics/ModuleLength:
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
Naming/AccessorMethodName:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
Style/AccessModifierDeclarations:
|
52
|
+
EnforcedStyle: inline
|
53
|
+
|
54
|
+
Style/HashEachMethods:
|
55
|
+
Enabled: true
|
56
|
+
|
57
|
+
Style/NumericPredicate:
|
58
|
+
Enabled: false
|
59
|
+
|
60
|
+
Style/TrailingCommaInArrayLiteral:
|
61
|
+
EnforcedStyleForMultiline: consistent_comma
|
62
|
+
|
63
|
+
Style/TrailingCommaInHashLiteral:
|
64
|
+
EnforcedStyleForMultiline: consistent_comma
|
65
|
+
|
66
|
+
Rails/ApplicationController:
|
67
|
+
Enabled: false
|
68
|
+
|
69
|
+
Rails/ApplicationRecord:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
Rails/ReflectionClassName:
|
73
|
+
Enabled: false
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2020-09-10 04:54:51 UTC using RuboCop version 0.90.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 6
|
10
|
+
# Configuration parameters: IgnoredMethods.
|
11
|
+
Metrics/AbcSize:
|
12
|
+
Max: 66
|
13
|
+
|
14
|
+
# Offense count: 3
|
15
|
+
# Configuration parameters: CountComments, CountAsOne.
|
16
|
+
Metrics/ClassLength:
|
17
|
+
Max: 349
|
18
|
+
|
19
|
+
# Offense count: 1
|
20
|
+
# Configuration parameters: IgnoredMethods.
|
21
|
+
Metrics/CyclomaticComplexity:
|
22
|
+
Max: 15
|
23
|
+
|
24
|
+
# Offense count: 1
|
25
|
+
# Configuration parameters: IgnoredMethods.
|
26
|
+
Metrics/PerceivedComplexity:
|
27
|
+
Max: 16
|
28
|
+
|
29
|
+
# Offense count: 30
|
30
|
+
Style/Documentation:
|
31
|
+
Enabled: false
|
data/Appraisals
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -95,6 +95,29 @@ rails db:migrate
|
|
95
95
|
<a name="configuration"></a>
|
96
96
|
## Configuration
|
97
97
|
|
98
|
+
All Reji configuration can be found in `config/initializers/reji.rb` file. You can change directly or update corresponding environment variables.
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
Reji.configure do |config|
|
102
|
+
# Stripe Keys
|
103
|
+
config.key = ENV['STRIPE_KEY']
|
104
|
+
config.secret = ENV['STRIPE_SECRET']
|
105
|
+
|
106
|
+
# Stripe Webhooks
|
107
|
+
config.webhook = {
|
108
|
+
secret: ENV['STRIPE_WEBHOOK_SECRET'],
|
109
|
+
tolerance: ENV['STRIPE_WEBHOOK_TOLERANCE'] || 300,
|
110
|
+
}
|
111
|
+
|
112
|
+
# Reji Model
|
113
|
+
config.model = ENV['REJI_MODEL'] || 'User'
|
114
|
+
config.model_id = ENV['REJI_MODEL_ID'] || 'user_id'
|
115
|
+
|
116
|
+
# Currency
|
117
|
+
config.currency = ENV['REJI_CURRENCY'] || 'usd'
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
98
121
|
<a name="billable-model"></a>
|
99
122
|
### Billable Model
|
100
123
|
|
@@ -110,6 +133,7 @@ Reji assumes your Billable model will be the `User` class. If you wish to change
|
|
110
133
|
|
111
134
|
```sh
|
112
135
|
REJI_MODEL=User
|
136
|
+
REJI_MODEL_ID=user_id
|
113
137
|
```
|
114
138
|
|
115
139
|
> If you're using a model other than `User` model, you'll need to publish and alter the [migrations](#installation) provided to match your alternative model's table name.
|
@@ -380,18 +404,18 @@ payment_method = user.find_payment_method(payment_method_id)
|
|
380
404
|
<a name="check-for-a-payment-method"></a>
|
381
405
|
### Determining If A User Has A Payment Method
|
382
406
|
|
383
|
-
To determine if a Billable model has a default payment method attached to their account, use the `
|
407
|
+
To determine if a Billable model has a default payment method attached to their account, use the `default_payment_method?` method:
|
384
408
|
|
385
409
|
```ruby
|
386
|
-
if user.
|
410
|
+
if user.default_payment_method?
|
387
411
|
#
|
388
412
|
end
|
389
413
|
```
|
390
414
|
|
391
|
-
To determine if a Billable model has at least one payment method attached to their account, use the `
|
415
|
+
To determine if a Billable model has at least one payment method attached to their account, use the `payment_method?` method:
|
392
416
|
|
393
417
|
```ruby
|
394
|
-
if user.
|
418
|
+
if user.payment_method?
|
395
419
|
#
|
396
420
|
end
|
397
421
|
```
|
@@ -605,14 +629,14 @@ Reji::Subscription.recurring
|
|
605
629
|
|
606
630
|
If a subscription requires a secondary payment action after creation the subscription will be marked as `incomplete`. Subscription statuses are stored in the `stripe_status` column of Reji's `subscriptions` database table.
|
607
631
|
|
608
|
-
Similarly, if a secondary payment action is required when swapping plans the subscription will be marked as `past_due`. When your subscription is in either of these states it will not be active until the customer has confirmed their payment. Checking if a subscription has an incomplete payment can be done using the `
|
632
|
+
Similarly, if a secondary payment action is required when swapping plans the subscription will be marked as `past_due`. When your subscription is in either of these states it will not be active until the customer has confirmed their payment. Checking if a subscription has an incomplete payment can be done using the `incomplete_payment?` method on the Billable model or a subscription instance:
|
609
633
|
|
610
634
|
```ruby
|
611
|
-
if user.
|
635
|
+
if user.incomplete_payment?('default')
|
612
636
|
#
|
613
637
|
end
|
614
638
|
|
615
|
-
if user.subscription('default').
|
639
|
+
if user.subscription('default').incomplete_payment?
|
616
640
|
#
|
617
641
|
end
|
618
642
|
```
|
@@ -846,9 +870,9 @@ The `tax_rates` method enables you to apply a tax rate on a model-by-model basis
|
|
846
870
|
|
847
871
|
```ruby
|
848
872
|
def plan_tax_rates
|
849
|
-
|
873
|
+
{
|
850
874
|
'plan-id' => ['tax-rate-id'],
|
851
|
-
|
875
|
+
}
|
852
876
|
end
|
853
877
|
```
|
854
878
|
|
@@ -866,12 +890,12 @@ This will also sync any subscription item tax rates so make sure you also proper
|
|
866
890
|
|
867
891
|
#### Tax Exemption
|
868
892
|
|
869
|
-
Reji also offers methods to determine if the customer is tax exempt by calling the Stripe API. The `
|
893
|
+
Reji also offers methods to determine if the customer is tax exempt by calling the Stripe API. The `not_tax_exempt?`, `tax_exempt?`, and `reverse_charge_applies` methods are available on the billable model:
|
870
894
|
|
871
895
|
```ruby
|
872
896
|
user = User.find(1)
|
873
|
-
user.
|
874
|
-
user.
|
897
|
+
user.tax_exempt?
|
898
|
+
user.not_tax_exempt?
|
875
899
|
user.reverse_charge_applies
|
876
900
|
```
|
877
901
|
|
@@ -885,7 +909,7 @@ By default, the billing cycle anchor is the date the subscription was created, o
|
|
885
909
|
```ruby
|
886
910
|
user = User.find(1)
|
887
911
|
|
888
|
-
anchor = Time.
|
912
|
+
anchor = Time.current.at_beginning_of_month.next_month
|
889
913
|
|
890
914
|
user.new_subscription('default', 'price_premium')
|
891
915
|
.anchor_billing_cycle_on(anchor.to_i)
|
@@ -953,7 +977,7 @@ The `trial_until` method allows you to provide a `Time` instance to specify when
|
|
953
977
|
|
954
978
|
```ruby
|
955
979
|
user.new_subscription('default', 'price_monthly')
|
956
|
-
.trial_until(Time.
|
980
|
+
.trial_until(Time.current + 10.days)
|
957
981
|
.create(payment_method)
|
958
982
|
```
|
959
983
|
|
@@ -981,7 +1005,7 @@ If you would like to offer trial periods without collecting the user's payment m
|
|
981
1005
|
```ruby
|
982
1006
|
user = User.create({
|
983
1007
|
# Populate other user properties...
|
984
|
-
:trial_ends_at => Time.
|
1008
|
+
:trial_ends_at => Time.current + 10.days,
|
985
1009
|
})
|
986
1010
|
```
|
987
1011
|
|
@@ -1016,12 +1040,12 @@ The `extend_trial` method allows you to extend the trial period of a subscriptio
|
|
1016
1040
|
```ruby
|
1017
1041
|
# End the trial 7 days from now...
|
1018
1042
|
subscription.extend_trial(
|
1019
|
-
Time.
|
1043
|
+
Time.current + 7.days
|
1020
1044
|
)
|
1021
1045
|
|
1022
1046
|
# Add an additional 5 days to the trial...
|
1023
1047
|
subscription.extend_trial(
|
1024
|
-
Time.at(subscription.trial_ends_at) + 5.days
|
1048
|
+
Time.zone.at(subscription.trial_ends_at) + 5.days
|
1025
1049
|
)
|
1026
1050
|
```
|
1027
1051
|
|
data/Rakefile
CHANGED
@@ -17,5 +17,11 @@ RSpec::Core::RakeTask.new('spec') do |task|
|
|
17
17
|
task.verbose = false
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
require 'rubocop/rake_task'
|
21
|
+
|
22
|
+
RuboCop::RakeTask.new do |task|
|
23
|
+
task.requires << 'rubocop-rails'
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Run the specs and rubocop'
|
27
|
+
task default: %i[spec rubocop]
|
@@ -18,14 +18,14 @@ module Reji
|
|
18
18
|
render template: 'payment'
|
19
19
|
end
|
20
20
|
|
21
|
-
private
|
22
|
-
|
23
|
-
def verify_redirect_url
|
21
|
+
private def verify_redirect_url
|
24
22
|
return if params[:redirect].blank?
|
25
23
|
|
26
24
|
url = URI(params[:redirect])
|
27
25
|
|
28
|
-
|
26
|
+
return unless url.host.blank? || url.host != URI(request.original_url).host
|
27
|
+
|
28
|
+
raise ActionController::Forbidden, 'Redirect host mismatch.'
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -9,26 +9,23 @@ module Reji
|
|
9
9
|
|
10
10
|
type = payload['type']
|
11
11
|
|
12
|
-
return
|
12
|
+
return missing_method if type.nil?
|
13
13
|
|
14
14
|
method = "handle_#{payload['type'].gsub('.', '_')}"
|
15
15
|
|
16
|
-
|
17
|
-
self.send(method, payload) :
|
18
|
-
self.missing_method
|
16
|
+
respond_to?(method, true) ? send(method, payload) : missing_method
|
19
17
|
end
|
20
18
|
|
21
|
-
protected
|
22
|
-
|
23
19
|
# Handle customer subscription updated.
|
24
|
-
|
25
|
-
|
20
|
+
# rubocop:disable Metrics/MethodLength
|
21
|
+
protected def handle_customer_subscription_updated(payload)
|
22
|
+
user = get_user_by_stripe_id(payload.dig('data', 'object', 'customer'))
|
26
23
|
|
27
|
-
return
|
24
|
+
return success_method if user.nil?
|
28
25
|
|
29
26
|
data = payload.dig('data', 'object')
|
30
27
|
|
31
|
-
return
|
28
|
+
return success_method if data.nil?
|
32
29
|
|
33
30
|
user.subscriptions
|
34
31
|
.select { |subscription| subscription.stripe_id == data['id'] }
|
@@ -37,7 +34,7 @@ module Reji
|
|
37
34
|
subscription.items.destroy_all
|
38
35
|
subscription.destroy
|
39
36
|
|
40
|
-
return
|
37
|
+
return success_method
|
41
38
|
end
|
42
39
|
|
43
40
|
# Plan...
|
@@ -47,123 +44,115 @@ module Reji
|
|
47
44
|
subscription.quantity = data['quantity']
|
48
45
|
|
49
46
|
# Trial ending date...
|
50
|
-
|
47
|
+
if data['trial_end'].present?
|
51
48
|
if subscription.trial_ends_at.nil? || subscription.trial_ends_at.to_i != data['trial_end']
|
52
|
-
subscription.trial_ends_at = Time.at(data['trial_end'])
|
49
|
+
subscription.trial_ends_at = Time.zone.at(data['trial_end'])
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
56
53
|
# Cancellation date...
|
57
|
-
|
58
|
-
if data['cancel_at_period_end']
|
59
|
-
|
60
|
-
subscription.trial_ends_at :
|
61
|
-
Time.at(data['cancel_at_period_end'])
|
54
|
+
subscription.ends_at =
|
55
|
+
if data['cancel_at_period_end'].blank?
|
56
|
+
nil
|
62
57
|
else
|
63
|
-
subscription.
|
58
|
+
(subscription.on_trial ? subscription.trial_ends_at : Time.zone.at(data['cancel_at_period_end']))
|
64
59
|
end
|
65
|
-
end
|
66
60
|
|
67
61
|
# Status...
|
68
|
-
unless data['status'].nil?
|
69
|
-
subscription.stripe_status = data['status']
|
70
|
-
end
|
62
|
+
subscription.stripe_status = data['status'] unless data['status'].nil?
|
71
63
|
|
72
64
|
subscription.save
|
73
65
|
|
74
66
|
# Update subscription items...
|
75
|
-
|
76
|
-
plans = []
|
67
|
+
next unless data.key?('items')
|
77
68
|
|
78
|
-
|
69
|
+
plans = []
|
79
70
|
|
80
|
-
|
81
|
-
items.each do |item|
|
82
|
-
plans << item.dig('plan', 'id')
|
71
|
+
items = data.dig('items', 'data') || []
|
83
72
|
|
84
|
-
|
85
|
-
|
86
|
-
subscription_item.quantity = item['quantity']
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
73
|
+
items.each do |item|
|
74
|
+
plans << item.dig('plan', 'id')
|
90
75
|
|
91
|
-
|
92
|
-
|
76
|
+
subscription.items.find_or_create_by({ stripe_id: item['id'] }) do |subscription_item|
|
77
|
+
subscription_item.stripe_plan = item.dig('plan', 'id')
|
78
|
+
subscription_item.quantity = item['quantity']
|
79
|
+
end
|
93
80
|
end
|
81
|
+
|
82
|
+
# Delete items that aren't attached to the subscription anymore...
|
83
|
+
subscription.items.where('stripe_plan NOT IN (?)', plans).destroy_all
|
94
84
|
end
|
95
85
|
|
96
|
-
|
86
|
+
success_method
|
97
87
|
end
|
88
|
+
# rubocop:enable Metrics/MethodLength
|
98
89
|
|
99
90
|
# Handle a cancelled customer from a Stripe subscription.
|
100
|
-
def handle_customer_subscription_deleted(payload)
|
101
|
-
user =
|
91
|
+
protected def handle_customer_subscription_deleted(payload)
|
92
|
+
user = get_user_by_stripe_id(payload.dig('data', 'object', 'customer'))
|
102
93
|
|
103
94
|
unless user.nil?
|
104
95
|
user.subscriptions
|
105
96
|
.select { |subscription| subscription.stripe_id == payload.dig('data', 'object', 'id') }
|
106
|
-
.each
|
97
|
+
.each(&:mark_as_cancelled)
|
107
98
|
end
|
108
99
|
|
109
|
-
|
100
|
+
success_method
|
110
101
|
end
|
111
102
|
|
112
103
|
# Handle customer updated.
|
113
|
-
def handle_customer_updated(payload)
|
114
|
-
user =
|
104
|
+
protected def handle_customer_updated(payload)
|
105
|
+
user = get_user_by_stripe_id(payload.dig('data', 'object', 'id'))
|
115
106
|
|
116
|
-
user
|
107
|
+
user&.update_default_payment_method_from_stripe
|
117
108
|
|
118
|
-
|
109
|
+
success_method
|
119
110
|
end
|
120
111
|
|
121
112
|
# Handle deleted customer.
|
122
|
-
def handle_customer_deleted(payload)
|
123
|
-
user =
|
113
|
+
protected def handle_customer_deleted(payload)
|
114
|
+
user = get_user_by_stripe_id(payload.dig('data', 'object', 'id'))
|
124
115
|
|
125
116
|
unless user.nil?
|
126
117
|
user.subscriptions.each { |subscription| subscription.skip_trial.mark_as_cancelled }
|
127
118
|
|
128
119
|
user.update({
|
129
|
-
:
|
130
|
-
:
|
131
|
-
:
|
132
|
-
:
|
120
|
+
stripe_id: nil,
|
121
|
+
trial_ends_at: nil,
|
122
|
+
card_brand: nil,
|
123
|
+
card_last_four: nil,
|
133
124
|
})
|
134
125
|
end
|
135
126
|
|
136
|
-
|
127
|
+
success_method
|
137
128
|
end
|
138
129
|
|
139
130
|
# Get the billable entity instance by Stripe ID.
|
140
|
-
def get_user_by_stripe_id(stripe_id)
|
131
|
+
protected def get_user_by_stripe_id(stripe_id)
|
141
132
|
Reji.find_billable(stripe_id)
|
142
133
|
end
|
143
134
|
|
144
135
|
# Handle successful calls on the controller.
|
145
|
-
def success_method
|
146
|
-
render plain: 'Webhook Handled', status:
|
136
|
+
protected def success_method
|
137
|
+
render plain: 'Webhook Handled', status: :ok
|
147
138
|
end
|
148
139
|
|
149
140
|
# Handle calls to missing methods on the controller.
|
150
|
-
def missing_method
|
141
|
+
protected def missing_method
|
151
142
|
head :ok
|
152
143
|
end
|
153
144
|
|
154
|
-
|
155
|
-
|
156
|
-
def verify_webhook_signature
|
145
|
+
protected def verify_webhook_signature
|
157
146
|
return if Reji.configuration.webhook[:secret].blank?
|
158
147
|
|
159
148
|
begin
|
160
149
|
Stripe::Webhook.construct_event(
|
161
150
|
request.body.read,
|
162
151
|
request.env['HTTP_STRIPE_SIGNATURE'],
|
163
|
-
Reji.configuration.webhook[:secret]
|
152
|
+
Reji.configuration.webhook[:secret]
|
164
153
|
)
|
165
154
|
rescue Stripe::SignatureVerificationError => e
|
166
|
-
raise AccessDeniedHttpError
|
155
|
+
raise AccessDeniedHttpError, e.message
|
167
156
|
end
|
168
157
|
end
|
169
158
|
end
|