module Chargify class Subscription < Base include ResponseHelper def self.find_by_customer_reference(reference) customer = Customer.find_by_reference(reference) find(:first, :params => {:customer_id => customer.id}) end # Strip off nested attributes of associations before saving, or type-mismatch errors will occur def save self.attributes.stringify_keys! self.attributes.delete('customer') self.attributes.delete('product') self.attributes.delete('credit_card') self.attributes.delete('bank_account') self.attributes.delete('paypal_account') self.attributes, options = extract_uniqueness_token(attributes) self.prefix_options.merge!(options) super end def cancel(params = {}) if params.blank? destroy else #Destroy does not support body, must work around it to send verb DELETE self.connection.post( element_path, { cancellation_message: params[:cancellation_message] || nil, reason_code: params[:reason_code] || nil }.to_xml(:root => :subscription), self.class.headers.merge({'X-Http-Method-Override' => 'DELETE'}) ) end end def build_metadata(params = {}) SubscriptionMetadata.new(params.reverse_merge({:resource_id => self.id})) end def create_metadata(params = {}) SubscriptionMetadata.create(params.reverse_merge({:resource_id => self.id})) end def metadata(params={}) params.merge!({:resource_id => self.id}) SubscriptionMetadata.find(:all, :params => params) end def component(id) Component.find(id, :params => {:subscription_id => self.id}) end def components(params = {}) params.merge!({:subscription_id => self.id}) Component.find(:all, :params => params) end def events(params = {}) params.merge!(:subscription_id => self.id) Event.all(:params => params) end def payment_profile if self.respond_to?('credit_card') credit_card elsif self.respond_to?('bank_account') bank_account elsif self.respond_to?('paypal_account') paypal_account end end # Perform a one-time charge on an existing subscription. # For more information, please see the one-time charge API docs available # at: http://support.chargify.com/faqs/api/api-charges def charge(attrs = {}) Chargify::Charge.create(attrs.merge(:subscription_id => self.id)) end # Record an external payment on an existing subscription. # This DOES NOT charge the customer's credit card. # For more information, please see the API docs available # at: https://docs.chargify.com/api-payments def payment(attrs = {}) Chargify::Payment.create(attrs.merge(:subscription_id => self.id)) end def credit(attrs = {}) attrs, options = extract_uniqueness_token(attrs) process_capturing_errors do post :credits, options, attrs.to_xml(:root => :credit) end end def refund(attrs = {}) attrs, options = extract_uniqueness_token(attrs) process_capturing_errors do post :refunds, options, attrs.to_xml(:root => :refund) end end def reactivate(params = {}) process_capturing_errors do put :reactivate, params end end def retry process_capturing_errors do put :retry end end def reset_balance process_capturing_errors do put :reset_balance end end def migrate(attrs = {}) Chargify::Migration.create(attrs.merge(:subscription_id => self.id)) end def statement(id) statement = Chargify::Statement.find(id) raise ActiveResource::ResourceNotFound.new(nil) if (statement.subscription_id != self.id) statement end def statements(params = {}) params.merge!(:subscription_id => self.id) Statement.find(:all, :params => params) end def invoices(params = {}) params.merge!(subscription_id: self.id) Invoice.find(:all, params: params) end def invoice(id) invoice = Chargify::Invoice.find(id) raise ActiveResource::ResourceNotFound.new(nil) if (invoice.subscription_id != self.id) invoice end def transactions(params = {}) params.merge!(:subscription_id => self.id) Transaction.find(:all, :params => params) end def adjustment(attrs = {}) attrs, options = extract_uniqueness_token(attrs) process_capturing_errors do post :adjustments, options, attrs.to_xml(:root => :adjustment) end end def add_coupon(code) process_capturing_errors do post :add_coupon, :code => code end end def remove_coupon(code=nil) process_capturing_errors do if code.nil? delete :remove_coupon else delete :remove_coupon, :code => code end end end def delayed_cancel(cancel_at_end_of_period = true) self.cancel_at_end_of_period = cancel_at_end_of_period save end def product_change(handle, delayed = false) self.product_handle = handle self.product_change_delayed = delayed save end def cancel_delayed_product_change self.next_product_id = nil save end private class Component < Base self.prefix = "/subscriptions/:subscription_id/" # All Subscription Components are considered already existing records, but the id isn't used def id self.component_id end end class Event < Base self.prefix = '/subscriptions/:subscription_id/' end class Statement < Base self.prefix = "/subscriptions/:subscription_id/" end class Transaction < Base self.prefix = "/subscriptions/:subscription_id/" def full_refund(attrs = {}) return false if self.transaction_type != 'payment' attrs.merge!(:amount_in_cents => self.amount_in_cents) self.refund(attrs) end def refund(attrs = {}) return false if self.transaction_type != 'payment' attrs.merge!(:payment_id => self.id) Subscription.find(self.prefix_options[:subscription_id]).refund(attrs) end class Taxation < Base class TaxRule < Base end end end end end