jam-cloud/web/app/controllers/api_recurly_controller.rb

348 lines
12 KiB
Ruby

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
}
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])
# CAPI Hook: Subscribe
begin
plan_code = params[:plan_code]
monthly_cost = case plan_code
when JamRuby::SubscriptionDefinitions::JAM_SILVER, JamRuby::SubscriptionDefinitions::JAM_SILVER_YEARLY
5.00
when JamRuby::SubscriptionDefinitions::JAM_GOLD, JamRuby::SubscriptionDefinitions::JAM_GOLD_YEARLY
10.00
when JamRuby::SubscriptionDefinitions::JAM_PLATINUM, JamRuby::SubscriptionDefinitions::JAM_PLATINUM_YEARLY
20.00
else
0.00
end
if monthly_cost > 0
ltv = monthly_cost * 12
CapiTransmitter.send_event('Subscribe', current_user, { value: monthly_cost.to_s, currency: 'USD', predicted_ltv: ltv.to_s })
end
rescue => e
puts "Error sending CAPI Subscribe event #{current_user.email}, #{e.message}"
end
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 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