mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
feat(billing): show tax in subscription upgrade preview (#44258)
This PR moves the client-side "Charge Today" calculation to the backend - relying on the `preview` endpoint data to show the `Charge Today`, `Prorated Credits` and `Customer Balance` in the Subscription Upgrade Preview. It also includes fields for displaying Tax information in the preview, only for enabled orgs. Do note that at the moment the Tax Preview will not change if the address in the Subscription Preview changes, that will be tackled in a follow-up PR. ## Changes - Replace client-side charge calculation with backend data: The upgrade dialog previously computed the prorated credit and total charge locally (using subscription period timestamps and plan prices). This PR uses the `upfront_charge` object returned by the subscription preview API instead. - Display itemized tax breakdown: When the backend returns tax data, the dialog now shows a line-by-line breakdown: plan cost → subtotal (if different) → tax (with rate %) → total charged today. - Use `tax_status` from the subscription preview to conditionally show tax details, and display a warning when tax calculation fails. ## Testing ### No taxes - Upgrade from Free to Paid Plan - With a Free Org with a billing address in Canada or any other non-enabled jurisdiction, start the upgrade to the Pro Plan - Assert that only the Charge Today field is shown in the summary <img width="410" height="298" alt="image" src="https://github.com/user-attachments/assets/e8c7e12e-833d-41d5-aec3-00092b12782f" /> ### Taxes - Upgrade Plan - Update an Org's Orb Customer on the Free or Pro Plan with the `automatic_tax_enabled: true` flag. ``` curl --location --request PUT 'https://api.withorb.com/v1/customers/external_customer_id/{ORG_SLUG}' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: ••••••' \ --data '{ "tax_configuration": { "tax_exempt": false, "tax_provider": "numeral", "automatic_tax_enabled": true } }' ``` - Update the Org address to a valid taxable address, like: ``` "address": { "country": "US", "line1": "100 Congress Ave", "city": "Austin", "state": "TX", "postal_code": "78701" } ``` - Assert that the tax information is shown in the preview, including Tax Rate, Prorated credits (if applicable), Customer balance (if applicable) and the price of the intended plan. <img width="465" height="470" alt="image" src="https://github.com/user-attachments/assets/dd6a7e27-1708-48a8-bbf3-5435e6d582c2" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added itemized breakdown of subscription charges, including plan cost, unused time credits, subtotal, and applicable taxes. * Enhanced billing estimates with detailed tax information display. * **Improvements** * Updated "Charge today" calculations to reflect real-time preview data for greater accuracy. * Improved billing estimate UI layout and clarity with better organization of charge details. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
1355ea7db1
commit
41e6b66d7b
4 files changed
+888
-135
No files matched your search
+120
-51
@@ -20,7 +20,7 @@ import {
|
||||
getPlanChangeType,
|
||||
} from '@/components/interfaces/Billing/Subscription/Subscription.utils'
|
||||
import AlertError from '@/components/ui/AlertError'
|
||||
import { OrganizationBillingSubscriptionPreviewResponse } from '@/data/organizations/organization-billing-subscription-preview'
|
||||
import { OrganizationBillingSubscriptionPreviewData } from '@/data/organizations/organization-billing-subscription-preview'
|
||||
import { OrgProject } from '@/data/projects/org-projects-infinite-query'
|
||||
import { useConfirmPendingSubscriptionChangeMutation } from '@/data/subscriptions/org-subscription-confirm-pending-change'
|
||||
import { useOrgSubscriptionUpdateMutation } from '@/data/subscriptions/org-subscription-update-mutation'
|
||||
@@ -54,6 +54,10 @@ const DOWNGRADE_PLAN_HEADINGS = {
|
||||
|
||||
type DowngradePlanHeadingKey = keyof typeof DOWNGRADE_PLAN_HEADINGS
|
||||
|
||||
type BreakdownItem =
|
||||
| { type: 'amount'; label: string; amount: number; tooltip?: string }
|
||||
| { type: 'notice'; label: string }
|
||||
|
||||
interface Props {
|
||||
selectedTier: 'tier_free' | 'tier_pro' | 'tier_team' | undefined
|
||||
onClose: () => void
|
||||
@@ -61,7 +65,7 @@ interface Props {
|
||||
subscriptionPreviewError: any
|
||||
subscriptionPreviewIsLoading: boolean
|
||||
subscriptionPreviewInitialized: boolean
|
||||
subscriptionPreview: OrganizationBillingSubscriptionPreviewResponse | undefined
|
||||
subscriptionPreview: OrganizationBillingSubscriptionPreviewData | undefined
|
||||
subscription: any
|
||||
currentPlanMeta: any
|
||||
projects: OrgProject[]
|
||||
@@ -211,23 +215,94 @@ export const SubscriptionPlanUpdateDialog = ({
|
||||
})
|
||||
: []
|
||||
|
||||
// Calculate remaining days in current billing cycle
|
||||
const now = Math.floor(Date.now() / 1000) // current time in seconds
|
||||
const remainingSeconds = subscription?.current_period_end - now
|
||||
const totalSeconds = subscription?.current_period_end - subscription?.current_period_start
|
||||
const remainingRatio = remainingSeconds / totalSeconds
|
||||
const upfrontCharge = subscriptionPreview?.upfront_charge
|
||||
|
||||
// Calculate prorated credit for current plan
|
||||
const currentPlanMonthlyPrice = currentPlanMeta?.price ?? 0
|
||||
const proratedCredit = currentPlanMonthlyPrice * remainingRatio
|
||||
const proratedCredit = upfrontCharge?.prorated_credit ?? 0
|
||||
const customerBalance = upfrontCharge?.customer_balance ?? 0
|
||||
const totalCharge = upfrontCharge?.total ?? 0
|
||||
const tax = upfrontCharge?.tax
|
||||
const taxableAmount = upfrontCharge?.taxable_amount
|
||||
const taxStatus = upfrontCharge?.tax_status
|
||||
const hasTax = taxStatus === 'calculated' && (tax?.tax_amount ?? 0) > 0
|
||||
const taxFailed = taxStatus === 'failed'
|
||||
|
||||
// Calculate new plan cost
|
||||
const newPlanCost = Number(subscriptionPlanMeta?.priceMonthly) ?? 0
|
||||
const newPlanCost = Number(subscriptionPlanMeta?.priceMonthly) || 0
|
||||
|
||||
const customerBalance = ((subscription?.customer_balance ?? 0) / 100) * -1
|
||||
const currentPlanId = subscription?.plan?.id
|
||||
const currentPlanName = subscription?.plan?.name
|
||||
|
||||
// Calculate total charge (new plan - prorated credit)
|
||||
const totalCharge = Math.max(0, newPlanCost - proratedCredit - customerBalance)
|
||||
// Derives the itemized charge breakdown rows shown above "Charge today".
|
||||
// Example: Pro -> Team upgrade with proration, tax, and credits:
|
||||
// Team Plan $25.00
|
||||
// Unused Time on Pro -$8.33
|
||||
// Subtotal $16.67
|
||||
// Tax (10%) $1.67
|
||||
// Credits -$5.00
|
||||
// ─────────────────────────────
|
||||
// Charge today $13.34
|
||||
const breakdownItems = useMemo(() => {
|
||||
const items: BreakdownItem[] = []
|
||||
|
||||
if (currentPlanId !== 'free' && proratedCredit > 0) {
|
||||
items.push({
|
||||
type: 'amount',
|
||||
label: `Unused Time on ${currentPlanName} Plan`,
|
||||
amount: -proratedCredit,
|
||||
tooltip:
|
||||
'Your previous plan was charged upfront, so a plan change will prorate any unused time in credits. If the prorated credits exceed the new plan charge, the excessive credits are added to your organization for future use.',
|
||||
})
|
||||
}
|
||||
|
||||
if (hasTax && tax) {
|
||||
if (taxableAmount !== newPlanCost) {
|
||||
items.push({ type: 'amount', label: 'Subtotal', amount: taxableAmount! })
|
||||
}
|
||||
items.push({
|
||||
type: 'amount',
|
||||
label: `Tax (${tax.tax_rate_percentage}%)`,
|
||||
amount: tax.tax_amount,
|
||||
})
|
||||
}
|
||||
|
||||
if (taxFailed) {
|
||||
items.push({
|
||||
type: 'notice',
|
||||
label: 'Tax could not be estimated and may be applied separately',
|
||||
})
|
||||
}
|
||||
|
||||
if (customerBalance > 0) {
|
||||
items.push({
|
||||
type: 'amount',
|
||||
label: 'Credits',
|
||||
amount: -customerBalance,
|
||||
tooltip: 'Credits will be used first before charging your card.',
|
||||
})
|
||||
}
|
||||
|
||||
// Prepend the plan cost row when there are adjustment items to show
|
||||
if (changeType !== 'downgrade' && items.length > 0) {
|
||||
items.unshift({
|
||||
type: 'amount',
|
||||
label: `${subscriptionPlanMeta?.name} Plan`,
|
||||
amount: newPlanCost,
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
}, [
|
||||
currentPlanId,
|
||||
currentPlanName,
|
||||
proratedCredit,
|
||||
hasTax,
|
||||
tax,
|
||||
taxableAmount,
|
||||
newPlanCost,
|
||||
taxFailed,
|
||||
customerBalance,
|
||||
changeType,
|
||||
subscriptionPlanMeta?.name,
|
||||
])
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
@@ -294,11 +369,37 @@ export const SubscriptionPlanUpdateDialog = ({
|
||||
{subscriptionPreviewInitialized && (
|
||||
<>
|
||||
<div className="mt-2 mb-4 text-foreground-light text-sm">
|
||||
{breakdownItems.map((item, i) =>
|
||||
item.type === 'amount' ? (
|
||||
<div
|
||||
key={i}
|
||||
className="flex items-center justify-between gap-2 border-b border-muted text-xs"
|
||||
>
|
||||
<div className="py-2 pl-0 flex items-center gap-1">
|
||||
<span>{item.label}</span>
|
||||
{item.tooltip && (
|
||||
<InfoTooltip className="max-w-sm">{item.tooltip}</InfoTooltip>
|
||||
)}
|
||||
</div>
|
||||
<div className="py-2 pr-0 text-right tabular-nums" translate="no">
|
||||
{formatCurrency(item.amount)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
key={i}
|
||||
className="flex items-center justify-between gap-2 border-b border-muted text-xs"
|
||||
>
|
||||
<div className="py-2 pl-0 text-foreground-lighter">{item.label}</div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-between gap-2 border-b border-muted text-foreground">
|
||||
<div className="py-2 pl-0">Charge today</div>
|
||||
<div className="py-2 pr-0 text-right" translate="no">
|
||||
<div className="py-2 pr-0 text-right tabular-nums" translate="no">
|
||||
{formatCurrency(totalCharge)}
|
||||
{subscription?.plan?.id !== 'free' && (
|
||||
{currentPlanId !== 'free' && (
|
||||
<>
|
||||
{' '}
|
||||
<Link
|
||||
@@ -313,39 +414,7 @@ export const SubscriptionPlanUpdateDialog = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{subscription?.plan?.id !== 'free' && (
|
||||
<div className="flex items-center justify-between gap-2 border-b border-muted text-xs">
|
||||
<div className="py-2 pl-0 flex items-center gap-1">
|
||||
<span>Unused Time on {subscription?.plan?.name} Plan</span>
|
||||
<InfoTooltip className="max-w-sm">
|
||||
Your previous plan was charged upfront, so a plan change will prorate
|
||||
any unused time in credits. If the prorated credits exceed the new plan
|
||||
charge, the excessive credits are added to your organization for future
|
||||
use.
|
||||
</InfoTooltip>
|
||||
</div>
|
||||
<div className="py-2 pr-0 text-right" translate="no">
|
||||
-{formatCurrency(proratedCredit)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Ignore rare case with negative balance (debt) */}
|
||||
{customerBalance > 0 && (
|
||||
<div className="flex items-center justify-between gap-2 border-b border-muted text-xs">
|
||||
<div className="py-2 pl-0 flex items-center gap-1">
|
||||
<span>Credits</span>
|
||||
<InfoTooltip>
|
||||
Credits will be used first before charging your card.
|
||||
</InfoTooltip>
|
||||
</div>
|
||||
<div className="py-2 pr-0 text-right" translate="no">
|
||||
{formatCurrency(customerBalance)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-between gap-2 text-foreground-lighter text-xs">
|
||||
<div className="flex items-center justify-between gap-2 text-foreground-lighter text-xs mt-4">
|
||||
<div className="py-2 pl-0 flex items-center gap-1">
|
||||
<span>Monthly invoice estimate</span>
|
||||
<InfoTooltip side="right">
|
||||
@@ -543,7 +612,7 @@ export const SubscriptionPlanUpdateDialog = ({
|
||||
</div>
|
||||
</InfoTooltip>
|
||||
</div>
|
||||
<div className="py-2 pr-0 text-right" translate="no">
|
||||
<div className="py-2 pr-0 text-right tabular-nums" translate="no">
|
||||
{formatCurrency(
|
||||
subscriptionPreview?.breakdown.reduce(
|
||||
(prev: number, cur) => prev + cur.total_price,
|
||||
|
||||
@@ -10,42 +10,6 @@ export type OrganizationBillingSubscriptionPreviewVariables = {
|
||||
tier?: SubscriptionTier
|
||||
}
|
||||
|
||||
export type OrganizationBillingSubscriptionPreviewResponse = {
|
||||
breakdown: {
|
||||
description: string
|
||||
unit_price: number
|
||||
unit_price_desc?: string
|
||||
quantity?: number
|
||||
total_price: number
|
||||
breakdown?: {
|
||||
project_name: string
|
||||
project_ref: string
|
||||
usage: number
|
||||
}[]
|
||||
}[]
|
||||
number_of_projects?: number
|
||||
plan_change_type?: 'downgrade' | 'none' | 'upgrade'
|
||||
active_projects?: {
|
||||
status:
|
||||
| 'INACTIVE'
|
||||
| 'ACTIVE_HEALTHY'
|
||||
| 'ACTIVE_UNHEALTHY'
|
||||
| 'COMING_UP'
|
||||
| 'UNKNOWN'
|
||||
| 'GOING_DOWN'
|
||||
| 'INIT_FAILED'
|
||||
| 'REMOVED'
|
||||
| 'RESTORING'
|
||||
| 'RESTARTING'
|
||||
| 'RESIZING'
|
||||
| 'UPGRADING'
|
||||
instance_size: string
|
||||
name: string
|
||||
ref: string
|
||||
}[]
|
||||
billed_via_partner?: boolean
|
||||
}
|
||||
|
||||
export async function previewOrganizationBillingSubscription({
|
||||
organizationSlug,
|
||||
tier,
|
||||
@@ -68,7 +32,7 @@ export async function previewOrganizationBillingSubscription({
|
||||
|
||||
if (error) handleError(error)
|
||||
|
||||
return data as OrganizationBillingSubscriptionPreviewResponse
|
||||
return data
|
||||
}
|
||||
|
||||
export type OrganizationBillingSubscriptionPreviewData = Awaited<
|
||||
|
||||
Vendored
+539
-44
File diff suppressed because it is too large.
Load diff
+228
-3
@@ -1335,6 +1335,26 @@ export interface paths {
|
||||
patch?: never
|
||||
trace?: never
|
||||
}
|
||||
'/platform/organizations/{slug}/documents/dpa-signed': {
|
||||
parameters: {
|
||||
query?: never
|
||||
header?: never
|
||||
path?: never
|
||||
cookie?: never
|
||||
}
|
||||
/**
|
||||
* Check if organization has signed any version of the DPA
|
||||
* @description Results are cached per organization for up to 24 hours. Signed status may not reflect immediately after a document is completed.
|
||||
*/
|
||||
get: operations['OrgDocumentsController_getDpaSignedStatus']
|
||||
put?: never
|
||||
post?: never
|
||||
delete?: never
|
||||
options?: never
|
||||
head?: never
|
||||
patch?: never
|
||||
trace?: never
|
||||
}
|
||||
'/platform/organizations/{slug}/documents/soc2-type-2-report': {
|
||||
parameters: {
|
||||
query?: never
|
||||
@@ -4653,6 +4673,13 @@ export interface components {
|
||||
state?: string | null
|
||||
}
|
||||
billing_name?: string
|
||||
/** @enum {boolean} */
|
||||
clear_tax_id?: true
|
||||
tax_id?: {
|
||||
country?: string
|
||||
type: string
|
||||
value: string
|
||||
}
|
||||
}
|
||||
Buffer: Record<string, never>
|
||||
BulkDeleteUserContentResponse: {
|
||||
@@ -6099,6 +6126,11 @@ export interface components {
|
||||
}
|
||||
timestamp: string
|
||||
}
|
||||
DocumentSignedStatusResponse: {
|
||||
/** Format: date-time */
|
||||
checked_at: string
|
||||
signed: boolean
|
||||
}
|
||||
DownloadableBackupsResponse: {
|
||||
backups: {
|
||||
id: number
|
||||
@@ -6964,6 +6996,7 @@ export interface components {
|
||||
OAUTH_SERVER_ALLOW_DYNAMIC_REGISTRATION: boolean
|
||||
OAUTH_SERVER_AUTHORIZATION_PATH: string | null
|
||||
OAUTH_SERVER_ENABLED: boolean
|
||||
PASSKEY_ENABLED: boolean
|
||||
PASSWORD_HIBP_ENABLED: boolean
|
||||
PASSWORD_MIN_LENGTH: number
|
||||
PASSWORD_REQUIRED_CHARACTERS: string
|
||||
@@ -6984,6 +7017,7 @@ export interface components {
|
||||
SECURITY_MANUAL_LINKING_ENABLED: boolean
|
||||
SECURITY_REFRESH_TOKEN_REUSE_INTERVAL: number
|
||||
SECURITY_SB_FORWARDED_FOR_ENABLED: boolean
|
||||
SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD: boolean
|
||||
SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION: boolean
|
||||
SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD: boolean
|
||||
SESSIONS_INACTIVITY_TIMEOUT: number
|
||||
@@ -7022,6 +7056,9 @@ export interface components {
|
||||
SMTP_SENDER_NAME: string
|
||||
SMTP_USER: string
|
||||
URI_ALLOW_LIST: string
|
||||
WEBAUTHN_RP_DISPLAY_NAME: string | null
|
||||
WEBAUTHN_RP_ID: string | null
|
||||
WEBAUTHN_RP_ORIGINS: string | null
|
||||
}
|
||||
InstallPlatformAppBody: {
|
||||
/** Format: uuid */
|
||||
@@ -7661,7 +7698,10 @@ export interface components {
|
||||
name: string
|
||||
projects: {
|
||||
name: string
|
||||
/** @description Project ref */
|
||||
/**
|
||||
* @description Project ref
|
||||
* @example abcdefghijklmnopqrst
|
||||
*/
|
||||
ref: string
|
||||
}[]
|
||||
}[]
|
||||
@@ -7672,7 +7712,10 @@ export interface components {
|
||||
name: string
|
||||
projects: {
|
||||
name: string
|
||||
/** @description Project ref */
|
||||
/**
|
||||
* @description Project ref
|
||||
* @example abcdefghijklmnopqrst
|
||||
*/
|
||||
ref: string
|
||||
}[]
|
||||
}[]
|
||||
@@ -8183,6 +8226,127 @@ export interface components {
|
||||
message: string
|
||||
}[]
|
||||
}
|
||||
PreviewSubscriptionChangeResponse: {
|
||||
active_projects: {
|
||||
/** @enum {string} */
|
||||
instance_size:
|
||||
| 'pico'
|
||||
| 'nano'
|
||||
| 'micro'
|
||||
| 'small'
|
||||
| 'medium'
|
||||
| 'large'
|
||||
| 'xlarge'
|
||||
| '2xlarge'
|
||||
| '4xlarge'
|
||||
| '8xlarge'
|
||||
| '12xlarge'
|
||||
| '16xlarge'
|
||||
| '24xlarge'
|
||||
| '24xlarge_optimized_memory'
|
||||
| '24xlarge_optimized_cpu'
|
||||
| '24xlarge_high_memory'
|
||||
| '48xlarge'
|
||||
| '48xlarge_optimized_memory'
|
||||
| '48xlarge_optimized_cpu'
|
||||
| '48xlarge_high_memory'
|
||||
name: string
|
||||
ref: string
|
||||
/** @enum {string} */
|
||||
status:
|
||||
| 'INACTIVE'
|
||||
| 'ACTIVE_HEALTHY'
|
||||
| 'ACTIVE_UNHEALTHY'
|
||||
| 'COMING_UP'
|
||||
| 'UNKNOWN'
|
||||
| 'GOING_DOWN'
|
||||
| 'INIT_FAILED'
|
||||
| 'REMOVED'
|
||||
| 'RESTORING'
|
||||
| 'UPGRADING'
|
||||
| 'PAUSING'
|
||||
| 'RESTORE_FAILED'
|
||||
| 'RESTARTING'
|
||||
| 'PAUSE_FAILED'
|
||||
| 'RESIZING'
|
||||
}[]
|
||||
billed_via_partner: boolean
|
||||
breakdown: {
|
||||
breakdown?: {
|
||||
amount?: number
|
||||
/** @enum {string} */
|
||||
project_db_instance_size?:
|
||||
| 'pico'
|
||||
| 'nano'
|
||||
| 'micro'
|
||||
| 'small'
|
||||
| 'medium'
|
||||
| 'large'
|
||||
| 'xlarge'
|
||||
| '2xlarge'
|
||||
| '4xlarge'
|
||||
| '8xlarge'
|
||||
| '12xlarge'
|
||||
| '16xlarge'
|
||||
| '24xlarge'
|
||||
| '24xlarge_optimized_memory'
|
||||
| '24xlarge_optimized_cpu'
|
||||
| '24xlarge_high_memory'
|
||||
| '48xlarge'
|
||||
| '48xlarge_optimized_memory'
|
||||
| '48xlarge_optimized_cpu'
|
||||
| '48xlarge_high_memory'
|
||||
project_name: string
|
||||
project_ref: string
|
||||
/** @enum {string} */
|
||||
project_status?:
|
||||
| 'INACTIVE'
|
||||
| 'ACTIVE_HEALTHY'
|
||||
| 'ACTIVE_UNHEALTHY'
|
||||
| 'COMING_UP'
|
||||
| 'UNKNOWN'
|
||||
| 'GOING_DOWN'
|
||||
| 'INIT_FAILED'
|
||||
| 'REMOVED'
|
||||
| 'RESTORING'
|
||||
| 'UPGRADING'
|
||||
| 'PAUSING'
|
||||
| 'RESTORE_FAILED'
|
||||
| 'RESTARTING'
|
||||
| 'PAUSE_FAILED'
|
||||
| 'RESIZING'
|
||||
usage: number
|
||||
}[]
|
||||
description: string
|
||||
quantity?: number
|
||||
total_price: number
|
||||
unit_price?: number
|
||||
unit_price_desc?: string
|
||||
}[]
|
||||
/** @enum {string} */
|
||||
monthly_invoice_tax_status: 'calculated' | 'not_applicable' | 'failed'
|
||||
number_of_projects: number
|
||||
/** @enum {boolean} */
|
||||
pending_subscription_flow: true
|
||||
/** @enum {string} */
|
||||
plan_change_type: 'upgrade' | 'downgrade' | 'none'
|
||||
slug: string
|
||||
upfront_charge: {
|
||||
customer_balance: number
|
||||
prorated_credit: number
|
||||
tax: {
|
||||
currency: string
|
||||
tax_amount: number
|
||||
tax_rate_percentage: number
|
||||
total_amount_excluding_tax: number
|
||||
total_amount_including_tax: number
|
||||
} | null
|
||||
/** @enum {string} */
|
||||
tax_status: 'calculated' | 'not_applicable' | 'failed'
|
||||
taxable_amount: number
|
||||
total: number
|
||||
} | null
|
||||
}
|
||||
PrivateLinkResponse: {
|
||||
appliedSuccessfully: boolean
|
||||
currentConfig: {
|
||||
@@ -10131,6 +10295,7 @@ export interface components {
|
||||
OAUTH_SERVER_ALLOW_DYNAMIC_REGISTRATION?: boolean | null
|
||||
OAUTH_SERVER_AUTHORIZATION_PATH?: string | null
|
||||
OAUTH_SERVER_ENABLED?: boolean | null
|
||||
PASSKEY_ENABLED?: boolean
|
||||
PASSWORD_HIBP_ENABLED?: boolean | null
|
||||
PASSWORD_MIN_LENGTH?: number | null
|
||||
/** @enum {string|null} */
|
||||
@@ -10158,6 +10323,7 @@ export interface components {
|
||||
SECURITY_MANUAL_LINKING_ENABLED?: boolean | null
|
||||
SECURITY_REFRESH_TOKEN_REUSE_INTERVAL?: number | null
|
||||
SECURITY_SB_FORWARDED_FOR_ENABLED?: boolean | null
|
||||
SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD?: boolean | null
|
||||
SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION?: boolean | null
|
||||
SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD?: boolean | null
|
||||
SESSIONS_INACTIVITY_TIMEOUT?: number | null
|
||||
@@ -10198,6 +10364,9 @@ export interface components {
|
||||
SMTP_SENDER_NAME?: string | null
|
||||
SMTP_USER?: string | null
|
||||
URI_ALLOW_LIST?: string | null
|
||||
WEBAUTHN_RP_DISPLAY_NAME?: string | null
|
||||
WEBAUTHN_RP_ID?: string | null
|
||||
WEBAUTHN_RP_ORIGINS?: string | null
|
||||
}
|
||||
UpdateGoTrueConfigHooksBody: {
|
||||
HOOK_AFTER_USER_CREATED_ENABLED?: boolean | null
|
||||
@@ -10266,6 +10435,9 @@ export interface components {
|
||||
slug: string
|
||||
stripe_customer_id: string
|
||||
}
|
||||
/** @example {
|
||||
* "password": "correct-horse-battery-staple"
|
||||
* } */
|
||||
UpdatePasswordBody: {
|
||||
password: string
|
||||
}
|
||||
@@ -10769,6 +10941,14 @@ export interface components {
|
||||
file_size_limit?: number | null
|
||||
public: boolean
|
||||
}
|
||||
/** @example {
|
||||
* "fileSizeLimit": 10485760,
|
||||
* "features": {
|
||||
* "imageTransformation": {
|
||||
* "enabled": true
|
||||
* }
|
||||
* }
|
||||
* } */
|
||||
UpdateStorageConfigBody: {
|
||||
external?: {
|
||||
/** @enum {string} */
|
||||
@@ -14707,7 +14887,9 @@ export interface operations {
|
||||
headers: {
|
||||
[name: string]: unknown
|
||||
}
|
||||
content?: never
|
||||
content: {
|
||||
'application/json': components['schemas']['PreviewSubscriptionChangeResponse']
|
||||
}
|
||||
}
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
@@ -15042,6 +15224,49 @@ export interface operations {
|
||||
}
|
||||
}
|
||||
}
|
||||
OrgDocumentsController_getDpaSignedStatus: {
|
||||
parameters: {
|
||||
query?: never
|
||||
header?: never
|
||||
path: {
|
||||
/** @description Organization slug */
|
||||
slug: string
|
||||
}
|
||||
cookie?: never
|
||||
}
|
||||
requestBody?: never
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown
|
||||
}
|
||||
content: {
|
||||
'application/json': components['schemas']['DocumentSignedStatusResponse']
|
||||
}
|
||||
}
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown
|
||||
}
|
||||
content?: never
|
||||
}
|
||||
/** @description Forbidden action */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown
|
||||
}
|
||||
content?: never
|
||||
}
|
||||
/** @description Rate limit exceeded */
|
||||
429: {
|
||||
headers: {
|
||||
[name: string]: unknown
|
||||
}
|
||||
content?: never
|
||||
}
|
||||
}
|
||||
}
|
||||
OrgDocumentsController_getSoc2Type2ReportUrl: {
|
||||
parameters: {
|
||||
query?: never
|
||||
|
||||
Reference in new issue
Block a user