Skip to content

essiene/brillig

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

                    ===================================
                    = Simple Billing Server (Brillig) =
                    ===================================

                    'Twas brillig and the slithy toves
                     did gyre and gimble in the wabe;
                     all mimsy were the borogoves
                     and the mome raths outgrabe...
                     
                                   -- Lewis S. Carroll

Introduction
=============

Ahem...er, yeah. So...Brillig is a bare-bones, scaled-down, no-frills, <insert 
favorite adjective here> implementation of a billing server. As a result, a
number of features have *intentionally* been left out::

 * Brillig has no concept of "users" (in the actual, human sense).
   Although the Admin UI will store users and groups (for authentication
   purposes only), these will not exist on the core billing server. This allows
   external systems the flexibility to maintain user-account mappings however
   they please.
   
 * Brillig will not track Services or Service Usage.
   A service, aka "the thing customers are paying for", is typically represented
   as an entity with Service Type, Name and Rating Profile fields.
   
   Whatever. All Brillig cares about is that customers know how they're charged
   and what they're being charged for. Callers are responsible for defining and
   maintaining services, tracking service usage and passing usage information
   along. You feed Brillig an account and usage information, and you'll get
   back an invoice (in a manner of speaking).
   
   To this end, we'll provide services to create and retrieve Rating Profiles
   (or "Tariffs"), update account usage and retrieve charges.
   
Okay, enough of that. Here's what Brillig _should_ handle::

 1. Accounts:
    An account is an abstract entity, represented by a unique identifier (UUID?)
    It exists, to act as a container for the other entities. Callers will
    probably want to map accounts to users in their backend systems; how they do
    this is up to them.
    
 2. Tariff Plans:
    A tariff plan is basically a relation for converting usage units to cost. 
    Since Brillig doesn't presume to know its caller's business requirements,
    callers are responsible for defining and updating their tariffs. We'll give
    y'all a shiny API to do it, even.
    
    Perhaps we should offer a way to do the reverse (determine usage from cost)?
    This would be useful for "prepaid" scenarios...what d'you think?
    
 3. Billing Types:
    This will be either "prepaid" or "postpaid", or some derivative of these two.
    
 4. Charges:
    A charge is generated in response to a billing "event", to inform a caller
    that an account is due to be billed. Brillig will return charges in machine-
    readable form; it is the caller's responsibility to transform this into
    whatever other form they desire (typically, a prettily-formatted invoice
    for their users).
    
 5. Payments:
    From Brillig's point of view, a payment is a request to adjust the balance
    of a specific account. Each payment is recorded as a credit to the said
    account. Callers will receive a "receipt identifier", which can be used to
    generate a receipt for the customer.
    
    Obviously, the actual transfer of funds will be handled by some other party;
    once again, we punt on doing any actual work :) Go talk to WebPay. Shoo.
    
 6. Reports:
    We-e-ell...let's get back to you on that one, shall we?


API (Version 1.0, First Draft)
===============================

A RESTful API is the primary means of interfacing with Brillig. For those who
require something else, a RESTful API will be provided. All weary souls who set
foot on these shores, seeking an API, shall find REST. Truly, they who pure of
heart and single of purpose, quest ardently to plumb the brillig depths, yea
shall they find REST.

So let it be written. So let it be known.

(Want SOAP? Try the Supermarket, or your local "aboki").

So, anyway...the API. Yeah.

API Security
-------------
Should we care about this at all, or leave it up to the network?

