- Nova features two different payment modes. We offer a monthly
- subscription which is managed by Patreon, and a Prepaid subscription
- which supports a dozen different payment providers. With Prepaid you pay
- in advance to charge your credit, then usage will be subtracted from
- your account credit. For low usage Prepaid is usually better as the
- monthly fee is much lower.
-
-
-
-
-
-
-
- Free
-
-
- Pro
-
-
- Prepaid
-
-
-
- Recurring price
-
-
- None
-
-
-
- {#snippet label()}
-
- €4 / month or
- €40 / year
-
- {/snippet}
- The Pro subscription is managed by Patreon. Patreon's own fees
- and sales tax will be added to this price. After paying you need
- to link your Nova account to Patreon to activate the plan.
-
-
- The minimum fee is only charged when usage is less than €1.
- This calculation is per day, the €1 amount is divided by the
- number of days in the month and if your usage is lower than
- that, you will be charged the minimum fee.
-
- Prepaid does not have a transfer limit, instead you are
- charged for what you use at a rate of €1 per terabyte
- downloaded. This applies to downloading your own files,
- other people's files and others downloading your files (if
- you have hotlinking enabled in your account settings).
-
-
- Paid plans do not have a concurrent connection limit.
-
- Files expire when they have not been downloaded in the last
- 120 days. A download is counted when more than 10% of the
- whole file was downloaded in a single request.
-
- The Pro plan has 240 day file expiry. The same rules apply
- as the free plan. Higher Patreon subscription plans are
- available where files do not expire at all.
-
-
-
-
-
- {#snippet label()}
- Files do not expire
- {/snippet}
-
- Files don't expire while your Prepaid plan is active. If
- your credit runs out you have one week to top up your
- balance. If you fail to do so your files will revert to the
- regular file expiry rules.
-
-
-
-
-
- Download page customization
-
-
- None
-
-
- None
-
-
- Theme, background, header and footer image can be customized
-
-
-
- Max file size
-
-
- 20 GB per file
-
-
- 100 GB per file
-
-
-
- Payment processors
-
-
- None
-
-
- PayPal, Credit/debit
-
-
- PayPal,
- Bitcoin,
- Litecoin,
- Monero
-
-
-
-
- Free
-
-
- {#if $user !== null && $user.subscription.id === "patreon_1"}
- You have this plan
- Thank you for supporting Nova!
- {:else}
-
- € 4 per month
-
- or
-
- € 40 per year!
-
-
- (Excluding tax)
-
- Subscription managed by Patreon
- {/if}
-
-
- {#if $user === null}
-
- Account required
-
- login
- Log in
-
- or
-
- how_to_reg
- Register
-
-
- Payments processed by Mollie
- No recurring payments
- {:else}
-
- {#if $user.subscription.type === ""}
-
- Deposit credit
-
- to activate Prepaid
- {:else if $user.subscription.type === "patreon"}
- Patreon subscription active. Prepaid cannot be activated
- {:else if $user.subscription.type === "prepaid"}
- Prepaid subscription is active
- Current balance
-
-
- Top up my credit
-
- {/if}
- {/if}
-
-
-
-
-
-
Other plans available on Patreon
-
-
-
-
diff --git a/svelte/src/lib/NovaAPI.ts b/svelte/src/lib/NovaAPI.ts
index 2db0d88..9930ac1 100644
--- a/svelte/src/lib/NovaAPI.ts
+++ b/svelte/src/lib/NovaAPI.ts
@@ -208,6 +208,20 @@ export const subscription_periods: SubscriptionPeriod[] = [
// same value the server divides the monthly fee by
export const days_per_month = 365.25 / 12
+// The price of the subscription period the user is in. This is also how far
+// the balance can go below zero before usage above the plan is refused
+export const period_price = (u: User) => {
+ const period = subscription_periods.find(p => p.months === u.subscription_months)
+ return period === undefined ? 0 :
+ u.subscription.monthly_fee * period.months * period.discount
+}
+
+// Whether usage above a limit of the plan is billed instead of refused. price
+// is what the plan charges for that usage. The server does the same check in
+// billsExtra
+export const bills_extra = (u: User, price: number) =>
+ u.usage_based_billing && price > 0 && u.balance_micro_eur >= -period_price(u)
+
export const get_misc_subscriptions = async () => {
return await check_response(
await fetch(get_endpoint() + "/misc/subscriptions")
diff --git a/svelte/src/user_home/HotlinkProgressBar.svelte b/svelte/src/user_home/HotlinkProgressBar.svelte
index ebef4e0..291de41 100644
--- a/svelte/src/user_home/HotlinkProgressBar.svelte
+++ b/svelte/src/user_home/HotlinkProgressBar.svelte
@@ -2,6 +2,7 @@
import ProgressBar from "util/ProgressBar.svelte";
import { formatDataVolume, formatEuros } from "util/Formatting"
import { user } from "lib/UserStore";
+import { bills_extra } from "lib/NovaAPI";
let { total = 0, used = 0 }: {
total?: number;
@@ -10,8 +11,11 @@ let { total = 0, used = 0 }: {
let frac = $derived(used / total)
let bill_shock = $derived($user !== null && $user.monthly_transfer_cap === total)
-let billable = $derived($user !== null && $user.subscription.price_per_tb_bandwidth > 0)
-let billed = $derived(billable && $user.usage_based_billing)
+let price = $derived($user === null ? 0 : $user.subscription.price_per_tb_bandwidth)
+let billed = $derived($user !== null && bills_extra($user, price))
+
+// Usage based billing is on, but the balance is too far below zero for it
+let overdrawn = $derived($user !== null && $user.usage_based_billing && price > 0 && !billed)
let included = $derived($user === null ? 0 : $user.subscription.monthly_transfer_cap)
@@ -50,6 +54,14 @@ let included = $derived($user === null ? 0 : $user.subscription.monthly_transfer
This is your bill shock limit. Increase
or disable the limit to continue sharing files.
+ {:else if overdrawn}
+
+ Your balance is too far below zero to bill more data transfer.
+ Top up your credit to continue sharing files.
+
Upgrade your plan or enable
diff --git a/svelte/src/user_home/SharingSettings.svelte b/svelte/src/user_home/SharingSettings.svelte
index 2f3f548..81304a3 100644
--- a/svelte/src/user_home/SharingSettings.svelte
+++ b/svelte/src/user_home/SharingSettings.svelte
@@ -3,11 +3,12 @@ import { onMount } from "svelte";
import { formatDataVolume, formatEuros } from "util/Formatting";
import ProgressBar from "util/ProgressBar.svelte";
import { loading_run } from "lib/Loading";
-import { get_endpoint, put_user } from 'lib/NovaAPI';
+import { get_endpoint, period_price, put_user } from 'lib/NovaAPI';
import SuccessMessage from 'util/SuccessMessage.svelte';
import { user } from "lib/UserStore";
let success_message: SuccessMessage = $state()
+
let transfer_cap = $state($user === null ? 0 : $user.monthly_transfer_cap / 1e12)
const update_user = async (e: SubmitEvent) => {
@@ -99,6 +100,12 @@ onMount(async () => {
{formatEuros($user.subscription.price_per_tb_bandwidth, 2)} per TB
for data transfer.
+
+ This usage is charged from your account credit afterwards. When
+ your balance is more than {formatEuros(period_price($user), 2)} below zero
+ (the price of your subscription period) the limits of your plan
+ apply again, until you top up your credit.
+