class Pay::Paddle::Subscription

Attributes

pay_subscription[R]

Public Class Methods

new(pay_subscription) click to toggle source
# File lib/pay/paddle/subscription.rb, line 66
def initialize(pay_subscription)
  @pay_subscription = pay_subscription
end
sync(subscription_id, object: nil, name: Pay.default_product_name) click to toggle source
# File lib/pay/paddle/subscription.rb, line 23
def self.sync(subscription_id, object: nil, name: Pay.default_product_name)
  # Passthrough is not return from this API, so we can't use that
  object ||= OpenStruct.new PaddlePay::Subscription::User.list({subscription_id: subscription_id}).try(:first)

  pay_customer = Pay::Customer.find_by(processor: :paddle, processor_id: object.user_id)

  # If passthrough exists (only on webhooks) we can use it to create the Pay::Customer
  if pay_customer.nil? && object.passthrough
    owner = Pay::Paddle.owner_from_passthrough(object.passthrough)
    pay_customer = owner&.set_payment_processor(:paddle, processor_id: object.user_id)
  end

  return unless pay_customer

  attributes = {
    paddle_cancel_url: object.cancel_url,
    paddle_update_url: object.update_url,
    processor_plan: object.plan_id || object.subscription_plan_id,
    quantity: object.quantity,
    status: object.state || object.status
  }

  # If paused or delete while on trial, set ends_at to match
  case attributes[:status]
  when "trialing"
    attributes[:trial_ends_at] = Time.zone.parse(object.next_bill_date)
    attributes[:ends_at] = nil
  when "paused", "deleted"
    attributes[:trial_ends_at] = nil
    attributes[:ends_at] = Time.zone.parse(object.next_bill_date)
  end

  # Update or create the subscription
  if (pay_subscription = pay_customer.subscriptions.find_by(processor_id: object.subscription_id))
    pay_subscription.with_lock do
      pay_subscription.update!(attributes)
    end
    pay_subscription
  else
    pay_customer.subscriptions.create!(attributes.merge(name: name, processor_id: object.subscription_id))
  end
end

Public Instance Methods

cancel() click to toggle source
# File lib/pay/paddle/subscription.rb, line 77
def cancel
  ends_at = on_trial? ? trial_ends_at : processor_subscription.next_payment[:date]
  PaddlePay::Subscription::User.cancel(processor_id)
  pay_subscription.update(status: :canceled, ends_at: ends_at)
rescue ::PaddlePay::PaddlePayError => e
  raise Pay::Paddle::Error, e
end
cancel_now!() click to toggle source
# File lib/pay/paddle/subscription.rb, line 85
def cancel_now!
  PaddlePay::Subscription::User.cancel(processor_id)
  pay_subscription.update(status: :canceled, ends_at: Time.current)
rescue ::PaddlePay::PaddlePayError => e
  raise Pay::Paddle::Error, e
end
on_grace_period?() click to toggle source
# File lib/pay/paddle/subscription.rb, line 92
def on_grace_period?
  canceled? && Time.current < ends_at || paused? && Time.current < paddle_paused_from
end
pause() click to toggle source
# File lib/pay/paddle/subscription.rb, line 100
def pause
  attributes = {pause: true}
  response = PaddlePay::Subscription::User.update(processor_id, attributes)
  pay_subscription.update(paddle_paused_from: Time.zone.parse(response[:next_payment][:date]))
rescue ::PaddlePay::PaddlePayError => e
  raise Pay::Paddle::Error, e
end
paused?() click to toggle source
# File lib/pay/paddle/subscription.rb, line 96
def paused?
  paddle_paused_from.present?
end
resume() click to toggle source
# File lib/pay/paddle/subscription.rb, line 108
def resume
  unless paused?
    raise StandardError, "You can only resume paused subscriptions."
  end

  attributes = {pause: false}
  PaddlePay::Subscription::User.update(processor_id, attributes)
  pay_subscription.update(status: :active, paddle_paused_from: nil)
rescue ::PaddlePay::PaddlePayError => e
  raise Pay::Paddle::Error, e
end
subscription(**options) click to toggle source
# File lib/pay/paddle/subscription.rb, line 70
def subscription(**options)
  hash = PaddlePay::Subscription::User.list({subscription_id: processor_id}, options).try(:first)
  OpenStruct.new(hash)
rescue ::PaddlePay::PaddlePayError => e
  raise Pay::Paddle::Error, e
end
swap(plan) click to toggle source
# File lib/pay/paddle/subscription.rb, line 120
def swap(plan)
  raise ArgumentError, "plan must be a string" unless plan.is_a?(String)

  attributes = {plan_id: plan, prorate: prorate}
  attributes[:quantity] = quantity if quantity?
  PaddlePay::Subscription::User.update(processor_id, attributes)
rescue ::PaddlePay::PaddlePayError => e
  raise Pay::Paddle::Error, e
end