tang 0.2.2 → 0.2.4
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 +4 -4
- data/Rakefile +3 -3
- data/app/controllers/tang/account/application_controller.rb +2 -4
- data/app/controllers/tang/account/cards_controller.rb +11 -8
- data/app/controllers/tang/account/coupons_controller.rb +1 -1
- data/app/controllers/tang/account/receipts_controller.rb +10 -4
- data/app/controllers/tang/account/subscriptions_controller.rb +11 -8
- data/app/controllers/tang/admin/application_controller.rb +4 -4
- data/app/controllers/tang/admin/coupons_controller.rb +18 -14
- data/app/controllers/tang/admin/customers_controller.rb +16 -16
- data/app/controllers/tang/admin/dashboard_controller.rb +1 -1
- data/app/controllers/tang/admin/invoices_controller.rb +6 -6
- data/app/controllers/tang/admin/payments_controller.rb +9 -9
- data/app/controllers/tang/admin/plans_controller.rb +21 -19
- data/app/controllers/tang/admin/search_controller.rb +15 -14
- data/app/controllers/tang/admin/subscriptions_controller.rb +16 -17
- data/app/controllers/tang/plans_controller.rb +1 -1
- data/app/helpers/tang/application_helper.rb +22 -28
- data/app/jobs/tang/import_charges_job.rb +4 -8
- data/app/jobs/tang/import_coupons_job.rb +3 -3
- data/app/jobs/tang/import_customers_job.rb +15 -13
- data/app/jobs/tang/import_invoices_job.rb +7 -7
- data/app/jobs/tang/import_plans_job.rb +4 -6
- data/app/jobs/tang/import_subscriptions_job.rb +4 -4
- data/app/mailers/application_mailer.rb +1 -1
- data/app/mailers/tang/stripe_mailer.rb +8 -9
- data/app/mailers/tang/subscription_mailer.rb +4 -1
- data/app/models/concerns/tang/customer.rb +32 -32
- data/app/models/tang/card.rb +7 -8
- data/app/models/tang/charge.rb +28 -50
- data/app/models/tang/coupon.rb +27 -25
- data/app/models/tang/invoice.rb +16 -17
- data/app/models/tang/invoice_item.rb +16 -18
- data/app/models/tang/plan.rb +31 -16
- data/app/models/tang/subscription.rb +34 -42
- data/app/services/tang/apply_customer_discount.rb +2 -2
- data/app/services/tang/apply_subscription_discount.rb +2 -2
- data/app/services/tang/cancel_subscription.rb +2 -2
- data/app/services/tang/change_subscription.rb +4 -4
- data/app/services/tang/create_coupon.rb +3 -5
- data/app/services/tang/create_invoice.rb +2 -2
- data/app/services/tang/create_plan.rb +9 -8
- data/app/services/tang/create_subscription.rb +18 -15
- data/app/services/tang/delete_card.rb +3 -3
- data/app/services/tang/delete_coupon.rb +3 -3
- data/app/services/tang/delete_customer.rb +2 -2
- data/app/services/tang/delete_plan.rb +2 -2
- data/app/services/tang/fail_invoice.rb +5 -6
- data/app/services/tang/pay_invoice.rb +2 -3
- data/app/services/tang/refresh_invoice_pdf.rb +9 -0
- data/app/services/tang/remove_customer_discount.rb +2 -2
- data/app/services/tang/remove_subscription_discount.rb +3 -3
- data/app/services/tang/save_card.rb +8 -9
- data/app/services/tang/update_coupon.rb +3 -5
- data/app/services/tang/update_customer.rb +4 -4
- data/app/services/tang/update_plan.rb +3 -5
- data/app/services/tang/update_subscription.rb +3 -5
- data/app/validators/future_validator.rb +4 -4
- data/app/views/tang/account/cards/show.html.erb +1 -1
- data/app/views/tang/account/receipts/_receipt.html.erb +1 -1
- data/app/views/tang/account/subscriptions/show.html.erb +14 -3
- data/app/views/tang/admin/coupons/show.html.erb +1 -1
- data/app/views/tang/admin/customers/show.html.erb +2 -2
- data/app/views/tang/admin/plans/show.html.erb +1 -1
- data/app/views/tang/admin/subscriptions/show.html.erb +2 -2
- data/app/views/tang/plans/index.html.erb +1 -1
- data/config/initializers/stripe.rb +2 -2
- data/config/initializers/stripe_event.rb +38 -33
- data/config/routes.rb +3 -1
- data/db/migrate/20160928154410_create_versions.rb +4 -4
- data/db/migrate/20160928161623_create_tang_stripe_webhooks.rb +1 -1
- data/db/migrate/20160928173328_create_tang_plans.rb +1 -1
- data/db/migrate/20160929152510_create_tang_coupons.rb +1 -1
- data/db/migrate/20160929152541_add_customer_fields.rb +1 -1
- data/db/migrate/20160929171640_create_tang_subscriptions.rb +2 -2
- data/db/migrate/20160929174251_create_tang_cards.rb +1 -1
- data/db/migrate/20161003035434_create_tang_invoices.rb +1 -1
- data/db/migrate/20161114181651_create_tang_invoice_items.rb +1 -1
- data/db/migrate/20161115201106_create_tang_charges.rb +1 -1
- data/db/migrate/20170523122759_add_group_to_plans.rb +1 -1
- data/db/migrate/20170701162853_add_stripe_indexes.rb +1 -1
- data/db/migrate/20170731010913_add_subscription_indexes.rb +1 -1
- data/db/migrate/20200827001523_add_invoice_pdf_to_invoices.rb +1 -1
- data/db/migrate/20230530172604_add_enable_customer_emails.rb +6 -0
- data/lib/generators/tang/install_generator.rb +1 -1
- data/lib/generators/templates/create_tang.rb +2 -2
- data/lib/tang/engine.rb +1 -1
- data/lib/tang/version.rb +1 -1
- data/lib/tang.rb +6 -6
- data/lib/tasks/cucumber.rake +50 -51
- data/lib/tasks/tang_tasks.rake +3 -3
- metadata +42 -30
|
@@ -13,17 +13,15 @@ module Tang
|
|
|
13
13
|
validates :currency, presence: true
|
|
14
14
|
|
|
15
15
|
def self.from_stripe(stripe_invoice_item, invoice)
|
|
16
|
-
if stripe_invoice_item.plan.present?
|
|
17
|
-
plan = Plan.find_by(stripe_id: stripe_invoice_item.plan.id)
|
|
18
|
-
end
|
|
16
|
+
plan = Plan.find_by(stripe_id: stripe_invoice_item.plan.id) if stripe_invoice_item.plan.present?
|
|
19
17
|
|
|
20
|
-
if stripe_invoice_item.type == 'subscription'
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
subscription = if stripe_invoice_item.type == 'subscription'
|
|
19
|
+
Subscription.find_by(stripe_id: stripe_invoice_item.id)
|
|
20
|
+
else
|
|
21
|
+
Subscription.find_by(stripe_id: stripe_invoice_item.subscription)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
InvoiceItem.find_or_create_by(stripe_id: stripe_invoice_item.id, invoice: invoice) do |ii|
|
|
27
25
|
ii.amount = stripe_invoice_item.amount
|
|
28
26
|
ii.currency = stripe_invoice_item.currency
|
|
29
27
|
|
|
@@ -36,8 +34,6 @@ module Tang
|
|
|
36
34
|
ii.subscription = subscription
|
|
37
35
|
ii.description = stripe_invoice_item.description
|
|
38
36
|
end
|
|
39
|
-
|
|
40
|
-
return invoice_item
|
|
41
37
|
end
|
|
42
38
|
|
|
43
39
|
def self.search(query)
|
|
@@ -45,13 +41,15 @@ module Tang
|
|
|
45
41
|
if query.present?
|
|
46
42
|
q = "%#{query.downcase}%"
|
|
47
43
|
customer_table = connection.quote_table_name(Customer.table_name)
|
|
48
|
-
invoice_items = InvoiceItem.joins(:customer, :subscription)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
invoice_items = InvoiceItem.joins(:customer, :subscription)
|
|
45
|
+
.where.not(description: nil)
|
|
46
|
+
.where(
|
|
47
|
+
"lower(tang_invoice_items.description) like ? or lower(#{customer_table}.stripe_id) like ? or lower(tang_subscriptions.stripe_id) like ?",
|
|
48
|
+
q, q, q
|
|
49
|
+
)
|
|
50
|
+
.distinct
|
|
53
51
|
end
|
|
54
|
-
|
|
52
|
+
invoice_items
|
|
55
53
|
end
|
|
56
54
|
end
|
|
57
55
|
end
|
data/app/models/tang/plan.rb
CHANGED
|
@@ -10,11 +10,27 @@ module Tang
|
|
|
10
10
|
validates :name, presence: true
|
|
11
11
|
validates :amount, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
12
12
|
validates :currency, length: { is: 3 }
|
|
13
|
-
validates :interval, inclusion: { in: %w
|
|
14
|
-
validates :interval_count, numericality: {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
validates :interval, inclusion: { in: %w[day week month year] }
|
|
14
|
+
validates :interval_count, numericality: {
|
|
15
|
+
only_integer: true,
|
|
16
|
+
greater_than: 0,
|
|
17
|
+
less_than_or_equal_to: 1
|
|
18
|
+
}, allow_nil: true, if: -> { interval == 'year' }
|
|
19
|
+
validates :interval_count, numericality: {
|
|
20
|
+
only_integer: true,
|
|
21
|
+
greater_than: 0,
|
|
22
|
+
less_than_or_equal_to: 12
|
|
23
|
+
}, allow_nil: true, if: -> { interval == 'month' }
|
|
24
|
+
validates :interval_count, numericality: {
|
|
25
|
+
only_integer: true,
|
|
26
|
+
greater_than: 0,
|
|
27
|
+
less_than_or_equal_to: 52
|
|
28
|
+
}, allow_nil: true, if: -> { interval == 'week' }
|
|
29
|
+
validates :interval_count, numericality: {
|
|
30
|
+
only_integer: true,
|
|
31
|
+
greater_than: 0,
|
|
32
|
+
less_than_or_equal_to: 365
|
|
33
|
+
}, allow_nil: true, if: -> { interval == 'day' }
|
|
18
34
|
validates :trial_period_days, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
|
|
19
35
|
validates :statement_descriptor, length: { maximum: 22 }, format: { without: /[<>"']/ }, allow_nil: true
|
|
20
36
|
|
|
@@ -23,17 +39,16 @@ module Tang
|
|
|
23
39
|
before_update :update_stripe_plan
|
|
24
40
|
before_destroy :delete_stripe_plan # should be soft delete
|
|
25
41
|
|
|
26
|
-
INTERVALS = [
|
|
42
|
+
INTERVALS = %w[day week month year].freeze
|
|
27
43
|
|
|
28
44
|
def period_days_from(date)
|
|
29
|
-
if interval == 'week'
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return date + interval_count.days
|
|
45
|
+
return date + interval_count.weeks if interval == 'week'
|
|
46
|
+
|
|
47
|
+
return date + interval_count.months if interval == 'month'
|
|
48
|
+
|
|
49
|
+
return date + interval_count.years if interval == 'year'
|
|
50
|
+
|
|
51
|
+
date + interval_count.days
|
|
37
52
|
end
|
|
38
53
|
|
|
39
54
|
def interval_count
|
|
@@ -43,8 +58,8 @@ module Tang
|
|
|
43
58
|
private
|
|
44
59
|
|
|
45
60
|
def default_values
|
|
46
|
-
self.currency = Tang.default_currency if
|
|
47
|
-
self.order = 0 if
|
|
61
|
+
self.currency = Tang.default_currency if currency.nil?
|
|
62
|
+
self.order = 0 if order.nil?
|
|
48
63
|
end
|
|
49
64
|
|
|
50
65
|
def create_stripe_plan
|
|
@@ -46,7 +46,9 @@ module Tang
|
|
|
46
46
|
before_save :check_for_upgrade
|
|
47
47
|
after_save :handle_upgrade
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
attr_writer :end_trial_now, :upgraded
|
|
50
|
+
|
|
51
|
+
STATUSES = %w[trialing active past_due canceled unpaid].freeze
|
|
50
52
|
|
|
51
53
|
def self.from_stripe(stripe_subscription)
|
|
52
54
|
customer = Tang.customer_class.find_by(stripe_id: stripe_subscription.customer)
|
|
@@ -56,38 +58,35 @@ module Tang
|
|
|
56
58
|
subscription.update(coupon: nil, coupon_start: nil) if stripe_subscription.discount.nil?
|
|
57
59
|
return subscription
|
|
58
60
|
end
|
|
59
|
-
|
|
61
|
+
nil
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
def self.build(stripe_subscription, customer, plan)
|
|
63
|
-
|
|
65
|
+
Subscription.find_or_create_by(stripe_id: stripe_subscription.id) do |s|
|
|
64
66
|
s.customer = customer
|
|
65
67
|
s.plan = plan
|
|
66
68
|
s.application_fee_percent = stripe_subscription.application_fee_percent
|
|
67
69
|
s.quantity = stripe_subscription.quantity
|
|
68
70
|
# s.tax_percent = stripe_subscription.tax_percent # removed from api in favor of tax rates
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
if stripe_subscription.trial_end.present?
|
|
72
|
+
s.trial_end = DateTime.strptime(stripe_subscription.trial_end.to_s, '%s')
|
|
73
|
+
end
|
|
74
|
+
if stripe_subscription.discount.present?
|
|
75
|
+
s.coupon = Coupon.find_by(stripe_id: stripe_subscription.discount.coupon.id)
|
|
76
|
+
end
|
|
71
77
|
s.status = stripe_subscription.status
|
|
72
78
|
end
|
|
73
|
-
return subscription
|
|
74
79
|
end
|
|
75
80
|
|
|
76
81
|
def period_start
|
|
77
82
|
invoice = invoices.order(:date).last
|
|
78
|
-
if invoice.present?
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
end
|
|
82
|
-
return created_at
|
|
83
|
+
return invoice.date if invoice.present?
|
|
84
|
+
|
|
85
|
+
created_at
|
|
83
86
|
end
|
|
84
87
|
|
|
85
88
|
def period_end
|
|
86
|
-
|
|
87
|
-
# if invoice.present?
|
|
88
|
-
# return invoice.period_end
|
|
89
|
-
# end
|
|
90
|
-
return plan.period_days_from(period_start)
|
|
89
|
+
plan.period_days_from(period_start)
|
|
91
90
|
end
|
|
92
91
|
|
|
93
92
|
def quantity
|
|
@@ -95,35 +94,28 @@ module Tang
|
|
|
95
94
|
end
|
|
96
95
|
|
|
97
96
|
def stripe_trial_end
|
|
98
|
-
return 'now' if
|
|
99
|
-
return
|
|
100
|
-
|
|
97
|
+
return 'now' if end_trial_now
|
|
98
|
+
return trial_end.to_i if trial_end.present?
|
|
99
|
+
|
|
100
|
+
nil
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
def end_trial_now
|
|
104
104
|
@end_trial_now || false
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
def end_trial_now=(val)
|
|
108
|
-
@end_trial_now = val
|
|
109
|
-
end
|
|
110
|
-
|
|
111
107
|
def upgraded
|
|
112
108
|
@upgraded || false
|
|
113
109
|
end
|
|
114
110
|
|
|
115
|
-
def upgraded=(val)
|
|
116
|
-
@upgraded = val
|
|
117
|
-
end
|
|
118
|
-
|
|
119
111
|
def discount_for_plan(plan)
|
|
120
112
|
amount_off = 0
|
|
121
|
-
if
|
|
122
|
-
amount_off = (
|
|
123
|
-
elsif
|
|
124
|
-
amount_off =
|
|
113
|
+
if coupon.percent_off.present?
|
|
114
|
+
amount_off = (coupon.percent_off.to_f / 100.0) * plan.amount.to_f
|
|
115
|
+
elsif coupon.amount_off.present?
|
|
116
|
+
amount_off = coupon.amount_off
|
|
125
117
|
end
|
|
126
|
-
|
|
118
|
+
amount_off
|
|
127
119
|
end
|
|
128
120
|
|
|
129
121
|
private
|
|
@@ -133,19 +125,19 @@ module Tang
|
|
|
133
125
|
# end
|
|
134
126
|
|
|
135
127
|
def check_for_upgrade
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
128
|
+
return unless plan_id_changed?
|
|
129
|
+
|
|
130
|
+
old_plan = Plan.find(plan_id_was) if plan_id_was.present?
|
|
131
|
+
self.upgraded = true if old_plan.nil? || old_plan.order < plan.order
|
|
140
132
|
end
|
|
141
133
|
|
|
142
134
|
def handle_upgrade
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
135
|
+
return unless upgraded
|
|
136
|
+
|
|
137
|
+
if Tang.delayed_email
|
|
138
|
+
SubscriptionMailer.upgraded(self).deliver_later
|
|
139
|
+
else
|
|
140
|
+
SubscriptionMailer.upgraded(self).deliver_now
|
|
149
141
|
end
|
|
150
142
|
end
|
|
151
143
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Tang
|
|
2
2
|
class ChangeSubscription
|
|
3
3
|
def self.call(subscription, plan)
|
|
4
|
-
return subscription
|
|
5
|
-
|
|
4
|
+
return subscription unless subscription.valid?
|
|
5
|
+
|
|
6
6
|
begin
|
|
7
7
|
stripe_sub = Stripe::Subscription.retrieve(subscription.stripe_id)
|
|
8
8
|
stripe_sub.plan = plan.stripe_id
|
|
@@ -13,7 +13,7 @@ module Tang
|
|
|
13
13
|
subscription.errors.add(:base, :invalid, message: e.message)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
subscription
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
-
end
|
|
19
|
+
end
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
module Tang
|
|
2
2
|
class CreateCoupon
|
|
3
3
|
def self.call(coupon)
|
|
4
|
-
|
|
5
|
-
return coupon
|
|
6
|
-
end
|
|
4
|
+
return coupon unless coupon.valid?
|
|
7
5
|
|
|
8
6
|
begin
|
|
9
7
|
Stripe::Coupon.create(
|
|
@@ -21,7 +19,7 @@ module Tang
|
|
|
21
19
|
return coupon
|
|
22
20
|
end
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
coupon
|
|
25
23
|
end
|
|
26
24
|
end
|
|
27
|
-
end
|
|
25
|
+
end
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
module Tang
|
|
2
2
|
class CreatePlan
|
|
3
3
|
def self.call(plan)
|
|
4
|
-
|
|
5
|
-
return plan
|
|
6
|
-
end
|
|
4
|
+
return plan unless plan.valid?
|
|
7
5
|
|
|
8
6
|
begin
|
|
7
|
+
stripe_product = Stripe::Product.create({ name: plan.name, type: 'service' })
|
|
8
|
+
|
|
9
9
|
Stripe::Plan.create(
|
|
10
10
|
id: plan.stripe_id,
|
|
11
|
-
name: plan.name,
|
|
11
|
+
# name: plan.name,
|
|
12
|
+
product: stripe_product.id,
|
|
12
13
|
currency: plan.currency,
|
|
13
14
|
amount: plan.amount,
|
|
14
15
|
interval: plan.interval,
|
|
15
16
|
interval_count: plan.interval_count,
|
|
16
|
-
trial_period_days: plan.trial_period_days
|
|
17
|
-
statement_descriptor: plan.statement_descriptor
|
|
17
|
+
trial_period_days: plan.trial_period_days
|
|
18
|
+
# statement_descriptor: plan.statement_descriptor
|
|
18
19
|
)
|
|
19
20
|
rescue Stripe::StripeError => e
|
|
20
21
|
plan.errors.add(:base, :invalid, message: e.message)
|
|
21
22
|
return plan
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
plan
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
|
-
end
|
|
28
|
+
end
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
module Tang
|
|
2
2
|
class CreateSubscription
|
|
3
3
|
def self.call(plan, customer, token)
|
|
4
|
+
puts "CreateSubscription.call(#{plan}, #{customer}, #{token})"
|
|
4
5
|
subscription = Subscription.new(
|
|
5
|
-
plan: plan,
|
|
6
|
-
customer: customer,
|
|
6
|
+
plan: plan,
|
|
7
|
+
customer: customer,
|
|
7
8
|
coupon: customer.subscription_coupon
|
|
8
9
|
)
|
|
9
10
|
return subscription if plan.nil? || customer.nil?
|
|
10
11
|
|
|
11
|
-
#
|
|
12
|
-
# A nil token will throw an error when calling create_stripe_subscription
|
|
12
|
+
# Check for token presence.
|
|
13
|
+
# A nil token will throw an error when calling create_stripe_subscription
|
|
13
14
|
# because the customer does not have a payment method.
|
|
15
|
+
return subscription if token.nil? && customer.stripe_id.blank?
|
|
14
16
|
|
|
15
17
|
begin
|
|
16
18
|
if customer.stripe_id.blank?
|
|
@@ -33,61 +35,62 @@ module Tang
|
|
|
33
35
|
# Save the payment method
|
|
34
36
|
stripe_card = Stripe::Customer.retrieve_source(
|
|
35
37
|
stripe_customer.id,
|
|
36
|
-
stripe_customer.default_source
|
|
38
|
+
stripe_customer.default_source
|
|
37
39
|
)
|
|
38
40
|
|
|
39
41
|
# Finalize customer with subscription and payment method
|
|
40
42
|
finalize_customer(customer, subscription, stripe_card)
|
|
41
|
-
|
|
42
43
|
rescue Stripe::StripeError => e
|
|
43
44
|
subscription.errors.add(:base, :invalid, message: e.message)
|
|
44
45
|
end
|
|
45
|
-
|
|
46
|
+
subscription
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def self.create_stripe_customer(customer, token)
|
|
50
|
+
puts "create_stripe_customer(#{customer}, #{token})"
|
|
49
51
|
if customer.coupon.present?
|
|
50
|
-
|
|
52
|
+
Stripe::Customer.create(
|
|
51
53
|
source: token,
|
|
52
54
|
email: customer.email,
|
|
53
55
|
coupon: customer.coupon.stripe_id
|
|
54
56
|
)
|
|
55
57
|
else
|
|
56
|
-
|
|
58
|
+
Stripe::Customer.create(
|
|
57
59
|
source: token,
|
|
58
60
|
email: customer.email
|
|
59
61
|
)
|
|
60
62
|
end
|
|
61
|
-
return stripe_customer
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
def self.update_stripe_customer(customer, token)
|
|
66
|
+
puts "update_stripe_customer(#{customer}, #{token})"
|
|
65
67
|
# Update the payment method
|
|
66
68
|
stripe_customer = Stripe::Customer.retrieve(customer.stripe_id)
|
|
67
69
|
if token.present?
|
|
68
70
|
stripe_customer.source = token
|
|
69
71
|
stripe_customer.save
|
|
70
72
|
end
|
|
71
|
-
|
|
73
|
+
stripe_customer
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
def self.create_stripe_subscription(customer, plan)
|
|
77
|
+
puts "create_stripe_subscription(#{customer}, #{plan})"
|
|
75
78
|
if customer.subscription_coupon.present?
|
|
76
|
-
|
|
79
|
+
Stripe::Subscription.create(
|
|
77
80
|
customer: customer.stripe_id,
|
|
78
81
|
plan: plan.stripe_id,
|
|
79
82
|
coupon: customer.subscription_coupon.stripe_id
|
|
80
83
|
)
|
|
81
84
|
else
|
|
82
|
-
|
|
85
|
+
Stripe::Subscription.create(
|
|
83
86
|
customer: customer.stripe_id,
|
|
84
87
|
plan: plan.stripe_id
|
|
85
88
|
)
|
|
86
89
|
end
|
|
87
|
-
return stripe_sub
|
|
88
90
|
end
|
|
89
91
|
|
|
90
92
|
def self.finalize_customer(customer, subscription, stripe_card)
|
|
93
|
+
puts "finalize_customer(#{customer}, #{subscription}, #{stripe_card})"
|
|
91
94
|
# Remove temporary coupon
|
|
92
95
|
customer.subscription_coupon = nil
|
|
93
96
|
# Save subscription data to customer
|
|
@@ -96,4 +99,4 @@ module Tang
|
|
|
96
99
|
customer.update_card_from_stripe(stripe_card)
|
|
97
100
|
end
|
|
98
101
|
end
|
|
99
|
-
end
|
|
102
|
+
end
|
|
@@ -4,12 +4,12 @@ module Tang
|
|
|
4
4
|
begin
|
|
5
5
|
Stripe::Customer.delete_source(
|
|
6
6
|
card.customer.stripe_id,
|
|
7
|
-
card.stripe_id
|
|
7
|
+
card.stripe_id
|
|
8
8
|
)
|
|
9
9
|
rescue Stripe::StripeError => e
|
|
10
10
|
card.errors.add(:base, :invalid, message: e.message)
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
card
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
|
-
end
|
|
15
|
+
end
|
|
@@ -3,11 +3,11 @@ module Tang
|
|
|
3
3
|
def self.call(coupon)
|
|
4
4
|
begin
|
|
5
5
|
c = Stripe::Coupon.retrieve(coupon.stripe_id)
|
|
6
|
-
c.delete
|
|
6
|
+
c.delete
|
|
7
7
|
rescue Stripe::StripeError => e
|
|
8
8
|
coupon.errors.add(:base, :invalid, message: e.message)
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
coupon
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
|
-
end
|
|
13
|
+
end
|
|
@@ -18,11 +18,10 @@ module Tang
|
|
|
18
18
|
subscription = Subscription.from_stripe(stripe_subscription)
|
|
19
19
|
invoice.update(subscription: subscription)
|
|
20
20
|
end
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return charge
|
|
21
|
+
|
|
22
|
+
subscription.fail! if subscription.present? && !subscription.past_due?
|
|
23
|
+
|
|
24
|
+
charge
|
|
26
25
|
end
|
|
27
26
|
end
|
|
28
|
-
end
|
|
27
|
+
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module Tang
|
|
2
2
|
class PayInvoice
|
|
3
3
|
def self.call(stripe_invoice)
|
|
4
|
-
|
|
5
4
|
# ensure the subscription exists
|
|
6
5
|
stripe_subscription = Stripe::Subscription.retrieve(stripe_invoice.subscription)
|
|
7
6
|
subscription = Subscription.find_by(stripe_id: stripe_invoice.subscription)
|
|
@@ -28,7 +27,7 @@ module Tang
|
|
|
28
27
|
customer.update_subscription_end(subscription)
|
|
29
28
|
end
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
charge
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
|
-
end
|
|
33
|
+
end
|
|
@@ -2,14 +2,14 @@ module Tang
|
|
|
2
2
|
class RemoveSubscriptionDiscount
|
|
3
3
|
def self.call(subscription)
|
|
4
4
|
begin
|
|
5
|
-
Stripe::Subscription.retrieve(subscription.stripe_id).delete_discount
|
|
5
|
+
Stripe::Subscription.retrieve(subscription.stripe_id).delete_discount
|
|
6
6
|
rescue Stripe::StripeError => e
|
|
7
7
|
subscription.errors.add(:base, :invalid, message: e.message)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
subscription.update(coupon: nil, coupon_start: nil)
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
subscription
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
|
-
end
|
|
15
|
+
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module Tang
|
|
2
2
|
class SaveCard
|
|
3
3
|
def self.call(customer, token)
|
|
4
|
-
if customer.card.present?
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
card = if customer.card.present?
|
|
5
|
+
customer.card
|
|
6
|
+
else
|
|
7
|
+
Card.new(customer: customer)
|
|
8
|
+
end
|
|
9
9
|
|
|
10
10
|
begin
|
|
11
11
|
if customer.stripe_id.present?
|
|
@@ -24,14 +24,13 @@ module Tang
|
|
|
24
24
|
# Save the payment method
|
|
25
25
|
stripe_card = Stripe::Customer.retrieve_source(
|
|
26
26
|
cu.id,
|
|
27
|
-
cu.default_source
|
|
27
|
+
cu.default_source
|
|
28
28
|
)
|
|
29
29
|
card.update_from_stripe(stripe_card)
|
|
30
|
-
|
|
31
30
|
rescue Stripe::StripeError => e
|
|
32
31
|
card.errors.add(:base, :invalid, message: e.message)
|
|
33
32
|
end
|
|
34
|
-
|
|
33
|
+
card
|
|
35
34
|
end
|
|
36
35
|
end
|
|
37
|
-
end
|
|
36
|
+
end
|