Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stripe refactorings #8407

Open
wants to merge 22 commits into
base: stripe-api-upgrade
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions app/assets/stylesheets/responsive/_settings_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,14 @@ $settings-collapse: 50em; //where the dashboard layout needs to change
.plan-overview__desc {
flex: 0 0 100%;
@include respond-min( $settings-collapse ){
flex: 0 0 30%;
}
}

.plan-overview__details{
flex: 0 0 70%;
@include respond-min( $settings-collapse ){
flex: 0 0 30%;
flex: 0 0 40%;
}
}

.plan-overview__amount {
flex: 0 0 30%;
flex: 0 0 100%;
@include respond-min( $settings-collapse ){
flex: 0 0 30%;
flex: 0 0 60%;
}
}

Expand Down
5 changes: 0 additions & 5 deletions app/assets/stylesheets/responsive/_settings_style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
font-weight: bold;
}

.plan-overview__details{
font-size: 0.875em;
color: #787774;
}

.plan-overview__amount {
font-size: 1em;
text-align: right;
Expand Down
18 changes: 3 additions & 15 deletions app/controllers/alaveteli_pro/plans_controller.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,19 @@
class AlaveteliPro::PlansController < AlaveteliPro::BaseController
include AlaveteliPro::StripeNamespace

skip_before_action :pro_user_authenticated?
before_action :authenticate, :check_has_current_subscription, only: [:show]

def index
default_plan_name = add_stripe_namespace('pro')
stripe_plan = Stripe::Plan.retrieve(default_plan_name)
@plan = AlaveteliPro::WithTax.new(stripe_plan)
@plans = AlaveteliPro::Plan.list
@pro_site_name = pro_site_name
end

def show
stripe_plan = Stripe::Plan.retrieve(
id: plan_name, expand: ['product']
)
@plan = AlaveteliPro::WithTax.new(stripe_plan)
rescue Stripe::InvalidRequestError
raise ActiveRecord::RecordNotFound
@plan = AlaveteliPro::Plan.retrieve(params[:id])
@plan || raise(ActiveRecord::RecordNotFound)
end

private

def plan_name
add_stripe_namespace(params.require(:id))
end

def authenticate
authenticated? || ask_to_login(
pro: true,
Expand Down
86 changes: 19 additions & 67 deletions app/controllers/alaveteli_pro/subscriptions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,47 +1,25 @@
class AlaveteliPro::SubscriptionsController < AlaveteliPro::BaseController
include AlaveteliPro::StripeNamespace
before_action :check_has_current_subscription, only: [:index]

skip_before_action :html_response, only: [:create, :authorise]
skip_before_action :pro_user_authenticated?, only: [:create, :authorise]

before_action :authenticate, only: [:create, :authorise]

before_action :check_allowed_to_subscribe_to_pro, only: [:create]
before_action :prevent_duplicate_submission, only: [:create]
before_action :check_plan_exists, only: [:create]
before_action :check_has_current_subscription, only: [:index]
before_action :load_plan, :load_coupon, only: [:create]

def index
@customer = current_user.pro_account.try(:stripe_customer)
@subscriptions = @customer.subscriptions.map do |subscription|
AlaveteliPro::SubscriptionWithDiscount.new(subscription)
end
if @customer.default_source
@card =
@customer.
sources.select { |card| card.id == @customer.default_source }.first
end

if referral_coupon
@discount_code = remove_stripe_namespace(referral_coupon.id)
@discount_terms = referral_coupon.metadata.humanized_terms
end
@subscriptions = current_user.pro_account.subscriptions
end

# TODO: remove reminder of Stripe params once shipped
#
# params =>
# {"utf8"=>"✓",
# "authenticity_token"=>"Ono2YgLcl1eC1gGzyd7Vf5HJJhOek31yFpT+8z+tKoo=",
# "stripe_token"=>"tok_s3kr3t…",
# "controller"=>"alaveteli_pro/subscriptions",
# "action"=>"create",
# "plan_id"=>"WDTK-pro"}
def create
begin
@pro_account = current_user.pro_account ||= current_user.build_pro_account

# Ensure previous incomplete subscriptions are cancelled to prevent them
# from using the new card
# from using the new token/card
@pro_account.subscriptions.incomplete.map(&:delete)

@token = Stripe::Token.retrieve(params[:stripe_token])
Expand All @@ -50,11 +28,11 @@ def create
@pro_account.update_stripe_customer

attributes = {
plan: params.require(:plan_id),
tax_percent: tax_percent,
plan: @plan.id,
tax_percent: @plan.tax_percent,
payment_behavior: 'allow_incomplete'
}
attributes[:coupon] = coupon_code if coupon_code?
attributes[:coupon] = @coupon.id if @coupon

@subscription = @pro_account.subscriptions.create(attributes)

Expand Down Expand Up @@ -84,7 +62,7 @@ def create
end

if flash[:error]
json_redirect_to plan_path(non_namespaced_plan_id)
json_redirect_to plan_path(@plan)
else
redirect_to authorise_subscription_path(@subscription.id)
end
Expand All @@ -111,9 +89,7 @@ def authorise
flash[:error] = _('There was a problem authorising your payment. You ' \
'have not been charged. Please try again.')

json_redirect_to plan_path(
remove_stripe_namespace(@subscription.plan.id)
)
json_redirect_to plan_path(@subscription.plan)

elsif @subscription.active?
current_user.add_role(:pro)
Expand All @@ -130,10 +106,10 @@ def authorise
end

rescue Stripe::RateLimitError,
Stripe::InvalidRequestError,
Stripe::AuthenticationError,
Stripe::APIConnectionError,
Stripe::StripeError => e
Stripe::InvalidRequestError,
Stripe::AuthenticationError,
Stripe::APIConnectionError,
Stripe::StripeError => e
if send_exception_notifications?
ExceptionNotifier.notify_exception(e, env: request.env)
end
Expand Down Expand Up @@ -199,37 +175,13 @@ def check_has_current_subscription
redirect_to pro_plans_path
end

def non_namespaced_plan_id
gbp marked this conversation as resolved.
Show resolved Hide resolved
remove_stripe_namespace(params[:plan_id]) if params[:plan_id]
end

def coupon_code?
params[:coupon_code].present?
end

def coupon_code
add_stripe_namespace(params.require(:coupon_code)).upcase
end

def referral_coupon
coupon_code =
add_stripe_namespace(AlaveteliConfiguration.pro_referral_coupon)

@referral_coupon ||=
unless coupon_code.blank?
begin
Stripe::Coupon.retrieve(coupon_code)
rescue Stripe::StripeError
end
end
end

def tax_percent
(BigDecimal(AlaveteliConfiguration.stripe_tax_rate).to_f * 100).to_f
def load_plan
@plan = AlaveteliPro::Plan.retrieve(params[:plan_id])
@plan || redirect_to(pro_plans_path)
end

def check_plan_exists
redirect_to(pro_plans_path) unless non_namespaced_plan_id
def load_coupon
@coupon = AlaveteliPro::Coupon.retrieve(params[:coupon_code])
end

def prevent_duplicate_submission
Expand Down
17 changes: 0 additions & 17 deletions app/controllers/concerns/alaveteli_pro/stripe_namespace.rb

This file was deleted.

17 changes: 0 additions & 17 deletions app/helpers/alaveteli_pro/account_helper.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
module AlaveteliPro::AccountHelper
def billing_frequency(billing_unit)
case billing_unit
when 'day'
_('Billed: Daily')
when 'week'
_('Billed: Weekly')
when 'month'
_('Billed: Monthly')
when 'year'
_('Billed: Annually')
end
end

def card_expiry_message(month, year)
if month == Date.today.month && year == Date.today.year
content_tag(:p, _('Expires soon'), class: 'card__expiring')
end
end

def subscription_amount(subscription)
AlaveteliPro::WithTax.new(subscription).amount_with_tax
end
end
45 changes: 45 additions & 0 deletions app/helpers/alaveteli_pro/plan_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
##
# Helper methods for formatting and displaying billing and plan information
# in the Alaveteli Pro interface
#
module AlaveteliPro::PlanHelper
def billing_frequency(plan)
if interval(plan) == 'day' && interval_count(plan) == 1
_('Billed: Daily')
elsif interval(plan) == 'week' && interval_count(plan) == 1
_('Billed: Weekly')
elsif interval(plan) == 'month' && interval_count(plan) == 1
_('Billed: Monthly')
elsif interval(plan) == 'year' && interval_count(plan) == 1
_('Billed: Annually')
else
_('Billed: every {{interval}}', interval: pluralize_interval(plan))
end
end

def billing_interval(plan)
if interval_count(plan) == 1
_('per user, per {{interval}}', interval: interval(plan))
else
_('per user, every {{interval}}', interval: pluralize_interval(plan))
end
end

private

def pluralize_interval(plan)
count = interval_count(plan)
interval = interval(plan)
return interval if count == 1

pluralize(count, interval)
end

def interval(plan)
plan.interval
end

def interval_count(plan)
plan.interval_count
end
end
26 changes: 26 additions & 0 deletions app/models/alaveteli_pro/coupon.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
##
# A wrapper for a Stripe::Coupon
#
class AlaveteliPro::Coupon < SimpleDelegator
extend AlaveteliPro::StripeNamespace
include AlaveteliPro::StripeNamespace

def self.referral
id = add_stripe_namespace(AlaveteliConfiguration.pro_referral_coupon)
retrieve(id) if id
end

def self.retrieve(id)
new(Stripe::Coupon.retrieve(add_stripe_namespace(id)))
rescue Stripe::InvalidRequestError
nil
end

def to_param
remove_stripe_namespace(id)
end

def terms
metadata.humanized_terms || name
end
end
12 changes: 12 additions & 0 deletions app/models/alaveteli_pro/customer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
##
# A wrapper for a Stripe::Customer
#
class AlaveteliPro::Customer < SimpleDelegator
def self.retrieve(id)
new(Stripe::Customer.retrieve(id))
end

def default_source
@default_source ||= sources.find { |c| c.id == __getobj__.default_source }
end
end
32 changes: 32 additions & 0 deletions app/models/alaveteli_pro/plan.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
##
# A wrapper for a Stripe::Plan
#
class AlaveteliPro::Plan < SimpleDelegator
extend AlaveteliPro::StripeNamespace
include AlaveteliPro::StripeNamespace
include Taxable

tax :amount

def self.list
[retrieve('pro')]
end

def self.retrieve(id)
new(Stripe::Plan.retrieve(add_stripe_namespace(id)))
rescue Stripe::InvalidRequestError
nil
end

def to_param
remove_stripe_namespace(id)
end

# product
def product
@product ||= (
product_id = __getobj__.product
Stripe::Product.retrieve(product_id) if product_id
)
end
end
Loading
Loading