pay 6.8.0 → 7.0.0

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/pay/webhooks/paddle_billing_controller.rb +51 -0
  3. data/app/controllers/pay/webhooks/{paddle_controller.rb → paddle_classic_controller.rb} +6 -6
  4. data/app/mailers/pay/application_mailer.rb +5 -1
  5. data/app/models/pay/charge.rb +1 -2
  6. data/app/models/pay/customer.rb +1 -2
  7. data/app/models/pay/merchant.rb +1 -3
  8. data/app/models/pay/payment_method.rb +1 -2
  9. data/app/models/pay/subscription.rb +10 -11
  10. data/app/models/pay/webhook.rb +10 -5
  11. data/app/views/pay/payments/show.html.erb +10 -17
  12. data/config/locales/en.yml +1 -1
  13. data/config/routes.rb +2 -1
  14. data/db/migrate/1_create_pay_tables.rb +6 -1
  15. data/lib/pay/braintree/subscription.rb +12 -2
  16. data/lib/pay/engine.rb +3 -2
  17. data/lib/pay/env.rb +1 -7
  18. data/lib/pay/fake_processor/subscription.rb +11 -1
  19. data/lib/pay/lemon_squeezy/billable.rb +90 -0
  20. data/lib/pay/lemon_squeezy/charge.rb +68 -0
  21. data/lib/pay/{paddle → lemon_squeezy}/error.rb +1 -1
  22. data/lib/pay/lemon_squeezy/payment_method.rb +40 -0
  23. data/lib/pay/lemon_squeezy/subscription.rb +185 -0
  24. data/lib/pay/lemon_squeezy/webhooks/subscription.rb +11 -0
  25. data/lib/pay/lemon_squeezy/webhooks/transaction_completed.rb +11 -0
  26. data/lib/pay/lemon_squeezy.rb +138 -0
  27. data/lib/pay/paddle_billing/billable.rb +90 -0
  28. data/lib/pay/paddle_billing/charge.rb +68 -0
  29. data/lib/pay/paddle_billing/error.rb +7 -0
  30. data/lib/pay/paddle_billing/payment_method.rb +40 -0
  31. data/lib/pay/paddle_billing/subscription.rb +185 -0
  32. data/lib/pay/paddle_billing/webhooks/subscription.rb +11 -0
  33. data/lib/pay/paddle_billing/webhooks/transaction_completed.rb +11 -0
  34. data/lib/pay/paddle_billing.rb +58 -0
  35. data/lib/pay/{paddle → paddle_classic}/billable.rb +9 -10
  36. data/lib/pay/paddle_classic/charge.rb +35 -0
  37. data/lib/pay/paddle_classic/error.rb +7 -0
  38. data/lib/pay/{paddle → paddle_classic}/payment_method.rb +4 -4
  39. data/lib/pay/{paddle → paddle_classic}/subscription.rb +39 -30
  40. data/lib/pay/{paddle → paddle_classic}/webhooks/signature_verifier.rb +4 -4
  41. data/lib/pay/{paddle → paddle_classic}/webhooks/subscription_cancelled.rb +5 -4
  42. data/lib/pay/{paddle → paddle_classic}/webhooks/subscription_created.rb +2 -2
  43. data/lib/pay/{paddle → paddle_classic}/webhooks/subscription_payment_refunded.rb +2 -2
  44. data/lib/pay/{paddle → paddle_classic}/webhooks/subscription_payment_succeeded.rb +7 -7
  45. data/lib/pay/{paddle → paddle_classic}/webhooks/subscription_updated.rb +2 -2
  46. data/lib/pay/paddle_classic.rb +82 -0
  47. data/lib/pay/receipts.rb +1 -1
  48. data/lib/pay/stripe/billable.rb +6 -2
  49. data/lib/pay/stripe/charge.rb +8 -4
  50. data/lib/pay/stripe/payment_method.rb +9 -1
  51. data/lib/pay/stripe/subscription.rb +54 -4
  52. data/lib/pay/stripe.rb +3 -4
  53. data/lib/pay/version.rb +1 -1
  54. data/lib/pay.rb +3 -2
  55. data/lib/tasks/pay.rake +2 -2
  56. metadata +33 -17
  57. data/lib/pay/paddle/charge.rb +0 -35
  58. data/lib/pay/paddle/response.rb +0 -0
  59. data/lib/pay/paddle.rb +0 -80
