Placing on Order
A Subscription
is created when a Plan
is selected and paid for.
As simple as it sounds, there are many variants to implement the previous
sentence.
Basic Pipeline
In the most basic pipeline, a user becomes a subscriber in 2 steps:
Click a
Plan
on the /pricing/ pageSubmit credit card information
Pipeline with Multiple Periods Paid in Advance
It is always better to receive more cash up-front so an intermediate step is often introduced to enable to pre-pay multiple periods in advance at a discount.
Click a
Plan
on the /pricing/ pagePick the number of periods paid in advance
Submit credit card information
Pipeline with Multiple Products in Shopping Cart
A growing business often offers multiple products (i.e. Plan
) that are
cross-saled to new and existing customers. In that case, the /pricing/ page
is replaced by a more complex catalog. Cart and checkout concepts appear.
Add multiple
Plan
to a user cartClick a checkout button
Submit credit card information
Pipeline to Bulk Subscribe Third-parties
Software-as-a-Service that target businesses (B2B) and/or other kind of structured groups almost always require one entity to pay for subscriptions on behalf of users that belong to it. This can be implemented through managers (or custom roles) to the subscribed entity (see Security) or through the entity buying multiple subscriptions in bluk, on behalf of its users. The later case requires an extra step to subscribe those third parties.
Click a
Plan
on the /pricing/ pageEnter email address of users to subscribe
Submit credit card information
Full Pipeline
Of course, all of the above cases can be combined together, which leads to a full pipeline as such:
Add multiple
Plan
to a user cartClick a checkout button
Pick the number of periods paid in advance
Enter email address of users to subscribe
Submit credit card information
Django Views
The two primary views to place an order are CartView
and BalanceView
.
CartView
is used to implement the checkout and place a new order while
BalanceView
is used to pay an Organization
balance due, either because
a charge wasn’t sucessful and/or the provider implements a subscribe-pay-later
policy.
CartView
for items in the cart, create new subscriptions or pay in advance.BalanceView
for subscriptions with balance dues
- class saas.views.billing.CartBaseView(**kwargs)
The main pupose of
CartBaseView
is generate an list of invoicables fromCartItem
records associated to arequest.user
.The invoicables list is generated from the following schema:
invoicables = [ { "subscription": Subscription, "lines": [Transaction, ...], "options": [Transaction, ...], }, ...]
Each subscription is either an actual record in the database (paying more periods on a subscription) or
Subscription
instance that only exists in memory but will be committed on checkout.The
Transaction
list keyed by “lines” contains in-memory instances for the invoice items that will be committed and charged when the order is finally placed.The
Transaction
list keyed by “options” contains in-memory instances the user can choose from. Options usually include various number of periods that can be pre-paid now for a discount. ex:$189.00 Subscription to medium-plan until 2015/11/07 (1 month) $510.30 Subscription to medium-plan until 2016/01/07 (3 months, 10% off) $907.20 Subscription to medium-plan until 2016/04/07 (6 months, 20% off)
- class saas.views.billing.BalanceView(**kwargs)
Set of invoicables for all subscriptions which have a balance due.
While
CartView
generates the invoicables from theCartItem
model,BalanceView
generates the invoicables fromSubscription
for which the amount payable by the customer is positive.The invoicables list is generated from the following schema:
invoicables = [ { "subscription": Subscription, "name": "", "descr": "", "lines": [Transaction, ...], "options": [Transaction, ...], }, ...]
GET displays the balance due by a subscriber.
Template:
To edit the layout of this page, create a local
saas/billing/balance.html
(example).- Template context:
STRIPE_PUB_KEY
Public key to send to stripe.cominvoicables
List of items to be invoiced (with options)organization
The provider of the productrequest
The HTTP request object
POST attempts to charge the card for the balance due.
- class saas.views.billing.CartView(**kwargs)
CartView
derives fromCartSeatsView
which itself derives fromCartPeriodsView
, all of which overrides theget
method to redirect to the appropriate step in the order pipeline no matter the original entry point.