pay 2.7.0 → 2.7.2

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.

Potentially problematic release.


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

Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +93 -57
  3. data/app/models/pay/application_record.rb +1 -0
  4. data/app/models/pay/charge.rb +1 -1
  5. data/app/models/pay/subscription.rb +1 -1
  6. data/db/migrate/20200603134434_add_data_to_pay_models.rb +2 -11
  7. data/db/migrate/20210309004259_add_data_to_pay_billable.rb +1 -10
  8. data/db/migrate/20210714175351_add_uniqueness_to_pay_models.rb +6 -0
  9. data/lib/generators/active_record/billable_generator.rb +44 -0
  10. data/lib/generators/active_record/merchant_generator.rb +44 -0
  11. data/lib/generators/active_record/templates/billable_migration.rb +17 -0
  12. data/lib/generators/active_record/templates/merchant_migration.rb +12 -0
  13. data/lib/generators/pay/{pay_generator.rb → billable_generator.rb} +2 -3
  14. data/lib/generators/pay/merchant_generator.rb +17 -0
  15. data/lib/generators/pay/orm_helpers.rb +10 -6
  16. data/lib/pay/adapter.rb +9 -0
  17. data/lib/pay/braintree/subscription.rb +2 -0
  18. data/lib/pay/env.rb +8 -0
  19. data/lib/pay/fake_processor/subscription.rb +2 -0
  20. data/lib/pay/paddle/subscription.rb +2 -0
  21. data/lib/pay/stripe/billable.rb +36 -44
  22. data/lib/pay/stripe/charge.rb +55 -2
  23. data/lib/pay/stripe/subscription.rb +62 -5
  24. data/lib/pay/stripe/webhooks/charge_refunded.rb +2 -7
  25. data/lib/pay/stripe/webhooks/charge_succeeded.rb +2 -8
  26. data/lib/pay/stripe/webhooks/checkout_session_async_payment_succeeded.rb +13 -0
  27. data/lib/pay/stripe/webhooks/checkout_session_completed.rb +13 -0
  28. data/lib/pay/stripe/webhooks/payment_intent_succeeded.rb +2 -8
  29. data/lib/pay/stripe/webhooks/payment_method_attached.rb +17 -0
  30. data/lib/pay/stripe/webhooks/payment_method_automatically_updated.rb +17 -0
  31. data/lib/pay/stripe/webhooks/payment_method_detached.rb +17 -0
  32. data/lib/pay/stripe/webhooks/subscription_created.rb +1 -36
  33. data/lib/pay/stripe/webhooks/subscription_deleted.rb +1 -9
  34. data/lib/pay/stripe/webhooks/subscription_renewing.rb +4 -6
  35. data/lib/pay/stripe/webhooks/subscription_updated.rb +1 -29
  36. data/lib/pay/stripe.rb +6 -0
  37. data/lib/pay/version.rb +1 -1
  38. metadata +14 -6
  39. data/app/models/pay.rb +0 -5
  40. data/lib/generators/active_record/pay_generator.rb +0 -58
  41. data/lib/generators/active_record/templates/migration.rb +0 -9
@@ -3,13 +3,8 @@ module Pay
3
3
  module Webhooks
4
4
  class ChargeRefunded
5
5
  def call(event)
6
- object = event.data.object
7
- charge = Pay.charge_model.find_by(processor: :stripe, processor_id: object.id)
8
-
9
- return unless charge.present?
10
-
11
- charge.update(amount_refunded: object.amount_refunded)
12
- notify_user(charge.owner, charge)
6
+ pay_charge = Pay::Stripe::Charge.sync(event.data.object.id)
7
+ notify_user(pay_charge.owner, pay_charge) if pay_charge
13
8
  end
14
9
 
15
10
  def notify_user(billable, charge)
@@ -3,14 +3,8 @@ module Pay
3
3
  module Webhooks
4
4
  class ChargeSucceeded
5
5
  def call(event)
6
- object = event.data.object
7
- billable = Pay.find_billable(processor: :stripe, processor_id: object.customer)
8
-
9
- return unless billable.present?
10
- return if billable.charges.where(processor_id: object.id).any?
11
-
12
- charge = Pay::Stripe::Billable.new(billable).save_pay_charge(object)
13
- notify_user(billable, charge)
6
+ pay_charge = Pay::Stripe::Charge.sync(event.data.object.id)
7
+ notify_user(pay_charge.owner, pay_charge) if pay_charge
14
8
  end
15
9
 
16
10
  def notify_user(billable, charge)
