Subscription states and billing history

Booknetic SaaS shows four state labels in your Tenants list. Here's what each one means in plain English and what's typically happening for the tenant when you...

Version:
Categories

What subscription state means in Booknetic SaaS

In Booknetic SaaS, every tenant on your platform has a subscription state — a short label that tells you, at a glance, where they stand financially: are they on a trial, are they paying you on a recurring cycle, did they cancel, did their access expire, or haven't they finished signing up yet.

Subscription state is the single most useful column on your Tenants list. It's how you spot churning customers, find trial users who never converted, and confirm that your paying tenants are actually current.

A few things are worth knowing up front:

  • Subscription state is calculated, not stored as a single enum. Booknetic SaaS keeps a small record for each tenant — which plan they're on, when their access ends, whether they have a live subscription with your payment provider, and whether their email is verified. The label you see ("Subscribed", "Expired", etc.) is derived from those fields each time you open the Tenants list.
  • Your payment provider is the source of truth for the money. Booknetic SaaS mirrors enough state to gate access and show you who's paid — but Stripe, PayPal, and WooCommerce each keep the full record of invoices, refunds, and dunning attempts on their side. We'll cover this honestly in the "What's stored in Booknetic SaaS vs what lives with your provider" section below.
  • State changes are event-driven. When a tenant subscribes, renews, cancels, or lapses, the change flows through a webhook from your provider into Booknetic SaaS. If the webhook isn't wired up correctly, Booknetic SaaS can fall out of sync with reality — see Setting up the Stripe webhook for the most common cause of drift.

The states you'll see in the Tenants list

Booknetic SaaS shows four state labels in your Tenants list. Here's what each one means in plain English and what's typically happening for the tenant when you see it.

State label What it means Typical situation
Subscribed The tenant has a live subscription with your payment provider, and their access has not yet expired. They're paying you on a monthly or annual cycle, or they're funded by their deposit balance and have enough balance to keep renewing.
Expired The tenant has (or had) a subscription with your provider, but their access window has passed and no renewal payment came through. A renewal payment failed, the tenant cancelled and the paid period ran out, or a trial ended without an upgrade.
Not activated The tenant signed up but never verified their email. They started the signup form, never clicked the verification link, and currently can't log into their tenant panel.
Not subscribed The tenant verified their email but doesn't have a live subscription. A tenant whose subscription was cancelled and the paid period is now also over, or any other state where they're past the trial but haven't paid.

A fifth label you'll often hear about — Trial — is a special case of "Subscribed": the tenant is on the Trial plan you configured in Booknetic SaaS → Settings → Plan Settings, their access window is the trial-duration window you set, and they haven't paid yet. The Tenants list shows trial tenants under the same Subscribed label until their trial expiry passes; once it passes, they flip to Expired. For the full trial flow, see Trials in Booknetic SaaS.

Important: Booknetic SaaS does not have a "Paused", "Past due", or "Dunning" label. If your payment provider puts a subscription into dunning (Stripe past_due, PayPal retry) and the renewal hasn't yet succeeded or failed for good, Booknetic SaaS will keep showing the tenant as Subscribed until the renewal either succeeds (extends the period) or the subscription gets fully cancelled. For visibility into in-flight dunning, check your Stripe Dashboard → Subscriptions or PayPal → Activity directly.

How a tenant moves between states

Tenants move between states based on events that happen at signup, in their Billing page, or — most commonly — at your payment provider when a webhook fires.

The table below maps the state they were in, the event that happened, and the state they ended up in. This is the full picture of how subscription state changes on your platform.

