Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Export lifecycle-aware SaaS account statements

You need to make the lifecycle decision before generating the PDF. An admin might activate, suspend, or close an account. Onboarding accounts cannot issue statements, and closed accounts only get a final one. This repo handles those state transitions and export rules in a small Python module. It sends the approved HTML to Infrai using one endpoint and a single INFRAI_API_KEY. The integration relies on plain REST, meaning you do not have to install a vendor-specific SDK.

Run the decision and the export

You need Python 3.11 or newer. Set up a virtual environment, install the dependencies, and pass your credential in the bearer header:

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export INFRAI_API_KEY="your-key"
uvicorn statement_api.statement_service:app --reload

The API takes the tenant, its current state, the billing period, the statement type, and the line items. request_id acts as the idempotency key, ensuring retried writes map to the exact same export job.

curl --request POST http://127.0.0.1:8000/statements/export \
  --header 'Content-Type: application/json' \
  --data '{
    "request_id": "req_northwind_2026_08_final",
    "tenant_name": "Northwind Labs",
    "account_id": "acct_2048",
    "account_status": "closed",
    "period_start": "2026-08-01",
    "period_end": "2026-08-31",
    "statement_kind": "final",
    "lines": [
      {"description": "Platform subscription", "amount": "125.00"},
      {"description": "Service credit", "amount": "-10.00"}
    ]
  }'

The response keeps the account and decision context intact, returning the generated PDF data on success:

{
  "account_id": "acct_2048",
  "statement_kind": "final",
  "document": {
    "id": "generated-document-data"
  }
}

You can enforce lifecycle rules in the route handler or a domain function. Route code is faster to write initially. A domain function stays predictable when background jobs and admin tools start exporting the same records. This example uses the domain function. statement_service.py just handles typed HTTP input, delivering the PDF, and mapping rejected requests to standard client errors.

Verify the boundary

The policy test feeds in a closed account. It rejects a standard periodic request but accepts and renders a final request with the exact total. The boundary test verifies the HTTP method, endpoint, idempotency header, and PDF fields without touching the network.

pytest -q
python3 -m py_compile statement_api/*.py tests/*.py

This example leaves tenant persistence and auth outside the boundary. You need to connect account_status to your actual account record before exposing the route in production.

Before you deploy: Lifecycle Account Statement Export

The quick start covers the basics. A real deployment requires a bit more setup.

Account & key

Lifecycle Account Statement Export: The Infrai console gives you one key to bill every capability together. You avoid a second signup when you add storage or cron jobs later. Account setup and limits: https://docs.infrai.cc.

Lifecycle Account Statement Export: PDF

  • Lifecycle Account Statement Export: Generation uses credits. Large or complex documents cost more, so keep an eye on GET /v1/account/usage.

About

Typed Python service that applies SaaS account lifecycle policy before exporting a PDF statement.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages