require 'jam_ruby/recurly_client' class ApiRecurlyController < ApiController before_filter :api_signed_in_user, :except => [:create_account] before_filter :create_client before_filter :ip_blacklist, :only => [:place_order] before_filter :user_blacklist, :only => [:place_order] respond_to :json # create Recurly account def create_account billing_info = params[:billing_info] shipping_info = params[:shipping_info] # should we let the user reuse this card next time? reuse_card_next_time = params[:reuse_card_next_time] == "true" # should we update the card info, or use what's on file this time? reuse_card_this_time = params[:reuse_card_this_time] == "true" # terms of service accepted? terms_of_service = params[:terms_of_service] == "true" if billing_info && Rails.application.config.remove_whitespace_credit_card number = billing_info[:number] billing_info[:number] = number.gsub(/\s+/, "") if number end if current_user # keep reuse card up-to-date User.where(id: current_user.id).update_all(reuse_card: params[:reuse_card_next_time]) else options = { first_name: billing_info[:first_name], last_name: billing_info[:last_name], email: params[:email], password: params[:password], password_confirmation: params[:password], terms_of_service: terms_of_service, location: {:country => billing_info[:country], :state => billing_info[:state], :city => billing_info[:city]}, reuse_card: reuse_card_next_time, affiliate_referral_id: cookies[:affiliate_visitor], origin: origin_cookie, timezone: current_timezone, facebook_click_id: cookies[:_fbc], facebook_browser_id: cookies[:_fbp] } options = User.musician_defaults(request.remote_ip, ApplicationHelper.base_uri(request) + "/confirm", any_user, options) user = UserManager.new.signup(options) if user.errors.any? # render any @user.errors on error respond_with_model(user) return else sign_in user end end begin billing_info[:ip_address] = request.remote_ip if billing_info if reuse_card_this_time # do not attempt to update any billing/shipping info unless the user re-inputs their info! @account = @client.get_account(current_user) else @account = @client.find_or_create_account(current_user, billing_info) end render :json => account_json(@account) rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 end end def delete_account @client.delete_account(current_user) render json: {}, status: 200 rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 end # get Recurly account def get_account @account = @client.get_account(current_user) render :json => account_json(@account) rescue RecurlyClientError => e render json: {message: x.inspect, errors: x.errors}, :status => 404 end # get Recurly payment history def payment_history @payments=@client.payment_history(current_user, params) render :json => {payments: @payments} rescue RecurlyClientError => x puts "Recurly error #{current_user.email}, #{x}" render json: {message: x.inspect, errors: x.errors}, :status => 404 end def invoice_history @invoices, account= @client.invoice_history(current_user, params) past_due = account && account.state == 'past_due' render :json => {entries: @invoices, past_due: past_due} rescue RecurlyClientError => x puts "Recurly error #{current_user.email}, #{x}" render json: {message: x.inspect, errors: x.errors}, :status => 404 end # update Recurly account def update_account @account=@client.update_account(current_user, params[:billing_info]) render :json => account_json(@account) rescue RecurlyClientError => x render json: {message: x.inspect, errors: x.errors}, :status => 404 end # get Billing Information def billing_info @account = @client.get_account(current_user) if @account render :json => account_json(@account) else render :json => {}, :status => 404 end rescue RecurlyClientError => x render json: {message: x.inspect, errors: x.errors}, :status => 404 end # update Billing Information def update_billing_info @account = @client.update_billing_info(current_user, params[:billing_info]) render :json => account_json(@account) rescue RecurlyClientError => x render json: {message: x.inspect, errors: x.errors}, :status => 404 end def update_payment begin recurly_token = params[:recurly_token] account = @client.find_or_create_account(current_user, nil, recurly_token) @client.update_billing_info_from_token(current_user, account, recurly_token) current_user.update_attribute(:stored_credit_card, true) past_due = account && account.has_past_due_invoice subscription = nil plan_code = current_user.desired_plan_code result, subscription, account = @client.handle_create_subscription(current_user, plan_code, account) has_billing_info = !account.nil? && !account[:billing_info].nil? render :json => { past_due: past_due, subscription: subscription, has_billing_info: has_billing_info, plan_code: current_user.subscription_plan_code, desired_plan_code: current_user.desired_plan_code, admin_override_plan_code: current_user.admin_override_plan_code, admin_override_ends_at: current_user.admin_override_ends_at, in_trial: !current_user.subscription_trial_ended?, trial_ends_at: current_user.subscription_trial_ends_at, subscription_rules: current_user.subscription_rules }, :status => 200 rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 end end def create_subscription begin sale = Sale.purchase_subscription(current_user, params[:recurly_token], params[:plan_code]) subscription = Recurly::Subscription.find(current_user.recurly_subscription_id) # CAPI: Subscribe # Fire event when a subscription is successfully created begin plan_code = params[:plan_code] value = '0.00' # Determine value based on plan (approximate cost) case plan_code when SubscriptionDefinitions::JAM_SILVER value = '5.00' when SubscriptionDefinitions::JAM_SILVER_YEARLY value = '50.00' when SubscriptionDefinitions::JAM_GOLD value = '10.00' when SubscriptionDefinitions::JAM_GOLD_YEARLY value = '100.00' when SubscriptionDefinitions::JAM_PLATINUM value = '20.00' when SubscriptionDefinitions::JAM_PLATINUM_YEARLY value = '200.00' end # Calculate predicted LTV (12 months for monthly, 1 year for yearly) # If it's a yearly plan, the value IS the yearly revenue if plan_code.to_s.include?('yearly') ltv = value else ltv = (value.to_f * 12).to_s end CapiTransmitter.send_event('Subscribe', current_user, { value: value, currency: 'USD', predicted_ltv: ltv }) rescue => e puts "Error sending CAPI Subscribe event #{current_user.email}, #{e.message}" end render :json => subscription.to_json rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 end end def get_subscription subscription, account = @client.find_subscription(current_user) past_due = account && account.has_past_due_invoice has_billing_info = !account.nil? && !account[:billing_info].nil? render :json => { past_due: past_due, subscription: subscription, has_billing_info: has_billing_info, plan_code: current_user.subscription_plan_code, desired_plan_code: current_user.desired_plan_code, admin_override_plan_code: current_user.admin_override_plan_code, admin_override_ends_at: current_user.admin_override_ends_at, in_trial: !current_user.subscription_trial_ended?, trial_ends_at: current_user.subscription_trial_ends_at, subscription_rules: current_user.subscription_rules, }, :status => 200 end def cancel_subscription begin @client.cancel_subscription(current_user.recurly_subscription_id) subscription = @client.find_subscription(current_user) if subscription render :json => subscription.to_json else render :json => {} end rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 end end def change_subscription_plan begin plan_code = params[:plan_code] if plan_code == '' plan_code = nil end result, subscription, account = @client.update_desired_subscription(current_user, plan_code) has_billing_info = !account.nil? && !account[:billing_info].nil? past_due = account && account.has_past_due_invoice if !result render json: {:message => "No change made to plan"}, :status => 422 else render :json => { past_due: past_due, subscription:subscription, has_billing_info: has_billing_info, plan_code: current_user.subscription_plan_code, desired_plan_code: current_user.desired_plan_code, admin_override_plan_code: current_user.admin_override_plan_code, admin_override_ends_at: current_user.admin_override_ends_at, in_trial: !current_user.subscription_trial_ended?, trial_ends_at: current_user.subscription_trial_ends_at, subscription_rules: current_user.subscription_rules } end rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 end end def list_invoices begin account = @client.get_account(current_user) if account.nil? render json:[], :status => 200 else return @client.list_invoices(current_user) end end end def change_subscription_payment begin @client.change_subscription_payment(current_user.recurly_subscription_id, params[:recurly_token], params[:billing_info]) subscription = Recurly::Subscription.find(current_user.recurly_subscription_id) render :json => subscription.to_json rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 end end def place_order error=nil response = {jam_tracks: [], gift_cards: []} #if Sale.is_mixed(current_user.shopping_carts) # msg = "has free and non-free items. Try removing non-free items." # render json: {message: "Cart " + msg, errors: {cart: [msg]}}, :status => 404 # return #end sales = Sale.place_order(current_user, current_user.shopping_carts) sales.each do |sale| sale.sale_line_items.each do |line_item| if line_item.is_jam_track? jam_track = line_item.product jam_track_right = jam_track.right_for_user(current_user) response[:jam_tracks] << {name: jam_track.name, id: jam_track.id, jam_track_right_id: jam_track_right.id, version: jam_track.version} elsif line_item.is_gift_card? gift_card = line_item.product response[:gift_cards] << {name: gift_card.name, id: gift_card.id} else raise 'unknown sale line item type: ' + line_item.product_type end end end if error render json: {errors: {message: error}}, :status => 404 else set_purchased_jamtrack_cookie render :json => response, :status => 200 end rescue RecurlyClientError => x render json: {message: x.inspect, errors: x.errors}, :status => 404 end private def create_client @client = RecurlyClient.new end def account_json(account) billing_info = account.billing_info.nil? ? nil : { :first_name => account.billing_info.first_name, :last_name => account.billing_info.last_name, :address1 => account.billing_info.address1, :address2 => account.billing_info.address2, :city => account.billing_info.city, :state => account.billing_info.state, :zip => account.billing_info.zip, :country => account.billing_info.country, :last_four => account.billing_info.last_four } { billing_info: billing_info } end end # class