From state Event To state Where the event comes from
(new signup) Tenant submits the signup form, email not yet verified Not activated Booknetic SaaS signup flow
Not activated Tenant clicks the email verification link Subscribed (on Trial plan, if you configured a trial) or Not subscribed (if no trial) Booknetic SaaS verification flow
Subscribed (trial) Tenant picks a paid plan in Billing and pays Subscribed (on paid plan) Tenant's Billing page → Stripe / PayPal / balance
Subscribed (trial) Trial duration passes without upgrade Expired Time-based, no event needed
Subscribed (paid) Successful renewal Subscribed (period extended) Webhook: Stripe invoice.paid / PayPal PAYMENT.SALE.COMPLETED
Subscribed (paid) Tenant clicks Cancel subscription in their Billing page Subscribed until the period ends, then Expired Tenant action → cancellation sent to provider
Subscribed (paid) Owner cancels via SaaS admin or via the provider's Dashboard Subscribed until the period ends, then Expired Owner action → cancellation sent to provider
Subscribed (paid) Renewal payment fails and the provider's dunning gives up Expired Webhook: Stripe customer.subscription.deleted / PayPal BILLING.SUBSCRIPTION.CANCELLED
Subscribed (paid) Tenant switches plan (upgrade/downgrade) Subscribed (on new plan, new period) Tenant's Billing page → new payment confirmed
Expired Tenant comes back and re-subscribes from Billing Subscribed (on chosen plan) Tenant's Billing page → Stripe / PayPal / balance
Expired / Not subscribed Owner manually pushes the expiry date forward in Tenants → Edit Subscribed until the new expiry Owner manual override (used for goodwill extensions)

Important nuance on cancellation: clicking Cancel subscription does not revoke access immediately. It stops the next recurring charge — your tenant keeps access through the end of the period they last paid for, and only flips to Expired once that period boundary passes. Same goes for an owner-initiated cancellation. For the full cancellation flow, see Cancelling and deleting tenants.

What's stored in Booknetic SaaS vs what lives with your provider

This is the most important section in this doc, and it's the section most owners read after they've already promised a customer something Booknetic SaaS can't deliver. Read it before the customer email lands, not after.

Booknetic SaaS is a thin mirror of state. Your payment provider — Stripe, PayPal, or WooCommerce — is the source of truth for the money. That has practical consequences for what you can show your tenants, what you can export, and what happens when things go wrong.

Here's the honest split.

What Booknetic SaaS stores locally on your WordPress site

