class Pay::Braintree::Subscription
Attributes
pay_subscription[R]
Public Class Methods
new(pay_subscription)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 22 def initialize(pay_subscription) @pay_subscription = pay_subscription end
Public Instance Methods
cancel()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 30 def cancel subscription = processor_subscription if on_trial? gateway.subscription.cancel(processor_subscription.id) pay_subscription.update(status: :canceled, ends_at: trial_ends_at) else gateway.subscription.update(subscription.id, { number_of_billing_cycles: subscription.current_billing_cycle }) pay_subscription.update(status: :canceled, ends_at: subscription.billing_period_end_date.to_date) end rescue ::Braintree::BraintreeError => e raise Pay::Braintree::Error, e end
cancel_now!()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 46 def cancel_now! gateway.subscription.cancel(processor_subscription.id) pay_subscription.update(status: :canceled, ends_at: Time.current) rescue ::Braintree::BraintreeError => e raise Pay::Braintree::Error, e end
on_grace_period?()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 53 def on_grace_period? canceled? && Time.current < ends_at end
pause()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 61 def pause raise NotImplementedError, "Braintree does not support pausing subscriptions" end
paused?()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 57 def paused? false end
resume()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 65 def resume unless on_grace_period? raise StandardError, "You can only resume subscriptions within their grace period." end if canceled? && on_trial? duration = trial_ends_at.to_date - Date.today customer.subscribe( name: name, plan: processor_plan, trial_period: true, trial_duration: duration.to_i, trial_duration_unit: :day ) else subscription = processor_subscription gateway.subscription.update(subscription.id, { never_expires: true, number_of_billing_cycles: nil }) end pay_subscription.update(status: :active) rescue ::Braintree::BraintreeError => e raise Pay::Braintree::Error, e end
subscription(**options)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 26 def subscription(**options) gateway.subscription.find(processor_id) end
swap(plan)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 94 def swap(plan) raise ArgumentError, "plan must be a string" unless plan.is_a?(String) if on_grace_period? && processor_plan == plan resume return end unless active? customer.subscribe(name: name, plan: plan, trial_period: false) return end braintree_plan = find_braintree_plan(plan) if would_change_billing_frequency?(braintree_plan) && prorate? swap_across_frequencies(braintree_plan) return end subscription = processor_subscription result = gateway.subscription.update(subscription.id, { plan_id: braintree_plan.id, price: braintree_plan.price, never_expires: true, number_of_billing_cycles: nil, options: { prorate_charges: prorate? } }) raise Error, "Braintree failed to swap plans: #{result.message}" unless result.success? rescue ::Braintree::BraintreeError => e raise Pay::Braintree::Error, e end
Private Instance Methods
discount_for_switching_to_monthly(current_plan, plan)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 150 def discount_for_switching_to_monthly(current_plan, plan) cycles = (money_remaining_on_yearly_plan(current_plan) / plan.price).floor OpenStruct.new( amount: plan.price, number_of_billing_cycles: cycles ) end
discount_for_switching_to_yearly()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 163 def discount_for_switching_to_yearly amount = 0 processor_subscription.discounts.each do |discount| if discount.id == "plan-credit" amount += discount.amount * discount.number_of_billing_cycles end end OpenStruct.new( amount: amount, number_of_billing_cycles: 1 ) end
find_braintree_plan(id)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 140 def find_braintree_plan(id) @braintree_plans ||= gateway.plan.all @braintree_plans.find { |p| p.id == id } end
gateway()
click to toggle source
# File lib/pay/braintree/subscription.rb, line 132 def gateway Pay.braintree_gateway end
money_remaining_on_yearly_plan(current_plan)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 158 def money_remaining_on_yearly_plan(current_plan) end_date = processor_subscription.billing_period_end_date.to_date (current_plan.price / 365) * (end_date - Date.today) end
swap_across_frequencies(plan)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 178 def swap_across_frequencies(plan) current_plan = find_braintree_plan(processor_plan) discount = if switching_to_monthly_plan?(current_plan, plan) discount_for_switching_to_monthly(current_plan, plan) else discount_for_switching_to_yearly end options = {} if discount.amount > 0 && discount.number_of_billing_cycles > 0 options = { discounts: { add: [ { inherited_from_id: "plan-credit", amount: discount.amount, number_of_billing_cycles: discount.number_of_billing_cycles } ] } } end cancel_now! customer.subscribe(**options.merge(name: name, plan: plan.id)) end
switching_to_monthly_plan?(current_plan, plan)
click to toggle source
Helper methods for swapping plans
# File lib/pay/braintree/subscription.rb, line 146 def switching_to_monthly_plan?(current_plan, plan) current_plan.billing_frequency == 12 && plan.billing_frequency == 1 end
would_change_billing_frequency?(plan)
click to toggle source
# File lib/pay/braintree/subscription.rb, line 136 def would_change_billing_frequency?(plan) plan.billing_frequency != find_braintree_plan(processor_plan).billing_frequency end