pay 6.8.0 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
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