Files
hanzo.ai/lib/checkout.ts
zeekay 6c65e3e941 @hanzo/app 0.2.0: the app SDK, renamed from @hanzo/rooms
Every import, the catalog pin and the docs name @hanzo/app and
github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and
components/rooms.tsx is components/app.tsx.
2026-10-22 19:07:20 -07:00

70 lines
2.7 KiB
TypeScript

/**
* pay's two addresses on this site: its plans, where a plan is chosen, and its
* card step, the one address a plan is bought at.
*
* hanzo-inc/pay is mounted at /pay on this origin. `/pay/cart` is every plan the
* catalog sells, one card each, priced by commerce and with a link's coupon
* quoted on the plans it covers; its close control and a finished purchase come
* back to `returnUrl`. It takes the organization billed, the coupon and the
* campaign the link carried.
*
* `/pay/confirm/card` names the plan and its price and asks for the card, with
* no picker before it. It takes the plan's catalog slug, the term, the seats, a
* first-month coupon commerce quoted for the plan (lib/coupon), the
* organization billed, and the hanzo.ai address to return to once paid. A
* month and one seat are pay's defaults and are not written. The price never
* rides along: commerce reads it.
*/
import type { Interval } from '@hanzo/app/lib/plans'
/** What pay's card step is opened on. */
export interface Order {
/** The catalog slug. */
plan: string
interval?: Interval
/** Seats, for a per-seat plan. */
quantity?: number
coupon?: string
/** The organization the purchase bills. */
org?: string
/** The campaign the link carried (lib/campaign), kept on every hop inside pay. */
campaign?: [string, string][]
/** Where pay sends the buyer once paid: an absolute hanzo.ai address. */
returnUrl: string
}
/** The path of pay's card step for `order`. */
export function checkout({ plan, interval = 'month', quantity = 1, coupon, org, campaign = [], returnUrl }: Order): string {
const q = new URLSearchParams({ plan })
if (interval === 'year') q.set('interval', 'year')
if (quantity > 1) q.set('quantity', String(quantity))
if (coupon) q.set('coupon', coupon)
if (org) q.set('org', org)
for (const [k, v] of campaign) q.append(k, v)
q.set('returnUrl', returnUrl)
return `/pay/confirm/card?${q}`
}
/** What pay's plans are opened on. */
export interface Browse {
/** The organization a purchase bills. */
org?: string
/** A coupon the link carried: pay quotes it on each plan it covers and says when it covers none. */
coupon?: string
/** The campaign the link carried (lib/campaign), kept on every hop inside pay. */
campaign?: [string, string][]
/** Where the close control and a finished purchase return to: an absolute hanzo.ai address. */
returnUrl: string
}
/** The path of pay's plans for `browse`. */
export function plans({ org, coupon, campaign = [], returnUrl }: Browse): string {
const q = new URLSearchParams()
if (org) q.set('org', org)
if (coupon) q.set('coupon', coupon)
for (const [k, v] of campaign) q.append(k, v)
q.set('returnUrl', returnUrl)
return `/pay/cart?${q}`
}