@@ -0,0 +1,82 @@
1
+ module Pay
2
+ module PaddleClassic
3
+ autoload :Billable, "pay/paddle_classic/billable"
4
+ autoload :Charge, "pay/paddle_classic/charge"
5
+ autoload :Error, "pay/paddle_classic/error"
6
+ autoload :PaymentMethod, "pay/paddle_classic/payment_method"
7
+ autoload :Subscription, "pay/paddle_classic/subscription"
8
+
9
+ module Webhooks
10
+ autoload :SignatureVerifier, "pay/paddle_classic/webhooks/signature_verifier"
11
+ autoload :SubscriptionCreated, "pay/paddle_classic/webhooks/subscription_created"
12
+ autoload :SubscriptionCancelled, "pay/paddle_classic/webhooks/subscription_cancelled"
13
+ autoload :SubscriptionPaymentRefunded, "pay/paddle_classic/webhooks/subscription_payment_refunded"
14
+ autoload :SubscriptionPaymentSucceeded, "pay/paddle_classic/webhooks/subscription_payment_succeeded"
15
+ autoload :SubscriptionUpdated, "pay/paddle_classic/webhooks/subscription_updated"
16
+ end
17
+
18
+ extend Env
19
+
20
+ def self.enabled?
21
+ return false unless Pay.enabled_processors.include?(:paddle_classic) && defined?(::Paddle)
22
+
23
+ Pay::Engine.version_matches?(required: "~> 2.1", current: ::Paddle::VERSION) || (raise "[Pay] paddle gem must be version ~> 2.1")
24
+ end
25
+
26
+ def self.client
27
+ @client ||= Paddle::Classic::Client.new(
28
+ vendor_id: vendor_id,
29
+ vendor_auth_code: vendor_auth_code,
30
+ sandbox: environment != "production"
31
+ )
32
+ end
33
+
34
+ def self.vendor_id
35
+ find_value_by_name(:paddle_classic, :vendor_id)
36
+ end
37
+
38
+ def self.vendor_auth_code
39
+ find_value_by_name(:paddle_classic, :vendor_auth_code)
40
+ end
41
+
42
+ def self.environment
43
+ find_value_by_name(:paddle_classic, :environment) || "production"
44
+ end
45
+
46
+ def self.public_key
47
+ find_value_by_name(:paddle_classic, :public_key)
48
+ end
49
+
50
+ def self.public_key_file
51
+ find_value_by_name(:paddle_classic, :public_key_file)
52
+ end
53
+
54
+ def self.public_key_base64
55
+ find_value_by_name(:paddle_classic, :public_key_base64)
56
+ end
57
+
58
+ def self.passthrough(owner:, **options)
59
+ options.merge(owner_sgid: owner.to_sgid.to_s).to_json
60
+ end
61
+
62
+ def self.parse_passthrough(passthrough)
63
+ JSON.parse(passthrough)
64
+ end
65
+
66
+ def self.owner_from_passthrough(passthrough)
67
+ GlobalID::Locator.locate_signed parse_passthrough(passthrough)["owner_sgid"]
68
+ rescue JSON::ParserError
69
+ nil
70
+ end
71
+
72
+ def self.configure_webhooks
73
+ Pay::Webhooks.configure do |events|
74
+ events.subscribe "paddle_classic.subscription_created", Pay::PaddleClassic::Webhooks::SubscriptionCreated.new
75
+ events.subscribe "paddle_classic.subscription_updated", Pay::PaddleClassic::Webhooks::SubscriptionUpdated.new
76
+ events.subscribe "paddle_classic.subscription_cancelled", Pay::PaddleClassic::Webhooks::SubscriptionCancelled.new
77
+ events.subscribe "paddle_classic.subscription_payment_succeeded", Pay::PaddleClassic::Webhooks::SubscriptionPaymentSucceeded.new
78
+ events.subscribe "paddle_classic.subscription_payment_refunded", Pay::PaddleClassic::Webhooks::SubscriptionPaymentRefunded.new
79
+ end
80
+ end
81
+ end
82
+ end
data/lib/pay/receipts.rb CHANGED
@@ -119,7 +119,7 @@ module Pay
119
119
  company: {
120
120
  name: Pay.business_name,
121
121
  address: Pay.business_address,
122
- email: Pay.support_email.address,
122
+ email: Pay.support_email&.address,
123
123
  logo: Pay.business_logo
124
124
  },
