Documentation

Complete guide to the Billing Calculator

Overview

The Billing Calculator is a modern web application designed for calculating and testing complex billing scenarios. Built with Next.js, TypeScript, and a KINFOLK-inspired minimal design.

It provides a comprehensive solution for managing usage-based billing, adjustments, credits, and payment processing with real-time calculations and PDF export capabilities.

Features

Core Features

  • ✓ Usage-based billing calculation
  • ✓ Multiple instance types support
  • ✓ Adjustments (discounts & surcharges)
  • ✓ Credit management
  • ✓ Unpaid amount & late fee handling
  • ✓ VAT calculation (10%)

Advanced Features

  • ✓ PDF statement export
  • ✓ Calculation history (50 entries)
  • ✓ Mock payment processing
  • ✓ Real-time calculations
  • ✓ Data visualization charts
  • ✓ Scenario comparison

Getting Started

1. Basic Information

Start by entering the basic billing information:

  • Target Date: Billing month
  • UUID: Unique identifier for the billing entity
  • Billing Group ID: Group identifier
  • Unpaid Amount: Previous period unpaid balance
  • Is Overdue: Apply late fee (5%)

2. Add Usage Entries

Add resource usage with available instance types:

compute.c2.c8m8 - ₩397/hour

compute.g2.t4.c8m64 - ₩166.67/hour

storage.volume.ssd - ₩100/GB/month

network.floating_ip - ₩25/hour

3. Apply Adjustments (Optional)

Add discounts or surcharges:

  • Type: DISCOUNT or SURCHARGE
  • Level: BILLING_GROUP or PROJECT
  • Method: RATE (%) or FIXED (amount)

4. Add Credits (Optional)

Apply credits to reduce billing amount:

  • FREE: Free promotional credits
  • PAID: Pre-purchased credits
  • PROMOTIONAL: Campaign credits

API Integration

Frontend API Client

The application uses Next.js API routes as a proxy to avoid CORS issues:

import { calculateBilling } from '@/lib/api/billing-api'

// Calculate billing
const statement = await calculateBilling({
  targetDate: new Date('2025-01'),
  uuid: 'test-uuid-001',
  billingGroupId: 'bg-kr-test',
  usage: [...],
  credits: [...],
  adjustments: [...],
  unpaidAmount: 0,
  isOverdue: false
})

Backend Endpoints

POST

/billing/meters

Send metering data

POST

/billing/admin/calculate

Trigger billing calculation

GET

/billing/payments/{month}/statements

Fetch billing statement

POST

/billing/payments/{month}

Process payment

System Architecture

Architecture Diagram

Frontend (Next.js)

React Components
UI Layer
Context API
State Management
React Query
Data Fetching

Next.js API Routes (Proxy)

CORS 해결 및 요청 중계
/api/billing/*

Backend (Flask Mock Server)

Metering
Usage Data
Calculation
Billing Logic
Statements
Results
Payments
Processing

Data Storage

In-Memory Storage (Mock Server) / LocalStorage (History)

Sequence Diagram

Complete billing calculation request flow

User
Frontend
API Proxy
Backend
1. Enter billing data
2. POST /api/billing/meters
3. Forward to backend
4. Store metering data
5. POST /admin/calculate
6. Calculate billing
7. GET /statements
8. Fetch statement
9. Return statement
10. Return to frontend
11. Display statement

Billing Flow

1

Metering Data Collection

Usage data is sent to the backend with counter information (name, type, volume, unit)

2

Calculation Trigger

Backend calculates subtotal based on usage, applies adjustments and credits

3

Statement Generation

Complete statement with line items, adjustments, credits, unpaid amount, and late fee

4

VAT & Final Amount

10% VAT is applied to calculate the final total amount due

5

Payment Processing

Mock payment is processed and receipt is generated

Code Examples

React Hook Usage

import { useBillingCalculation } from '@/hooks/useBillingCalculation'

function MyComponent() {
  const { mutate: calculate, isLoading } = useBillingCalculation()

  const handleCalculate = () => {
    calculate(billingInput, {
      onSuccess: (statement) => {
        console.log('Statement:', statement)
      },
      onError: (error) => {
        console.error('Error:', error)
      }
    })
  }

  return <button onClick={handleCalculate}>Calculate</button>
}

Context API Usage

import { useBilling, useCalculatedStatement } from '@/contexts/BillingContext'

function StatementComponent() {
  const { actions } = useBilling()
  const statement = useCalculatedStatement()

  return (
    <div>
      {statement && (
        <div>Total: {statement.totalAmount}</div>
      )}
    </div>
  )
}

PDF Export

import { generateStatementPDF } from '@/lib/pdf/statementPDF'

// Generate and download PDF
generateStatementPDF(statement)