mirror of
https://github.com/aljazceru/opencode.git
synced 2026-01-01 07:04:20 +01:00
wip: gateway
This commit is contained in:
71
cloud/core/src/billing.ts
Normal file
71
cloud/core/src/billing.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Resource } from "sst"
|
||||
import { Stripe } from "stripe"
|
||||
import { Database, eq, sql } from "./drizzle"
|
||||
import { BillingTable, UsageTable } from "./schema/billing.sql"
|
||||
import { Actor } from "./actor"
|
||||
import { fn } from "./util/fn"
|
||||
import { z } from "zod"
|
||||
import { Identifier } from "./identifier"
|
||||
import { centsToMicroCents } from "./util/price"
|
||||
|
||||
export namespace Billing {
|
||||
export const stripe = () =>
|
||||
new Stripe(Resource.STRIPE_SECRET_KEY.value, {
|
||||
apiVersion: "2025-03-31.basil",
|
||||
})
|
||||
|
||||
export const get = async () => {
|
||||
return Database.use(async (tx) =>
|
||||
tx
|
||||
.select({
|
||||
customerID: BillingTable.customerID,
|
||||
paymentMethodID: BillingTable.paymentMethodID,
|
||||
balance: BillingTable.balance,
|
||||
reload: BillingTable.reload,
|
||||
})
|
||||
.from(BillingTable)
|
||||
.where(eq(BillingTable.workspaceID, Actor.workspace()))
|
||||
.then((r) => r[0]),
|
||||
)
|
||||
}
|
||||
|
||||
export const consume = fn(
|
||||
z.object({
|
||||
requestID: z.string().optional(),
|
||||
model: z.string(),
|
||||
inputTokens: z.number(),
|
||||
outputTokens: z.number(),
|
||||
reasoningTokens: z.number().optional(),
|
||||
cacheReadTokens: z.number().optional(),
|
||||
cacheWriteTokens: z.number().optional(),
|
||||
costInCents: z.number(),
|
||||
}),
|
||||
async (input) => {
|
||||
const workspaceID = Actor.workspace()
|
||||
const cost = centsToMicroCents(input.costInCents)
|
||||
|
||||
return await Database.transaction(async (tx) => {
|
||||
await tx.insert(UsageTable).values({
|
||||
workspaceID,
|
||||
id: Identifier.create("usage"),
|
||||
requestID: input.requestID,
|
||||
model: input.model,
|
||||
inputTokens: input.inputTokens,
|
||||
outputTokens: input.outputTokens,
|
||||
reasoningTokens: input.reasoningTokens,
|
||||
cacheReadTokens: input.cacheReadTokens,
|
||||
cacheWriteTokens: input.cacheWriteTokens,
|
||||
cost,
|
||||
})
|
||||
const [updated] = await tx
|
||||
.update(BillingTable)
|
||||
.set({
|
||||
balance: sql`${BillingTable.balance} - ${cost}`,
|
||||
})
|
||||
.where(eq(BillingTable.workspaceID, workspaceID))
|
||||
.returning()
|
||||
return updated.balance
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user