pay 7.3.0 → 11.2.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.
- checksums.yaml +4 -4
- data/README.md +8 -4
- data/app/controllers/pay/payments_controller.rb +2 -0
- data/app/controllers/pay/webhooks/lemon_squeezy_controller.rb +45 -0
- data/app/jobs/pay/customer_sync_job.rb +1 -1
- data/app/models/concerns/pay/routing.rb +13 -0
- data/{lib → app/models}/pay/braintree/charge.rb +7 -12
- data/{lib/pay/braintree/billable.rb → app/models/pay/braintree/customer.rb} +33 -71
- data/{lib → app/models}/pay/braintree/payment_method.rb +4 -10
- data/{lib → app/models}/pay/braintree/subscription.rb +23 -61
- data/app/models/pay/charge.rb +16 -45
- data/app/models/pay/customer.rb +5 -16
- data/app/models/pay/fake_processor/charge.rb +19 -0
- data/{lib/pay/fake_processor/billable.rb → app/models/pay/fake_processor/customer.rb} +28 -38
- data/{lib → app/models}/pay/fake_processor/merchant.rb +4 -9
- data/app/models/pay/fake_processor/payment_method.rb +13 -0
- data/app/models/pay/fake_processor/subscription.rb +70 -0
- data/app/models/pay/lemon_squeezy/charge.rb +96 -0
- data/app/models/pay/lemon_squeezy/customer.rb +80 -0
- data/app/models/pay/lemon_squeezy/payment_method.rb +29 -0
- data/app/models/pay/lemon_squeezy/subscription.rb +129 -0
- data/app/models/pay/merchant.rb +2 -11
- data/{lib → app/models}/pay/paddle_billing/charge.rb +15 -13
- data/{lib/pay/paddle_billing/billable.rb → app/models/pay/paddle_billing/customer.rb} +20 -35
- data/{lib → app/models}/pay/paddle_billing/payment_method.rb +13 -13
- data/{lib → app/models}/pay/paddle_billing/subscription.rb +40 -43
- data/{lib → app/models}/pay/paddle_classic/charge.rb +15 -18
- data/{lib/pay/paddle_classic/billable.rb → app/models/pay/paddle_classic/customer.rb} +11 -31
- data/{lib → app/models}/pay/paddle_classic/payment_method.rb +3 -11
- data/{lib → app/models}/pay/paddle_classic/subscription.rb +17 -37
- data/app/models/pay/payment_method.rb +4 -5
- data/app/models/pay/stripe/charge.rb +155 -0
- data/{lib/pay/stripe/billable.rb → app/models/pay/stripe/customer.rb} +78 -111
- data/{lib → app/models}/pay/stripe/merchant.rb +5 -20
- data/{lib → app/models}/pay/stripe/payment_method.rb +11 -17
- data/{lib → app/models}/pay/stripe/subscription.rb +83 -112
- data/app/models/pay/subscription.rb +13 -47
- data/app/models/pay/webhook.rb +5 -1
- data/app/views/pay/user_mailer/payment_action_required.text.erb +9 -0
- data/app/views/pay/user_mailer/payment_failed.text.erb +9 -0
- data/app/views/pay/user_mailer/receipt.text.erb +20 -0
- data/app/views/pay/user_mailer/refund.text.erb +21 -0
- data/app/views/pay/user_mailer/subscription_renewing.text.erb +8 -0
- data/app/views/pay/user_mailer/subscription_trial_ended.text.erb +8 -0
- data/app/views/pay/user_mailer/subscription_trial_will_end.text.erb +8 -0
- data/config/locales/en.yml +1 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20250415151129_add_object_to_pay_models.rb +7 -0
- data/db/migrate/2_add_pay_sti_columns.rb +24 -0
- data/lib/pay/attributes.rb +16 -8
- data/lib/pay/braintree.rb +25 -6
- data/lib/pay/engine.rb +2 -0
- data/lib/pay/fake_processor.rb +2 -6
- data/lib/pay/lemon_squeezy/webhooks/order.rb +11 -0
- data/lib/pay/lemon_squeezy/webhooks/subscription.rb +3 -3
- data/lib/pay/lemon_squeezy/webhooks/subscription_payment.rb +11 -0
- data/lib/pay/lemon_squeezy.rb +58 -104
- data/lib/pay/nano_id.rb +1 -1
- data/lib/pay/paddle_billing.rb +15 -6
- data/lib/pay/paddle_classic/webhooks/signature_verifier.rb +1 -1
- data/lib/pay/paddle_classic.rb +11 -9
- data/lib/pay/receipts.rb +45 -44
- data/lib/pay/stripe/webhooks/charge_updated.rb +11 -0
- data/lib/pay/stripe/webhooks/customer_updated.rb +13 -9
- data/lib/pay/stripe/webhooks/payment_action_required.rb +10 -6
- data/lib/pay/stripe/webhooks/payment_failed.rb +6 -4
- data/lib/pay/stripe/webhooks/subscription_renewing.rb +9 -4
- data/lib/pay/stripe.rb +28 -9
- data/lib/pay/version.rb +1 -1
- data/lib/pay.rb +19 -1
- data/lib/tasks/pay.rake +2 -2
- metadata +45 -43
- data/app/views/pay/stripe/_checkout_button.html.erb +0 -21
- data/lib/pay/braintree/authorization_error.rb +0 -9
- data/lib/pay/braintree/error.rb +0 -23
- data/lib/pay/fake_processor/charge.rb +0 -21
- data/lib/pay/fake_processor/error.rb +0 -6
- data/lib/pay/fake_processor/payment_method.rb +0 -21
- data/lib/pay/fake_processor/subscription.rb +0 -90
- data/lib/pay/lemon_squeezy/billable.rb +0 -90
- data/lib/pay/lemon_squeezy/charge.rb +0 -68
- data/lib/pay/lemon_squeezy/error.rb +0 -7
- data/lib/pay/lemon_squeezy/payment_method.rb +0 -40
- data/lib/pay/lemon_squeezy/subscription.rb +0 -185
- data/lib/pay/lemon_squeezy/webhooks/transaction_completed.rb +0 -11
- data/lib/pay/paddle_billing/error.rb +0 -7
- data/lib/pay/paddle_classic/error.rb +0 -7
- data/lib/pay/stripe/charge.rb +0 -176
- data/lib/pay/stripe/error.rb +0 -7
@@ -0,0 +1,8 @@
|
|
1
|
+
Your <%= Pay.application_name %> trial is ending soon
|
2
|
+
|
3
|
+
This is just a friendly reminder that your <%= Pay.application_name %> trial will be ending soon.
|
4
|
+
|
5
|
+
You may manage your subscription via your account: <%= root_url %>
|
6
|
+
If you have any questions, please hit reply and let us know.
|
7
|
+
|
8
|
+
— The <%= Pay.application_name %> Team
|
data/config/locales/en.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -6,4 +6,5 @@ Pay::Engine.routes.draw do
|
|
6
6
|
post "webhooks/braintree", to: "pay/webhooks/braintree#create" if Pay::Braintree.enabled?
|
7
7
|
post "webhooks/paddle_billing", to: "pay/webhooks/paddle_billing#create" if Pay::PaddleBilling.enabled?
|
8
8
|
post "webhooks/paddle_classic", to: "pay/webhooks/paddle_classic#create" if Pay::PaddleClassic.enabled?
|
9
|
+
post "webhooks/lemon_squeezy", to: "pay/webhooks/lemon_squeezy#create" if Pay::LemonSqueezy.enabled?
|
9
10
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class AddObjectToPayModels < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
add_column :pay_charges, :object, Pay::Adapter.json_column_type
|
4
|
+
add_column :pay_customers, :object, Pay::Adapter.json_column_type
|
5
|
+
add_column :pay_subscriptions, :object, Pay::Adapter.json_column_type
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class AddPayStiColumns < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
add_column :pay_customers, :type, :string
|
4
|
+
add_column :pay_charges, :type, :string
|
5
|
+
add_column :pay_subscriptions, :type, :string
|
6
|
+
|
7
|
+
rename_column :pay_payment_methods, :type, :payment_method_type
|
8
|
+
add_column :pay_payment_methods, :type, :string
|
9
|
+
|
10
|
+
add_column :pay_merchants, :type, :string
|
11
|
+
|
12
|
+
Pay::Customer.find_each do |pay_customer|
|
13
|
+
pay_customer.update(type: "Pay::#{pay_customer.processor.classify}::Customer")
|
14
|
+
|
15
|
+
pay_customer.charges.update_all(type: "Pay::#{pay_customer.processor.classify}::Charge")
|
16
|
+
pay_customer.subscriptions.update_all(type: "Pay::#{pay_customer.processor.classify}::Subscription")
|
17
|
+
pay_customer.payment_methods.update_all(type: "Pay::#{pay_customer.processor.classify}::PaymentMethod")
|
18
|
+
end
|
19
|
+
|
20
|
+
Pay::Merchant.find_each do |pay_merchant|
|
21
|
+
pay_merchant.update(type: "Pay::#{pay_merchant.processor.classify}::Merchant")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/pay/attributes.rb
CHANGED
@@ -13,8 +13,8 @@ module Pay
|
|
13
13
|
cattr_accessor :pay_braintree_customer_attributes
|
14
14
|
|
15
15
|
has_many :pay_customers, class_name: "Pay::Customer", as: :owner, inverse_of: :owner
|
16
|
-
has_many :
|
17
|
-
has_many :
|
16
|
+
has_many :pay_charges, through: :pay_customers, class_name: "Pay::Charge", source: :charges
|
17
|
+
has_many :pay_subscriptions, through: :pay_customers, class_name: "Pay::Subscription", source: :subscriptions
|
18
18
|
has_one :payment_processor, -> { where(default: true, deleted_at: nil) }, class_name: "Pay::Customer", as: :owner, inverse_of: :owner
|
19
19
|
|
20
20
|
after_commit :cancel_active_pay_subscriptions!, on: [:destroy]
|
@@ -31,9 +31,13 @@ module Pay
|
|
31
31
|
def set_payment_processor(processor_name, allow_fake: false, **attributes)
|
32
32
|
raise Pay::Error, "Processor `#{processor_name}` is not allowed" if processor_name.to_s == "fake_processor" && !allow_fake
|
33
33
|
|
34
|
-
|
34
|
+
# Safety check to make sure this is a valid Pay processor
|
35
|
+
klass = "Pay::#{processor_name.to_s.classify}::Customer".constantize
|
36
|
+
raise ArgumentError, "not a valid payment processor" if klass.ancestors.exclude?(Pay::Customer)
|
37
|
+
|
38
|
+
with_lock do
|
35
39
|
pay_customers.update_all(default: false)
|
36
|
-
pay_customer = pay_customers.active.where(processor: processor_name).first_or_initialize
|
40
|
+
pay_customer = pay_customers.active.where(processor: processor_name, type: klass.name).first_or_initialize
|
37
41
|
pay_customer.update!(attributes.merge(default: true))
|
38
42
|
end
|
39
43
|
|
@@ -44,7 +48,11 @@ module Pay
|
|
44
48
|
def add_payment_processor(processor_name, allow_fake: false, **attributes)
|
45
49
|
raise Pay::Error, "Processor `#{processor_name}` is not allowed" if processor_name.to_s == "fake_processor" && !allow_fake
|
46
50
|
|
47
|
-
|
51
|
+
# Safety check to make sure this is a valid Pay processor
|
52
|
+
klass = "Pay::#{processor_name.to_s.classify}::Customer".constantize
|
53
|
+
raise ArgumentError, "not a valid payment processor" if klass.ancestors.exclude?(Pay::Customer)
|
54
|
+
|
55
|
+
pay_customer = pay_customers.active.where(processor: processor_name, type: klass.name).first_or_initialize
|
48
56
|
pay_customer.update!(attributes)
|
49
57
|
pay_customer
|
50
58
|
end
|
@@ -60,7 +68,7 @@ module Pay
|
|
60
68
|
end
|
61
69
|
|
62
70
|
def cancel_active_pay_subscriptions!
|
63
|
-
|
71
|
+
pay_subscriptions.active.each(&:cancel_now!)
|
64
72
|
end
|
65
73
|
end
|
66
74
|
|
@@ -73,9 +81,9 @@ module Pay
|
|
73
81
|
end
|
74
82
|
|
75
83
|
def set_merchant_processor(processor_name, **attributes)
|
76
|
-
|
84
|
+
with_lock do
|
77
85
|
pay_merchants.update_all(default: false)
|
78
|
-
pay_merchant = pay_merchants.where(processor: processor_name).first_or_initialize
|
86
|
+
pay_merchant = pay_merchants.where(processor: processor_name, type: "Pay::#{processor_name.to_s.classify}::Merchant").first_or_initialize
|
79
87
|
pay_merchant.update!(attributes.merge(default: true))
|
80
88
|
end
|
81
89
|
|
data/lib/pay/braintree.rb
CHANGED
@@ -1,11 +1,30 @@
|
|
1
1
|
module Pay
|
2
2
|
module Braintree
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
class Error < Pay::Error
|
4
|
+
# For any manually raised Braintree error results (for failure responses)
|
5
|
+
# we can raise this exception manually but treat it as if we wrapped an exception
|
6
|
+
|
7
|
+
attr_reader :result
|
8
|
+
|
9
|
+
def initialize(result)
|
10
|
+
if result.is_a?(::Braintree::ErrorResult)
|
11
|
+
super(result.message)
|
12
|
+
@result = result
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def cause
|
19
|
+
super || result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class AuthorizationError < Error
|
24
|
+
def message
|
25
|
+
I18n.t("pay.errors.braintree.authorization")
|
26
|
+
end
|
27
|
+
end
|
9
28
|
|
10
29
|
module Webhooks
|
11
30
|
autoload :SubscriptionCanceled, "pay/braintree/webhooks/subscription_canceled"
|
data/lib/pay/engine.rb
CHANGED
@@ -28,12 +28,14 @@ module Pay
|
|
28
28
|
Pay::Braintree.configure_webhooks if Pay::Braintree.enabled?
|
29
29
|
Pay::PaddleBilling.configure_webhooks if Pay::PaddleBilling.enabled?
|
30
30
|
Pay::PaddleClassic.configure_webhooks if Pay::PaddleClassic.enabled?
|
31
|
+
Pay::LemonSqueezy.configure_webhooks if Pay::LemonSqueezy.enabled?
|
31
32
|
end
|
32
33
|
|
33
34
|
config.to_prepare do
|
34
35
|
Pay::Stripe.setup if Pay::Stripe.enabled?
|
35
36
|
Pay::Braintree.setup if Pay::Braintree.enabled?
|
36
37
|
Pay::PaddleBilling.setup if Pay::PaddleBilling.enabled?
|
38
|
+
Pay::LemonSqueezy.setup if Pay::LemonSqueezy.enabled?
|
37
39
|
|
38
40
|
if defined?(::Receipts::VERSION)
|
39
41
|
if Pay::Engine.version_matches?(required: "~> 2", current: ::Receipts::VERSION)
|
data/lib/pay/fake_processor.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
module Pay
|
2
2
|
module FakeProcessor
|
3
|
-
|
4
|
-
|
5
|
-
autoload :Error, "pay/fake_processor/error"
|
6
|
-
autoload :PaymentMethod, "pay/fake_processor/payment_method"
|
7
|
-
autoload :Subscription, "pay/fake_processor/subscription"
|
8
|
-
autoload :Merchant, "pay/fake_processor/merchant"
|
3
|
+
class Error < Pay::Error
|
4
|
+
end
|
9
5
|
end
|
10
6
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Pay
|
2
|
-
module
|
2
|
+
module LemonSqueezy
|
3
3
|
module Webhooks
|
4
4
|
class Subscription
|
5
|
-
def call(
|
6
|
-
Pay::
|
5
|
+
def call(subscription)
|
6
|
+
Pay::LemonSqueezy::Subscription.sync(subscription.id, object: subscription)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/pay/lemon_squeezy.rb
CHANGED
@@ -1,138 +1,92 @@
|
|
1
1
|
module Pay
|
2
2
|
module LemonSqueezy
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
autoload :Merchant, "pay/stripe/merchant"
|
7
|
-
autoload :PaymentMethod, "pay/stripe/payment_method"
|
8
|
-
autoload :Subscription, "pay/stripe/subscription"
|
3
|
+
class Error < Pay::Error
|
4
|
+
delegate :message, to: :cause
|
5
|
+
end
|
9
6
|
|
10
7
|
module Webhooks
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :CheckoutSessionCompleted, "pay/stripe/webhooks/checkout_session_completed"
|
15
|
-
autoload :CheckoutSessionAsyncPaymentSucceeded, "pay/stripe/webhooks/checkout_session_async_payment_succeeded"
|
16
|
-
autoload :CustomerDeleted, "pay/stripe/webhooks/customer_deleted"
|
17
|
-
autoload :CustomerUpdated, "pay/stripe/webhooks/customer_updated"
|
18
|
-
autoload :PaymentActionRequired, "pay/stripe/webhooks/payment_action_required"
|
19
|
-
autoload :PaymentFailed, "pay/stripe/webhooks/payment_failed"
|
20
|
-
autoload :PaymentIntentSucceeded, "pay/stripe/webhooks/payment_intent_succeeded"
|
21
|
-
autoload :PaymentMethodAttached, "pay/stripe/webhooks/payment_method_attached"
|
22
|
-
autoload :PaymentMethodDetached, "pay/stripe/webhooks/payment_method_detached"
|
23
|
-
autoload :PaymentMethodUpdated, "pay/stripe/webhooks/payment_method_updated"
|
24
|
-
autoload :SubscriptionCreated, "pay/stripe/webhooks/subscription_created"
|
25
|
-
autoload :SubscriptionDeleted, "pay/stripe/webhooks/subscription_deleted"
|
26
|
-
autoload :SubscriptionRenewing, "pay/stripe/webhooks/subscription_renewing"
|
27
|
-
autoload :SubscriptionUpdated, "pay/stripe/webhooks/subscription_updated"
|
28
|
-
autoload :SubscriptionTrialWillEnd, "pay/stripe/webhooks/subscription_trial_will_end"
|
8
|
+
autoload :Order, "pay/lemon_squeezy/webhooks/order"
|
9
|
+
autoload :Subscription, "pay/lemon_squeezy/webhooks/subscription"
|
10
|
+
autoload :SubscriptionPayment, "pay/lemon_squeezy/webhooks/subscription_payment"
|
29
11
|
end
|
30
12
|
|
31
13
|
extend Env
|
32
14
|
|
33
|
-
REQUIRED_VERSION = "~> 1"
|
34
|
-
|
35
15
|
def self.enabled?
|
36
|
-
return false unless Pay.enabled_processors.include?(:
|
16
|
+
return false unless Pay.enabled_processors.include?(:lemon_squeezy) && defined?(::LemonSqueezy)
|
37
17
|
|
38
|
-
Pay::Engine.version_matches?(required:
|
18
|
+
Pay::Engine.version_matches?(required: "~> 1.0", current: ::LemonSqueezy::VERSION) || (raise "[Pay] lemonsqueezy gem must be version ~> 1.0")
|
39
19
|
end
|
40
20
|
|
41
21
|
def self.setup
|
42
|
-
::
|
22
|
+
::LemonSqueezy.config.api_key = api_key
|
23
|
+
end
|
43
24
|
|
44
|
-
|
45
|
-
|
25
|
+
def self.api_key
|
26
|
+
find_value_by_name(:lemon_squeezy, :api_key)
|
27
|
+
end
|
46
28
|
|
47
|
-
|
48
|
-
|
49
|
-
# https://github.com/stripe/stripe-ruby#configuring-automatic-retries
|
50
|
-
::Stripe.max_network_retries = 2
|
29
|
+
def self.store_id
|
30
|
+
find_value_by_name(:lemon_squeezy, :store_id)
|
51
31
|
end
|
52
32
|
|
53
|
-
def self.
|
54
|
-
find_value_by_name(:
|
33
|
+
def self.signing_secret
|
34
|
+
find_value_by_name(:lemon_squeezy, :signing_secret)
|
55
35
|
end
|
56
36
|
|
57
|
-
def self.
|
58
|
-
|
37
|
+
def self.passthrough(owner:, **options)
|
38
|
+
owner.to_sgid.to_s
|
59
39
|
end
|
60
40
|
|
61
|
-
def self.
|
62
|
-
|
41
|
+
def self.owner_from_passthrough(passthrough)
|
42
|
+
GlobalID::Locator.locate_signed passthrough
|
43
|
+
rescue JSON::ParserError
|
44
|
+
nil
|
63
45
|
end
|
64
46
|
|
65
47
|
def self.configure_webhooks
|
66
48
|
Pay::Webhooks.configure do |events|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
events.subscribe "
|
71
|
-
events.subscribe "
|
72
|
-
|
73
|
-
events.subscribe "stripe.payment_intent.succeeded", Pay::Stripe::Webhooks::PaymentIntentSucceeded.new
|
74
|
-
|
75
|
-
# Warn user of upcoming charges for their subscription. This is handy for
|
76
|
-
# notifying annual users their subscription will renew shortly.
|
77
|
-
# This probably should be ignored for monthly subscriptions.
|
78
|
-
events.subscribe "stripe.invoice.upcoming", Pay::Stripe::Webhooks::SubscriptionRenewing.new
|
79
|
-
|
80
|
-
# Payment action is required to process an invoice
|
81
|
-
events.subscribe "stripe.invoice.payment_action_required", Pay::Stripe::Webhooks::PaymentActionRequired.new
|
82
|
-
|
83
|
-
# If an invoice payment fails, we want to notify the user via email to update their payment details
|
84
|
-
events.subscribe "stripe.invoice.payment_failed", Pay::Stripe::Webhooks::PaymentFailed.new
|
85
|
-
|
86
|
-
# If a subscription is manually created on Stripe, we want to sync
|
87
|
-
events.subscribe "stripe.customer.subscription.created", Pay::Stripe::Webhooks::SubscriptionCreated.new
|
88
|
-
|
89
|
-
# If the plan, quantity, or trial ending date is updated on Stripe, we want to sync
|
90
|
-
events.subscribe "stripe.customer.subscription.updated", Pay::Stripe::Webhooks::SubscriptionUpdated.new
|
91
|
-
|
92
|
-
# When a customers subscription is canceled, we want to update our records
|
93
|
-
events.subscribe "stripe.customer.subscription.deleted", Pay::Stripe::Webhooks::SubscriptionDeleted.new
|
94
|
-
|
95
|
-
# When a customers subscription trial period is 3 days from ending or ended immediately this event is fired
|
96
|
-
events.subscribe "stripe.customer.subscription.trial_will_end", Pay::Stripe::Webhooks::SubscriptionTrialWillEnd.new
|
97
|
-
|
98
|
-
# Monitor changes for customer's default card changing and invoice credit updates
|
99
|
-
events.subscribe "stripe.customer.updated", Pay::Stripe::Webhooks::CustomerUpdated.new
|
100
|
-
|
101
|
-
# If a customer was deleted in Stripe, their subscriptions should be cancelled
|
102
|
-
events.subscribe "stripe.customer.deleted", Pay::Stripe::Webhooks::CustomerDeleted.new
|
103
|
-
|
104
|
-
# If a customer's payment source was deleted in Stripe, we should update as well
|
105
|
-
events.subscribe "stripe.payment_method.attached", Pay::Stripe::Webhooks::PaymentMethodAttached.new
|
106
|
-
events.subscribe "stripe.payment_method.updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
107
|
-
events.subscribe "stripe.payment_method.card_automatically_updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
108
|
-
events.subscribe "stripe.payment_method.detached", Pay::Stripe::Webhooks::PaymentMethodDetached.new
|
109
|
-
|
110
|
-
# If an account is updated in stripe, we should update it as well
|
111
|
-
events.subscribe "stripe.account.updated", Pay::Stripe::Webhooks::AccountUpdated.new
|
112
|
-
|
113
|
-
# Handle subscriptions in Stripe Checkout Sessions
|
114
|
-
events.subscribe "stripe.checkout.session.completed", Pay::Stripe::Webhooks::CheckoutSessionCompleted.new
|
115
|
-
events.subscribe "stripe.checkout.session.async_payment_succeeded", Pay::Stripe::Webhooks::CheckoutSessionAsyncPaymentSucceeded.new
|
49
|
+
events.subscribe "lemon_squeezy.order_created", Pay::LemonSqueezy::Webhooks::Order.new
|
50
|
+
events.subscribe "lemon_squeezy.subscription_created", Pay::LemonSqueezy::Webhooks::Subscription.new
|
51
|
+
events.subscribe "lemon_squeezy.subscription_updated", Pay::LemonSqueezy::Webhooks::Subscription.new
|
52
|
+
events.subscribe "lemon_squeezy.subscription_payment_refunded", Pay::LemonSqueezy::Webhooks::SubscriptionPayment.new
|
53
|
+
events.subscribe "lemon_squeezy.subscription_payment_success", Pay::LemonSqueezy::Webhooks::SubscriptionPayment.new
|
116
54
|
end
|
117
55
|
end
|
118
56
|
|
119
|
-
def self.
|
120
|
-
|
121
|
-
|
57
|
+
def self.construct_from_webhook_event(event)
|
58
|
+
data = event["data"]
|
59
|
+
case data
|
60
|
+
when Array
|
61
|
+
data.map do |object|
|
62
|
+
construct_from_webhook_event(object)
|
63
|
+
end
|
64
|
+
when Hash
|
65
|
+
type = {
|
66
|
+
"orders" => ::LemonSqueezy::Order,
|
67
|
+
"subscriptions" => ::LemonSqueezy::Subscription,
|
68
|
+
"subscription-invoices" => ::LemonSqueezy::SubscriptionInvoice
|
69
|
+
}.fetch(data["type"])
|
70
|
+
|
71
|
+
object = type.new(data)
|
72
|
+
object.meta = event["meta"]
|
73
|
+
object
|
74
|
+
end
|
122
75
|
end
|
123
76
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
77
|
+
# An Order may have subscriptions or be a one-time purchase
|
78
|
+
def self.sync_order(order_id, object: nil)
|
79
|
+
subscriptions = ::LemonSqueezy::Subscription.list(order_id: order_id).data
|
80
|
+
subscriptions.each do |subscription|
|
81
|
+
Pay::LemonSqueezy::Subscription.sync(subscription.id, object: subscription)
|
82
|
+
::LemonSqueezy::SubscriptionInvoice.list(subscription_id: subscription.id).data.each do |invoice|
|
83
|
+
Pay::LemonSqueezy::Charge.sync_subscription_invoice(invoice.id, object: invoice)
|
84
|
+
end
|
85
|
+
end
|
131
86
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
nil
|
87
|
+
if subscriptions.empty?
|
88
|
+
Pay::LemonSqueezy::Charge.sync_order(order_id, object: object)
|
89
|
+
end
|
136
90
|
end
|
137
91
|
end
|
138
92
|
end
|
data/lib/pay/nano_id.rb
CHANGED
data/lib/pay/paddle_billing.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Pay
|
2
2
|
module PaddleBilling
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
autoload :PaymentMethod, "pay/paddle_billing/payment_method"
|
7
|
-
autoload :Subscription, "pay/paddle_billing/subscription"
|
3
|
+
class Error < Pay::Error
|
4
|
+
delegate :message, to: :cause
|
5
|
+
end
|
8
6
|
|
9
7
|
module Webhooks
|
10
8
|
autoload :Subscription, "pay/paddle_billing/webhooks/subscription"
|
@@ -16,7 +14,8 @@ module Pay
|
|
16
14
|
def self.enabled?
|
17
15
|
return false unless Pay.enabled_processors.include?(:paddle_billing) && defined?(::Paddle)
|
18
16
|
|
19
|
-
Pay::Engine.version_matches?(required: "~> 2.
|
17
|
+
Pay::Engine.version_matches?(required: "~> 2.5",
|
18
|
+
current: ::Paddle::VERSION) || (raise "[Pay] paddle gem must be version ~> 2.5")
|
20
19
|
end
|
21
20
|
|
22
21
|
def self.setup
|
@@ -54,5 +53,15 @@ module Pay
|
|
54
53
|
events.subscribe "paddle_billing.transaction.completed", Pay::PaddleBilling::Webhooks::TransactionCompleted.new
|
55
54
|
end
|
56
55
|
end
|
56
|
+
|
57
|
+
def self.sync_transaction(transaction_id)
|
58
|
+
transaction = ::Paddle::Transaction.retrieve(id: transaction_id)
|
59
|
+
|
60
|
+
if transaction.subscription_id.present?
|
61
|
+
Pay::PaddleBilling::Subscription.sync(transaction.subscription_id)
|
62
|
+
else
|
63
|
+
Pay::PaddleBilling::Charge.sync(transaction_id, object: transaction)
|
64
|
+
end
|
65
|
+
end
|
57
66
|
end
|
58
67
|
end
|
@@ -61,7 +61,7 @@ module Pay
|
|
61
61
|
# array will be assumed to be an associative array, and will be serialized
|
62
62
|
# as a PHP associative array rather than a multidimensional array.
|
63
63
|
def serialize(var, assoc = false)
|
64
|
-
s = ""
|
64
|
+
s = +""
|
65
65
|
case var
|
66
66
|
when Array
|
67
67
|
s << "a:#{var.size}:{"
|
data/lib/pay/paddle_classic.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Pay
|
2
2
|
module PaddleClassic
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
autoload :PaymentMethod, "pay/paddle_classic/payment_method"
|
7
|
-
autoload :Subscription, "pay/paddle_classic/subscription"
|
3
|
+
class Error < Pay::Error
|
4
|
+
delegate :message, to: :cause
|
5
|
+
end
|
8
6
|
|
9
7
|
module Webhooks
|
10
8
|
autoload :SignatureVerifier, "pay/paddle_classic/webhooks/signature_verifier"
|
@@ -20,7 +18,8 @@ module Pay
|
|
20
18
|
def self.enabled?
|
21
19
|
return false unless Pay.enabled_processors.include?(:paddle_classic) && defined?(::Paddle)
|
22
20
|
|
23
|
-
Pay::Engine.version_matches?(required: "~> 2.
|
21
|
+
Pay::Engine.version_matches?(required: "~> 2.5",
|
22
|
+
current: ::Paddle::VERSION) || (raise "[Pay] paddle gem must be version ~> 2.5")
|
24
23
|
end
|
25
24
|
|
26
25
|
def self.client
|
@@ -73,9 +72,12 @@ module Pay
|
|
73
72
|
Pay::Webhooks.configure do |events|
|
74
73
|
events.subscribe "paddle_classic.subscription_created", Pay::PaddleClassic::Webhooks::SubscriptionCreated.new
|
75
74
|
events.subscribe "paddle_classic.subscription_updated", Pay::PaddleClassic::Webhooks::SubscriptionUpdated.new
|
76
|
-
events.subscribe "paddle_classic.subscription_cancelled",
|
77
|
-
|
78
|
-
events.subscribe "paddle_classic.
|
75
|
+
events.subscribe "paddle_classic.subscription_cancelled",
|
76
|
+
Pay::PaddleClassic::Webhooks::SubscriptionCancelled.new
|
77
|
+
events.subscribe "paddle_classic.subscription_payment_succeeded",
|
78
|
+
Pay::PaddleClassic::Webhooks::SubscriptionPaymentSucceeded.new
|
79
|
+
events.subscribe "paddle_classic.subscription_payment_refunded",
|
80
|
+
Pay::PaddleClassic::Webhooks::SubscriptionPaymentRefunded.new
|
79
81
|
end
|
80
82
|
end
|
81
83
|
end
|