uncloud/doc/README-billing.org

3.3 KiB

How to handle billing in general

Manual test flow / setting up bills

  • Needs orders

Orders

  • Orders are the heart of uncloud billing
  • Have a starting date
  • Have an ending date
  • Orders are immutable
  • Can usually not be cancelled / cancellation is not a refund

    • Customer/user commits on a certain period -> gets discount based on it
  • Can be upgraded

    • Create a new order
    • We link the new order to the old order and say this one replaces it
    • If the price of the new order is HIGHER than the OLD order, then we charge the difference until the end of the order period
    • In the next billing run we set the OLD order to not to bill anymore
    • And only the NEW order will be billed afterwards
  • Can be downgraded in the next period (but not for this period)

    • We create a new order, same as for upgrade
    • The new order starts directly after the OLD order
    • As the amount is LOWER than the OLD order, no additional charge is done during this order period
  • We might need to have an activate datetime

    • When to implement this
  • Order periods can be

Statuses

  • CREATING/PREPARING
  • INACTIVE (?)
  • TO_BILL
  • NOT_TO_BILL: we use this to accelerate queries to the DB

Updating status of orders

  • If has succeeding order and billing date is last month -> set inactive

Bills

  • Are always for a month
  • Can be preliminary

Which orders to include

  • Not the cancelled ones / not active ones

Flows / Approach

Finding all orders for a bill

  • Get all orders, state != NOT_TO_BILL; for each order do:

    • is it a one time order?

      • has it a bill assigned?

        • yes: set to NOT_TO_BILL
        • no:

          • get_or_create_bill_for_this_month
          • assign bill to this order
          • set to NOT_TO_BILL
    • is it a recurring order?

      • if it has a REPLACING order:

  • First of month
  • Last of month

Handling replacement of orders

  • The OLD order will appear in the month that it was cancelled on the bill
  • The OLD order needs to be set to NOT_TO_BILL after it was billed the last time
  • The NEW order will be added pro rata if the amount is higher in the same month
  • The NEW order will be used next month
Disabling the old order
  • On billing run
  • If order.replacement_order (naming!) is set

    • if the order.replacement_order starts during THIS_MONTH

      • add order to bill
    • if NOT:

      • the order was already replaced in a previous billing period
      • set the order to NOT_TO_BILL
Billing the new order
  • If order.previous_order

Handling multiple times a recurring order

  • For each recurring order check the order.period

    • Find out when it was billed last

      • lookup latest bill
    • Calculate how many times it has been used until 2359, last day of month

      • For preliminary bill: until datetime.now()
      • Call the bill_end_datetime
      • Getting duration: bill_end_datetime - order.last_billed

        • Amount in seconds; duration_in_seconds
      • Divide duration_in_seconds by order.period; amount_used:

        • If >= 1: add amount_used * order.recurring_amount to bill