For each tenant, Booknetic SaaS keeps a small record:

  • Which plan they're on.
  • When their current access ends (the Expires in date you see in the tenant's Billing page).
  • Whether they have a live subscription with your payment provider, and a reference ID for that subscription.
  • Their deposit balance, if you've enabled the WooCommerce top-up rail.
  • Whether they've verified their signup email.

And for each significant billing event, Booknetic SaaS appends a row to that tenant's billing history:

  • The date of the event.
  • The amount.
  • The payment method used (credit card via Stripe, PayPal, or balance).
  • The status (paid, cancelled, etc.).
  • An identifier to cross-reference with your payment provider.

That's it. It's enough to power your admin views, gate tenant access at the right moments, and keep a log you can scroll through. It is not enough to be your accounting system.

What lives with Stripe (when your tenant pays with Stripe)

When a tenant pays you via Stripe Checkout, Stripe keeps:

  • The full subscription record (current period, next renewal date, full history).
  • Every invoice — paid, unpaid, void, refunded — as a downloadable PDF.
  • Payment intent IDs and the underlying card detail (PCI-scoped — Booknetic SaaS never sees the card number).
  • Refund records, including partial refunds and dispute history.
  • Dunning attempts (Stripe Smart Retries) and the result of each retry.
  • The tenant's email-on-file at Stripe, used for receipt delivery.

Anything that needs a PDF, a refund detail, a chargeback record, or a card-on-file update happens in your Stripe Dashboard, not in Booknetic SaaS. We mirror enough of the subscription state to know "yes, they're paid through this date" — we don't mirror the financial detail.

What lives with PayPal (when your tenant pays with PayPal)

PayPal stores the Billing Agreement — the recurring-payments contract with your tenant — plus every transaction under that agreement:

  • The agreement state (Active, Suspended, Cancelled).
  • Every PAYMENT.SALE (renewal payment) record.
  • The payer's PayPal-side details.
  • Refund records on PayPal's side.

When you click Cancel subscription in Booknetic SaaS for a PayPal-paid tenant, Booknetic asks PayPal to suspend the agreement (not terminate it). The agreement remains in PayPal and is theoretically resumable from PayPal's side. For legal off-boarding (full agreement termination), do it from your PayPal Dashboard.

What lives with WooCommerce (when your tenants top up via deposit)

If you've enabled the WooCommerce deposit/balance rail, the deposit ledger lives in WooCommerce:

  • Every WC order that funded a tenant's deposit (with the WC payment method used — Stripe-WC, bank transfer, COD, anything WC supports).
  • The WC customer record for the tenant.
  • WC's own refund records on the deposit orders.

Booknetic SaaS only stores the resulting balance on each tenant. If you refund a WooCommerce deposit order in your WC admin, Booknetic SaaS does not automatically subtract from the tenant's balance — you'll need to adjust the balance manually in Booknetic SaaS → Tenants → Edit.

The single rule that keeps this manageable

If a customer asks you for anything that involves a number, a PDF, or a refund record, the answer is usually:

  1. Booknetic SaaS shows you the state (subscribed / expired, period-end date, current plan, payment method used).
  2. Stripe / PayPal / WooCommerce shows you the detail (the invoice PDF, the refund record, the dispute, the card-on-file).

Owners who treat Booknetic SaaS as their accounting backbone burn a lot of time on phantom reconciliation problems. Owners who treat it as a mirror of provider state, and Stripe / PayPal / WC as the authoritative ledger, have a much easier time.

How to find a tenant's billing history

Owner-side billing history lives inside the SaaS admin, on the per-tenant view.

  1. Open WP Admin → Booknetic SaaS → Tenants.
  2. Find the tenant row.
  3. Click the row's actions menu (the three-dot menu at the end of the row) and choose Payment history.

The Payment history view lists every billing event for that tenant — payment received, subscription cancelled, balance deposited. Each row shows:

  • The date of the event.
  • The amount.
  • The plan involved.
  • The payment method (card via Stripe, PayPal, or balance).
  • The status of the event.
  • A reference identifier you can cross-check against your provider.

From the tenant's own perspective, the same information shows up in their own Booknetic panel — they open Billing inside their tenant admin and scroll to the Billing history section beneath the plan-card grid.

What this view doesn't show. The Payment history view in the SaaS admin does not show: invoice PDFs, refund detail, dunning retry history, or the card-on-file. For any of those, open the corresponding Stripe / PayPal / WC record using the reference identifier from the Booknetic row.

Where to find a tenant's next renewal date

Two places, with the same answer but different ergonomics.

From the tenant's perspective — Billing → Current plan

When the tenant opens their Billing → Current plan modal, the Expires in field shows the date their current access ends. For a tenant on a recurring subscription, that's also the date their next renewal will run.

From the owner's perspective — Tenants → tenant row

The Tenants list shows each tenant's expiry date in the Expires on column. For a tenant on a Stripe or PayPal subscription, that's the date the next renewal payment will be attempted by the provider.

For the richest view of an upcoming renewal — exact amount, scheduled retry behaviour if the card fails, etc. — go to your Stripe Dashboard → Customers → [the tenant] → Subscriptions or PayPal → Activity → Recurring payments. Stripe and PayPal have a much more detailed picture of "what happens next" than Booknetic SaaS does.

Note on timing. The tenant's Expires in date and the actual moment access cuts off are based on your WordPress server's timezone. For most setups this won't matter — the renewal happens at the same instant the period ends, and your tenant won't notice. If you need precise timing across timezones (e.g. for international customers), confirm your WordPress site timezone in WP Admin → Settings → General → Timezone and test with a sandbox tenant.

Owner workflow: see all your paying tenants this month

There isn't a built-in "this month's paying tenants" filter in Booknetic SaaS — but you can assemble the view from two screens.

From Booknetic SaaS

  1. Open WP Admin → Booknetic SaaS → Tenants.
  2. Filter the list by Subscribed status.
  3. Sort by the Expires on column to see who's coming up for renewal and who has a recent renewal behind them.

This gives you the set of tenants currently on a paid plan. It doesn't show you the dollar amounts per tenant — for that, drop into each tenant's Payment history.

From Stripe / PayPal

For the revenue view in the same period:

  • Stripe Dashboard → Payments (or Subscriptions → All subscriptions filtered by status Active) — gives you the list of active subscriptions, current period totals, MRR, and revenue trends.
  • PayPal → Activity → All transactions filtered by date and type (recurring payment) — gives you the equivalent for your PayPal-paid tenants.

The provider Dashboards are where your accounting view actually lives. Booknetic SaaS gives you the tenant-level association ("this tenant is the one paying you"); the provider gives you the transaction-level totals.

Owner workflow: export billing data for accounting

Booknetic SaaS does not currently include a native "Export billing history" button on the Tenants or Payment history screens. There's no built-in CSV / Excel export from inside the SaaS admin.

That's the honest answer. Here's how to get your accounting data anyway.

Option 1 — Export from your payment provider

This is the recommended path because the provider has the full record anyway.

  • Stripe: open Stripe Dashboard → Payments (or Customers, or Subscriptions), set the date range, click Export at the top right, and download CSV. Stripe's export includes invoice IDs, customer email, amounts in your currency, fees, and net amounts — everything your bookkeeper actually needs.
  • PayPal: open PayPal → Activity → All transactions, set the date range, click Download, and choose CSV or PDF format.
  • WooCommerce (for deposit/top-up volume): WooCommerce has its own Orders → Export path, or you can use any WooCommerce CSV export extension. The WC orders that funded tenant deposits are flagged with the Booknetic deposit line item.

Option 2 — Match Booknetic SaaS to your provider record

If you specifically need to know which tenant each provider transaction belongs to, use the reference identifier column in Tenants → tenant → Payment history to cross-match against the Stripe subscription ID or the PayPal agreement_id in your provider export. This is a manual step, but it's the only way to bridge tenant-level identity (in Booknetic SaaS) with transaction-level financial detail (in your provider).

What we don't recommend

  • Scraping the SaaS admin's Payment history view manually into a spreadsheet — accurate, but it's slow and you'll miss refund records and dunning detail anyway. Provider export is faster and more complete.
  • Building anything that depends on Booknetic SaaS being your sole accounting source. As covered above, Booknetic SaaS only mirrors a thin slice of state.

A note for product feedback. A built-in CSV export of the tenant billing history is a frequent customer request. If this would unblock you, tell us through the standard product feedback channels — it's on the team's radar.

Common questions

Where can I see when my tenant's next renewal will happen? The Expires in date in the tenant's Billing → Current plan modal is the most accessible answer for the tenant; the Expires on column on your Tenants list is the equivalent for you. For the provider-side picture (exact amount, retry behaviour, in-flight dunning), go to your Stripe Dashboard or PayPal account directly.

Can I export billing history to CSV? Not from inside Booknetic SaaS directly — there's no native CSV export button on the Tenants or Payment history screens. The standard path is to export from your payment provider's Dashboard (Stripe Dashboard → Payments → Export, or PayPal Activity → Download), and cross-match against the tenant's reference identifier in Booknetic SaaS if you need to attribute revenue to specific tenants.

What happens if I refund an invoice in Stripe — does Booknetic SaaS know? No. Booknetic SaaS does not automatically update a tenant's subscription state when you issue a refund in Stripe (or PayPal, or WooCommerce). The tenant will keep showing as Subscribed with the same Expires on date until you adjust it manually. If a refund is part of a cancellation, the standard fix is to open Booknetic SaaS → Tenants → Edit on the tenant, set their Expires on to an earlier date (typically today), and save. If the refund is partial and you intended the tenant to lose part of their period — the same edit applies; just set the date you want their access to end. This is a known gap and is a candidate for a future product update; for now, keep a habit of mirroring refund actions manually.

Why does my tenant show "Subscribed" in Booknetic SaaS but Stripe says "past_due"? Because Booknetic SaaS doesn't have a "past_due" or "dunning" state of its own — it only flips to Expired when Stripe fully gives up and fires customer.subscription.deleted (or when the period boundary passes without a successful renewal). While Stripe is still retrying the card with Smart Retries, Booknetic SaaS will continue showing the tenant as Subscribed. Two things to check:

  1. The webhook is healthy. If your Stripe webhook is misconfigured (wrong secret, wrong URL, signature failing), Booknetic SaaS won't hear about the eventual cancellation when Stripe gives up — and the tenant will stay "Subscribed" forever, mistakenly. Verify your webhook setup at Setting up the Stripe webhook. This is the single most common cause of "Booknetic and Stripe disagree."
  2. Your provider is the truth. While dunning is in flight, the truth is in Stripe, not in Booknetic SaaS. If you need to act on the dunning state — e.g. email the tenant a "card failed" message yourself — read it from your Stripe Dashboard.

Can I see refunds in the Booknetic SaaS billing history? No — refunds issued in Stripe, PayPal, or WooCommerce do not appear in the Payment history view inside Booknetic SaaS. The Booknetic-side log only records payment-received, subscription-cancelled, and deposit-credited events. For refund visibility, use your provider's Dashboard.

My tenant cancelled — when does their access actually end? At the end of the period they last paid for, not immediately. Booknetic SaaS keeps showing the tenant as Subscribed through the end of their paid period, then flips them to Expired when the period boundary passes. This applies to tenant-initiated and owner-initiated cancellations alike, on both Stripe and PayPal. For the full cancellation flow (and the cancel-first, then verify-at-provider, then optionally delete pattern), see Cancelling and deleting tenants.

What's the difference between "Expired" and "Not subscribed"? Expired means the tenant had a subscription (free trial, paid, or balance-funded) and the access window ran out. Not subscribed means the tenant verified their email, exists as a tenant, but never had a subscription to begin with — or, more rarely, had one that fully completed its cancellation cycle so far in the past that even the post-cancellation paid period is over. From the tenant's experience, both states feel similar: they hit Booknetic SaaS's expired-plan limits and can recover by picking a plan in their Billing page.

Gotchas to know about

The webhook is the sync mechanism — keep it healthy

Almost every "Booknetic SaaS and my provider disagree" support ticket traces back to a misconfigured webhook. If your Stripe webhook secret is empty, wrong, or points to the wrong endpoint, renewals will silently fail to update the tenant's expiry date — even though Stripe is happily charging the card. Same for PayPal: if the paypal_webhook_id isn't configured, the PAYMENT.SALE.COMPLETED events get rejected and Booknetic SaaS never extends the expiry.

If your tenants are paying but their Expires in dates aren't moving, the webhook is the first place to look. See Setting up the Stripe webhook for the full setup and troubleshooting guide.

Booknetic SaaS doesn't reconcile refunds — you do

We covered this above; it bears repeating because it's the most common reconciliation issue. A refund issued in Stripe, PayPal, or WooCommerce does not propagate back into Booknetic SaaS. If a refund should also revoke access, you have to mirror that change in Tenants → Edit → Expires on. Build this into your refund workflow as a habit — your future self will thank you.

Cancelling at the provider doesn't always update Booknetic SaaS instantly

If you cancel a subscription directly from the Stripe or PayPal Dashboard (rather than through Booknetic SaaS), the cancellation propagates back to Booknetic SaaS via the webhook — eventually. But if the webhook isn't wired up correctly, the tenant will continue to show as Subscribed in Booknetic SaaS until the original Expires on date passes. Cancelling through Booknetic SaaS (tenant's Billing → Cancel subscription, or your owner-side equivalent) is usually the cleaner path because it triggers both the provider cancel and the local state update at the same time.

