Skip to content

Commit

Permalink
Merge branch 'stripe-prices' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
gbp committed Nov 22, 2024
2 parents b9fe64b + 54c67cc commit 9153a2c
Show file tree
Hide file tree
Showing 21 changed files with 438 additions and 331 deletions.
6 changes: 3 additions & 3 deletions app/controllers/alaveteli_pro/plans_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ class AlaveteliPro::PlansController < AlaveteliPro::BaseController
before_action :authenticate, :check_has_current_subscription, only: [:show]

def index
@plans = AlaveteliPro::Plan.list
@prices = AlaveteliPro::Price.list
@pro_site_name = pro_site_name
end

def show
@plan = AlaveteliPro::Plan.retrieve(params[:id])
@plan || raise(ActiveRecord::RecordNotFound)
@price = AlaveteliPro::Price.retrieve(params[:id])
@price || raise(ActiveRecord::RecordNotFound)
end

private
Expand Down
18 changes: 9 additions & 9 deletions app/controllers/alaveteli_pro/subscriptions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class AlaveteliPro::SubscriptionsController < AlaveteliPro::BaseController

before_action :check_allowed_to_subscribe_to_pro, only: [:create]
before_action :prevent_duplicate_submission, only: [:create]
before_action :load_plan, :load_coupon, only: [:create]
before_action :load_price, :load_coupon, only: [:create]

def index
@customer = current_user.pro_account.try(:stripe_customer)
Expand All @@ -28,8 +28,8 @@ def create
@pro_account.update_stripe_customer

attributes = {
plan: @plan.id,
tax_percent: @plan.tax_percent,
items: [{ price: @price.id }],
tax_percent: @price.tax_percent,
payment_behavior: 'allow_incomplete'
}
attributes[:coupon] = @coupon.id if @coupon
Expand Down Expand Up @@ -62,7 +62,7 @@ def create
end

if flash[:error]
json_redirect_to plan_path(@plan)
json_redirect_to plan_path(@price)
else
redirect_to authorise_subscription_path(@subscription.id)
end
Expand All @@ -89,7 +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(@subscription.plan)
json_redirect_to plan_path(@subscription.price)

elsif @subscription.active?
current_user.add_role(:pro)
Expand Down Expand Up @@ -168,16 +168,16 @@ def check_allowed_to_subscribe_to_pro
end

def check_has_current_subscription
# TODO: This doesn't take the plan in to account
# TODO: This doesn't take the price in to account
return if @user.pro_account.try(:subscription?)

flash[:notice] = _("You don't currently have a Pro subscription")
redirect_to pro_plans_path
end

def load_plan
@plan = AlaveteliPro::Plan.retrieve(params[:plan_id])
@plan || redirect_to(pro_plans_path)
def load_price
@price = AlaveteliPro::Price.retrieve(params[:price_id])
@price || redirect_to(pro_plans_path)
end

def load_coupon
Expand Down
45 changes: 0 additions & 45 deletions app/helpers/alaveteli_pro/plan_helper.rb

This file was deleted.

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

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

private

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

pluralize(count, interval)
end

def interval(price)
price.recurring['interval']
end

def interval_count(price)
price.recurring['interval_count']
end
end
32 changes: 0 additions & 32 deletions app/models/alaveteli_pro/plan.rb

This file was deleted.

33 changes: 33 additions & 0 deletions app/models/alaveteli_pro/price.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
##
# A wrapper for a Stripe::Price
#
class AlaveteliPro::Price < SimpleDelegator
include Taxable

tax :unit_amount

def self.list
AlaveteliConfiguration.stripe_prices.map do |(_key, id)|
retrieve(id)
end
end

def self.retrieve(id)
key = AlaveteliConfiguration.stripe_prices.key(id)
new(Stripe::Price.retrieve(key))
rescue Stripe::InvalidRequestError
nil
end

def to_param
AlaveteliConfiguration.stripe_prices[id] || id
end

# product
def product
@product ||= (
product_id = __getobj__.product
Stripe::Product.retrieve(product_id) if product_id
)
end
end
6 changes: 3 additions & 3 deletions app/models/alaveteli_pro/subscription.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def delete
Stripe::Subscription.cancel(id)
end

# plan
def plan
@plan ||= AlaveteliPro::Plan.new(__getobj__.plan)
# price
def price
@price ||= AlaveteliPro::Price.new(items.first.price)
end

private
Expand Down
8 changes: 4 additions & 4 deletions app/views/alaveteli_pro/plans/_pricing_tiers.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="pricing__tiers">
<% @plans.each do |plan| %>
<% @prices.each do |price| %>
<div class="pricing__tier pricing__tier--primary">
<div class="pricing__tier__heading">
<h2><%= _('Professional') %></h2>
Expand All @@ -10,10 +10,10 @@

<p class="price-label">
<span class="price-label__amount">
<%= format_currency(plan.amount_with_tax, no_cents_if_whole: true) %>
<%= format_currency(price.unit_amount_with_tax, no_cents_if_whole: true) %>
</span>

<%= billing_interval(plan) %>
<%= billing_interval(price) %>
</p>
</div>

