import z from 'zod'; import { updateUsage, usage } from '../interfaces/Usage'; import { authedServiceRequest, serviceRequest, serviceResponse, } from '../interfaces/common'; import { metadata } from '../interfaces/Metadata'; import { invoice } from './InvoiceService'; export const zSubscriptionStatus = z.enum(['Pending', 'Active', 'Canceled']); export const subscriptionUpgrade = z.object({ productId: z.string(), priceId: z.string(), botId: z.string().nullable(), sourceIds: z.array(z.string()).nullable(), }); export const subscription = z.object({ _id: z.string(), organizationId: z.string(), stripeCustomerId: z.string(), stripeSubscriptionId: z.string(), stripeProductId: z.string(), stripePriceId: z.string(), status: zSubscriptionStatus, upgrade: subscriptionUpgrade.nullable(), usageLimits: usage, meta: metadata, }); export type Subscription = z.infer; export type SubscriptionUpgrade = z.infer; export interface SubscriptionService { create(request: CreateSubscriptionRequest): Promise; stageUpgrade(request: StageUpgradeSubscriptionRequest): Promise; upgrade(request: UpgradeSubscriptionRequest): Promise; finalizeUpgrade(request: FinalizeUpgradeSubscriptionRequest): Promise; syncUpgrade(request: SyncSubscriptionUpgradeRequest): Promise; latest(request: LatestSubscriptionRequest): Promise; get(request: GetSubscriptionRequest): Promise; list(request: ListSubscriptionsRequest): Promise; superSetUsageLimits(request: SuperSetSubscriptionUsageLimitsRequest): Promise; } /** ****************************************************************************** * Create Subscription ******************************************************************************* */ export const createSubscriptionParams = z.object({ stripeCustomerId: z.string(), stripeSubscriptionId: z.string().nullable(), stripeProductId: z.string().nullable(), stripePriceId: z.string().nullable(), status: zSubscriptionStatus, }); export const createSubscriptionRequest = authedServiceRequest.merge( z.object({ params: createSubscriptionParams, }), ); export const createSubscriptionResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), }), ); export type CreateSubscriptionParams = z.infer; export type CreateSubscriptionRequest = z.infer; export type CreateSubscriptionResponse = z.infer; /** ****************************************************************************** * Stage Upgrade Subscription ******************************************************************************* */ export const stageUpgradeSubscriptionParams = z.object({ botId: z.string().nullable(), sourceIds: z.array(z.string()).nullable(), usage: updateUsage.optional(), }); export const stageUpgradeSubscriptionRequest = authedServiceRequest.merge( z.object({ params: stageUpgradeSubscriptionParams, }), ); export const stageUpgradeSubscriptionResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), }), ); export type StageUpgradeSubscriptionParams = z.infer; export type StageUpgradeSubscriptionRequest = z.infer; export type StageUpgradeSubscriptionResponse = z.infer; /** ****************************************************************************** * Upgrade Subscription ******************************************************************************* */ export const uprgadeSubscriptionParams = z.object({ productId: z.string(), priceId: z.string(), }); export const uprgadeSubscriptionRequest = authedServiceRequest.merge( z.object({ params: uprgadeSubscriptionParams, }), ); export const uprgadeSubscriptionResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), sessionUrl: z.string().nullable().optional(), redirectUrl: z.string().nullable().optional(), }), ); export type UpgradeSubscriptionParams = z.infer; export type UpgradeSubscriptionRequest = z.infer; export type UpgradeSubscriptionResponse = z.infer; /** ****************************************************************************** * Finalize Subscription ******************************************************************************* */ export const finalizeUpgradeSubscriptionParams = z.object({ stripeSubscriptionId: z.string(), }); export const finalizeUpgradeSubscriptionRequest = authedServiceRequest.merge( z.object({ params: finalizeUpgradeSubscriptionParams, }), ); export const finalizeUpgradeSubscriptionResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), }), ); export type FinalizeUpgradeSubscriptionParams = z.infer; export type FinalizeUpgradeSubscriptionRequest = z.infer; export type FinalizeUpgradeSubscriptionResponse = z.infer; /** ****************************************************************************** * Sync Subscription Upgrade ******************************************************************************* */ export const syncSubscriptionUpgradeParams = z.object({}); export const syncSubscriptionUpgradeRequest = authedServiceRequest.merge( z.object({ params: syncSubscriptionUpgradeParams, }), ); export const syncSubscriptionUpgradeResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), }), ); export type SyncSubscriptionUpgradeParams = z.infer; export type SyncSubscriptionUpgradeRequest = z.infer; export type SyncSubscriptionUpgradeResponse = z.infer; /** ****************************************************************************** * Update Latest Subscription ******************************************************************************* */ export const updateLatestSubscriptionParams = subscription; export const updateLatestSubscriptionRequest = serviceRequest.merge( z.object({ params: updateLatestSubscriptionParams, }), ); export const updateLatestSubscriptionResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), }), ); export type UpdateLatestSubscriptionParams = z.infer; export type UpdateLatestSubscriptionRequest = z.infer; export type UpdateLatestSubscriptionResponse = z.infer; /** ****************************************************************************** * Get Latest Subscription ******************************************************************************* */ export const latestSubscriptionParams = z.object({ organizationId: z.string().optional(), }); export const latestSubscriptionRequest = authedServiceRequest.merge( z.object({ params: latestSubscriptionParams, }), ); export const latestSubscriptionResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), }), ); export type LatestSubscriptionParams = z.infer; export type LatestSubscriptionRequest = z.infer; export type LatestSubscriptionResponse = z.infer; /** ****************************************************************************** * Get Subscription ******************************************************************************* */ export const getSubscriptionParams = z.object({ subscriptionId: z.string(), }); export const getSubscriptionRequest = authedServiceRequest.merge( z.object({ params: getSubscriptionParams, }), ); export const getSubscriptionResponse = serviceResponse.merge( z.object({ subscription: subscription.nullable().optional(), }), ); export type GetSubscriptionParams = z.infer; export type GetSubscriptionRequest = z.infer; export type GetSubscriptionResponse = z.infer; /** ****************************************************************************** * List Subscriptions ******************************************************************************* */ export const listSubscriptionsParams = z.object({}); export const listSubscriptionsRequest = authedServiceRequest.merge( z.object({ params: listSubscriptionsParams, }), ); export const listSubscriptionsResponse = serviceResponse.merge( z.object({ subscriptions: z.array(subscription).optional(), }), ); export type ListSubscriptionsParams = z.infer; export type ListSubscriptionsRequest = z.infer; export type ListSubscriptionsResponse = z.infer; /** ****************************************************************************** * Super Set Subscription Usage Limits ******************************************************************************* */ export const superSetSubscriptionUsageLimitsParams = z.object({ usageLimits: usage, resetCurrentUsage: z.boolean(), }); export const superSetSubscriptionUsageLimitsRequest = authedServiceRequest.merge( z.object({ params: superSetSubscriptionUsageLimitsParams, }), ); export const superSetSubscriptionUsageLimitsResponse = serviceResponse.merge( z.object({ subscription: subscription.optional(), invoice: invoice.optional(), }), ); export type SuperSetSubscriptionUsageLimitsParams = z.infer; export type SuperSetSubscriptionUsageLimitsRequest = z.infer; export type SuperSetSubscriptionUsageLimitsResponse = z.infer;