UpcomingInvoice() — supabase Function Reference
Architecture documentation for the UpcomingInvoice() function in UpcomingInvoice.tsx from the supabase codebase.
Entity Profile
Dependency Diagram
graph TD 2c85c7d8_937d_2785_9b6c_5080fa88a0c8["UpcomingInvoice()"] 33d44cde_fee6_d849_e1fe_792e48dd1fdb["formatUsage()"] 2c85c7d8_937d_2785_9b6c_5080fa88a0c8 -->|calls| 33d44cde_fee6_d849_e1fe_792e48dd1fdb fced348a_ab7f_11cf_18fe_5313984546b4["billingMetricUnit()"] 2c85c7d8_937d_2785_9b6c_5080fa88a0c8 -->|calls| fced348a_ab7f_11cf_18fe_5313984546b4 style 2c85c7d8_937d_2785_9b6c_5080fa88a0c8 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
apps/studio/components/interfaces/Organization/BillingSettings/BillingBreakdown/UpcomingInvoice.tsx lines 51–313
const UpcomingInvoice = ({ slug }: UpcomingInvoiceProps) => {
const {
data: upcomingInvoice,
error: error,
isPending: isLoading,
isError,
isSuccess,
} = useOrgUpcomingInvoiceQuery({ orgSlug: slug })
// For non-platform customers, compute is broken down per project and contains a breakdown array
const computeItems =
upcomingInvoice?.lines?.filter((item) => item.description?.toLowerCase().includes('compute')) ||
[]
const computeCreditsItem =
upcomingInvoice?.lines?.find((item) => item.description.startsWith('Compute Credits')) ?? null
const planItem = upcomingInvoice?.lines?.find((item) =>
item.description?.toLowerCase().includes('plan')
)
const regularComputeItems = computeItems.filter(
(it) => !it.metadata?.is_branch && !it.metadata?.is_read_replica
)
const branchingComputeItems = computeItems.filter((it) => it.metadata?.is_branch)
const replicaComputeItems = computeItems.filter((it) => it.metadata?.is_read_replica)
const otherItems =
upcomingInvoice?.lines
?.filter(
(item) =>
!item.description?.toLowerCase().includes('compute') &&
!item.description?.toLowerCase().includes('plan') &&
item.amount_before_discount > 0
)
.sort((a, b) => b.amount_before_discount - a.amount_before_discount) || []
return (
<>
{isLoading && (
<div className="space-y-2">
<ShimmeringLoader />
<ShimmeringLoader className="w-3/4" />
<ShimmeringLoader className="w-1/2" />
</div>
)}
{isError && <AlertError subject="Failed to retrieve upcoming invoice" error={error} />}
{isSuccess && (
<div>
<div>
<Table className="w-full text-sm">
<TableBody>
<TableRow>
<TableCell className="!py-2 px-0">{planItem?.description}</TableCell>
<TableCell className="text-right py-2 px-0">
{planItem == null ? (
'-'
) : (
<InvoiceLineItemAmount
amount={planItem.amount}
amountBeforeDiscount={planItem.amount_before_discount}
/>
)}
</TableCell>
</TableRow>
{/* Compute section */}
<ComputeLineItem
computeItems={regularComputeItems}
title="Compute"
computeCredits={computeCreditsItem}
tooltip={
<p className="prose text-xs">
The first project is covered by Compute Credits. Additional projects incur
compute costs starting at <span translate="no">$10</span>/month, independent
of activity. See{' '}
<Link
href={`${DOCS_URL}/guides/platform/manage-your-usage/compute`}
target="_blank"
>
docs
</Link>
.
</p>
}
/>
{/* Read Replica compute */}
<ComputeLineItem
title="Replica Compute"
computeItems={replicaComputeItems}
tooltip={
<p className="prose text-xs">
Each Read Replica is a dedicated database. You are charged for its resources:
Compute, Disk Size, provisioned Disk IOPS, provisioned Disk Throughput, and
IPv4. See{' '}
<Link
href={`${DOCS_URL}/guides/platform/manage-your-usage/read-replicas`}
target="_blank"
>
docs
</Link>
.
</p>
}
/>
{/* Branching compute */}
{branchingComputeItems.length > 0 && (
<TableRow>
<TableCell className="py-2 px-0">
<div className="flex items-center gap-1">
<span>Branching</span>
<InfoTooltip className="max-w-sm">
<ul className="ml-6 list-disc">
{branchingComputeItems
.flatMap((it) => it.breakdown)
.map((breakdown) => (
<li key={`branching-breakdown-${breakdown!.project_ref}`}>
{breakdown!.project_name} ({breakdown!.usage} Hours)
</li>
))}
</ul>
<p className="mt-2">
See{' '}
<Link
className="underline"
href={`${DOCS_URL}/guides/platform/manage-your-usage/branching`}
target="_blank"
>
docs
</Link>{' '}
on how billing for Branching works.
</p>
</InfoTooltip>
</div>
</TableCell>
<TableCell className="text-right py-2 px-0">
<InvoiceLineItemAmount
amount={branchingComputeItems.reduce((prev, cur) => prev + cur.amount, 0)}
amountBeforeDiscount={branchingComputeItems.reduce(
(prev, cur) => prev + (cur.amount_before_discount ?? 0),
0
)}
/>
</TableCell>
</TableRow>
)}
{/* Non-compute items */}
{otherItems.map((item) => (
<TableRow key={item.description}>
<TableCell className="py-2 px-0">
<div className="gap-1 flex items-center">
<span>{item.description ?? 'Unknown'}</span>
{((item.breakdown && item.breakdown.length > 0) ||
item.usage_metric != null) && (
<InfoTooltip className="max-w-sm">
{item.unit_price_desc && (
<p className="mb-2" translate="no">
Pricing: {item.unit_price_desc}
</p>
)}
{item.breakdown && item.breakdown.length > 0 && (
<>
<p>Projects using {item.description}:</p>
<ul className="ml-6 list-disc">
{item.breakdown.map((breakdown) => (
<li
key={`${item.description}-breakdown-${breakdown.project_ref}`}
>
<Link
className="underline"
href={`/project/${breakdown.project_ref}`}
target="_blank"
>
{breakdown.project_name}
</Link>{' '}
{item.usage_metric && (
<span>
({formatUsage(item.usage_metric, breakdown)}{' '}
{billingMetricUnit(item.usage_metric)})
</span>
)}
</li>
))}
</ul>
</>
)}
{item.usage_metric &&
usageBillingDocsLink[item.usage_metric] != null && (
<p className="mt-2">
See{' '}
<Link
className="underline"
href={usageBillingDocsLink[item.usage_metric]!}
target="_blank"
>
docs
</Link>{' '}
on how billing for {item.description} works and{' '}
<Link className="underline" href={`/organization/${slug}/usage`}>
usage page
</Link>{' '}
for a detailed breakdown.
</p>
)}
</InfoTooltip>
)}
</div>
</TableCell>
<TableCell className="text-right py-2 px-0">
<InvoiceLineItemAmount
amount={item.amount}
amountBeforeDiscount={item.amount_before_discount}
/>
</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TableCell className="font-medium py-2 px-0 flex items-center">
<span className="mr-2">Current Costs</span>
<InfoTooltip>
Costs accumulated from the beginning of the billing cycle up to now.
</InfoTooltip>
</TableCell>
<TableCell className="text-right font-medium py-2 px-0" translate="no">
{formatCurrency(upcomingInvoice?.amount_total) ?? '-'}
</TableCell>
</TableRow>
{upcomingInvoice?.amount_projected && (
<TableRow>
<TableCell className="font-medium py-2 px-0 flex items-center">
<span className="mr-2">Projected Costs</span>
<InfoTooltip className="max-w-xs">
Projected costs at the end of the billing cycle. Includes predictable costs
for Compute Hours, IPv4, Custom Domain and Point-In-Time-Recovery, but no
costs for metrics like MAU, storage or function invocations. Final amounts
may vary depending on your usage.
</InfoTooltip>
</TableCell>
<TableCell className="text-right font-medium py-2 px-0" translate="no">
{formatCurrency(upcomingInvoice.amount_projected) ?? '-'}
</TableCell>
</TableRow>
)}
</TableFooter>
</Table>
</div>
</div>
)}
</>
)
}
Domain
Subdomains
Source
Frequently Asked Questions
What does UpcomingInvoice() do?
UpcomingInvoice() is a function in the supabase codebase.
What does UpcomingInvoice() call?
UpcomingInvoice() calls 2 function(s): billingMetricUnit, formatUsage.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free