kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: WIP stripe billing refactor update for 2025
rodzic
8ea3a4f4b6
commit
78d8e13250
|
@ -8,6 +8,7 @@ import { registerV1AdminConsumersGetConsumerByToken } from './consumers/admin-ge
|
|||
import { registerV1ConsumersCreateConsumer } from './consumers/create-consumer'
|
||||
import { registerV1ConsumersGetConsumer } from './consumers/get-consumer'
|
||||
import { registerV1ProjectsListConsumers } from './consumers/list-consumers'
|
||||
import { registerV1ConsumersRefreshConsumerToken } from './consumers/refresh-consumer-token'
|
||||
import { registerV1ConsumersUpdateConsumer } from './consumers/update-consumer'
|
||||
import { registerHealthCheck } from './health-check'
|
||||
import { registerV1ProjectsCreateProject } from './projects/create-project'
|
||||
|
@ -90,6 +91,7 @@ registerV1ProjectsUpdateProject(privateRouter)
|
|||
registerV1ConsumersGetConsumer(privateRouter)
|
||||
registerV1ConsumersCreateConsumer(privateRouter)
|
||||
registerV1ConsumersUpdateConsumer(privateRouter)
|
||||
registerV1ConsumersRefreshConsumerToken(privateRouter)
|
||||
registerV1ProjectsListConsumers(privateRouter)
|
||||
|
||||
// Webhook event handlers
|
||||
|
@ -131,4 +133,5 @@ export type ApiRoutes =
|
|||
| ReturnType<typeof registerV1ConsumersGetConsumer>
|
||||
| ReturnType<typeof registerV1ConsumersCreateConsumer>
|
||||
| ReturnType<typeof registerV1ConsumersUpdateConsumer>
|
||||
| ReturnType<typeof registerV1ConsumersRefreshConsumerToken>
|
||||
| ReturnType<typeof registerV1ProjectsListConsumers>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { parseFaasIdentifier } from '@agentic/validators'
|
||||
|
||||
import { and, db, eq, schema } from '@/db'
|
||||
import { assert, sha256 } from '@/lib/utils'
|
||||
import { assert } from '@/lib/utils'
|
||||
|
||||
import type { AuthenticatedContext } from '../types'
|
||||
import { acl } from '../acl'
|
||||
import { createConsumerToken } from '../create-consumer-token'
|
||||
import { upsertStripeConnectCustomer } from './upsert-stripe-connect-customer'
|
||||
import { upsertStripeCustomer } from './upsert-stripe-customer'
|
||||
import { upsertStripePricing } from './upsert-stripe-pricing'
|
||||
|
@ -16,12 +18,12 @@ export async function upsertConsumer(
|
|||
deploymentId,
|
||||
consumerId
|
||||
}: {
|
||||
plan?: string
|
||||
plan: string
|
||||
deploymentId?: string
|
||||
consumerId?: string
|
||||
}
|
||||
) {
|
||||
assert(consumerId || deploymentId, 400)
|
||||
assert(consumerId || deploymentId, 400, 'Missing required "deploymentId"')
|
||||
const userId = c.get('userId')
|
||||
let projectId: string | undefined
|
||||
|
||||
|
@ -33,7 +35,6 @@ export async function upsertConsumer(
|
|||
|
||||
if (!consumerId) {
|
||||
assert(projectId, 400, 'Missing required "deploymentId"')
|
||||
assert(plan, 400, 'Missing required "plan"')
|
||||
}
|
||||
|
||||
const [{ user, stripeCustomer }, existingConsumer] = await Promise.all([
|
||||
|
@ -52,18 +53,24 @@ export async function upsertConsumer(
|
|||
if (consumerId) {
|
||||
assert(existingConsumer, 404, `Consumer not found "${consumerId}"`)
|
||||
assert(existingConsumer.id === consumerId, 403)
|
||||
await acl(c, existingConsumer, { label: 'Consumer' })
|
||||
|
||||
if (projectId) {
|
||||
assert(
|
||||
existingConsumer.projectId === projectId,
|
||||
400,
|
||||
`Deployment "${deploymentId}" does not belong to with consumer "${consumerId}" project "${existingConsumer.projectId}"`
|
||||
`Deployment "${deploymentId}" does not belong to project "${existingConsumer.projectId}" for consumer "${consumerId}"`
|
||||
)
|
||||
}
|
||||
|
||||
consumerId = existingConsumer.id
|
||||
deploymentId ??= existingConsumer.deploymentId
|
||||
projectId ??= existingConsumer.projectId
|
||||
} else {
|
||||
assert(
|
||||
!existingConsumer,
|
||||
409,
|
||||
`User "${user.email}" already has a subscription for project "${projectId ?? ''}"`
|
||||
)
|
||||
}
|
||||
|
||||
assert(consumerId)
|
||||
|
@ -99,6 +106,15 @@ export async function upsertConsumer(
|
|||
`Deployment has been disabled by its owner "${deployment.id}"`
|
||||
)
|
||||
|
||||
if (plan) {
|
||||
const pricingPlan = deployment.pricingPlanMap[plan]
|
||||
assert(
|
||||
pricingPlan,
|
||||
400,
|
||||
`Pricing plan "${plan}" not found for deployment "${deploymentId}"`
|
||||
)
|
||||
}
|
||||
|
||||
let consumer = existingConsumer
|
||||
|
||||
if (consumer) {
|
||||
|
@ -116,8 +132,7 @@ export async function upsertConsumer(
|
|||
userId,
|
||||
projectId,
|
||||
deploymentId,
|
||||
// TODO: refactor / improve token generation
|
||||
token: sha256().slice(0, 24),
|
||||
token: createConsumerToken(),
|
||||
_stripeCustomerId: stripeCustomer.id
|
||||
})
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue