lib/pay/billable.rb in pay-0.0.2 vs lib/pay/billable.rb in pay-1.0.0.beta2

- old
+ new

@@ -1,79 +1,109 @@ -require 'pay/billable/stripe' -require 'pay/billable/braintree' +require 'pay/billable/sync_email' module Pay module Billable extend ActiveSupport::Concern included do - include Pay::Billable::Stripe - include Pay::Billable::Braintree + include Pay::Billable::SyncEmail - has_many :subscriptions, foreign_key: :owner_id + has_many :charges, class_name: Pay.chargeable_class, foreign_key: :owner_id, inverse_of: :owner + has_many :subscriptions, class_name: Pay.subscription_class, foreign_key: :owner_id, inverse_of: :owner attribute :plan, :string attribute :quantity, :integer attribute :card_token, :string end - def customer(token = nil) + def customer check_for_processor - send("#{processor}_customer", token) + raise Pay::Error, "Email is required to create a customer" if email.nil? + + customer = send("#{processor}_customer") + update_card(card_token) if card_token.present? + customer end - def subscribe(name = 'default', plan = 'default', processor = 'stripe') - self.processor = processor - send("create_#{processor}_subscription", name, plan) + def customer_name + [try(:first_name), try(:last_name)].compact.join(" ") end + def charge(amount_in_cents, options = {}) + check_for_processor + send("create_#{processor}_charge", amount_in_cents, options) + end + + def subscribe(name: 'default', plan: 'default', **options) + check_for_processor + send("create_#{processor}_subscription", name, plan, options) + end + def update_card(token) check_for_processor + customer if processor_id.nil? send("update_#{processor}_card", token) end + def on_trial?(name: 'default', plan: nil) + return true if default_generic_trial?(name, plan) + + sub = subscription(name: name) + return sub && sub.on_trial? if plan.nil? + + sub && sub.on_trial? && sub.processor_plan == plan + end + + def on_generic_trial? + trial_ends_at? && trial_ends_at > Time.zone.now + end + def processor_subscription(subscription_id) check_for_processor send("#{processor}_subscription", subscription_id) end - def subscribed?(name = 'default', plan = nil) - subscription = subscription(name) + def subscribed?(name: 'default', processor_plan: nil) + subscription = subscription(name: name) return false if subscription.nil? - return subscription.active? if plan.nil? + return subscription.active? if processor_plan.nil? - subscription.active? && subscription.plan == plan + subscription.active? && subscription.processor_plan == processor_plan end - def subscription(name = 'default') + def subscription(name: 'default') subscriptions.for_name(name).last end + def invoice! + send("#{processor}_invoice!") + end + + def upcoming_invoice + send("#{processor}_upcoming_invoice") + end + private def check_for_processor - raise StandardError, 'No processor selected' unless processor + raise StandardError, "No payment processor selected. Make sure to set the #{Pay.billable_class}'s `processor` attribute to either 'stripe' or 'braintree'." unless processor end def create_subscription(subscription, processor, name, plan, qty = 1) subscriptions.create!( name: name || 'default', processor: processor, processor_id: subscription.id, processor_plan: plan, - trial_ends_at: trial_end_date(subscription), + trial_ends_at: send("#{processor}_trial_end_date", subscription), quantity: qty, ends_at: nil ) end - def update_card_on_file(card) - update!( - card_brand: card.brand, - card_last4: card.last4, - card_exp_month: card.exp_month, - card_exp_year: card.exp_year - ) + def default_generic_trial?(name, plan) + # Generic trials don't have plans or custom names + plan.nil? && name == 'default' && on_generic_trial? end end end