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