pay 2.3.0 → 2.4.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pay might be problematic. Click here for more details.

Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -2
  3. data/app/controllers/pay/webhooks/braintree_controller.rb +1 -1
  4. data/app/mailers/pay/user_mailer.rb +14 -35
  5. data/app/models/pay/subscription.rb +12 -18
  6. data/app/views/pay/user_mailer/payment_action_required.html.erb +1 -1
  7. data/app/views/pay/user_mailer/receipt.html.erb +6 -6
  8. data/app/views/pay/user_mailer/refund.html.erb +6 -6
  9. data/app/views/pay/user_mailer/subscription_renewing.html.erb +1 -1
  10. data/config/locales/en.yml +137 -0
  11. data/db/migrate/20200603134434_add_data_to_pay_models.rb +6 -1
  12. data/lib/pay.rb +7 -41
  13. data/lib/pay/billable.rb +9 -9
  14. data/lib/pay/braintree/billable.rb +11 -11
  15. data/lib/pay/braintree/charge.rb +3 -3
  16. data/lib/pay/braintree/subscription.rb +21 -13
  17. data/lib/pay/errors.rb +73 -0
  18. data/lib/pay/paddle/billable.rb +34 -5
  19. data/lib/pay/paddle/charge.rb +2 -2
  20. data/lib/pay/paddle/subscription.rb +22 -13
  21. data/lib/pay/paddle/webhooks/subscription_cancelled.rb +1 -1
  22. data/lib/pay/paddle/webhooks/subscription_created.rb +1 -1
  23. data/lib/pay/paddle/webhooks/subscription_payment_refunded.rb +2 -2
  24. data/lib/pay/paddle/webhooks/subscription_payment_succeeded.rb +8 -29
  25. data/lib/pay/paddle/webhooks/subscription_updated.rb +15 -12
  26. data/lib/pay/receipts.rb +6 -6
  27. data/lib/pay/stripe.rb +3 -0
  28. data/lib/pay/stripe/billable.rb +4 -4
  29. data/lib/pay/stripe/charge.rb +2 -2
  30. data/lib/pay/stripe/subscription.rb +20 -12
  31. data/lib/pay/stripe/webhooks/charge_refunded.rb +2 -2
  32. data/lib/pay/stripe/webhooks/charge_succeeded.rb +1 -1
  33. data/lib/pay/stripe/webhooks/payment_action_required.rb +1 -1
  34. data/lib/pay/stripe/webhooks/subscription_created.rb +1 -1
  35. data/lib/pay/stripe/webhooks/subscription_renewing.rb +4 -3
  36. data/lib/pay/version.rb +1 -1
  37. metadata +11 -74
@@ -10,7 +10,7 @@ module Pay
10
10
 
11
11
  # User canceled subscriptions have an ends_at
12
12
  # Automatically canceled subscriptions need this value set
13
- subscription.update!(ends_at: DateTime.parse(data["cancellation_effective_date"])) if subscription.ends_at.blank? && data["cancellation_effective_date"].present?
13
+ subscription.update!(ends_at: Time.zone.parse(data["cancellation_effective_date"])) if subscription.ends_at.blank? && data["cancellation_effective_date"].present?
14
14
  end
15
15
  end
16
16
  end
@@ -22,7 +22,7 @@ module Pay
22
22
  return
23
23
  end
24
24
 
25
- subscription = Pay.subscription_model.new(owner: owner, name: "default", processor: "paddle", processor_id: data["subscription_id"], status: :active)
25
+ subscription = Pay.subscription_model.new(owner: owner, name: Pay.default_product_name, processor: "paddle", processor_id: data["subscription_id"], status: :active)
26
26
  end
27
27
 
28
28
  subscription.quantity = data["quantity"]
@@ -10,9 +10,9 @@ module Pay
10
10
  notify_user(charge.owner, charge)
11
11
  end
12
12
 
13
- def notify_user(user, charge)
13
+ def notify_user(billable, charge)
14
14
  if Pay.send_emails
