← Public packages
@kentcdodds/stripe
Stripe helpers for customers, payments, invoices, subscriptions, products, payment links, refunds, and balance.
src/account.ts
157 lines · 4.7 KB · TypeScriptimport { formatStripeAmount, stripeDate, stripeList, stripeRequest } from './stripe-core.ts'
/**
* Get the Stripe account profile for the authenticated key.
* @example
* import { getAccount } from 'kody:@kentcdodds/stripe/account'
* const account = await getAccount()
*/
export async function getAccount() {
const account = await stripeRequest({ path: 'account' })
return {
id: account.id ?? null,
displayName: account.settings?.dashboard?.display_name ?? account.business_profile?.name ?? null,
email: account.email ?? null,
country: account.country ?? null,
defaultCurrency: account.default_currency ?? null,
chargesEnabled: Boolean(account.charges_enabled),
payoutsEnabled: Boolean(account.payouts_enabled),
}
}
/** Get available and pending balance amounts. */
export async function getBalance() {
const balance = await stripeRequest({ path: 'balance' })
const shape = (entries: any[]) =>
(entries ?? []).map((entry) => ({
amount: entry.amount,
currency: entry.currency,
display: formatStripeAmount(entry.amount, entry.currency),
}))
return {
livemode: Boolean(balance.livemode),
available: shape(balance.available),
pending: shape(balance.pending),
}
}
export type ListBalanceTransactionsInput = {
/** Filter by type, e.g. 'charge', 'refund', 'payout'. */
type?: string
/** Created window: ISO strings, Date, or unix seconds. */
createdGte?: string | number | Date
createdLte?: string | number | Date
maxItems?: number
}
function toUnixSeconds(value: string | number | Date | undefined) {
if (value == null) return undefined
if (typeof value === 'number') return value
const date = value instanceof Date ? value : new Date(value)
if (Number.isNaN(date.getTime())) throw new Error('Invalid date: ' + String(value))
return Math.floor(date.getTime() / 1000)
}
/** List balance transactions (money movements) with compact summaries. */
export async function listBalanceTransactions(input: ListBalanceTransactionsInput = {}) {
const { items, hasMore } = await stripeList('balance_transactions', {
maxItems: input.maxItems ?? 25,
query: {
type: input.type,
created: {
gte: toUnixSeconds(input.createdGte),
lte: toUnixSeconds(input.createdLte),
},
},
})
return {
hasMore,
transactions: items.map((txn) => ({
id: txn.id,
type: txn.type,
status: txn.status,
amount: txn.amount,
fee: txn.fee,
net: txn.net,
currency: txn.currency,
display: formatStripeAmount(txn.amount, txn.currency),
description: txn.description ?? null,
created: stripeDate(txn.created),
availableOn: stripeDate(txn.available_on),
})),
}
}
export type ListPayoutsInput = {
status?: 'pending' | 'paid' | 'failed' | 'canceled' | 'in_transit'
maxItems?: number
}
/** List payouts to the connected bank account. */
export async function listPayouts(input: ListPayoutsInput = {}) {
const { items, hasMore } = await stripeList('payouts', {
maxItems: input.maxItems ?? 25,
query: { status: input.status },
})
return {
hasMore,
payouts: items.map((payout) => ({
id: payout.id,
status: payout.status,
amount: payout.amount,
currency: payout.currency,
display: formatStripeAmount(payout.amount, payout.currency),
arrivalDate: stripeDate(payout.arrival_date),
created: stripeDate(payout.created),
method: payout.method ?? null,
description: payout.description ?? null,
})),
}
}
export type ListEventsInput = {
/** Event type filter, e.g. 'invoice.paid' or 'charge.*'. */
type?: string
maxItems?: number
}
/** List recent Stripe events (useful for debugging webhooks and activity). */
export async function listEvents(input: ListEventsInput = {}) {
const { items, hasMore } = await stripeList('events', {
maxItems: input.maxItems ?? 25,
query: { type: input.type },
})
return {
hasMore,
events: items.map((event) => ({
id: event.id,
type: event.type,
created: stripeDate(event.created),
livemode: Boolean(event.livemode),
objectId: event.data?.object?.id ?? null,
objectType: event.data?.object?.object ?? null,
})),
}
}
/**
* Account/balance dispatcher. Defaults to get-account.
* Actions: get-account, get-balance, list-balance-transactions, list-payouts, list-events.
*/
export default async function account(input: Record<string, unknown> = {}) {
const action = String(input.action ?? 'get-account')
switch (action) {
case 'get-account':
return await getAccount()
case 'get-balance':
return await getBalance()
case 'list-balance-transactions':
return await listBalanceTransactions(input as ListBalanceTransactionsInput)
case 'list-payouts':
return await listPayouts(input as ListPayoutsInput)
case 'list-events':
return await listEvents(input as ListEventsInput)
default:
throw new Error('Unknown account action: ' + action)
}
}