API Methods
-------------
 1. Create a new account:
    
    POST `/api/1.0/accounts`
    
    The request body should be the JSON-encoded structure below:
    
    {
      "balance" :      <decimal: current account balance>,
      "tariff_plan" :  <string: unique identifier of existing tariff plan>,
      "type" :         <string: unique identifier of existing billing type>
    }
    
    If successful, a 201 (Created) status is returned, along with the JSON
    below:
    
    {
      "id" :            <string: UUID representing the new account>,
      "details_url" :   <url: `/api/1.0/accounts/{id}`
                              Fetch this account's details>,
      "charges_url" :   <url: `/api/1.0/accounts/{id}/charges`
                              Fetch this account's charges>,
      "payments_url" :  <url: `/api/1.0/accounts/{id}/payments`
                              Fetch this account's payments>,
      "usage_url" :     <url: `/api/1.0/accounts/{id}/usage`
                              Fetch this account's service usage
    }
    
    The URLs are described in more detail below.
    
 2. Update an account:
    
    PUT `/api/1.0/accounts/{id}`
    
    Where `id` is the unique id of the account. The request body should be
    the JSON-encoded structure below:
    
    {
      "tariff_plan" :  <string: unique identifier of changed tariff plan>,
      "type" :         <string: unique identifier of changed billing type>
    }
    
    Note that "balance" is absent; once you create an account, the only way to
    change its balance is by making payments. The "balance" parameter is only
    provided during account creation to aid in migrating accounts from existing
    systems.
    
    If successful, a 204 (No Content) status is returned.
    
    
                    "O frabjous day! Callooh! Callay!"
                    
(I seriously vote we include this in our national anthem...somehow. Yeah.)

    
 3. Get details for an account:
    
    GET `/api/1.0/accounts/{id}`
    
    Where `id` is the unique id of the account. If successful, a 200 status code
    is returned, along with the JSON below:
    
    {
      "id" :           <string: same as above>,
      "tariff_plan" :  <string: same as above>,
      "type" :         <string: same as above>,
      "charges" :      <url: same as above>,
      "payments" :     <url: same as above>
    }
    
 4. Get account charges:
    
    GET `/api/1.0/accounts/{id}/charges`
    
    If successful, returns 200 (OK) along with the following JSON:
    
    [{
      "id" :       <string: unique identifier for this charge>,
      "account" :  <string: unique identifier of account>,
      "date" :     <datetime: date invoice was created>,
      "total" :    <decimal: total amount due>,
      "items" : [{
            "name" :   <string: typically the name of this service, or whatever>,
            "usage" :  <number: supplied by the caller>,
            "charge" : <decimal: determined by applying a tariff to `usage`>,
            "total" :  <decimal: total cost for this service>
          }, ...]
    }, ...]
    
    Each charge may have one or more items, and multiple charges may be
    returned from the call.
    
 5. Get account payments:
    
    GET `/api/1.0/accounts/{id}/payments`
    
    If successful, returns 200 (OK), along with the following JSON:
    
    [{
      "id" :       <string: unique identifier for this payment>,
      "account" :  <string: unique identifier of account>,
      "date" :     <datetime: date payment was made>,
      "type" :     <string: type of payment, e.g. "Full", "Partial" etc.>,
      "amount" :   <decimal: total amount remitted>
    }, ...]
    
    Multiple payments may be returned from the call.
    
 6. Make account payments:
    
    PUT `/api/1.0/accounts/{id}/payments`
    
    The request body should be the JSON-encoded structure below:
    
    {
      "date" :    <datetime: the date payment was made>,
      "type" :    <string: the type of payment>,
      "amount" :  <decimal: the amount being remitted>
    }
    
    If successful, a 204 (No Content) response is returned.
    
 7. Update service usage for account:
    
    PUT `/api/1.0/accounts/{id}/usage`
    
    The request body should be the JSON-encoded structure below:
    
    [{
      "name" :   <string: typically, the name of the service>,
      "usage" :  <number: service usage, defined by the caller>
    }, ...]
    
    If successful, a 204 response is returned.
    
So, we're almost done with the API. Is it not beamific?
(See, I can make up words too...eat that Charlie Dee! Yeah.)

 8. Create tariff plan:
    
    POST `/api/1.0/tariffs`
    
    The request body should be the JSON-encoded structure below:
    
    {
      "name" :  <string: a name for this tariff plan>
    }
 
 9. Create billing type
    
    POST `/api/1.0/billing-types`
    
    The request body should be the JSON-encoded structure below:
    
    {
      "name" :  <string: >
    }
 

                    Beware the Jabberwock, my son!
                    The jaws that bite, the claws that catch!
                    Beware the Jubjub bird, and shun
                    the frumious Bandersnatch!

("Shun the frumious Bandersnatch"...that's good advice right there. Yeah.)

About

A bare-bones, scaled-down, no-frills billing server. Or something like that.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%