@@ -0,0 +1,13 @@
1
+ module Pay
2
+ module Stripe
3
+ module Webhooks
4
+ class CheckoutSessionAsyncPaymentSucceeded
5
+ def call(event)
6
+ if event.data.object.subscription
7
+ Pay::Stripe::Subscription.sync(event.data.object.subscription)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Pay
2
+ module Stripe
3
+ module Webhooks
4
+ class CheckoutSessionCompleted
5
+ def call(event)
6
+ if event.data.object.subscription
7
+ Pay::Stripe::Subscription.sync(event.data.object.subscription)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,15 +4,9 @@ module Pay
4
4
  class PaymentIntentSucceeded
5
5
  def call(event)
6
6
  object = event.data.object
7
- billable = Pay.find_billable(processor: :stripe, processor_id: object.customer)
8
-
9
- return unless billable.present?
10
-
11
7
  object.charges.data.each do |charge|
12
- next if billable.charges.where(processor_id: charge.id).any?
13
-
14
- charge = Pay::Stripe::Billable.new(billable).save_pay_charge(charge)
15
- notify_user(billable, charge)
8
+ pay_charge = Pay::Stripe::Charge.sync(charge.id)
9
+ notify_user(pay_charge.owner, pay_charge) if pay_charge
16
10
  end
17
11
  end
18
12
 
@@ -0,0 +1,17 @@
1
+ module Pay
2
+ module Stripe
3
+ module Webhooks
4
+ class PaymentMethodAttached
5
+ def call(event)
6
+ object = event.data.object
7
+ pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
8
+
9
+ # Couldn't find user, we can skip
10
+ return unless pay_customer.present?
11
+
12
+ Pay::Stripe::Billable.new(pay_customer).sync_payment_method(payment_method_id: object.id)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Pay
2
+ module Stripe
3
+ module Webhooks
4
+ class PaymentMethodAutomaticallyUpdated
5
+ def call(event)
6
+ object = event.data.object
7
+ pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
8
+
9
+ # Couldn't find user, we can skip
10
+ return unless pay_customer.present?
11
+
12
+ Pay::Stripe::Billable.new(pay_customer).sync_payment_method(payment_method_id: object.id)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Pay
2
+ module Stripe
3
+ module Webhooks
4
+ class PaymentMethodDetached
5
+ def call(event)
6
+ object = event.data.object
7
+ pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
8
+
9
+ # Couldn't find user, we can skip
10
+ return unless pay_customer.present?
11
+
12
+ Pay::Stripe::Billable.new(pay_customer).sync_payment_method(payment_method_id: object.id)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -3,42 +3,7 @@ module Pay
3
3
  module Webhooks
4
4
  class SubscriptionCreated
5
5
  def call(event)
6
- object = event.data.object
7
-
8
- # We may already have the subscription in the database, so we can update that record
9
- subscription = Pay.subscription_model.find_by(processor: :stripe, processor_id: object.id)
10
-
11
- # Create the subscription in the database if we don't have it already
12
- if subscription.nil?
13
- # The customer should already be in the database
14
- owner = Pay.find_billable(processor: :stripe, processor_id: object.customer)
15
-
16
- if owner.nil?
17
- Rails.logger.error("[Pay] Unable to find Pay::Billable with processor: :stripe and processor_id: '#{object.customer}'. Searched these models: #{Pay.billable_models.join(", ")}")
18
- return
19
- end
20
-
21
- subscription = Pay.subscription_model.new(name: Pay.default_product_name, owner: owner, processor: :stripe, processor_id: object.id)
22
- end
23
-
24
- subscription.application_fee_percent = object.application_fee_percent
25
- subscription.processor_plan = object.plan.id
26
- subscription.quantity = object.quantity
27
- subscription.status = object.status
28
- subscription.trial_ends_at = Time.at(object.trial_end) if object.trial_end.present?
29
-
30
- # If user was on trial, their subscription ends at the end of the trial
31
- subscription.ends_at = if object.cancel_at_period_end && subscription.on_trial?
32
- subscription.trial_ends_at
33
-
34
- # User wasn't on trial, so subscription ends at period end
35
- elsif object.cancel_at_period_end
36
- Time.at(object.current_period_end)
37
-
38
- # Subscription isn't marked to cancel at period end
39
- end
40
-
41
- subscription.save!
6
+ Pay::Stripe::Subscription.sync(event.data.object.id)
42
7
  end
43
8
  end
44
9
  end
@@ -3,15 +3,7 @@ module Pay
3
3
  module Webhooks
4
4
  class SubscriptionDeleted
5
5
  def call(event)