15
- Pay::UserMailer.refund(user, charge).deliver_later
15
+ Pay::UserMailer.with(billable: billable, charge: charge).refund.deliver_later
16
16
  end
17
17
  end
18
18
  end
@@ -21,41 +21,20 @@ module Pay
21
21
  amount: Integer(data["sale_gross"].to_f * 100),
22
22
  card_type: data["payment_method"],
23
23
  paddle_receipt_url: data["receipt_url"],
24
- created_at: DateTime.parse(data["event_time"])
25
- }.merge(payment_params(data["subscription_id"]))
24
+ created_at: Time.zone.parse(data["event_time"])
25
+ }
26
26
 
27
- charge.update(params)
27
+ payment_information = user.paddle_payment_information(data["subscription_id"])
28
+
29
+ charge.update(params.merge(payment_information))
30
+ user.update(payment_information)
28
31
 
29
32
  charge
30
33
  end
31
34
 
32
- def notify_user(user, charge)
35
+ def notify_user(billable, charge)
33
36
  if Pay.send_emails && charge.respond_to?(:receipt)
34
- Pay::UserMailer.receipt(user, charge).deliver_later
35
- end
36
- end
37
-
38
- private
39
-
40
- def payment_params(subscription_id)
41
- subscription_user = PaddlePay::Subscription::User.list({subscription_id: subscription_id}).try(:first)
42
- payment_information = subscription_user ? subscription_user[:payment_information] : nil
43
- return {} if payment_information.nil?
44
-
45
- case payment_information[:payment_method]
46
- when "card"
47
- {
48
- card_type: payment_information[:card_type],
49
- card_last4: payment_information[:last_four_digits],
50
- card_exp_month: payment_information[:expiry_date].split("/").first,
51
- card_exp_year: payment_information[:expiry_date].split("/").last
52
- }
53
- when "paypal"
54
- {
55
- card_type: "PayPal"
56
- }
57
- else
58
- {}
37
+ Pay::UserMailer.with(billable: billable, charge: charge).receipt.deliver_later
59
38
  end
60
39
  end
61
40
  end
@@ -7,24 +7,27 @@ module Pay
7
7
 
8
8
  return if subscription.nil?
9
9
 
10
- subscription.status = data["status"] == "deleted" ? "canceled" : data["status"]
10
+ case data["status"]
11
+ when "deleted"
12
+ subscription.status = "canceled"
13
+ subscription.ends_at = Time.zone.parse(data["next_bill_date"]) || Time.zone.now if subscription.ends_at.blank?
14
+ when "trialing"
15
+ subscription.status = "trialing"
16
+ subscription.trial_ends_at = Time.zone.parse(data["next_bill_date"])
17
+ when "active"
18
+ subscription.status = "active"
19
+ subscription.paddle_paused_from = Time.zone.parse(data["paused_from"]) if data["paused_from"].present?
20
+ else
21
+ subscription.status = data["status"]
22
+ end
23
+
11
24
  subscription.quantity = data["new_quantity"]
12
25
  subscription.processor_plan = data["subscription_plan_id"]
13
26
  subscription.paddle_update_url = data["update_url"]
14
27
  subscription.paddle_cancel_url = data["cancel_url"]
15
28
 
16
- subscription.trial_ends_at = DateTime.parse(data["next_bill_date"]) if data["status"] == "trialing"
17
-
18
29
  # If user was on trial, their subscription ends at the end of the trial
19
- subscription.ends_at = if ["paused", "deleted"].include?(data["status"]) && subscription.on_trial?
20
- subscription.trial_ends_at
21
-
22
- # User wasn't on trial, so subscription ends at period end
23
- elsif ["paused", "deleted"].include?(data["status"])
24
- DateTime.parse(data["next_bill_date"])
25
-
26
- # Subscription isn't marked to cancel at period end
27
- end
30
+ subscription.ends_at = subscription.trial_ends_at if subscription.on_trial?
28
31
 
29
32
  subscription.save!
30
33
  end
data/lib/pay/receipts.rb CHANGED
@@ -28,13 +28,13 @@ module Pay
28
28
 
29
29
  def line_items
