import {z} from 'zod' export type CustomerRequestEntity = {id?: string | undefined, email?: string | undefined, name?: string | undefined}; export type CustomFieldRequestType = 'text' | 'checkbox'; export type TextFieldConfig = {max_length?: number | undefined, min_length?: number | undefined}; export type CheckboxFieldConfig = {label?: string | undefined}; export type CustomFieldRequestEntity = {type: CustomFieldRequestType, key: string, label: string, optional?: boolean | undefined, text?: TextFieldConfig | undefined, checkbox?: CheckboxFieldConfig | undefined}; export type CreateCheckoutRequest = {request_id?: string | undefined, product_id: string, units?: number | undefined, custom_price?: number | undefined, discount_code?: string | undefined, affiliate_code?: string | undefined, customer?: CustomerRequestEntity | undefined, custom_fields?: Array | undefined, custom_field?: Array | undefined, success_url?: string | undefined, metadata?: {[key: string]: unknown} | undefined}; export type CreateApiV1CheckoutsArgs = {body: CreateCheckoutRequest}; export type CreateApiV1CheckoutsOptions = {baseUrl?: string | undefined, ApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const environmentMode = z.enum(["test", "prod", "sandbox"]); export const productFeatureType = z.enum(["custom", "file", "licenseKey", "customerCredits"]); export const customerCreditsFeatureEntity = z.object({amount: z.string(), unit_label: z.string().nullable().optional(), bucket_name: z.string().nullable().optional()}); export const featureEntity = z.object({id: z.string(), type: productFeatureType, description: z.string(), customer_credits: customerCreditsFeatureEntity.nullable().optional()}); export const usagePriceSettlementMode = z.enum(["prepaid", "postpaid"]); export const usagePriceTargetAccount = z.enum(["shared", "per_unit"]); export const usagePriceTrialUsageMode = z.enum(["free", "accrue"]); export const usagePriceEntity = z.object({id: z.string(), meter_id: z.string(), unit_price: z.number(), free_allowance: z.number().int(), cap: z.number().int().nullable().optional(), settlement_mode: usagePriceSettlementMode, target_account: usagePriceTargetAccount, target_account_name: z.string().nullable().optional(), trial_usage_mode: usagePriceTrialUsageMode}); export const productBillingType = z.enum(["recurring", "onetime"]); export const productBillingPeriod = z.enum(["every-month", "every-three-months", "every-six-months", "every-year", "every-day", "once", "custom"]); export const productStatus = z.enum(["active", "archived"]); export const taxMode = z.enum(["inclusive", "exclusive"]); export const taxCategory = z.enum(["saas", "digital-goods-service", "ebooks"]); export const customFieldType = z.enum(["text", "checkbox"]); export const text = z.object({max_length: z.number().nullable().optional(), minimum_length: z.number().nullable().optional(), value: z.string().nullable().optional()}); export const checkbox = z.object({label: z.string().nullable().optional(), value: z.boolean().nullable().optional()}); export const customField = z.object({type: customFieldType, key: z.string().max(200), label: z.string().max(200), optional: z.boolean().nullable().optional(), text: text.nullable().optional(), checkbox: checkbox.nullable().optional()}); export const productEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), name: z.string(), description: z.string(), image_url: z.string().optional(), image_urls: z.array(z.string()).optional(), features: z.array(featureEntity).optional(), usage_prices: z.array(usagePriceEntity).optional(), price: z.number(), currency: z.string(), billing_type: productBillingType, billing_period: productBillingPeriod, recurring_interval: z.string().nullable().optional(), recurring_interval_count: z.number().int().nullable().optional(), trial_period_days: z.number().int().nullable().optional(), trial_price: z.number().int().nullable().optional(), status: productStatus, tax_mode: taxMode, business_net_pricing: z.boolean().optional(), tax_category: taxCategory, product_url: z.string().optional(), default_success_url: z.string().nullable().optional(), custom_fields: z.array(customField).nullable().optional(), created_at: z.string(), updated_at: z.string()}); export const orderStatus = z.enum(["pending", "paid"]); export const orderType = z.enum(["recurring", "onetime"]); export const orderEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), customer: z.string().nullable().optional(), product: z.string(), transaction: z.string().nullable().optional(), discount: z.string().nullable().optional(), amount: z.number(), sub_total: z.number().optional(), tax_amount: z.number().optional(), discount_amount: z.number().optional(), amount_due: z.number().optional(), amount_paid: z.number().optional(), currency: z.string(), fx_amount: z.number().nullable().optional(), fx_currency: z.string().nullable().optional(), fx_rate: z.number().nullable().optional(), status: orderStatus, type: orderType, affiliate: z.string().nullable().optional(), created_at: z.string(), updated_at: z.string()}); export const customerEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), email: z.string(), name: z.string().nullable().optional(), metadata: z.record(z.string(), z.unknown()).nullable().optional(), country: z.string().nullable(), external_id: z.string().nullable().optional(), created_at: z.string(), updated_at: z.string()}); export const subscriptionItemEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), product_id: z.string().optional(), price_id: z.string().optional(), units: z.number().nullable().optional()}); export const subscriptionCollectionMethod = z.literal("charge_automatically"); export const subscriptionStatus = z.enum(["active", "canceled", "unpaid", "paused", "trialing", "scheduled_cancel", "past_due"]); export const transactionType = z.enum(["payment", "invoice"]); export const transactionStatus = z.enum(["pending", "paid", "refunded", "partialRefund", "chargedBack", "uncollectible", "declined", "canceled", "void"]); export const transactionEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), amount: z.number(), amount_paid: z.number().nullable().optional(), discount_amount: z.number().nullable().optional(), currency: z.string(), type: transactionType, tax_country: z.string().nullable().optional(), tax_amount: z.number().nullable().optional(), status: transactionStatus, refunded_amount: z.number().nullable().optional(), order: z.string().nullable().optional(), subscription: z.string().nullable().optional(), customer: z.string().nullable().optional(), description: z.string().optional(), period_start: z.number().optional(), period_end: z.number().optional(), created_at: z.number()}); export const subscriptionEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), product: z.union([productEntity, z.string()]), customer: z.union([customerEntity, z.string()]), items: z.array(subscriptionItemEntity).optional(), collection_method: subscriptionCollectionMethod, status: subscriptionStatus, last_transaction_id: z.string().optional(), last_transaction: transactionEntity.optional(), last_transaction_date: z.string().optional(), next_transaction_date: z.string().optional(), current_period_start_date: z.string().optional(), current_period_end_date: z.string().optional(), canceled_at: z.string().nullable().optional(), created_at: z.string(), updated_at: z.string(), discount: z.object({id: z.string().optional(), discountCode: z.string().optional(), name: z.string().optional(), type: z.enum(["percentage", "fixed"]).optional(), amount: z.number().optional(), duration: z.enum(["forever", "once", "repeating"]).optional(), durationInMonths: z.number().optional()}).optional(), metadata: z.record(z.string(), z.unknown()).optional()}); export const licenseStatus = z.enum(["inactive", "active", "expired", "disabled"]); export const licenseInstanceEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), name: z.string(), status: z.enum(["active", "deactivated"]), created_at: z.string()}); export const licenseEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), product_id: z.string(), status: licenseStatus, key: z.string(), activation: z.number(), activation_limit: z.number().nullable().optional(), expires_at: z.string().nullable().optional(), created_at: z.string(), instance: licenseInstanceEntity.nullable().optional()}); export const featureFileEntity = z.object({id: z.string(), file_name: z.string(), url: z.string(), type: z.string(), size: z.number()}); export const fileFeatureEntity = z.object({files: z.array(featureFileEntity)}); export const productFeatureEntity = z.object({id: z.string().nullable().optional(), description: z.string().nullable().optional(), type: productFeatureType.optional(), private_note: z.string().nullable().optional(), file: fileFeatureEntity.nullable().optional(), license_key: licenseEntity.nullable().optional(), customer_credits: customerCreditsFeatureEntity.nullable().optional(), license: licenseEntity.nullable().optional()}); export const checkoutEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), status: z.enum(["pending", "processing", "completed", "expired"]), request_id: z.string().optional(), product: z.union([z.string(), productEntity]), units: z.number().optional(), custom_price: z.number().int().optional(), order: orderEntity.optional(), subscription: z.union([z.string(), subscriptionEntity]).optional(), customer: z.union([z.string(), customerEntity]).optional(), custom_fields: z.array(customField).optional(), checkout_url: z.string().optional(), success_url: z.string().nullable().optional(), license_keys: z.array(licenseEntity).optional(), feature: productFeatureEntity.optional(), metadata: z.record(z.string(), z.unknown()).optional(), discount: z.object({id: z.string().optional(), discountCode: z.string().optional(), name: z.string().optional(), type: z.enum(["percentage", "fixed"]).optional(), amount: z.number().optional(), duration: z.enum(["forever", "once", "repeating"]).optional(), durationInMonths: z.number().optional()}).optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Creates a new checkout session. * * POST /v1/checkouts */ export const createApiV1Checkouts = async (args: CreateApiV1CheckoutsArgs, options?: CreateApiV1CheckoutsOptions) => { const {baseUrl = "https://api.creem.io", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (ApiKey !== undefined) headers.set("x-api-key", ApiKey) const url = `${baseUrl.replace(/\/+$/, '')}/v1/checkouts${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(checkoutEntity, await res.json()) };