125
125
  line_items: receipt_line_items
@@ -227,12 +227,16 @@ module Pay
227
227
  mode: "payment"
228
228
  }
229
229
 
230
- # Embedded checkouts cannot use URLs
231
- if options[:ui_mode] != "embedded"
230
+ # Hosted (the default) checkout sessions require a success_url and cancel_url
231
+ if ["", "hosted"].include? options[:ui_mode].to_s
232
232
  args[:success_url] = merge_session_id_param(options.delete(:success_url) || root_url)
233
233
  args[:cancel_url] = merge_session_id_param(options.delete(:cancel_url) || root_url)
234
234
  end
235
235
 
236
+ if options[:return_url]
237
+ args[:return_url] = merge_session_id_param(options.delete(:return_url))
238
+ end
239
+
236
240
  # Line items are optional
237
241
  if (line_items = options.delete(:line_items))
238
242
  quantity = options.delete(:quantity) || 1
@@ -15,12 +15,16 @@ module Pay
15
15
  def self.sync(charge_id, object: nil, stripe_account: nil, try: 0, retries: 1)
16
16
  # Skip loading the latest charge details from the API if we already have it
17
17
  object ||= ::Stripe::Charge.retrieve({id: charge_id, expand: ["invoice.total_discount_amounts.discount", "invoice.total_tax_amounts.tax_rate", "refunds"]}, {stripe_account: stripe_account}.compact)
18
-
19
- # Ignore charges without a Customer
20
- return if object.customer.blank?
18
+ if object.customer.blank?
19
+ Rails.logger.debug "Stripe Charge #{object.id} does not have a customer"
20
+ return
21
+ end
21
22
 
22
23
  pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
23
- return unless pay_customer
24
+ if pay_customer.blank?
25
+ Rails.logger.debug "Pay::Customer #{object.customer} is not in the database while syncing Stripe Charge #{object.id}"
26
+ return
27
+ end
24
28
 
25
29
  refunds = []
26
30
  object.refunds.auto_paging_each { |refund| refunds << refund }
@@ -28,9 +28,16 @@ module Pay
28
28
  # Syncs PaymentMethod objects from Stripe
29
29
  def self.sync(id, object: nil, stripe_account: nil, try: 0, retries: 1)
30
30
  object ||= ::Stripe::PaymentMethod.retrieve(id, {stripe_account: stripe_account}.compact)
31
+ if object.customer.blank?
32
+ Rails.logger.debug "Stripe PaymentMethod #{object.id} does not have a customer"
33
+ return
34
+ end
31
35
 
32
36
  pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
33
- return unless pay_customer
37
+ if pay_customer.blank?
38
+ Rails.logger.debug "Pay::Customer #{object.customer} is not in the database while syncing Stripe PaymentMethod #{object.id}"
39
+ return
40
+ end
34
41
 
35
42
  default_payment_method_id = pay_customer.customer.invoice_settings.default_payment_method
36
43
  default = (id == default_payment_method_id)
@@ -57,6 +64,7 @@ module Pay
57
64
 
