Subscriptions for Rails
This gem helps with building services which have paid subscriptions. It includes the models to store subscription status, and provides integration with PayPal for paid subscriptions.
Assumptions
SubscriptionFu makes the following assumptions on how subscriptions are used:
There is a subscription subject, i.e. a user or some other object which needs a subscription in order to access your site. In the examples below we'll use "group".
You have a subscription initiator, which is usually the user object. In the examples below we'll use "user"
Installation
Add to your Gemfile:
gem 'subscription_fu', :git => "git://github.com/mobalean/subscription_fu.git"
Run "bundle install".
Then install the required files:
rails g subscription_fu:install
Updating
See UPDATING.md
Configuration
Edit config/initializers/subscription_fu.rb (generated by the install generator)
Add "needs_subscription" to the subscription subject:
class Group < ActiveRecord::Base needs_subscription ... end
Create subscriptions and transactions controllers and views, for example see examples
General subscription flow
The user starts the subscription process by selecting a plan (if multiple ones are available, otherwise you can skip this and just have a subscribe button). We assume you'll do that selection in SubscriptionsController#new.
link_to image_tag("https://www.paypal.com/ja_JP/JP/i/btn/btn_xpressCheckout.gif", :alt => "PayPal で決済を行う"), subscription_path, :method => :post
The subscribe form posts to SubscriptionsController#create, which creates an inactive subscription and associated transaction, and finally redirects the user to a checkout URL:
@subscription = current_group.build_next_subscription("basic") @subscription.save! @transaction = @subscription.initiate_activation(current_user) redirect_to @transaction.start_checkout(url_for(:action => :confirm, :controller => "transactions"), url_for(:action => :abort, :controller => "transactions"))
If the transaction gets approved, the user will get back to TransactionsController#confirm. Otherwise she might not return or return to TransactionsController#abort.
The TransactionsController#confirm is supposed to show the user a final confirmation screen before executing the transaction. To load a pending transaction, use a before filter like this:
before_filter :require_valid_transaction def require_valid_transaction @token = params[:token] @transaction = current_group.pending_transaction(@token) unless @transaction logger.info("Invalid transaction for token: #{@token}") flash[:error] = "Invalid transaction, please try again." redirect_to root_path end end
The form would look like this: (HAML with simple_form)
= simple_form_for @transaction, :url => transaction_path do |f| = hidden_field_tag :token, @token .submit= f.button :submit, '申込む'
The confirmation form posts to TransactionsController#update, which completes the transaction:
if @transaction.complete flash[:notice] = "Sucessfully updated your subscription." else flash[:error] = "Transaction was not successfull, please try again." end redirect_to root_path
That's it.
Using the subscriptions
Once setup, your subscription subject (the group in our example) will get a couple new methods. To check whether or not it has a subscription, use:
group.active_subscription?
For getting the group's plan, you can simply use:
group.subscription_plan
Which will give you an instance of the subscription plan as defined in the initializer.
For more details, see SubscriptionFu::Models