30
30
  line_items = [
31
- ["Date", created_at.to_s],
32
- ["Account Billed", "#{owner.name} (#{owner.email})"],
33
- ["Product", product],
34
- ["Amount", ActionController::Base.helpers.number_to_currency(amount / 100.0)],
35
- ["Charged to", charged_to]
31
+ [I18n.t("receipt.date"), created_at.to_s],
32
+ [I18n.t("receipt.account_billed"), "#{owner.name} (#{owner.email})"],
33
+ [I18n.t("receipt.product"), product],
34
+ [I18n.t("receipt.amount"), ActionController::Base.helpers.number_to_currency(amount / 100.0)],
35
+ [I18n.t("receipt.charged_to"), charged_to]
36
36
  ]
37
- line_items << ["Additional Info", owner.extra_billing_info] if owner.extra_billing_info?
37
+ line_items << [I18n.t("receipt.additional_info"), owner.extra_billing_info] if owner.extra_billing_info?
38
38
  line_items
39
39
  end
40
40
  end
data/lib/pay/stripe.rb CHANGED
@@ -15,6 +15,9 @@ module Pay
15
15
  ::Stripe.api_version = "2020-08-27"
16
16
  ::StripeEvent.signing_secret = signing_secret
17
17
 
18
+ # Used by Stripe to identify Pay for support
19
+ ::Stripe.set_app_info("PayRails", partner_id: "pp_partner_IqhY0UExnJYLxg", version: Pay::VERSION, url: "https://github.com/pay-rails/pay")
20
+
18
21
  Pay.charge_model.include Pay::Stripe::Charge
19
22
  Pay.subscription_model.include Pay::Stripe::Subscription
20
23
  end
@@ -17,7 +17,7 @@ module Pay
17
17
  create_stripe_customer
18
18
  end
19
19
  rescue ::Stripe::StripeError => e
20
- raise Error, e.message
20
+ raise Pay::Stripe::Error, e
21
21
  end
22
22
 
23
23
  def create_setup_intent
@@ -47,7 +47,7 @@ module Pay
47
47
  # Create a new charge object
48
48
  Stripe::Webhooks::ChargeSucceeded.new.create_charge(self, payment_intent.charges.first)
49
49
  rescue ::Stripe::StripeError => e
50
- raise Error, e.message
50
+ raise Pay::Stripe::Error, e
51
51
  end
52
52
 
53
53
  # Handles Billable#subscribe
@@ -80,7 +80,7 @@ module Pay
80
80
 
81
81
  subscription
82
82
  rescue ::Stripe::StripeError => e
83
- raise Error, e.message
83
+ raise Pay::Stripe::Error, e
84
84
  end
85
85
 
86
86
  # Handles Billable#update_card
@@ -97,7 +97,7 @@ module Pay
97
97
  update_stripe_card_on_file(payment_method.card)
98
98
  true
99
99
  rescue ::Stripe::StripeError => e
100
- raise Error, e.message
100
+ raise Pay::Stripe::Error, e
101
101
  end
102
102
 
103
103
  def update_stripe_email!
@@ -14,7 +14,7 @@ module Pay
14
14
  def stripe_charge
15
15
  ::Stripe::Charge.retrieve(processor_id)
16
16
  rescue ::Stripe::StripeError => e
17
- raise Error, e.message
17
+ raise Pay::Stripe::Error, e
18
18
  end
19
19
 
20
20
  def stripe_refund!(amount_to_refund)
@@ -25,7 +25,7 @@ module Pay
25
25
 
26
26
  update(amount_refunded: amount_to_refund)
27
27
  rescue ::Stripe::StripeError => e
28
- raise Error, e.message
28
+ raise Pay::Stripe::Error, e
29
29
  end
30
30
  end
31
31
  end
@@ -3,14 +3,6 @@ module Pay
3
3
  module Subscription
4
4
  extend ActiveSupport::Concern
5
5
 
6
- included do
7
- scope :stripe, -> { where(processor: :stripe) }
8
- end
9
-
10
- def stripe?
11
- processor == "stripe"
12
- end
13
-
14
6
  def stripe_cancel
