Skip to main content

GrowFlow Billing Client

Python client for GrowFlow Billing API - subscription management, checkout sessions, invoices, and more.

Documentation: See growflow-billing-docs for complete API documentation and examples.

Node.js: Looking for the Node.js/TypeScript client? See @growflow/billing-client.

Installation

pip install growflow-billing-client

Or install from source:

pip install git+https://github.com/growflow/growflow-billing-client.git

Quick Start

import asyncio
from growflow_billing import GrowFlowBillingClient

async def main():
    async with GrowFlowBillingClient(api_key="sk_live_xxx") as client:
        # Get available plans
        plans = await client.get_plans()
        for plan in plans:
            print(f"{plan.name}: {plan.price_monthly} {plan.currency}/month")

        # Create a checkout session
        session = await client.create_checkout_session(
            customer_external_id="customer_123",
            plan_slug="pro",
            billing_cycle="monthly",
            success_url="https://yourapp.com/billing?status=success",
            cancel_url="https://yourapp.com/billing?status=canceled",
        )
        print(f"Checkout URL: {session.checkout_url}")

asyncio.run(main())

Features

  • Plans: List available subscription plans
  • Subscribers: Create and manage subscribers
  • Subscriptions: Get subscription status, cancel, change plans
  • Checkout: Create Stripe checkout sessions
  • Portal: Create Stripe customer portal sessions
  • Invoices: List invoice history with PDF downloads
  • Products: List and purchase add-on products

API Reference

Client Initialization

from growflow_billing import GrowFlowBillingClient

client = GrowFlowBillingClient(
    api_key="sk_live_xxx",                              # Required
    base_url="https://billing.growflow.studio/api/v1", # Optional
    timeout=30.0,                                       # Optional (seconds)
    max_retries=3,                                      # Optional
)

Plans

# List all active plans
plans = await client.get_plans()

# Access plan properties
for plan in plans:
    print(plan.slug)           # e.g., "pro"
    print(plan.name)           # e.g., "Pro Plan"
    print(plan.price_monthly)  # e.g., Decimal("349.00")
    print(plan.price_yearly)   # e.g., Decimal("3490.00")
    print(plan.limits)         # e.g., {"conversations": 5000, "stores": 3}
    print(plan.features)       # e.g., ["premium_support", "api_access"]
    print(plan.trial_days)     # e.g., 14

Subscribers

# Create a new subscriber
subscriber = await client.create_subscriber(
    external_id="store_123",      # Your internal ID
    email="owner@store.com",
    name="My Store",
    company_name="Store Inc.",    # Optional
    vat_number="IT12345678901",   # Optional
)

# Get subscriber by external ID
subscriber = await client.get_subscriber(external_id="store_123")

Subscriptions

# Get active subscription
subscription = await client.get_subscription(external_id="store_123")

if subscription:
    print(subscription.status)              # "active", "trialing", "past_due", etc.
    print(subscription.plan_slug)           # "pro"
    print(subscription.billing_cycle)       # "monthly" or "yearly"
    print(subscription.current_period_end)  # datetime
    print(subscription.is_trialing)         # bool
    print(subscription.trial_days_remaining) # int or None

# Cancel subscription
await client.cancel_subscription(
    subscription_id="sub_xxx",
    at_period_end=True,  # Cancel at end of billing period
)

# Change plan
await client.change_plan(
    subscription_id="sub_xxx",
    new_plan_slug="enterprise",
    prorate=True,
)

Checkout Sessions

# Create checkout session for new subscription
session = await client.create_checkout_session(
    customer_external_id="store_123",
    plan_slug="pro",
    billing_cycle="monthly",  # or "yearly"
    success_url="https://yourapp.com/billing?status=success",
    cancel_url="https://yourapp.com/billing?status=canceled",
    coupon_code="WELCOME20",  # Optional discount code
)

# Redirect user to Stripe checkout
redirect_url = session.checkout_url

Customer Portal

# Create portal session for subscription management
portal = await client.create_portal_session(
    customer_external_id="store_123",
    return_url="https://yourapp.com/billing",
)

# Redirect user to Stripe portal
redirect_url = portal.portal_url

Invoices

# List invoices
invoices = await client.get_invoices(
    external_id="store_123",
    limit=20,
)

for invoice in invoices:
    print(invoice.number)            # "INV-0001"
    print(invoice.status)            # "paid", "open", "void"
    print(invoice.amount_paid)       # 34900 (cents)
    print(invoice.currency)          # "eur"
    print(invoice.invoice_pdf)       # URL to PDF
    print(invoice.hosted_invoice_url) # Stripe hosted page

# Create a one-off invoice for a dynamic amount (e.g. a reseller's consolidated
# monthly charge = sum of its stores' plan prices minus discount). Pass a stable
# `reference` so a retried charge for the same period is idempotent.
invoice = await client.create_subscriber_invoice(
    "agency_123",                     # subscriber external id (the agency)
    amount=110.60,                    # major units (euros), not cents
    description="Consolidated — 3 stores (2026-07)",
    reference="consolidated:agency_123:2026-07",
    metadata={"period": "2026-07"},
)
print(invoice.hosted_invoice_url)

Error Handling

from growflow_billing import (
    GrowFlowBillingError,
    AuthenticationError,
    NotFoundError,
    ConflictError,
    ValidationError,
    RateLimitError,
)

try:
    plans = await client.get_plans()
except AuthenticationError:
    print("Invalid API key")
except NotFoundError as e:
    print(f"Resource not found: {e.message}")
except RateLimitError:
    print("Rate limit exceeded, try again later")
except GrowFlowBillingError as e:
    print(f"API error: {e.message} (status: {e.status_code})")

Configuration

Environment variables:

GROWFLOW_BILLING_API_KEY=sk_live_xxx
GROWFLOW_BILLING_URL=https://billing.growflow.studio/api/v1

License

MIT License - see LICENSE for details.

Metadata

Release files for growflowbilling-client 1.12.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for growflowbilling-client 1.12.0
File Size Uploaded Provenance Actions
growflowbilling_client-1.12.0.tar.gz 56.4 kB Without provenance Details for growflowbilling_client-1.12.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for growflowbilling-client 1.12.0
File Interpreter ABI Platform Actions
growflowbilling_client-1.12.0-py3-none-any.whl Python 3 none any Details for growflowbilling_client-1.12.0-py3-none-any.whl

Total release size: 102.2 kB

Release files / growflowbilling_client-1.12.0.tar.gz

Download URL growflowbilling_client-1.12.0.tar.gz
Size 56.4 kB
Tags Source
SHA-256 checksum
How to use checksums
cfd961a6663d50d5e925bad76e6e9f4dda8d33db012c8fc8f58adb351662cd79
BLAKE2b-256 checksum
How to use checksums
b5bdbd2bf63fa47887f5985bd0ff8792dcc28850df742ee1c585e414f7d8e109
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / growflowbilling_client-1.12.0-py3-none-any.whl

Download URL growflowbilling_client-1.12.0-py3-none-any.whl
Size 45.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d816bd3ffb2b1ff42c5bc07fd0cd045f2ae0d4c53452999354a26d75a78856d5
BLAKE2b-256 checksum
How to use checksums
8a1eddc09ed53aa996bc4707c7196bee2cf5a5ba7ec20b0123f2820a9001ed51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Security for growflowbilling-client 1.12.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page