6
- object = event.data.object
7
- subscription = Pay.subscription_model.find_by(processor: :stripe, processor_id: object.id)
8
-
9
- # We couldn't find the subscription for some reason, maybe it's from another service
10
- return if subscription.nil?
11
-
12
- # User canceled subscriptions have an ends_at
13
- # Automatically canceled subscriptions need this value set
14
- subscription.update!(ends_at: Time.at(object.ended_at)) if subscription.ends_at.blank? && object.ended_at.present?
6
+ Pay::Stripe::Subscription.sync(event.data.object.id)
15
7
  end
16
8
  end
17
9
  end
@@ -5,12 +5,10 @@ module Pay
5
5
  def call(event)
6
6
  # Event is of type "invoice" see:
7
7
  # https://stripe.com/docs/api/invoices/object
8
- subscription = Pay.subscription_model.find_by(
9
- processor: :stripe,
10
- processor_id: event.data.object.subscription
11
- )
12
- date = Time.zone.at(event.data.object.next_payment_attempt)
13
- notify_user(subscription.owner, subscription, date) if subscription.present?
8
+ subscription = Pay.subscription_model.find_by(processor: :stripe, processor_id: event.data.object.subscription)
9
+ return unless subscription
10
+
11
+ notify_user(subscription.owner, subscription, Time.zone.at(event.data.object.next_payment_attempt))
14
12
  end
15
13
 
16
14
  def notify_user(billable, subscription, date)
@@ -3,35 +3,7 @@ module Pay
3
3
  module Webhooks
4
4
  class SubscriptionUpdated
5
5
  def call(event)
6
- object = event.data.object
7
- subscription = Pay.subscription_model.find_by(processor: :stripe, processor_id: object.id)
8
-
9
- return if subscription.nil?
10
-
11
- # Delete any subscription attempts that have expired
12
- if object.status == "incomplete_expired"
13
- subscription.destroy
14
- return
15
- end
16
-
17
- subscription.application_fee_percent = object.application_fee_percent
18
- subscription.processor_plan = object.plan.id
19
- subscription.quantity = object.quantity
20
- subscription.status = object.status
21
- subscription.trial_ends_at = Time.at(object.trial_end) if object.trial_end.present?
22
-
23
- # If user was on trial, their subscription ends at the end of the trial
24
- subscription.ends_at = if object.cancel_at_period_end && subscription.on_trial?
25
- subscription.trial_ends_at
26
-
27
- # User wasn't on trial, so subscription ends at period end
28
- elsif object.cancel_at_period_end
29
- Time.at(object.current_period_end)
30
-
31
- # Subscription isn't marked to cancel at period end
32
- end
33
-
34
- subscription.save!
6
+ Pay::Stripe::Subscription.sync(event.data.object.id)
35
7
  end
36
8
  end
37
9
  end
data/lib/pay/stripe.rb CHANGED
@@ -10,6 +10,8 @@ module Pay
10
10
  autoload :AccountUpdated, "pay/stripe/webhooks/account_updated"
11
11
  autoload :ChargeRefunded, "pay/stripe/webhooks/charge_refunded"
12
12
  autoload :ChargeSucceeded, "pay/stripe/webhooks/charge_succeeded"
13
+ autoload :CheckoutSessionCompleted, "pay/stripe/webhooks/checkout_session_completed"
14
+ autoload :CheckoutSessionAsyncPaymentSucceeded, "pay/stripe/webhooks/checkout_session_async_payment_succeeded"
13
15
  autoload :CustomerDeleted, "pay/stripe/webhooks/customer_deleted"
14
16
  autoload :CustomerUpdated, "pay/stripe/webhooks/customer_updated"
15
17
  autoload :PaymentActionRequired, "pay/stripe/webhooks/payment_action_required"
@@ -86,6 +88,10 @@ module Pay
86
88
 
87
89
  # If an account is updated in stripe, we should update it as well
88
90
  events.subscribe "stripe.account.updated", Pay::Stripe::Webhooks::AccountUpdated.new
91
+
92
+ # Handle subscriptions in Stripe Checkout Sessions
93
+ events.subscribe "stripe.checkout.session.completed", Pay::Stripe::Webhooks::CheckoutSessionCompleted.new
94
+ events.subscribe "stripe.checkout.session.async_payment_succeeded", Pay::Stripe::Webhooks::CheckoutSessionAsyncPaymentSucceeded.new
89
95
  end
90
96
  end
91
97
  end
data/lib/pay/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pay
2
- VERSION = "2.7.0"
2
+ VERSION = "2.7.2"
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.7.0
4
+ version: 2.7.2
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: 2021-05-19 00:00:00.000000000 Z
12
+ date: 2021-08-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -125,7 +125,6 @@ files:
125
125
  - app/jobs/pay/email_sync_job.rb
126
126
  - app/mailers/pay/application_mailer.rb