15
7
  subscription = processor_subscription
16
8
  subscription.cancel_at_period_end = true
@@ -19,24 +11,40 @@ module Pay
19
11
  new_ends_at = on_trial? ? trial_ends_at : Time.at(subscription.current_period_end)
20
12
  update(ends_at: new_ends_at)
21
13
  rescue ::Stripe::StripeError => e
22
- raise Error, e.message
14
+ raise Pay::Stripe::Error, e
23
15
  end
24
16
 
25
17
  def stripe_cancel_now!
26
18
  processor_subscription.delete
27
19
  update(ends_at: Time.zone.now, status: :canceled)
28
20
  rescue ::Stripe::StripeError => e
29
- raise Error, e.message
21
+ raise Pay::Stripe::Error, e
22
+ end
23
+
24
+ def stripe_on_grace_period?
25
+ canceled? && Time.zone.now < ends_at
26
+ end
27
+
28
+ def stripe_paused?
29
+ false
30
+ end
31
+
32
+ def stripe_pause
33
+ raise NotImplementedError, "Stripe does not support pausing subscriptions"
30
34
  end
31
35
 
32
36
  def stripe_resume
37
+ unless on_grace_period?
38
+ raise StandardError, "You can only resume subscriptions within their grace period."
39
+ end
40
+
33
41
  subscription = processor_subscription
34
42
  subscription.plan = processor_plan
35
43
  subscription.trial_end = on_trial? ? trial_ends_at.to_i : "now"
36
44
  subscription.cancel_at_period_end = false
37
45
  subscription.save
38
46
  rescue ::Stripe::StripeError => e
39
- raise Error, e.message
47
+ raise Pay::Stripe::Error, e
40
48
  end
41
49
 
42
50
  def stripe_swap(plan)
@@ -48,7 +56,7 @@ module Pay
48
56
  subscription.quantity = quantity if quantity?
49
57
  subscription.save
50
58
  rescue ::Stripe::StripeError => e
51
- raise Error, e.message
59
+ raise Pay::Stripe::Error, e
52
60
  end
53
61
  end
54
62
  end
@@ -12,9 +12,9 @@ module Pay
12
12
  notify_user(charge.owner, charge)
13
13
  end
14
14
 
15
- def notify_user(user, charge)
15
+ def notify_user(billable, charge)
16
16
  if Pay.send_emails
17
- Pay::UserMailer.refund(user, charge).deliver_later
17
+ Pay::UserMailer.with(billable: billable, charge: charge).refund.deliver_later
18
18
  end
19
19
  end
20
20
  end
@@ -34,7 +34,7 @@ module Pay
34
34
 
35
35
  def notify_user(billable, charge)
36
36
  if Pay.send_emails && charge.respond_to?(:receipt)
37
- Pay::UserMailer.receipt(billable, charge).deliver_later
37
+ Pay::UserMailer.with(billable: billable, charge: charge).receipt.deliver_later
38
38
  end
39
39
  end
40
40
  end
@@ -17,7 +17,7 @@ module Pay
17
17
 
18
18
  def notify_user(billable, payment_intent_id, subscription)
19
19
  if Pay.send_emails
20
- Pay::UserMailer.payment_action_required(billable, payment_intent_id, subscription).deliver_later
20
+ Pay::UserMailer.with(billable: billable, payment_intent_id: payment_intent_id, subscription: subscription).payment_action_required.deliver_later
21
21
  end
22
22
  end
23
23
  end
@@ -18,7 +18,7 @@ module Pay
18
18
  return
19
19
  end
20
20
 
21
- subscription = Pay.subscription_model.new(name: "default", owner: owner, processor: :stripe, processor_id: object.id)
21
+ subscription = Pay.subscription_model.new(name: Pay.default_product_name, owner: owner, processor: :stripe, processor_id: object.id)
22
22
  end
23
23
 
24
24
  subscription.quantity = object.quantity
@@ -9,12 +9,13 @@ module Pay
9
9
  processor: :stripe,
10
10
  processor_id: event.data.object.subscription
