• This repository has been archived on 12/Dec/2018
  • Stars
    star
    151
  • Rank 246,057 (Top 5 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 16 years ago
  • Updated about 16 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Subscription management and processing (TrustCommerce, BrainTree, etc.)

Freemium¶ ↑

The Freemium plugin attempts to encapsulate the Right Way to offer service subscriptions. It is built to handle multiple subscription plans (free, premium, premium plus, etc.), let you control your own invoices, and to interact with any merchant gateway that supports either automated recurring billing or credit card storage.

Freemium is a different beast from ActiveMerchant. Where the latter is optimized for one-off billing of credit cards (as in a retail environment), Freemium is optimized for storage and recurring billing of credit cards. This makes it a much cleaner and more complete solution for handling subscriptions. At the time of this writing, however, Freemium actually depends on ActiveMerchant because of its excellent CreditCard model, which I plan to steal.

This plugin was born out of my attempts to figure out the correct way to handle subscriptions. I decided that the safest/cleanest way was to simply keep track of how far out the subscription had been paid, and when that date came near, bill the subscription again to extend the paid_through date. The approach has turned out well, I think, though I strongly encourage anyone and everyone to review the processes in this plugin to make sure the assumptions it makes are appropriate.

Gateway Requirements¶ ↑

Rule #1: You never want to store credit card numbers yourself. This means that you need a gateway that either provides Automated Recurring Billing (ARB - a common offering) or credit card storage (e.g. TrustCommerce’s Citadel).

Freemium will work with any gateway that provides credit card storage (the preferred method!), but it will not work with every gateway that provides ARB. Just because your gateway provides ARB doesn’t mean that your application can fire-and-forget; you still needs to know about successful transactions (to send invoices) and failed transactions (to send warnings and/or expire a subscription). In order for your application to know about these events without your intervention, the ARB module either needs to send event notifications or it needs to provide an API to retrieve and review recent transactions.

Freemium will only work with ARB modules that provide an API to retrieve and review recent transactions. This is by far the safest route, since most gateways only send email notifications that must be manually processed by a human (ugh!) and the others can have unreliable event notification systems (e.g. PayPal, see talklikeaduck.denhaven2.com/articles/2007/09/02/how-to-cure-the-paypal-subscription-blues). And in any case, ARB modules that send event notifications hardly ever tell you about successful transactions, so you still have to keep track of the periodic cycles so you can send invoices, which makes the whole ARB thing barely useful.

So what we really need is a list of known good and known bad gateways. The list below is just the beginning, off the top of my head.

Good Gateways:¶ ↑

  • TrustCommerce with Citadel (can use Citadel and/or ARB)

  • Braintree Payment Solutions (SecureVault, or ARB)

Probably Good Gateways:¶ ↑

  • Authorize.net (CIM, or ARB if they also offer transaction review API)

Bad Gateways:¶ ↑

  • LoudCommerce’s LinkPoint (no storage, and no transaction review)

Expiration¶ ↑

I’ve tried to build Freemium with the understanding that sometimes a cron task might not run, and if that happens the customers should not get screwed. That means, for example, not expiring a customer account just because a billing process didn’t run. So the process for expiring a subscription is as follows: the first nightly billing process that runs after a subscription’s last paid day will set the final expiration date of that subscription. The final expiration date will be calculated as a certain number of days (the grace period) after the date of the billing process (grace begins when the program knows the account is pastdue). The first billing process that runs on or after the expiration date will then actually expire the subscription.

So there’s some possible slack in the timeline. Suppose a subscription is paid through the 14th and there’s a 2 day grace period. That means if a billing process runs on the 13th, then not until the 15th, the subscription will be set to expire on the 17th - the subscriber gets an extra day of grace because your billing process didn’t run.

Misc¶ ↑

  • If there’s no grace period then the same billing process will both set the expiration date and then actually expire the subscription, thanks to the order of events.

  • Expiring a subscription means downgrading it to a free plan (if any) or removing the plan altogether.

Install¶ ↑

1) Generate and run the migration:

> ./script/generate freemium_migration
> rake db:migrate

2) Populate the database with your subscription plan (create a migration to create SubscriptionPlan records)

> ./script/generate migration populate_subscription_plans

3) Create config/initializers/freemium.rb and configure at least the following:

gateway         pick one, then see rdoc for your gateway's options to see what needs to be configured (api key, etc.)
billing_control set to :full or :arb, depending on whether you're using your gateway's ARB module
grace period    in days, zero days grace is ok
mailer          for customized invoices, etc.

4) Create a SubscriptionsController (or similar) that does whatever it takes to get a unique billing key. This might mean storing the credit card (e.g. TrustCommerce Citadel) and/or setting up automated recurring billing, or getting the three keys from Amazon FPS. Most of these gateways don’t have concrete API classes in Freemium yet. If you write a gateway, let me know and I’ll include it.

5) Create association from your User model (or whatever) to the Subscription model.

6) Add a before_filter (or other logic) to properly enforce your premium plan. The filter should check that the User has an active Subscription to a SubscriptionPlan of the appropriate type.

7) Add ‘/PATH/TO/DEPLOYED/APP/script/runner -e production Subscription.run_billing’ to a daily cron task.

8) Tell me how any of this could be improved. I want this plugin to make freemium billing dead-simple.

Copyright © 2007 Lance Ivy, released under the MIT license

More Repositories

1

snail

A Ruby gem to assist with collecting and formatting international addresses
Ruby
115
star
2

recordselect

Replaces <select> tags with a full-HTML, RESTful JavaScript record browser (Rails plugin)
Ruby
45
star
3

components

Rails components with inheritable views, caching, and good encapsulation.
Ruby
26
star
4

semantic-attributes

object-oriented activerecord validations and machine/human formatting
Ruby
23
star
5

mass_assignment

a better mass assignment method for ActiveRecord that allows contextual whitelists of assignable attributes
Ruby
20
star
6

nested_assignment

A proof-of-concept for adding nested mass assignment to ActiveRecord.
Ruby
20
star
7

presenting

components + scaffolding == presentations
Ruby
13
star
8

benchmarkforrails

configurable benchmarking for rails
Ruby
13
star
9

timber

Rake tasks for dealing with large rails logs, e.g. a memory-efficient task to interleave logs from multiple machines into a single chronological file. Also provides a foundation for extending custom log parsing. Does NOT require Hodel 3000.
Ruby
10
star
10

active_record_merge

Adds a merge! method to ActiveRecord, for joining records together and updating associations.
Ruby
7
star
11

photor

Photo Organizer (in Ruby)
Ruby
3
star
12

ssh-dev-env

Manages a personal workspace on EC2 with hibernation and idle timeouts.
Shell
2
star
13

HexBoard

creating a board of hex tiles in 3d, using swift and scenekit
Swift
1
star
14

dotfiles

Shell
1
star
15

simplecov-stdout

A SimpleCov formatter that prints actionable feedback directly to stdout.
Ruby
1
star
16

typeorm-relay-connection

TypeORM implementation of the Relay Connection spec
TypeScript
1
star