Balance-funded tenants behave slightly differently

If a tenant pays you via the WooCommerce deposit/balance rail, their renewals are funded by deducting from their stored balance instead of charging a card. As long as their balance covers the next cycle's amount, Booknetic SaaS automatically deducts and extends the Expires on date — no provider webhook involved. The tenant's billing history will show the deduction the same way it shows a Stripe or PayPal payment. The catch: if the balance runs out, the next "renewal" simply doesn't happen, and the tenant flips to Expired at the next period boundary. There's no automatic top-up from a payment method.

Manually issued Stripe invoices don't extend access

If you issue a one-off invoice directly in your Stripe Dashboard (for example, a manual annual upgrade or a special-deal invoice), and the tenant pays it, the corresponding Stripe webhook arrives at Booknetic SaaS — but it's flagged as a manual-billing event and does not extend the tenant's expiry date. To honour that manual invoice in Booknetic SaaS, push the tenant's Expires on date forward yourself in Tenants → Edit.

Where to go next

  • Read Trials in Booknetic SaaS for the full picture of how a trial tenant becomes a paid tenant — that's the single most important transition on your platform.
  • Read Plans and plan capabilities to design the plans that subscription state actually maps to — capabilities and limits are what change when a tenant moves between states.
  • Read Cancelling and deleting tenants for the safe order to cancel a subscription, verify the cancellation at your provider, and only then (if needed) delete the tenant record.
  • Read Setting up the Stripe webhook — webhook health is the single biggest determinant of whether Booknetic SaaS and your provider stay in sync.
  • Read Stripe subscription billing in Booknetic SaaS for the broader Stripe billing reference including dunning, refunds, and the test/live mode boundary.