Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Rails models for handling free/paid subscriptions for services
Ruby
branch: master

- improved error reporting so we'll know why paypal rejects us if the…

…y do

- updated gems, added Gemfile.lock
- updated paypal-express
latest commit b6fcee219d
@mreinsch mreinsch authored
Failed to load latest commit information.
app/models/subscription_fu
config/locales also copy locale file
examples added example routes
lib
spec - improved error reporting so we'll know why paypal rejects us if the…
.gitignore - improved error reporting so we'll know why paypal rejects us if the…
Gemfile dropped rake requirement, latest version is fine again
Gemfile.lock
LICENSE skeleton
README.md
Rakefile
UPDATING.md sync canceled profiles from paypal
subscription_fu.gemspec

README.md

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

  1. Edit config/initializers/subscription_fu.rb (generated by the install generator)

  2. Add "needs_subscription" to the subscription subject:

    class Group < ActiveRecord::Base
      needs_subscription
      ...
    end
    
  3. Create subscriptions and transactions controllers and views, for example see examples

General subscription flow

  1. 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
    
  2. 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"))
    
  3. If the transaction gets approved, the user will get back to TransactionsController#confirm. Otherwise she might not return or return to TransactionsController#abort.

  4. 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, '申込む'
    
  5. 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

Something went wrong with that request. Please try again.