11
11
  )
12
- notify_user(subscription.owner, subscription) if subscription.present?
12
+ date = Time.zone.at(event.data.object.next_payment_attempt)
13
+ notify_user(subscription.owner, subscription, date) if subscription.present?
13
14
  end
14
15
 
15
- def notify_user(user, subscription)
16
+ def notify_user(billable, subscription, date)
16
17
  if Pay.send_emails
17
- Pay::UserMailer.subscription_renewing(user, subscription).deliver_later
18
+ Pay::UserMailer.with(billable: billable, subscription: subscription, date: date).subscription_renewing.deliver_later
18
19
  end
19
20
  end
20
21
  end
data/lib/pay/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pay
2
- VERSION = "2.3.0"
2
+ VERSION = "2.4.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pay
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Charnes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-12-11 00:00:00.000000000 Z
12
+ date: 2021-02-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -88,33 +88,25 @@ dependencies:
88
88
  - !ruby/object:Gem::Version
89
89
  version: 0.0.1
90
90
  - !ruby/object:Gem::Dependency
91
- name: byebug
91
+ name: minitest-rails
92
92
  requirement: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '6'
97
+ - - "<"
98
+ - !ruby/object:Gem::Version
99
+ version: '7.0'
97
100
  type: :development
98
101
  prerelease: false
99
102
  version_requirements: !ruby/object:Gem::Requirement
100
103
  requirements:
101
104
  - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- - !ruby/object:Gem::Dependency
105
- name: minitest-rails
106
- requirement: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
105
  - !ruby/object:Gem::Version
110
106
  version: '6'
111
- type: :development
112
- prerelease: false
113
- version_requirements: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
107
+ - - "<"
116
108
  - !ruby/object:Gem::Version
117
- version: '6'
109
+ version: '7.0'
118
110
  - !ruby/object:Gem::Dependency
119
111
  name: mocha
120
112
  requirement: !ruby/object:Gem::Requirement
@@ -129,20 +121,6 @@ dependencies:
129
121
  - - ">="
130
122
  - !ruby/object:Gem::Version
131
123
  version: '0'
132
- - !ruby/object:Gem::Dependency
133
- name: pry
134
- requirement: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- type: :development
140
- prerelease: false
141
- version_requirements: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
124
  - !ruby/object:Gem::Dependency
147
125
  name: standardrb
148
126
  requirement: !ruby/object:Gem::Requirement
@@ -157,48 +135,6 @@ dependencies:
157
135
  - - ">="
158
136
  - !ruby/object:Gem::Version
159
137
  version: '0'
160
- - !ruby/object:Gem::Dependency
161
- name: sqlite3
162
- requirement: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: '1.4'
167
- type: :development
168
- prerelease: false
169
- version_requirements: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: '1.4'
174
- - !ruby/object:Gem::Dependency
175
- name: mysql2
176
- requirement: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: '0'
181
- type: :development
182
- prerelease: false
183
- version_requirements: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- - !ruby/object:Gem::Dependency
189
- name: pg
190
- requirement: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
- type: :development
196
- prerelease: false
197
- version_requirements: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - ">="
200
- - !ruby/object:Gem::Version
201
- version: '0'
202
138
  - !ruby/object:Gem::Dependency
203
139
  name: vcr
204
140
  requirement: !ruby/object:Gem::Requirement
@@ -280,6 +216,7 @@ files:
280
216
  - lib/pay/braintree/subscription.rb
281
217
  - lib/pay/engine.rb
282
218
  - lib/pay/env.rb
219
+ - lib/pay/errors.rb
283
220
  - lib/pay/paddle.rb
284
221
  - lib/pay/paddle/billable.rb
285
222
  - lib/pay/paddle/charge.rb
@@ -328,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
328
265
  - !ruby/object:Gem::Version
329
266
  version: '0'
330
267
  requirements: []
331
- rubygems_version: 3.1.4
268
+ rubygems_version: 3.2.3
332
269
  signing_key:
333
270
  specification_version: 4
334
271
  summary: A Ruby on Rails subscription engine.