Skip to main content
Zyra Zyra
Features Pricing Security FAQ Documentation
Sign In Sign up for free

Documentation › User Guides › Organizations › Stage 3 › Understand billing and invoices

Understand billing and invoices

Chapter 6 · about 12 minutes to read

You've sized your fleet, trimmed waste, and given the right people the right roles. This last chapter explains exactly how the bill comes together, where you find it, and how to dispute or apply credit against it.

Time: about 12 minutes. Prerequisites: at least one Virtual Server that has run for an hour or more.

How cost accumulates

A background job calls update_virtual_server_costs (see backend/app/services/billing_calculator.py) continuously. For every VS with status = "running":

  1. Compute elapsed hours since started_at, in exact Decimal arithmetic.
  2. Multiply by cost_per_hour (default 0.10, configured per VS at deploy time).
  3. Round to 4 decimal places.
  4. Write the result to total_cost on the virtual_servers row.

The number you see on the VS detail page under Cost so far is always within seconds of fresh.

Current-month usage

Open Billing → Usage to see, for the current calendar month: sum of total_cost across every VS; per-VS breakdown (sorted by spend, descending); per-day spend chart; forecast based on rolling 7-day spend.

[SCREENSHOT: Billing → Usage with the per-day bar chart and month-end forecast]

When invoices are generated

At the end of each calendar month, the invoice generator (backend/app/services/invoice_generator.py) creates one invoices row per organisation with:

  • invoice_number — INV-YYYY-NNNN, sequential per year.
  • period_start / period_end — calendar month boundaries.
  • subtotal — sum of every VS's total_cost in window, exact decimal.
  • tax_amount — applied if your org's billing profile has a tax rate.
  • total — subtotal + tax_amount.
  • currency — USD by default.
  • status — starts draft, transitions to issued, then paid after capture.

A PDF is rendered on demand (or pre-generated when the invoice issues) and stored in MinIO under invoices/<year>/<invoice_number>.pdf, with local-disk fallback if MinIO is briefly unavailable. The signed download URL is what the pdf_url column exposes.

Downloading invoices

Open Billing → Invoices. Sorted newest first, scoped to your organisation via the /invoices endpoint. Click the invoice number for line items, Download PDF for the file, or Pay now if status = issued and you have a Stripe payment method on file.

Stripe — what's live, what's pending

Zyra uses Stripe for card payments. Two honest facts:

  1. Test-mode Stripe is fully wired. End-to-end card capture, customer creation, invoice payment, and webhook reconciliation all run against Stripe test keys today. Validate the flow with standard Stripe test cards.
  2. Live Stripe keys are pending founder action. Production keys require the Zyra business entity to finish Stripe's verification. Until that closes, real-money charges are not enabled. Invoices still generate, still itemise correctly, and still reconcile — they're just not auto-charged.

[VERIFY: confirm live Stripe go-live date once Hadar receives Stripe production approval]

Until live keys are in place, the founder-side workflow is: invoice issues → email the customer → customer pays via ACH/wire details on the invoice → finance marks the invoice paid.

Credit balance

Zyra tracks pre-paid credits and goodwill credits as a per-organisation balance. Credits apply automatically against the next invoice at issue time:

  • Pre-paid credit. Customer pays $X upfront; balance ticks down as VSs accrue cost.
  • Goodwill credit. Issued by support to compensate for outages, SLA breaches (see Chapter 2), or onboarding promos.

Open Billing → Credit balance for the running total and full history. [VERIFY: confirm credit-balance UI is exposed to org_admin or finance-only at launch]

Refunds and disputes

  • Within 30 days, undisputed. Billing → Invoices → <invoice> → Request refund. Support reviews and refunds via the same Stripe payment method, or issues equivalent goodwill credit.
  • SLA-driven credit. The monthly SLA report rolls breaches into a credit amount automatically. Review at SLA → Report; accept and the credit lands on next month's invoice.
  • Dispute on the card directly. Stripe forwards the chargeback to Zyra; we respond with the invoice PDF, usage records, and audit log. Don't dispute on the card if a support-issued credit will resolve it faster.

Tax and VAT

Tax is applied based on the Billing profile (org address + tax ID, see Settings → Billing). For EU customers a valid VAT ID disables tax (reverse charge); for US customers the relevant state tax is added. [VERIFY: list of tax jurisdictions live at MVP1 GA — confirm before quoting specific states/countries]

What just happened

You closed the loop: cost accumulates in real time, rolls into a numbered invoice at month-end, surfaces as a downloadable PDF, and reconciles against credits or Stripe (test mode live, production keys pending the founder finishing Stripe's verification). This was the last chapter of Stage 3.

Troubleshooting

  • Invoice total doesn't match my own math. Open the invoice detail page and check per-VS lines against total_cost on each VS row. If you see drift you've probably forgotten about a stopped-then-restarted VS that accrued cost in two segments.
  • PDF link returns 404. PDF generation is async; the row exists before the file uploads. Wait 60 seconds and refresh, or hit Regenerate PDF.
  • Credit balance not applied. Credits apply at invoice issue, not at consumption. They'll show up when the month closes.
  • "Pay now" is greyed out. No Stripe payment method on file, or live keys not yet active.

← Previous: Invite your team

Back to Organization Guide →

Last reviewed: 2026-05-21

© 2026 Zyra. All rights reserved. | Privacy Policy | Terms of Service | Careers