import {z} from 'zod' export type SubscriptionPriceId = string; export type PaymentAmount = number; export type SubscriptionInterval = 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'; export type SubscriptionIntervalCount = number; export type SubscriptionPaymentMethods = Array; export type SubscriptionDescription = string; export type SubscriptionCustomerId = string; export type PaymentCustomer = {email?: string | undefined, name?: string | undefined, phone?: string | undefined}; export type Country = string; export type Address = {country?: Country | undefined, city?: string | undefined, line1?: string | undefined, line2?: string | undefined, zip?: string | undefined, state?: string | undefined}; export type PaymentBillingDetails = {name?: string | undefined, email?: string | undefined, phone?: string | undefined, company?: string | undefined, taxId?: string | undefined, address?: Address | undefined}; export type PaymentShippingDetails = {name?: string | undefined, email?: string | undefined, phone?: string | undefined, company?: string | undefined, taxId?: string | undefined, address?: Address | undefined}; export type SubscriptionTrialPeriodEnd = number; export type SubscriptionCallbackUrl = string; export type SubscriptionPaymentCallbackUrl = string; export type SubscriptionPauseAtPeriodEnd = boolean; export type SubscriptionCancelAtPeriodEnd = boolean; export type SubscriptionPauseIntervalCount = number; export type SubscriptionSkipIntervalCount = number; export type SubscriptionRetrySchedule = Array<{interval: 'day' | 'week' | 'month' | 'year', intervalCount: number}>; export type SubscriptionProrate = boolean; export type SubscriptionNextPaymentAt = number; export type Metadata = Record; export type UpdateSubscriptionRequest = {priceId?: SubscriptionPriceId | undefined, amount?: PaymentAmount | undefined, interval?: SubscriptionInterval | undefined, intervalCount?: SubscriptionIntervalCount | undefined, allowedPaymentMethods?: SubscriptionPaymentMethods | undefined, description?: SubscriptionDescription | undefined, customerId?: SubscriptionCustomerId | undefined, customer?: PaymentCustomer | undefined, billingDetails?: PaymentBillingDetails | undefined, shippingDetails?: PaymentShippingDetails | undefined, trialPeriodEnd?: SubscriptionTrialPeriodEnd | undefined, callbackUrl?: SubscriptionCallbackUrl | undefined, paymentCallbackUrl?: SubscriptionPaymentCallbackUrl | undefined, pauseAtPeriodEnd?: SubscriptionPauseAtPeriodEnd | undefined, cancelAtPeriodEnd?: SubscriptionCancelAtPeriodEnd | undefined, pauseIntervalCount?: SubscriptionPauseIntervalCount | undefined, skipIntervalCount?: SubscriptionSkipIntervalCount | undefined, retrySchedule?: SubscriptionRetrySchedule | undefined, prorate?: SubscriptionProrate | undefined, nextPaymentAt?: SubscriptionNextPaymentAt | undefined, metadata?: Metadata | undefined}; export type UpdateApiSubscriptionsIdArgs = {body: UpdateSubscriptionRequest}; export type UpdateApiSubscriptionsIdOptions = {baseUrl?: string | undefined, APIKey?: string | undefined, fetch?: typeof fetch | undefined}; export const subscriptionId = z.string(); export const paymentAmount = z.number().int(); export const paymentCurrency = z.string(); export const subscriptionPaymentMethods = z.array(z.string()); export const subscriptionDescription = z.string(); export const accountId = z.string(); export const livemode = z.boolean(); export const subscriptionStatus = z.enum(["PENDING", "EXPIRED", "TRIALING", "ACTIVE", "PAST_DUE", "PAUSED", "CANCELED"]); export const subscriptionPriceId = z.string(); export const subscriptionProductId = z.string(); export const subscriptionCustomerId = z.string(); export const paymentCustomer = z.object({email: z.string().optional(), name: z.string().optional(), phone: z.string().optional()}); export const country = z.string(); export const address = z.object({country: country.optional(), city: z.string().optional(), line1: z.string().optional(), line2: z.string().optional(), zip: z.string().optional(), state: z.string().optional()}); export const paymentBillingDetails = z.object({name: z.string().optional(), email: z.string().optional(), phone: z.string().optional(), company: z.string().optional(), taxId: z.string().optional(), address: address.optional()}); export const paymentShippingDetails = z.object({name: z.string().optional(), email: z.string().optional(), phone: z.string().optional(), company: z.string().optional(), taxId: z.string().optional(), address: address.optional()}); export const subscriptionInterval = z.enum(["minute", "hour", "day", "week", "month", "quarter", "year"]); export const subscriptionIntervalCount = z.number().int(); export const subscriptionPauseIntervalCount = z.number().int(); export const subscriptionSkipIntervalCount = z.number().int(); export const paymentOrderId = z.string().min(1).max(40); export const paymentId = z.string(); export const paymentStatus = z.enum(["SUCCEEDED", "PENDING", "FAILED", "CANCELED", "REFUNDED", "PARTIALLY_REFUNDED", "AUTHORIZED", "EXPIRED", "PENDING_PROCESSING", "PAID_OUT"]); export const paymentStatusCode = z.string(); export const paymentStatusMessage = z.string(); export const subscriptionLastPayment = z.object({id: paymentId.optional(), status: paymentStatus.optional(), statusCode: paymentStatusCode.optional(), statusMessage: paymentStatusMessage.optional()}); export const paymentPaymentMethodCard = z.object({country: country.optional(), brand: z.enum(["visa", "mastercard", "diners", "amex", "jcb", "unionpay", "discover", "unknown"]).optional(), type: z.enum(["debit", "credit"]).optional(), threeDSecure: z.boolean().optional(), threeDSecureVersion: z.string().optional(), threeDSecureFlow: z.enum(["CHALLENGE", "FRICTIONLESS", "FRICTIONLESS_CHALLENGE", "DIRECT"]).optional(), expiration: z.number().int().optional(), last4: z.string().optional(), fingerprint: z.string().optional(), tokenizationMethod: z.enum(["applePay", "googlePay", "clickToPay"]).optional(), cardholderName: z.string().optional(), cardholderEmail: z.string().optional()}); export const paymentPaymentMethodBizum = z.object({phoneNumber: z.string().optional()}); export const subscriptionPaymentMethod = z.object({method: z.enum(["card", "bizum"]).optional(), card: paymentPaymentMethodCard.optional(), bizum: paymentPaymentMethodBizum.optional()}); export const subscriptionCurrentPeriodStart = z.number(); export const subscriptionCurrentPeriodEnd = z.number(); export const subscriptionTrialPeriodEnd = z.number(); export const subscriptionTrialAmount = z.number().int().gte(1); export const subscriptionTrialIntervalCount = z.number().int().gte(1).lte(31); export const subscriptionNextPaymentAt = z.number().int(); export const subscriptionRetryCount = z.number().int(); export const subscriptionRetrySchedule = z.array(z.object({interval: z.enum(["day", "week", "month", "year"]), intervalCount: z.number().int().gte(1).lte(31)})); export const subscriptionCancelAtPeriodEnd = z.boolean(); export const subscriptionPauseAtPeriodEnd = z.boolean(); export const subscriptionLastProrationAt = z.number().int(); export const subscriptionLastProration = z.object({credit: z.number().int().optional(), charge: z.number().int().optional(), net: z.number().int().optional(), paymentId: paymentId.optional()}); export const iP = z.string(); export const lang = z.string(); export const deviceType = z.string(); export const deviceModel = z.string(); export const browser = z.string(); export const browserVersion = z.string(); export const os = z.string(); export const osVersion = z.string(); export const source = z.string(); export const sourceVersion = z.string(); export const userAgent = z.string(); export const browserAccept = z.string(); export const browserColorDepth = z.string(); export const browserScreenHeight = z.string(); export const browserScreenWidth = z.string(); export const browserTimezoneOffset = z.string(); export const paymentTraceDetails = z.object({ip: iP.optional(), countryCode: country.optional(), lang: lang.optional(), deviceType: deviceType.optional(), deviceModel: deviceModel.optional(), browser: browser.optional(), browserVersion: browserVersion.optional(), os: os.optional(), osVersion: osVersion.optional(), source: source.optional(), sourceVersion: sourceVersion.optional(), userAgent: userAgent.optional(), browserAccept: browserAccept.optional(), browserColorDepth: browserColorDepth.optional(), browserScreenHeight: browserScreenHeight.optional(), browserScreenWidth: browserScreenWidth.optional(), browserTimezoneOffset: browserTimezoneOffset.optional(), userId: z.string().optional(), userEmail: z.string().optional()}); export const paymentSequenceId = z.string(); export const subscriptionCallbackUrl = z.string(); export const subscriptionPaymentCallbackUrl = z.string(); export const metadata = z.object({}); export const createdAt = z.number().int(); export const updatedAt = z.number().int(); export const subscription = z.object({id: subscriptionId, amount: paymentAmount, currency: paymentCurrency.optional(), allowedPaymentMethods: subscriptionPaymentMethods.optional(), description: subscriptionDescription.optional(), accountId: accountId, livemode: livemode, status: subscriptionStatus, priceId: subscriptionPriceId.optional(), productId: subscriptionProductId.optional(), customerId: subscriptionCustomerId.optional(), customer: paymentCustomer.optional(), billingDetails: paymentBillingDetails.optional(), shippingDetails: paymentShippingDetails.optional(), interval: subscriptionInterval, intervalCount: subscriptionIntervalCount, pauseIntervalCount: subscriptionPauseIntervalCount.optional(), skipIntervalCount: subscriptionSkipIntervalCount.optional(), lastOrderId: paymentOrderId.optional(), lastPayment: subscriptionLastPayment.optional(), paymentMethod: subscriptionPaymentMethod.optional(), currentPeriodStart: subscriptionCurrentPeriodStart.optional(), currentPeriodEnd: subscriptionCurrentPeriodEnd.optional(), trialPeriodEnd: subscriptionTrialPeriodEnd.optional(), trialAmount: subscriptionTrialAmount.optional(), trialIntervalCount: subscriptionTrialIntervalCount.optional(), nextPaymentAt: subscriptionNextPaymentAt.optional(), retryCount: subscriptionRetryCount.optional(), retrySchedule: subscriptionRetrySchedule.optional(), cancelAtPeriodEnd: subscriptionCancelAtPeriodEnd.optional(), pauseAtPeriodEnd: subscriptionPauseAtPeriodEnd.optional(), lastProrationAt: subscriptionLastProrationAt.optional(), lastProration: subscriptionLastProration.optional(), traceDetails: paymentTraceDetails.optional(), sequenceId: paymentSequenceId.optional(), callbackUrl: subscriptionCallbackUrl.optional(), paymentCallbackUrl: subscriptionPaymentCallbackUrl.optional(), metadata: metadata.optional(), createdAt: createdAt.optional(), updatedAt: updatedAt.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 }; /** * Update Subscription * * PUT /subscriptions/{id} */ export const updateApiSubscriptionsId = async (args: UpdateApiSubscriptionsIdArgs, options?: UpdateApiSubscriptionsIdOptions) => { const {baseUrl = "https://api.monei.com/v1", 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("Authorization", APIKey) const url = `${baseUrl.replace(/\/+$/, '')}/subscriptions/${encodeURIComponent(String(args.id))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "PUT", 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(subscription, await res.json()) };