58
65
  {
59
66
  payment_method_type: payment_method.type,
67
+ email: details.try(:email), # Link
60
68
  brand: details.try(:brand)&.capitalize,
61
69
  last4: details.try(:last4).to_s,
62
70
  exp_month: details.try(:exp_month).to_s,
@@ -10,6 +10,7 @@ module Pay
10
10
  :ends_at,
11
11
  :name,
12
12
  :on_trial?,
13
+ :past_due?,
13
14
  :pause_starts_at,
14
15
  :pause_starts_at?,
15
16
  :processor_id,
@@ -28,12 +29,24 @@ module Pay
28
29
  :current_period_end,
29
30
  to: :pay_subscription
30
31
 
32
+ def self.sync_from_checkout_session(session_id, stripe_account: nil)
33
+ checkout_session = ::Stripe::Checkout::Session.retrieve({id: session_id}, {stripe_account: stripe_account}.compact)
34
+ sync(checkout_session.subscription)
35
+ end
36
+
31
37
  def self.sync(subscription_id, object: nil, name: nil, stripe_account: nil, try: 0, retries: 1)
32
38
  # Skip loading the latest subscription details from the API if we already have it
33
39
  object ||= ::Stripe::Subscription.retrieve({id: subscription_id}.merge(expand_options), {stripe_account: stripe_account}.compact)
40
+ if object.customer.blank?
41
+ Rails.logger.debug "Stripe Subscription #{object.id} does not have a customer"
42
+ return
43
+ end
34
44
 
35
45
  pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
36
- return unless pay_customer
46
+ if pay_customer.blank?
47
+ Rails.logger.debug "Pay::Customer #{object.customer} is not in the database while syncing Stripe Subscription #{object.id}"
48
+ return
49
+ end
37
50
 
38
51
  attributes = {
39
52
  application_fee_percent: object.application_fee_percent,
@@ -82,6 +95,17 @@ module Pay
82
95
  Time.at(object.current_period_end)
83
96
  end
84
97
 
98
+ # Sync payment method if directly attached to subscription
99
+ if object.default_payment_method
100
+ if object.default_payment_method.is_a? String
101
+ Pay::Stripe::PaymentMethod.sync(object.default_payment_method)
102
+ attributes[:payment_method_id] = object.default_payment_method
103
+ else
104
+ Pay::Stripe::PaymentMethod.sync(object.default_payment_method.id, object: object.default_payment_method)
105
+ attributes[:payment_method_id] = object.default_payment_method.id
106
+ end
107
+ end
108
+
85
109
  # Update or create the subscription
86
110
  pay_subscription = pay_customer.subscriptions.find_by(processor_id: object.id)
87
111
  if pay_subscription
@@ -123,6 +147,7 @@ module Pay
123
147
  def self.expand_options
124
148
  {
125
149
  expand: [
150
+ "default_payment_method",
126
151
  "pending_setup_intent",
127
152
  "latest_invoice.payment_intent",
128
153
  "latest_invoice.charge",
@@ -151,9 +176,28 @@ module Pay
151
176
  stripe_sub&.pending_setup_intent&.client_secret || stripe_sub&.latest_invoice&.payment_intent&.client_secret
152
177
  end
153
178
 
179
+ # Sets the default_payment_method on a subscription
180
+ # Pass an empty string to unset
181
+ def update_payment_method(id)
182
+ @stripe_subscription = ::Stripe::Subscription.update(processor_id, {default_payment_method: id}.merge(expand_options), stripe_options)
183
+ pay_subscription.update(payment_method_id: @stripe_subscription.default_payment_method&.id)
184
+ rescue ::Stripe::StripeError => e
185
+ raise Pay::Stripe::Error, e
186
+ end
187
+
188
+ # Marks a subscription to cancel at period end
189
+ #
190
+ # If subscription is already past_due, the subscription will be cancelled immediately
191
+ # To disable this, pass past_due_cancel_now: false
154
192
  def cancel(**options)
155
- @stripe_subscription = ::Stripe::Subscription.update(processor_id, {cancel_at_period_end: true}.merge(expand_options), stripe_options)
156
- pay_subscription.update(ends_at: (on_trial? ? trial_ends_at : Time.at(@stripe_subscription.current_period_end)))
193
+ return if canceled?
194
+
195
+ if past_due? && options.fetch(:past_due_cancel_now, true)
196
+ cancel_now!
197
+ else
198
+ @stripe_subscription = ::Stripe::Subscription.update(processor_id, {cancel_at_period_end: true}.merge(expand_options), stripe_options)
199
+ pay_subscription.update(ends_at: (on_trial? ? trial_ends_at : Time.at(@stripe_subscription.current_period_end)))
200
+ end
157
201
  rescue ::Stripe::StripeError => e
158
202
  raise Pay::Stripe::Error, e
159
203
  end
@@ -163,6 +207,8 @@ module Pay
163
207
  # cancel_now!(prorate: true)
164
208
  # cancel_now!(invoice_now: true)
165
209
  def cancel_now!(**options)
210
+ return if canceled?
211
+
166
212
  @stripe_subscription = ::Stripe::Subscription.cancel(processor_id, options.merge(expand_options), stripe_options)
167
213
  pay_subscription.update(ends_at: Time.current, status: :canceled)
168
214
  rescue ::Stripe::StripeError => e
@@ -236,8 +282,12 @@ module Pay
236
282
  )
237
283
  end
238
284
 
285
+ def resumable?
286
+ on_grace_period? || paused?
287
+ end
288
+
239
289
  def resume
240
- unless on_grace_period? || paused?
290
+ unless resumable?
241
291
  raise StandardError, "You can only resume subscriptions within their grace period."
242
292
  end
243
293
 
data/lib/pay/stripe.rb CHANGED
@@ -30,7 +30,7 @@ module Pay
30
30
 
31
31
  extend Env
32
32
 
33
- REQUIRED_VERSION = "~> 9"
33
+ REQUIRED_VERSION = "~> 10"
34
34
 
35
35
  # A list of database model names that include Pay
36
36
  # Used for safely looking up models with client_reference_id
@@ -44,7 +44,6 @@ module Pay
44
44
 
45
45
  def self.setup
46
46
  ::Stripe.api_key = private_key
47
- ::Stripe.api_version ||= "2023-08-16"
48
47
 
49
48
  # Used by Stripe to identify Pay for support
50
49
  ::Stripe.set_app_info("PayRails", partner_id: "pp_partner_IqhY0UExnJYLxg", version: Pay::VERSION, url: "https://github.com/pay-rails/pay")
@@ -123,13 +122,13 @@ module Pay
123
122
 
124
123
  def self.to_client_reference_id(record)
125
124
  raise ArgumentError, "#{record.class.name} does not include Pay. Allowed models: #{model_names.to_a.join(", ")}" unless model_names.include?(record.class.name)
126
- [record.class.name, record.id].join("/")
125
+ [record.class.name, record.id].join("_")
127
126
  end
128
127
 
129
128
  def self.find_by_client_reference_id(client_reference_id)
130
129
  # If there is a client reference ID, make sure we have a Pay::Customer record
131
130
  # client_reference_id should be in the format of "User/1"
132
- model_name, id = client_reference_id.split("/", 2)
131
+ model_name, id = client_reference_id.split("_", 2)
133
132
 
134
133
  # Only allow model names that use Pay
135
134
  return unless model_names.include?(model_name)
data/lib/pay/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pay
2
- VERSION = "6.8.0"
2
+ VERSION = "7.0.0"
3
3
  end
data/lib/pay.rb CHANGED
@@ -17,7 +17,8 @@ module Pay
17
17
  # Payment processors
18
18
  autoload :Braintree, "pay/braintree"
19
19
  autoload :FakeProcessor, "pay/fake_processor"
20
- autoload :Paddle, "pay/paddle"
20
+ autoload :PaddleBilling, "pay/paddle_billing"
21
+ autoload :PaddleClassic, "pay/paddle_classic"
21
22
  autoload :Stripe, "pay/stripe"
22
23
 
23
24
  autoload :Webhooks, "pay/webhooks"
@@ -55,7 +56,7 @@ module Pay
55
56
  @@routes_path = "/pay"
56
57
 
57
58
  mattr_accessor :enabled_processors
58
- @@enabled_processors = [:stripe, :braintree, :paddle]
59
+ @@enabled_processors = [:stripe, :braintree, :paddle_billing, :paddle_classic]
59
60
 
60
61
  mattr_accessor :send_emails
61
62
  @@send_emails = true
data/lib/tasks/pay.rake CHANGED
@@ -20,8 +20,8 @@ def sync_default_payment_method(pay_customer, retries: 2)
20
20
  when "stripe"
21
21
  payment_method_id = pay_customer.customer.invoice_settings.default_payment_method
22
22
  Pay::Stripe::PaymentMethod.sync(payment_method_id) if payment_method_id
23
- when "paddle"
24
- Pay::Paddle::PaymentMethod.sync(pay_customer: pay_customer)
23
+ when "paddle_classic"
24
+ Pay::PaddleClassic::PaymentMethod.sync(pay_customer: pay_customer)
25
25
  end
26
26
  rescue
27
27
  sleep 0.5
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: 6.8.0
4
+ version: 7.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Charnes
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-08-22 00:00:00.000000000 Z
13
+ date: 2023-12-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -44,7 +44,8 @@ files:
44
44
  - app/controllers/pay/application_controller.rb
45
45
  - app/controllers/pay/payments_controller.rb
46
46
  - app/controllers/pay/webhooks/braintree_controller.rb
47
- - app/controllers/pay/webhooks/paddle_controller.rb
47
+ - app/controllers/pay/webhooks/paddle_billing_controller.rb
48
+ - app/controllers/pay/webhooks/paddle_classic_controller.rb
48
49
  - app/controllers/pay/webhooks/stripe_controller.rb
49
50
  - app/helpers/pay/application_helper.rb
50
51
  - app/jobs/pay/application_job.rb
@@ -103,20 +104,35 @@ files:
103
104
  - lib/pay/fake_processor/merchant.rb
104
105
  - lib/pay/fake_processor/payment_method.rb
105
106
  - lib/pay/fake_processor/subscription.rb
107
+ - lib/pay/lemon_squeezy.rb
108
+ - lib/pay/lemon_squeezy/billable.rb
109
+ - lib/pay/lemon_squeezy/charge.rb
110
+ - lib/pay/lemon_squeezy/error.rb
111
+ - lib/pay/lemon_squeezy/payment_method.rb
112
+ - lib/pay/lemon_squeezy/subscription.rb
113
+ - lib/pay/lemon_squeezy/webhooks/subscription.rb
114
+ - lib/pay/lemon_squeezy/webhooks/transaction_completed.rb
106
115
  - lib/pay/nano_id.rb
107
- - lib/pay/paddle.rb
108
- - lib/pay/paddle/billable.rb
109
- - lib/pay/paddle/charge.rb
110
- - lib/pay/paddle/error.rb
111
- - lib/pay/paddle/payment_method.rb
112
- - lib/pay/paddle/response.rb
113
- - lib/pay/paddle/subscription.rb
114
- - lib/pay/paddle/webhooks/signature_verifier.rb
115
- - lib/pay/paddle/webhooks/subscription_cancelled.rb
116
- - lib/pay/paddle/webhooks/subscription_created.rb
117
- - lib/pay/paddle/webhooks/subscription_payment_refunded.rb
118
- - lib/pay/paddle/webhooks/subscription_payment_succeeded.rb
119
- - lib/pay/paddle/webhooks/subscription_updated.rb
116
+ - lib/pay/paddle_billing.rb
117
+ - lib/pay/paddle_billing/billable.rb
118
+ - lib/pay/paddle_billing/charge.rb
119
+ - lib/pay/paddle_billing/error.rb
120
+ - lib/pay/paddle_billing/payment_method.rb
121
+ - lib/pay/paddle_billing/subscription.rb
122
+ - lib/pay/paddle_billing/webhooks/subscription.rb
123
+ - lib/pay/paddle_billing/webhooks/transaction_completed.rb
124
+ - lib/pay/paddle_classic.rb
125
+ - lib/pay/paddle_classic/billable.rb
126
+ - lib/pay/paddle_classic/charge.rb
127
+ - lib/pay/paddle_classic/error.rb
128
+ - lib/pay/paddle_classic/payment_method.rb
129
+ - lib/pay/paddle_classic/subscription.rb
130
+ - lib/pay/paddle_classic/webhooks/signature_verifier.rb
131
+ - lib/pay/paddle_classic/webhooks/subscription_cancelled.rb
132
+ - lib/pay/paddle_classic/webhooks/subscription_created.rb
133
+ - lib/pay/paddle_classic/webhooks/subscription_payment_refunded.rb
134
+ - lib/pay/paddle_classic/webhooks/subscription_payment_succeeded.rb
135
+ - lib/pay/paddle_classic/webhooks/subscription_updated.rb
120
136
  - lib/pay/payment.rb
121
137
  - lib/pay/receipts.rb
122
138
  - lib/pay/stripe.rb
@@ -168,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
184
  - !ruby/object:Gem::Version
169
185
  version: '0'
170
186
  requirements: []
171
- rubygems_version: 3.4.19
187
+ rubygems_version: 3.4.22
172
188
  signing_key:
173
189
  specification_version: 4
174
190
  summary: Payments engine for Ruby on Rails
@@ -1,35 +0,0 @@
1
- module Pay
2
- module Paddle
3
- class Charge
4
- attr_reader :pay_charge
5
-
6
- delegate :processor_id, :customer, to: :pay_charge
7
-
8
- def initialize(pay_charge)
9
- @pay_charge = pay_charge
10
- end
11
-
12
- def charge
13
- return unless customer.subscription
14
- payments = PaddlePay::Subscription::Payment.list({subscription_id: customer.subscription.processor_id})
15
- charges = payments.select { |p| p[:id].to_s == processor_id }
16
- charges.try(:first)
17
- rescue ::PaddlePay::PaddlePayError => e
18
- raise Pay::Paddle::Error, e
19
- end
20
-
21
- def refund!(amount_to_refund)
22
- return unless customer.subscription
23
- payments = PaddlePay::Subscription::Payment.list({subscription_id: customer.subscription.processor_id, is_paid: 1})
24
- if payments.count > 0
25
- PaddlePay::Subscription::Payment.refund(payments.last[:id], {amount: amount_to_refund})
26
- pay_charge.update(amount_refunded: amount_to_refund)
27
- else
28
- raise Error, "Payment not found"
29
- end
30
- rescue ::PaddlePay::PaddlePayError => e
31
- raise Pay::Paddle::Error, e
32
- end
33
- end
34
- end
35
- end
File without changes
data/lib/pay/paddle.rb DELETED
@@ -1,80 +0,0 @@
1
- module Pay
2
- module Paddle
3
- autoload :Billable, "pay/paddle/billable"
4
- autoload :Charge, "pay/paddle/charge"
5
- autoload :Error, "pay/paddle/error"
6
- autoload :PaymentMethod, "pay/paddle/payment_method"
7
- autoload :Subscription, "pay/paddle/subscription"
8
-
9
- module Webhooks
10
- autoload :SignatureVerifier, "pay/paddle/webhooks/signature_verifier"
11
- autoload :SubscriptionCreated, "pay/paddle/webhooks/subscription_created"
12
- autoload :SubscriptionCancelled, "pay/paddle/webhooks/subscription_cancelled"
13
- autoload :SubscriptionPaymentRefunded, "pay/paddle/webhooks/subscription_payment_refunded"
14
- autoload :SubscriptionPaymentSucceeded, "pay/paddle/webhooks/subscription_payment_succeeded"
15
- autoload :SubscriptionUpdated, "pay/paddle/webhooks/subscription_updated"
16
- end
17
-
18
- extend Env
19
-
20
- def self.enabled?
21
- return false unless Pay.enabled_processors.include?(:paddle) && defined?(::PaddlePay)
22
-
23
- Pay::Engine.version_matches?(required: "~> 0.2", current: ::PaddlePay::VERSION) || (raise "[Pay] paddle gem must be version ~> 0.2")
24
- end
25
-
26
- def self.setup
27
- ::PaddlePay.config.vendor_id = vendor_id
28
- ::PaddlePay.config.vendor_auth_code = vendor_auth_code
29
- ::PaddlePay.config.environment = environment
30
- end
31
-
32
- def self.vendor_id
33
- find_value_by_name(:paddle, :vendor_id)
34
- end
35
-
36
- def self.vendor_auth_code
37
- find_value_by_name(:paddle, :vendor_auth_code)
38
- end
39
-
40
- def self.environment
41
- find_value_by_name(:paddle, :environment) || "production"
42
- end
43
-
44
- def self.public_key
45
- find_value_by_name(:paddle, :public_key)
46
- end
47
-
48
- def self.public_key_file
49
- find_value_by_name(:paddle, :public_key_file)
50
- end
51
-
52
- def self.public_key_base64
53
- find_value_by_name(:paddle, :public_key_base64)
54
- end
55
-
56
- def self.passthrough(owner:, **options)
57
- options.merge(owner_sgid: owner.to_sgid.to_s).to_json
58
- end
59
-
60
- def self.parse_passthrough(passthrough)
61
- JSON.parse(passthrough)
62
- end
63
-
64
- def self.owner_from_passthrough(passthrough)
65
- GlobalID::Locator.locate_signed parse_passthrough(passthrough)["owner_sgid"]
66
- rescue JSON::ParserError
67
- nil
68
- end
69
-
70
- def self.configure_webhooks
71
- Pay::Webhooks.configure do |events|
72
- events.subscribe "paddle.subscription_created", Pay::Paddle::Webhooks::SubscriptionCreated.new
73
- events.subscribe "paddle.subscription_updated", Pay::Paddle::Webhooks::SubscriptionUpdated.new
74
- events.subscribe "paddle.subscription_cancelled", Pay::Paddle::Webhooks::SubscriptionCancelled.new
75
- events.subscribe "paddle.subscription_payment_succeeded", Pay::Paddle::Webhooks::SubscriptionPaymentSucceeded.new
76
- events.subscribe "paddle.subscription_payment_refunded", Pay::Paddle::Webhooks::SubscriptionPaymentRefunded.new
77
- end
78
- end
79
- end
80
- end