Expand All @@ -27,7 +27,7 @@
<li><%= _('Friendly support') %></li>
</ul>

<%= link_to _('Sign up'), plan_path(plan), class: 'button button-pop' %>
<%= link_to _('Sign up'), plan_path(price), class: 'button button-pop' %>
</div>
</div>
<% end %>
Expand Down
8 changes: 4 additions & 4 deletions app/views/alaveteli_pro/plans/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
<h3><%= _('Selected plan') %></h3>
<div class="plan-overview">
<div class="plan-overview__desc">
<%= @plan.product.name %>
<%= @price.product.name %>
</div>
<div class="plan-overview__amount">
<%= format_currency(@plan.amount_with_tax) %>
<%= billing_frequency(@plan) %>
<%= format_currency(@price.unit_amount_with_tax) %>
<%= billing_frequency(@price) %>
</div>
</div>
</div>
Expand Down Expand Up @@ -65,7 +65,7 @@
</div>

<div class="settings__section">
<%= hidden_field_tag 'plan_id', @plan.id %>
<%= hidden_field_tag 'price_id', @price.id %>
<%= submit_tag _('Subscribe'), id: 'js-stripe-submit', disabled: true, data: { disable_with: 'Processing...' } %>
<%= link_to _('Cancel'), pro_plans_path, class: 'settings__cancel-button' %>
<p id="card-errors"></p>
Expand Down
6 changes: 3 additions & 3 deletions app/views/alaveteli_pro/subscriptions/_subscription.html.erb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

<div class="plan-overview">
<div class="plan-overview__desc">
<%= subscription.plan.product.name %>
<%= subscription.price.product.name %>
</div>

<div class="plan-overview__amount">
<%= format_currency(subscription.plan.amount_with_tax) %>
<%= billing_frequency(subscription.plan) %>
<%= format_currency(subscription.price.unit_amount_with_tax) %>
<%= billing_frequency(subscription.price) %>
<% if subscription.discounted? %>
<br>
<%= _('<strong>{{discounted_amount}}</strong> with discount ' \
Expand Down
21 changes: 21 additions & 0 deletions config/general.yml-example
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,27 @@ STRIPE_SECRET_KEY: ''
# ---
STRIPE_NAMESPACE: ''

# List of Stripe Prices which if a user signs up to will grant them access to
# Alaveteli Pro. Rendered on the Pro pricing pages in the order defined here.
#
# STRIPE_PRICES - Hash of objects with key equal to the Stripe Price IDs as the
# value equal to parameterise short human readable string.
#
# Note: Historical Stripe Price IDs listed here should include STRIPE_NAMESPACE.
#
# STRIPE_PRICES = Hash (default: { pro: 'pro' })
#
# Examples:
#
# STRIPE_PRICES:
# ALAVETELI-pro: pro
# price_123: pro-new-price
# price_456: pro-annual-billing
#
# ---
STRIPE_PRICES:
pro: pro

# Stripe.com webhook secret. Only required for Alaveteli Pro.
#
# STRIPE_WEBHOOK_SECRET: - String (default: '')
Expand Down
9 changes: 8 additions & 1 deletion doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Highlighted Features

* Migrated from Stripe Plans to Stripe Prices (Graeme Porteous)
* Change notes so that records tagged with `name:value` will be associated with
notes tagged as `name` (Graeme Porteous)
* Upgrade Stripe API version (Graeme Porteous)
Expand Down Expand Up @@ -96,7 +97,6 @@
* Don't show users that have closed their account or been banned on leaderboards
(Chris Mytton)


## Upgrade Notes

* _Required:_ This upgrade requires upgrading Ruby from 3.0 to 3.1 or later.
Expand Down Expand Up @@ -147,6 +147,13 @@
version from `2017-01-27` to `2020-03-02`. No changes should be necessary to
your Stripe account.

* _Optional:_ We have moved from Stripe Plans to Stripe Prices. Previously we
hardcoded the Stripe Plan ID of `pro`, but with changes to the Stripe
dashboard this ID can no longer be created. Migration to the Prices API will
allow for more flexibly, pricing changes, and multiple price points - for
example annual pricing. For new prices you need to configure `STRIPE_PRICES`
in `config/general.yml`.

# 0.44.0.1

## Highlighted Features
Expand Down
9 changes: 8 additions & 1 deletion lib/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ module AlaveteliConfiguration
SMTP_MAILER_PORT: 25,
SMTP_MAILER_USER_NAME: '',
STRIPE_NAMESPACE: '',
STRIPE_PRICES: { pro: 'pro' },
STRIPE_PUBLISHABLE_KEY: '',
STRIPE_SECRET_KEY: '',
STRIPE_TAX_RATE: '0.20',
Expand Down Expand Up @@ -145,7 +146,13 @@ def self.get(key, default)
def self.method_missing(name)
key = name.to_s.upcase
if DEFAULTS.key?(key.to_sym)
get(key, DEFAULTS[key.to_sym])
value = get(key, DEFAULTS[key.to_sym])
case value
when Hash
value.with_indifferent_access
else
value
end
else
super
end
Expand Down
Loading

0 comments on commit 9153a2c

Please sign in to comment.