mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
/beta's questions, hints and options are marked with phrase() and drawn with t(), so every answer posted to the leads and beta endpoints, every track() payload and every comparison keeps the English value. The referral's tracking channel is a fixed field instead of the button's label, which is now translated. Plurals are two keys, "Skip the rest" sits at the inline end, and the program cards align to the start. The bot and billing pages translate what they hand ProductLanding, with prices and rates as values; /brand wraps its own words.
100 lines
4.4 KiB
TypeScript
100 lines
4.4 KiB
TypeScript
'use client'
|
|
|
|
import type { ReactNode } from 'react'
|
|
import { ArrowRight, CreditCard, Gauge, Layers, Receipt, RefreshCw, Shield, Zap } from 'lucide-react'
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
import { ProductLanding } from '@/components/product/ProductLanding'
|
|
import { ProductFooter } from '@/components/products/ProductFooter'
|
|
|
|
/**
|
|
* Billing, through the ONE product kit — see /ledger for the argument.
|
|
*
|
|
* Every word is the one that was here. The four stat tiles went with the
|
|
* hand-rolled hero: `Any Model / Real-time / SOX / Multi-Currency` were labels
|
|
* rather than measurements — and one of them, SOX, was a compliance CLAIM made
|
|
* in two words with nothing behind it, which /trust would not have let stand.
|
|
*/
|
|
|
|
const DOCS = 'https://docs.hanzo.ai/docs/cli/billing'
|
|
const GITHUB = 'https://github.com/hanzoai'
|
|
|
|
export default function BillingPage({ source }: { source: ReactNode }) {
|
|
const { t } = useI18n()
|
|
return (
|
|
<>
|
|
<ProductLanding
|
|
badge={t('Billing & Metering')}
|
|
badgeIcon={CreditCard}
|
|
title="Hanzo Billing"
|
|
lede={t('Subscriptions, usage, invoices. Charge a fixed price, charge for what someone used, or charge for both on the same invoice. Plans, prices, meters, coupons and credits are separate objects, so a pricing change is a new price rather than a migration — and your servers never hold a card number to do any of it.')}
|
|
ctas={[
|
|
{ label: t('Read the docs'), href: DOCS, icon: ArrowRight },
|
|
{ label: 'GitHub', href: GITHUB },
|
|
]}
|
|
what={{
|
|
eyebrow: t('What is Hanzo Billing'),
|
|
title: t('The objects you bill with'),
|
|
sub: t('Small pieces that compose, rather than one plan type that has to cover every case.'),
|
|
pillars: [
|
|
{
|
|
icon: Layers,
|
|
title: t('Plans and prices'),
|
|
body: t('A plan says what someone gets. A price says what it costs. Keeping them apart is what lets you change a price without touching anyone already on the old one.'),
|
|
},
|
|
{
|
|
icon: Gauge,
|
|
title: t('Meters'),
|
|
body: t('Post an event when something is used and the meter aggregates it. The invoice reads the meter at the end of the period, so nobody has to add up rows by hand.'),
|
|
},
|
|
{
|
|
icon: Receipt,
|
|
title: t('Invoices'),
|
|
body: t('Line items assembled from the subscription and the meters, with tax calculated on the invoice itself. Preview one before it is issued, which is when a pricing mistake is still cheap.'),
|
|
},
|
|
],
|
|
}}
|
|
code={{
|
|
head: { eyebrow: t('Get started'), title: t('Report the use, then charge for it') },
|
|
lang: 'typescript',
|
|
source,
|
|
ctas: [
|
|
{ label: t('Read the docs'), href: DOCS, icon: ArrowRight },
|
|
{ label: t('View on GitHub'), href: GITHUB },
|
|
],
|
|
}}
|
|
features={{
|
|
eyebrow: t('Capabilities'),
|
|
title: t('What the endpoint gives you'),
|
|
items: [
|
|
{
|
|
icon: RefreshCw,
|
|
title: t('Credits and refunds'),
|
|
body: t('Issue credit against a balance, or refund a payment that already settled. Both leave a record, because a customer arguing about a bill is really arguing about a history.'),
|
|
},
|
|
{
|
|
icon: Shield,
|
|
title: t('Coupons and discounts'),
|
|
body: t('Apply one to a subscription or to a single invoice. A discount is an object on the invoice rather than an adjusted number, so the reason the total changed is still legible.'),
|
|
},
|
|
{
|
|
icon: Zap,
|
|
title: t('Webhooks'),
|
|
body: t('The provider tells us a payment settled and we tell you. One endpoint per provider, so adding a second processor does not mean a second integration on your side.'),
|
|
},
|
|
],
|
|
}}
|
|
finalCta={{
|
|
icon: CreditCard,
|
|
title: t('Send your first meter event'),
|
|
sub: t('Report what someone used, and let the invoice read the meter at the end of the period.'),
|
|
buttons: [
|
|
{ label: t('Read the docs'), href: DOCS, icon: ArrowRight },
|
|
{ label: t('View on GitHub'), href: GITHUB },
|
|
],
|
|
}}
|
|
/>
|
|
<ProductFooter slug="billing" name="Billing" />
|
|
</>
|
|
)
|
|
}
|