127
127
  - app/mailers/pay/user_mailer.rb
128
- - app/models/pay.rb
129
128
  - app/models/pay/application_record.rb
130
129
  - app/models/pay/charge.rb
131
130
  - app/models/pay/subscription.rb
@@ -145,11 +144,15 @@ files:
145
144
  - db/migrate/20210309004259_add_data_to_pay_billable.rb
146
145
  - db/migrate/20210406215234_add_currency_to_pay_charges.rb
147
146
  - db/migrate/20210406215506_add_application_fee_to_pay_models.rb
148
- - lib/generators/active_record/pay_generator.rb
149
- - lib/generators/active_record/templates/migration.rb
147
+ - db/migrate/20210714175351_add_uniqueness_to_pay_models.rb
148
+ - lib/generators/active_record/billable_generator.rb
149
+ - lib/generators/active_record/merchant_generator.rb
150
+ - lib/generators/active_record/templates/billable_migration.rb
151
+ - lib/generators/active_record/templates/merchant_migration.rb
152
+ - lib/generators/pay/billable_generator.rb
150
153
  - lib/generators/pay/email_views_generator.rb
154
+ - lib/generators/pay/merchant_generator.rb
151
155
  - lib/generators/pay/orm_helpers.rb
152
- - lib/generators/pay/pay_generator.rb
153
156
  - lib/generators/pay/views_generator.rb
154
157
  - lib/pay.rb
155
158
  - lib/pay/adapter.rb
@@ -199,10 +202,15 @@ files:
199
202
  - lib/pay/stripe/webhooks/account_updated.rb
200
203
  - lib/pay/stripe/webhooks/charge_refunded.rb
201
204
  - lib/pay/stripe/webhooks/charge_succeeded.rb
205
+ - lib/pay/stripe/webhooks/checkout_session_async_payment_succeeded.rb
206
+ - lib/pay/stripe/webhooks/checkout_session_completed.rb
202
207
  - lib/pay/stripe/webhooks/customer_deleted.rb
203
208
  - lib/pay/stripe/webhooks/customer_updated.rb
204
209
  - lib/pay/stripe/webhooks/payment_action_required.rb
205
210
  - lib/pay/stripe/webhooks/payment_intent_succeeded.rb
211
+ - lib/pay/stripe/webhooks/payment_method_attached.rb
212
+ - lib/pay/stripe/webhooks/payment_method_automatically_updated.rb
213
+ - lib/pay/stripe/webhooks/payment_method_detached.rb
206
214
  - lib/pay/stripe/webhooks/payment_method_updated.rb
207
215
  - lib/pay/stripe/webhooks/subscription_created.rb
208
216
  - lib/pay/stripe/webhooks/subscription_deleted.rb
data/app/models/pay.rb DELETED
@@ -1,5 +0,0 @@
1
- module Pay
2
- def self.table_name_prefix
3
- "pay_"
4
- end
5
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rails/generators/active_record"
4
- require "generators/pay/orm_helpers"
5
-
6
- module ActiveRecord
7
- module Generators
8
- class PayGenerator < ActiveRecord::Generators::Base
9
- include Pay::Generators::OrmHelpers
10
- source_root File.expand_path("../templates", __FILE__)
11
-
12
- def copy_pay_billable_migration
13
- if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
14
- migration_template "migration.rb", "#{migration_path}/add_pay_billable_to_#{table_name}.rb", migration_version: migration_version
15
- end
16
- # TODO: Throw error here that model should already exist if it doesn't
17
- end
18
-
19
- def inject_pay_billable_content
20
- content = model_contents
21
-
22
- class_path = if namespaced?
23
- class_name.to_s.split("::")
24
- else
25
- [class_name]
26
- end
27
-
28
- indent_depth = class_path.size - 1
29
- content = content.split("\n").map { |line| " " * indent_depth + line }.join("\n") << "\n"
30
-
31
- inject_into_class(model_path, class_path.last, content) if model_exists?
32
- end
33
-
34
- def migration_data
35
- <<RUBY
36
- t.string :processor
37
- t.string :processor_id
38
- t.datetime :trial_ends_at
39
- t.string :card_type
40
- t.string :card_last4
41
- t.string :card_exp_month
42
- t.string :card_exp_year
43
- t.text :extra_billing_info
44
- RUBY
45
- end
46
-
47
- def rails5_and_up?
48
- Rails::VERSION::MAJOR >= 5
49
- end
50
-
51
- def migration_version
52
- if rails5_and_up?
53
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class AddPayBillableTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
4
- def change
5
- change_table :<%= table_name %>, bulk: true do |t|
6
- <%= migration_data -%>
7
- end
8
- end
9
- end