@better-auth-ui/core
Version:
Authentication components and data utilities for [Better Auth](https://better-auth.com), available for React and Solid.
130 lines (114 loc) • 2.99 kB
text/typescript
export type BillingScope =
| { type: "user"; userId: string }
| {
type: "organization"
organizationId: string
organizationSlug: string
}
export type BillingInterval = "one-time" | "month" | "year"
export type BillingPrice = {
id: string
amount: number
currency: string
interval: BillingInterval
intervalCount?: number
}
export type BillingPlan = {
id: string
name: string
description?: string
prices: BillingPrice[]
features?: string[]
highlighted?: boolean
seatBased?: boolean
}
export type BillingSubscriptionStatus =
| "active"
| "trialing"
| "past_due"
| "paused"
| "canceled"
| "incomplete"
| "unknown"
export type BillingSubscription = {
id: string
planId: string
priceId?: string
interval?: BillingInterval
planName?: string
status: BillingSubscriptionStatus
currentPeriodEnd?: Date
cancelAtPeriodEnd?: boolean
canceledAt?: Date
seats?: number
}
export type BillingUsage = {
id: string
label: string
used: number
limit?: number
unit?: string
}
export type BillingState = {
subscription?: BillingSubscription
usage: BillingUsage[]
}
export type BillingCheckoutInput = {
planId: string
priceId: string
seats?: number
}
export type BillingActionResult = {
url?: string
}
export type BillingCapabilities = {
cancel: boolean
restore: boolean
seats: boolean
}
export type BillingScopeCapabilities = {
user: boolean
organization: boolean
}
/** Provider-neutral billing operations consumed by every BAUI billing view. */
export interface BillingAdapter {
readonly id: string
readonly supports: BillingCapabilities
/** Billing scopes supported by the provider client. Omit for custom adapters. */
readonly scopes?: BillingScopeCapabilities
listPlans(scope: BillingScope, signal?: AbortSignal): Promise<BillingPlan[]>
getState(scope: BillingScope, signal?: AbortSignal): Promise<BillingState>
checkout(
scope: BillingScope,
input: BillingCheckoutInput
): Promise<BillingActionResult>
openPortal(scope: BillingScope): Promise<BillingActionResult>
cancel(
scope: BillingScope,
subscriptionId: string
): Promise<BillingActionResult>
restore(
scope: BillingScope,
subscriptionId: string
): Promise<BillingActionResult>
updateSeats(
scope: BillingScope,
subscriptionId: string,
seats: number
): Promise<BillingActionResult>
}
export const billingScopeKey = (scope: BillingScope) =>
scope.type === "user"
? `user:${scope.userId}`
: `organization:${scope.organizationId}:${scope.organizationSlug}`
export function followBillingAction(result: BillingActionResult) {
if (!result.url || typeof window === "undefined") return
try {
const url = new URL(result.url, window.location.href)
if (url.protocol === "http:" || url.protocol === "https:") {
window.location.assign(url.href)
}
} catch {
// Ignore malformed adapter responses instead of interrupting the UI.
}
}