Documentation for larsasub v0.38.2.
On an older version? Your release notes ship with the package (CHANGELOG.md).
Environment variables
Every environment variable the shipped config/larsasub.php reads, with its
default, grouped the way the config file is. Use it as the checklist for your
.env; what each setting does, and how it interacts with the others, is on
Configuration.
- Before you start
- Core
- Billable model
- Mollie
- Mollie Connect
- Application fees
- Settlements
- Multilingual plan content
- Terms acceptance
- Invoicing
- Subscription rules
- Dunning
- Notifications
- Company notification toggles
- Email theme
- Policies
- Data retention
- Scheduling
- Standalone dashboards
Before you start
Not every setting has an environment variable. These are configured in
config/larsasub.php only, by design: the per-notification user toggles,
the policy model map, the email theme's light/dark tokens, feature defaults,
redirect destinations, reference-code prefixes, the dunning method list and
reminder steps, the VIES validator class and timeout, and the VIES sweep's delay
and limit.
Three things about .env values are worth knowing before you copy anything:
- Laravel turns
true,falseandnullinto their PHP values, andKEY=into an empty string — not into "unset". Where an empty value means something different from the default, the comment below says so. - Quote a value that holds
#or spaces: an unquoted#starts a comment. - With
php artisan config:cache, a changed.envvalue takes effect only after you cache the config again.
A config you published before a key existed does not read its variable at all
until you add the key — larsasub:doctor lists the keys your published config
is missing. See Validation and upgrades.
Core
LARSASUB_PROVIDER=mollie
LARSASUB_DB_CONNECTION= # empty = the framework's default connection
LARSASUB_TABLE_PREFIX=larsasub_ # change before running the migrations
LARSASUB_LOG_CHANNEL=larsasub # empty, or your own channel name, to merge with the app log
LARSASUB_CURRENCY_DEFAULT=EUR # EUR is the only supported value; must be in LARSASUB_CURRENCY_ALLOWED
LARSASUB_CURRENCY_ALLOWED=EUR # comma-separated; enforced on single payments and standalone charges
LARSASUB_LICENSE_TIER=single # single | unlimited | platform
LARSASUB_NGROK_DOMAIN= # development only (APP_ENV local/development); schemeless gets https://
LARSASUB_WEBHOOK_RATE_LIMIT=300,1 # "attempts,minutes" per IP; empty or null disables throttling
See Configuration for the licence tiers:
Mollie Connect requires LARSASUB_LICENSE_TIER=platform.
Billable model
LARSASUB_BILLABLE_RESOLUTION_MODE=auto # auto | explicit
The billable model class, its relation and an explicit-mode owner resolver are config-file only. See Billable models.
Mollie
MOLLIE_KEY=test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
MOLLIE_KEY is read by mollie/laravel-mollie, not by LarsaSub's own config.
A test_ key puts every call in test mode. In Connect mode tenant payments go
through each tenant's OAuth token instead; this key remains the platform's own.
Mollie Connect
LARSASUB_CONNECT_ENABLED=false # requires LARSASUB_LICENSE_TIER=platform
LARSASUB_CONNECT_TENANT_RELATION= # relation on the billable model; required once enabled
LARSASUB_CONNECT_TENANT_LABEL=organization # what the dashboards call a tenant
LARSASUB_CONNECT_TENANT_NAME_ATTRIBUTE=name # tenant attribute shown as the app name in subscriber mails
LARSASUB_CONNECT_TENANT_OWNER_ATTRIBUTE=owner_id # tenant attribute holding the owner's user id
LARSASUB_CONNECT_AUTHORIZE_ROUTE=larsasub.mollie.connect.authorize
LARSASUB_CONNECT_ALSO_NOTIFY_PLATFORM=false # also send tenant company mails to the platform's sales recipients
LARSASUB_CONNECT_DISCONNECT_DRAIN_DAYS=30 # a requested disconnect drains at most this long; positive whole number
MOLLIE_CONNECT_CLIENT_ID= # app_…; another prefix is a boot failure
MOLLIE_CONNECT_CLIENT_SECRET=
MOLLIE_ORGANIZATION_ID= # the platform's own organization: no fees on it
Boot warns while Connect is on and the client id and secret are not both set. See Mollie Connect.
Application fees
Connect only: the fee the platform takes on each tenant payment.
LARSASUB_CONNECT_FEE_ENABLED=false
LARSASUB_CONNECT_FEE_TYPE=percentage # percentage | fixed (anything else is a boot failure)
LARSASUB_CONNECT_FEE_VALUE=10 # 10 % of the payment, or a fixed 10.00 in its currency
LARSASUB_CONNECT_FEE_DESCRIPTION="Platform fee"
A plan's own fee type and value take precedence over these. See Application fees.
Settlements
LARSASUB_SETTLEMENTS_SYNC_PLATFORM=false # also sync the platform's own Mollie account
LARSASUB_SETTLEMENTS_PLATFORM_TOKEN= # organization access token (settlements.read, payments.read)
LARSASUB_SETTLEMENTS_PLATFORM_PROFILE_ID= # pfl_…; Mollie requires it with an organization token
Mollie's Settlements API refuses an API key, so the platform pass needs the token; boot warns when the switch is on without it, and when the token is set without a profile id. The token is read from the environment only and never stored. See Settlements.
Multilingual plan content
LARSASUB_LOCALES= # e.g. nl,en; empty = single-language
LARSASUB_LOCALE_DEFAULT= # empty = the FIRST supported locale
LARSASUB_LOCALE_FALLBACK= # empty = app.fallback_locale
LARSASUB_LOG_LOCALE= # language of model-log lines; empty = app.locale at package boot
LARSASUB_LOG_LOCALE is the one way to choose the log language other than
config/app.php's locale: an App::setLocale() in your service provider runs
after the package booted and does not count. See
The model-log language.
Terms acceptance
LARSASUB_TERMS_PROVIDER= # a TermsProvider class name; empty = feature off
LARSASUB_TERMS_WITHDRAWAL_CONSENT=false # second checkbox: waive the 14-day withdrawal right
Invoicing
LARSASUB_INVOICING_ENABLED=false
LARSASUB_INVOICE_VAT_RATE=21.0
LARSASUB_PRICES_INCLUDE_VAT=true # false ADDS VAT before collection
LARSASUB_INVOICE_PRICE_DISPLAY=exclusive # exclusive | inclusive (PDF presentation only)
LARSASUB_INVOICE_COUNTRY_DISPLAY=name # name | code (Netherlands vs NL)
LARSASUB_INVOICE_SELLER_NAME= # empty = config('app.name')
LARSASUB_INVOICE_SELLER_VAT=
LARSASUB_INVOICE_SELLER_COC=
LARSASUB_INVOICE_SELLER_ADDRESS=
LARSASUB_INVOICE_SELLER_COUNTRY=NL
LARSASUB_INVOICE_PREFIX=INV # INV-000001
LARSASUB_CREDIT_NOTE_PREFIX=CN # CN-000001
LARSASUB_VAT_VALIDATION_ENABLED=false # check business VAT numbers in VIES (opt-in)
LARSASUB_VAT_RECHECK_DAYS=30 # re-check a valid number after N days; empty = only on change
LARSASUB_PRICES_INCLUDE_VAT changes what is collected, not only what is
printed — read VAT and prices before you
change it on a live install. Boot warns while invoicing is on and
LARSASUB_INVOICE_SELLER_VAT is empty.
LARSASUB_INVOICE_SELLER_VAT is also the requester of a VIES check in simple
mode: without it VIES answers, but issues no consultation number. Run
php artisan larsasub:check-vat-numbers --unchecked before you switch
LARSASUB_VAT_VALIDATION_ENABLED on. See
Validating VAT numbers.
Subscription rules
LARSASUB_MIN_DAYS_BEFORE_CHANGE=0 # 0 = no restriction
LARSASUB_MAX_NOTICE_MONTHS=1 # null or empty disables the cap
LARSASUB_FREE_PLAN_MANDATE=activate # activate | mandate | refuse
LARSASUB_BEFORE_FIRST_CHARGE= # empty = no hook; an invokable class name
LARSASUB_FREE_PLAN_MANDATE decides what a plan that collects nothing does.
All three ask the same question first — is there already something to collect
with?
activate— no payment method is asked for.mandate— activate, and set a mandate up for later, but only when the subscriber has no usable one yet.refuse— decline the subscription, again only when there is no usable mandate. A subscriber who already has one may take a free plan.
An unrecognised value is a boot failure, not a silent fallback — see
free_plan_mandate.
LARSASUB_BEFORE_FIRST_CHARGE names the invokable that may put cost lines on a
subscription before its first charge is composed. It fires on a plan change
as well as a new subscription, and is handed the previous subscription (null
on a new one) so it can tell the two apart — a hook that only means to act on
signups tests for that. A class name, never a closure: a closure does not
survive config:cache. A class that does not exist or cannot take the hook's
arguments is a boot failure. See
before_first_charge.
Dunning
LARSASUB_DUNNING_CHARGEBACK_FOLLOW_UP=true # follow-up charge after a chargeback (default on)
LARSASUB_DUNNING_CHARGEBACK_FOLLOW_UP_APPLICATION_FEE=false # Connect: fee again on the follow-up
LARSASUB_DUNNING_DOUBLE_PAID=signal # reversed after the follow-up was paid: signal | refund | credit
LARSASUB_DUNNING_CHARGEBACK_REVERSAL_CHECK_DAYS=60 # days after a chargeback execute-charges looks for its reversal; 0 = off
LARSASUB_DUNNING_REMINDERS_ENABLED=false # reminder series (needs LARSASUB_DUNNING_REMINDERS_SINCE)
LARSASUB_DUNNING_REMINDERS_SINCE= # Y-m-d, first day whose debts get a series; required once on
A chargeback on a paid charge becomes a follow-up charge the customer can pay
again, for the methods in dunning.chargeback_follow_up_methods (config only,
default ['directdebit']). An unknown LARSASUB_DUNNING_DOUBLE_PAID, and an
empty or unparsable LARSASUB_DUNNING_REMINDERS_SINCE while the series is on,
are boot failures. See Dunning and
Recurring charges.
Notifications
LARSASUB_NOTIFICATIONS_SALES= # empty = nobody; a role name, or a comma-separated email list
LARSASUB_NOTIFICATION_CHANNELS=mail # comma-separated: mail, database (company mails only)
LARSASUB_NOTIFICATIONS_PAYMENT_URL= # absolute URL with {charge}, or an invokable class name
LARSASUB_NOTIFICATIONS_FIRST_PAYMENT_URL= # absolute URL with {subscription}/{charge}, or an invokable class name
LARSASUB_NOTIFICATIONS_USER_APP_URL= # where a SUBSCRIBER's own environment lives, for the
# button under every user mail. Absolute URL or an
# invokable class name receiving the billable; no
# placeholders. Company mails ignore it
LARSASUB_NOTIFICATIONS_TENANT_ADMIN_URL= # Connect mode: where a TENANT administers.
# Absolute URL or an invokable class name; no placeholders
LARSASUB_NOTIFICATIONS_TENANT_MODEL_URL= # Connect mode: where a TENANT views ONE record
# ("view payment"). Same two forms; the invokable
# receives the model the mail is about
LARSASUB_NOTIFICATIONS_ATTACHMENTS=false # false | invoice | an invokable class name
Leaving
LARSASUB_NOTIFICATIONS_SALESempty discards every company notification with no tenant to go to (payment failed, subscription cancelled, …) — silently, since there is nobody to send them to.ConfigValidatorwarns about this at boot andlarsasub:doctorreports it.
Keep mail in LARSASUB_NOTIFICATION_CHANNELS. No package notification
implements a channel other than mail and database (another is skipped with
a log warning), and a plain address takes only mail. So database alone
sends no subscriber mail at all (no user notification implements it), nothing
to a sales address without a user account, and no credit-expiry company mail.
Boot warns about an owner mailed at its own billable_email;
larsasub:doctor names the sales addresses. See
Channels.
Every URL hook runs in the queue worker: an invokable gets its context from its
argument, never from auth(), session() or request(). A value that reads as
a class name but is not an existing invokable class is a boot failure. See
Notifications.
PAYMENT_URL and FIRST_PAYMENT_URL fall back to their bundled dashboard, so
leaving them empty only works while that dashboard is registered. With the
payments dashboard off, an empty PAYMENT_URL leaves the payment-failed,
chargeback and reminder mails without a pay button; with the subscription
dashboard off, an empty FIRST_PAYMENT_URL leaves the first-payment-failed
mail with no action button at all. ConfigValidator warns for exactly that
combination.
USER_APP_URL answers a different question from those two: they put an action
button in ONE mail, it sets the default destination of all the others. Set it
whenever a subscriber's environment lives somewhere other than app.url — under
Connect, or with per-tenant hostnames. Two things it deliberately does not
touch: company mails (half their audience is the platform, for which
app.url is correct — use TENANT_ADMIN_URL for the other half), and the
footer line, which names the platform and is an attribution rather than a way
back.
Published
emails/layout.blade.php? The button there reads$appUrl, and this key arrives as a new$userAppUrlvariable — so setting it does nothing until you port that one line.larsasub:doctorsays so; UPGRADE.md holds the diff.
The two TENANT_* keys are Connect-only and each has its own chain below it.
TENANT_ADMIN_URL falls through to a resolver an admin-panel package
registered, then to a bundled tenant dashboard route if one is registered, and
only then to no button. TENANT_MODEL_URL falls through to a registered
resolver, then to no deep link. What neither ever falls back to is the
platform's own URL — that is the one address a tenant must not be sent, so
the mail carries one fewer button instead.
ATTACHMENTS=invoice needs barryvdh/laravel-dompdf (boot warns without it).
A class name works too, but escaping its backslashes in .env is awkward — set
that form in the config file. See Attachments.
Company notification toggles
LARSASUB_NOTIFY_COMPANY_SUBSCRIPTION_ACTIVATED=true
LARSASUB_NOTIFY_COMPANY_SUBSCRIPTION_STARTED=false # the upcoming→active moment; off, see notifications.md
LARSASUB_NOTIFY_COMPANY_SUBSCRIPTION_CANCELLED=true
LARSASUB_NOTIFY_COMPANY_SUBSCRIPTION_CHANGED=true
LARSASUB_NOTIFY_COMPANY_PAYMENT_FAILED=true
LARSASUB_NOTIFY_COMPANY_CHARGE_CANCELED=true
LARSASUB_NOTIFY_COMPANY_CHARGE_EXPIRED=true
LARSASUB_NOTIFY_COMPANY_DUNNING_REMINDER=false # a copy of every reminder step
LARSASUB_NOTIFY_COMPANY_CHARGEBACK=true
LARSASUB_NOTIFY_COMPANY_REFUND=true
LARSASUB_NOTIFY_COMPANY_SINGLE_PAYMENT_PAID=true
LARSASUB_NOTIFY_COMPANY_SINGLE_PAYMENT_FAILED=true
LARSASUB_NOTIFY_COMPANY_SINGLE_PAYMENT_CHARGEBACK=true
LARSASUB_NOTIFY_COMPANY_SINGLE_PAYMENT_REFUND=true
LARSASUB_NOTIFY_COMPANY_PAYMENT_NEEDS_ATTENTION=true
LARSASUB_NOTIFY_COMPANY_CONNECT_CONNECTION_LOST=true
LARSASUB_NOTIFY_COMPANY_CONNECT_DISCONNECTED_OPEN_PAYMENTS=true
LARSASUB_NOTIFY_COMPANY_MANDATE_REGISTRATION_FAILED=true
LARSASUB_NOTIFY_COMPANY_CREDIT_ADDED=false
LARSASUB_NOTIFY_COMPANY_CREDIT_EXPIRING=false
LARSASUB_NOTIFY_COMPANY_CREDIT_EXPIRED=false
LARSASUB_NOTIFY_COMPANY_CHARGE_PAID=false # the receipt for every successful collection
CHARGE_PAID is the receipt for a recurring collection that succeeded, and it
is off for a reason of scale rather than taste: on a host with any volume it is
one mail per customer per billing period into the sales inbox, which is a
reporting question. Its subscriber counterpart
(notifications.user.payment_paid) has no environment variable — the user
toggles are config-file only. Any value other than true, 1, yes or on —
an empty one included — reads as off. See
Notification toggles.
Email theme
LARSASUB_EMAIL_PRIMARY="#4077F4"
# LARSASUB_EMAIL_PRIMARY_INK="#FFFFFF" # leave out to derive a readable label colour
Quote the value. An unquoted # starts a comment in .env, so
LARSASUB_EMAIL_PRIMARY=#4077F4 sets it to an empty string — and the mail
keeps the default colour instead of yours.
LARSASUB_EMAIL_PRIMARY is the button surface; LARSASUB_EMAIL_PRIMARY_INK
is the label printed on it, and leaving it out means the package derives a
readable one. Leave it out, not empty: KEY= is an empty string rather than
an absent one. (The email theme treats both as absent, but the rest of .env
does not work that way, so the habit is worth keeping.)
The remaining light/dark tokens — including heading and accent_text — are
config-file only. See Email theme.
Policies
LARSASUB_ADMIN_ROLE= # empty = nobody is admin; a role name, or a comma-separated email list
LARSASUB_SELF_SERVICE_CREDITS=false # policies.models.billable_credit.actions.purchase
With LARSASUB_ADMIN_ROLE empty, nobody passes an admin check — including the
simple-mode management dashboards — and boot warns. A value containing @ or a
comma is read as email addresses; anything else as a role name. See
The admin role.
Data retention
LARSASUB_MODEL_LOGS_RETENTION_DAYS=730 # empty, null or 0 disables pruning
LARSASUB_NOTIFICATION_DELIVERIES_RETENTION_DAYS=365 # empty, null or 0 disables pruning
LARSASUB_DUNNING_RETENTION_DAYS= # resolved reminder series; empty keeps them (default)
Scheduling
LARSASUB_SCHEDULING_ENABLED=true # false: every scheduled command is a no-op; billing stops
LARSASUB_SCHEDULING_AUTO_REGISTER=true # false: schedule the commands yourself
LARSASUB_SCHEDULING_TIMEZONE= # empty = app timezone
LARSASUB_SCHEDULING_MUTEX_EXPIRES_AFTER_MINUTES=60 # overlap-mutex expiry; non-positive = 60
Frequencies
Each value must be the name of a Laravel scheduler method (everyFifteenMinutes,
hourly, daily, twiceDaily, weekly, … — the full list is in
Command frequencies). A misspelled
value registers silently as that command's own default, shown here.
LARSASUB_PLAN_CHARGES_FREQUENCY=daily # must run daily, at or before execute-charges
LARSASUB_EXECUTE_CHARGES_FREQUENCY=daily # see "Reconciliation" before you keep daily
LARSASUB_END_SUBSCRIPTIONS_FREQUENCY=daily
LARSASUB_DETECT_STARTED_FREQUENCY=daily
LARSASUB_END_BILLABLE_SUBSCRIPTIONS_FREQUENCY=daily
LARSASUB_RENEW_BILLABLE_SUBSCRIPTIONS_FREQUENCY=daily
LARSASUB_ANNOUNCE_RENEWAL_BILLABLE_SUBSCRIPTIONS_FREQUENCY=daily
LARSASUB_CLEANUP_UNUSED_BILLABLE_SUBSCRIPTIONS_FREQUENCY=twiceDaily
LARSASUB_NOTIFY_CHARGES_FREQUENCY=daily
LARSASUB_PROCESS_EXPIRED_CREDITS_FREQUENCY=daily
LARSASUB_NOTIFY_EXPIRING_CREDITS_FREQUENCY=daily
LARSASUB_PROCESS_DUNNING_FREQUENCY=daily
LARSASUB_VALIDATE_MANDATES_FREQUENCY=weekly
LARSASUB_PRUNE_MODEL_LOGS_FREQUENCY=daily
LARSASUB_PRUNE_NOTIFICATION_DELIVERIES_FREQUENCY=daily
LARSASUB_PRUNE_DUNNING_CASES_FREQUENCY=daily
LARSASUB_SYNC_SETTLEMENTS_FREQUENCY=daily
LARSASUB_CHECK_VAT_NUMBERS_FREQUENCY=twiceDaily
A LARSASUB_PLAN_CHARGES_FREQUENCY of weekly or monthly, or twiceDaily
against a daily execute run, collects charges late; boot warns. So does a
LARSASUB_RENEW_BILLABLE_SUBSCRIPTIONS_FREQUENCY of weekly or monthly, or
twiceDaily beside a daily plan-charges or execute-charges run: the renewed
term's first charge is collected late.
With the shipped daily execute frequency the reconciliation safety net is not
there (boot warns too) — see Reconciliation.
Behaviour
LARSASUB_EXECUTE_CHARGES_LIMIT= # empty / non-positive = no limit
LARSASUB_CLEANUP_UNUSED_BILLABLE_SUBSCRIPTIONS_HOURS=12
LARSASUB_NOTIFY_CHARGES_DAYS_BEFORE=10 # announcement lead time for charges created with notify = true
LARSASUB_NOTIFY_CREDIT_EXPIRATION_DAYS_BEFORE=14
LARSASUB_VALIDATE_MANDATES_DELAY_MS=100
LARSASUB_VALIDATE_MANDATES_LIMIT= # empty/invalid = the built-in 5000; never unbounded
LARSASUB_RECONCILE_UNRESOLVED_AFTER_MINUTES=30 # clamped to 1–59
LARSASUB_RECONCILE_LOOKUP_CEILING=500
LARSASUB_RECONCILE_PARK_AFTER_HOURS=24
LARSASUB_RECOVER_MANDATES_WITHIN_DAYS=30 # how far back the mandate recovery pass looks; NOT an off switch
LARSASUB_SYNC_SETTLEMENTS_LOOKBACK_DAYS=60 # days of payouts each settlement sync looks at; invalid = 60
LARSASUB_EXECUTE_CHARGES_LIMITis a money setting, not a performance knob. Capacity islimit × runs per day, and it must stay ahead of your peak day. See Scheduled commands.
LARSASUB_RECOVER_MANDATES_WITHIN_DAYS=0 (or false, or text) does not switch
the pass off: it keeps running with a one-day window, and boot warns. See
Mandate recovery.
Standalone dashboards
LARSASUB_STANDALONE_MIDDLEWARE= # comma-separated, the COMPLETE stack; empty keeps web,auth,verified
LARSASUB_STANDALONE_GUARD= # empty = the app's default guard; authenticate it in the middleware too
LARSASUB_STANDALONE_DOMAIN= # e.g. billing.example.com
LARSASUB_STANDALONE_PAGE_SIZE=50
LARSASUB_STANDALONE_LIST_LIMIT=500
LARSASUB_STANDALONE_THEME_VIEW= # a Blade view included after larsasub.css
LARSASUB_STANDALONE_SHOW_BACK=true
LARSASUB_STANDALONE_BACK_URL=/
A LARSASUB_STANDALONE_GUARD that the middleware does not authenticate
(auth:<guard>) renders the dashboards and then denies every action; boot warns.
See Routes and authentication.
Per-dashboard switches
LARSASUB_DASHBOARD_SUBSCRIPTION=true
LARSASUB_DASHBOARD_PAYMENTS=true
LARSASUB_DASHBOARD_PAYMENT_METHODS=true
LARSASUB_DASHBOARD_CREDIT=true
LARSASUB_DASHBOARD_PROFILE=true
LARSASUB_DASHBOARD_INVOICES=true # also needs LARSASUB_INVOICING_ENABLED=true
LARSASUB_DASHBOARD_TENANT_CONNECT=true # Connect mode only
LARSASUB_DASHBOARD_TENANT_SUBSCRIPTIONS=true
LARSASUB_DASHBOARD_TENANT_SUBSCRIBERS=true
LARSASUB_DASHBOARD_TENANT_CHARGES=true
LARSASUB_DASHBOARD_TENANT_FEES=true # Connect mode only
LARSASUB_DASHBOARD_TENANT_INVOICES=true # also needs LARSASUB_INVOICING_ENABLED=true
Per-dashboard URL prefixes
LARSASUB_STANDALONE_SUBSCRIPTION_URL=billing/dashboard
LARSASUB_STANDALONE_PAYMENTS_URL=billing/payments
LARSASUB_STANDALONE_METHODS_URL=billing/payment-methods
LARSASUB_STANDALONE_CREDIT_URL=billing/credit
LARSASUB_STANDALONE_PROFILE_URL=billing/profile
LARSASUB_STANDALONE_INVOICES_URL=billing/invoices
LARSASUB_STANDALONE_TENANT_CONNECT_URL=billing/admin/connect
LARSASUB_STANDALONE_TENANT_SUBSCRIPTIONS_URL=billing/admin/subscriptions
LARSASUB_STANDALONE_TENANT_SUBSCRIBERS_URL=billing/admin/subscribers
LARSASUB_STANDALONE_TENANT_CHARGES_URL=billing/admin/charges
LARSASUB_STANDALONE_TENANT_FEES_URL=billing/admin/fees
LARSASUB_STANDALONE_TENANT_INVOICES_URL=billing/admin/invoices