{"version":3,"file":"index.mjs","names":["getAllowedSubscriptionChannels","subCode"],"sources":["../src/billing-store.ts","../src/paystack-sdk.ts","../src/utils.ts","../src/reference-access.ts","../src/middleware.ts","../src/limits.ts","../src/subscription-lifecycle.ts","../src/reconciliation.ts","../src/route-modules/checkout.ts","../src/route-modules/catalog.ts","../src/route-modules/subscriptions.ts","../src/route-modules/webhook.ts","../src/route-modules/shared.ts","../src/routes.ts","../src/schema.ts","../src/operations.ts","../src/index.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"better-auth\";\n\nimport type {\n  Member,\n  PaystackOrganization,\n  PaystackPlan,\n  PaystackProduct,\n  PaystackTransaction,\n  Subscription,\n  User,\n} from \"./types\";\n\ntype Adapter = GenericEndpointContext[\"context\"][\"adapter\"];\ntype WhereValue = string | number | boolean | null;\ntype WhereClause = { field: string; value: WhereValue }[];\n\nexport interface BillingStore {\n  findSubscriptionById(id: string): Promise<Subscription | null>;\n  findSubscriptionByCode(subscriptionCode: string): Promise<Subscription | null>;\n  findSubscriptionsByReference(referenceId: string): Promise<Subscription[]>;\n  findCurrentSubscription(referenceId: string): Promise<Subscription | null>;\n  findSubscriptionsByTransactionReference(reference: string): Promise<Subscription[]>;\n  createSubscription(data: Partial<Subscription> & Record<string, unknown>): Promise<Subscription>;\n  updateSubscription(\n    id: string,\n    update: Partial<Subscription> & Record<string, unknown>,\n  ): Promise<Subscription | null>;\n  updateSubscriptionByCode(\n    subscriptionCode: string,\n    update: Partial<Subscription> & Record<string, unknown>,\n  ): Promise<Subscription | null>;\n  createTransaction(\n    data: Partial<PaystackTransaction> & Record<string, unknown>,\n  ): Promise<PaystackTransaction>;\n  findTransactionByReference(reference: string): Promise<PaystackTransaction | null>;\n  updateTransactionByReference(\n    reference: string,\n    update: Partial<PaystackTransaction> & Record<string, unknown>,\n  ): Promise<PaystackTransaction | null>;\n  listTransactions(referenceId: string): Promise<PaystackTransaction[]>;\n  listProducts(): Promise<PaystackProduct[]>;\n  findProductByName(name: string): Promise<PaystackProduct | null>;\n  findProductBySlug(slug: string): Promise<PaystackProduct | null>;\n  updateProduct(\n    id: string,\n    update: Partial<PaystackProduct> & Record<string, unknown>,\n  ): Promise<void>;\n  upsertProductByPaystackId(\n    paystackId: string,\n    data: Partial<PaystackProduct> & Record<string, unknown>,\n  ): Promise<void>;\n  listPlans(): Promise<PaystackPlan[]>;\n  findPlanByName(name: string): Promise<PaystackPlan | null>;\n  findPlanByCode(planCode: string): Promise<PaystackPlan | null>;\n  upsertPlanByPaystackId(\n    paystackId: string,\n    data: Partial<PaystackPlan> & Record<string, unknown>,\n  ): Promise<void>;\n  findUser(id: string): Promise<User | null>;\n  findOrganization(id: string): Promise<PaystackOrganization | null>;\n  findOrganizationOwner(organizationId: string): Promise<Member | null>;\n  listMembers(organizationId: string): Promise<Member[]>;\n  listTeams(organizationId: string): Promise<unknown[]>;\n  saveCustomerCode(\n    referenceId: string,\n    customerCode: string,\n    isOrganization: boolean,\n  ): Promise<void>;\n}\n\nfunction sortSubscriptionsForCurrent(subscriptions: Subscription[]): Subscription[] {\n  const statusRank = new Map([\n    [\"active\", 0],\n    [\"trialing\", 1],\n    [\"incomplete\", 2],\n    [\"past_due\", 3],\n    [\"canceled\", 4],\n  ]);\n\n  return [...subscriptions].sort((a, b) => {\n    const rankA = statusRank.get(a.status) ?? 99;\n    const rankB = statusRank.get(b.status) ?? 99;\n    if (rankA !== rankB) return rankA - rankB;\n    return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();\n  });\n}\n\nexport function createBillingStore(ctx: GenericEndpointContext): BillingStore {\n  return createBillingStoreFromAdapter(ctx.context.adapter);\n}\n\nexport function createBillingStoreFromAdapter(adapter: Adapter): BillingStore {\n  const findOne = async <T>(model: string, where: WhereClause): Promise<T | null> =>\n    ((await adapter.findOne<T>({ model, where })) ?? null) as T | null;\n\n  const findMany = async <T>(model: string, where?: WhereClause): Promise<T[]> =>\n    (await adapter.findMany<T>({ model, ...(where ? { where } : {}) })) ?? [];\n\n  return {\n    findSubscriptionById: (id) =>\n      findOne<Subscription>(\"subscription\", [{ field: \"id\", value: id }]),\n    findSubscriptionByCode: (subscriptionCode) =>\n      findOne<Subscription>(\"subscription\", [\n        { field: \"paystackSubscriptionCode\", value: subscriptionCode },\n      ]),\n    findSubscriptionsByReference: (referenceId) =>\n      findMany<Subscription>(\"subscription\", [{ field: \"referenceId\", value: referenceId }]),\n    async findCurrentSubscription(referenceId) {\n      const subscriptions = await this.findSubscriptionsByReference(referenceId);\n      return sortSubscriptionsForCurrent(subscriptions)[0] ?? null;\n    },\n    findSubscriptionsByTransactionReference: (reference) =>\n      findMany<Subscription>(\"subscription\", [\n        { field: \"paystackTransactionReference\", value: reference },\n      ]),\n    createSubscription: async (data) =>\n      await adapter.create({\n        model: \"subscription\",\n        data: data as Omit<Subscription, \"id\">,\n      }),\n    updateSubscription: (id, update) =>\n      adapter.update<Subscription>({\n        model: \"subscription\",\n        update,\n        where: [{ field: \"id\", value: id }],\n      }),\n    updateSubscriptionByCode: (subscriptionCode, update) =>\n      adapter.update<Subscription>({\n        model: \"subscription\",\n        update,\n        where: [{ field: \"paystackSubscriptionCode\", value: subscriptionCode }],\n      }),\n    createTransaction: async (data) =>\n      await adapter.create({\n        model: \"paystackTransaction\",\n        data: data as Omit<PaystackTransaction, \"id\">,\n      }),\n    findTransactionByReference: (reference) =>\n      findOne<PaystackTransaction>(\"paystackTransaction\", [\n        { field: \"reference\", value: reference },\n      ]),\n    updateTransactionByReference: (reference, update) =>\n      adapter.update<PaystackTransaction>({\n        model: \"paystackTransaction\",\n        update,\n        where: [{ field: \"reference\", value: reference }],\n      }),\n    async listTransactions(referenceId) {\n      const transactions = await findMany<PaystackTransaction>(\"paystackTransaction\", [\n        { field: \"referenceId\", value: referenceId },\n      ]);\n      return transactions.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n    },\n    async listProducts() {\n      const products = await findMany<PaystackProduct>(\"paystackProduct\");\n      return products.sort((a, b) => a.name.localeCompare(b.name));\n    },\n    findProductByName: (name) =>\n      findOne<PaystackProduct>(\"paystackProduct\", [{ field: \"name\", value: name }]),\n    findProductBySlug: (slug) =>\n      findOne<PaystackProduct>(\"paystackProduct\", [{ field: \"slug\", value: slug }]),\n    async updateProduct(id, update) {\n      await adapter.update({\n        model: \"paystackProduct\",\n        update,\n        where: [{ field: \"id\", value: id }],\n      });\n    },\n    async upsertProductByPaystackId(paystackId, data) {\n      const existing = await findOne<PaystackProduct>(\"paystackProduct\", [\n        { field: \"paystackId\", value: paystackId },\n      ]);\n      if (existing?.id !== undefined) {\n        const { createdAt: _createdAt, ...update } = data;\n        await adapter.update({\n          model: \"paystackProduct\",\n          update,\n          where: [{ field: \"id\", value: String(existing.id) }],\n        });\n        return;\n      }\n      await adapter.create({ model: \"paystackProduct\", data });\n    },\n    listPlans: () => findMany<PaystackPlan>(\"paystackPlan\"),\n    findPlanByName: (name) =>\n      findOne<PaystackPlan>(\"paystackPlan\", [{ field: \"name\", value: name }]),\n    findPlanByCode: (planCode) =>\n      findOne<PaystackPlan>(\"paystackPlan\", [{ field: \"planCode\", value: planCode }]),\n    async upsertPlanByPaystackId(paystackId, data) {\n      const existing = await findOne<PaystackPlan>(\"paystackPlan\", [\n        { field: \"paystackId\", value: paystackId },\n      ]);\n      if (existing?.id !== undefined) {\n        const { createdAt: _createdAt, ...update } = data;\n        await adapter.update({\n          model: \"paystackPlan\",\n          update,\n          where: [{ field: \"id\", value: existing.id }],\n        });\n        return;\n      }\n      await adapter.create({ model: \"paystackPlan\", data });\n    },\n    findUser: (id) => findOne<User>(\"user\", [{ field: \"id\", value: id }]),\n    findOrganization: (id) =>\n      findOne<PaystackOrganization>(\"organization\", [{ field: \"id\", value: id }]),\n    findOrganizationOwner: (organizationId) =>\n      findOne<Member>(\"member\", [\n        { field: \"organizationId\", value: organizationId },\n        { field: \"role\", value: \"owner\" },\n      ]),\n    listMembers: (organizationId) =>\n      findMany<Member>(\"member\", [{ field: \"organizationId\", value: organizationId }]),\n    listTeams: (organizationId) =>\n      findMany(\"team\", [{ field: \"organizationId\", value: organizationId }]),\n    async saveCustomerCode(referenceId, customerCode, isOrganization) {\n      await adapter.update({\n        model: isOrganization ? \"organization\" : \"user\",\n        update: { paystackCustomerCode: customerCode },\n        where: [{ field: \"id\", value: referenceId }],\n      });\n    },\n  };\n}\n","import { APIError } from \"better-auth/api\";\nimport {\n  PaystackError,\n  PaystackResponse,\n  type CustomerCreatePayload,\n} from \"@alexasomba/paystack-node\";\nimport type { components } from \"@alexasomba/paystack-node\";\nimport type { PaystackClientLike } from \"./types\";\n\n/**\n * Interface for checking if a result is a PaystackResponse from the SDK v1.9.1+\n */\nfunction IsPaystackResponse(value: unknown): value is PaystackResponse<unknown> {\n  return value instanceof PaystackResponse;\n}\n\n/**\n * Unwraps a Paystack SDK result, extracting the data or throwing an APIError if the request failed.\n * Leverages the native .unwrap() method in SDK v1.9.1+ if available.\n */\nexport function unwrapSdkResult<T = unknown>(result: unknown): T {\n  if (IsPaystackResponse(result)) {\n    try {\n      return result.unwrap() as T;\n    } catch (e: unknown) {\n      if (e instanceof PaystackError) {\n        throw new APIError(\"BAD_REQUEST\", {\n          message: e.message,\n          status: e.status,\n        });\n      }\n\n      throw new APIError(\"BAD_REQUEST\", {\n        message: (e as Error)?.message ?? \"Paystack API error\",\n      });\n    }\n  }\n\n  // Fallback for custom or legacy structures (e.g. from mocks in tests)\n  let current = result;\n\n  // Handle nested { data: { data: ... } } or { status: true, data: ... }\n  while (current !== null && current !== undefined && typeof current === \"object\") {\n    const body = current as Record<string, unknown>;\n\n    // Check for Paystack Error shape\n    if (body.status === false) {\n      throw new APIError(\"BAD_REQUEST\", {\n        message: (body.message as string | undefined) ?? \"Paystack API error\",\n      });\n    }\n\n    // Stop if we have found the actual transaction/subscription payload properties\n    if (\"authorization_url\" in body || \"reference\" in body || \"customer_code\" in body) {\n      break;\n    }\n\n    // If there's a data property, unwrap it and continue checking\n    if (\n      \"data\" in body &&\n      body.data !== undefined &&\n      body.data !== null &&\n      typeof body.data === \"object\"\n    ) {\n      current = body.data;\n      continue;\n    }\n    break;\n  }\n\n  return current as T;\n}\n\n/**\n * Returns the operations object from a Paystack client.\n * For v1.9.1+, the client itself uses the grouped structure.\n */\nexport function getPaystackOps(client?: PaystackClientLike): PaystackClientLike | undefined {\n  return client;\n}\n\ninterface ChargeAuthorizationPayload {\n  email: string;\n  amount: number;\n  authorization_code: string;\n  reference: string;\n  metadata?: string;\n}\n\ninterface CreateSubscriptionPayload {\n  customer: string;\n  plan: string;\n  authorization?: string;\n  start_date?: string;\n}\n\nexport interface PaystackAdapter {\n  initializeTransaction(\n    body: components[\"schemas\"][\"TransactionInitialize\"],\n  ): Promise<components[\"schemas\"][\"TransactionInitializeResponse\"][\"data\"]>;\n  verifyTransaction(reference: string): Promise<unknown>;\n  chargeAuthorization(body: ChargeAuthorizationPayload): Promise<unknown>;\n  createCustomer(body: CustomerCreatePayload): Promise<unknown>;\n  listProducts(): Promise<components[\"schemas\"][\"ProductListsResponseArray\"][]>;\n  fetchProduct(productId: number): Promise<unknown>;\n  listPlans(): Promise<components[\"schemas\"][\"PlanListResponseArray\"][]>;\n  createSubscription(body: CreateSubscriptionPayload): Promise<unknown>;\n  fetchSubscription(subscriptionCode: string): Promise<unknown>;\n  disableSubscription(body: { code: string; token: string }): Promise<unknown>;\n  enableSubscription(body: { code: string; token: string }): Promise<unknown>;\n  manageSubscriptionLink(subscriptionCode: string): Promise<{ link: string }>;\n}\n\nexport function createPaystackAdapter(client?: PaystackClientLike): PaystackAdapter {\n  const requireClient = (): PaystackClientLike => {\n    if (client === undefined || client === null) {\n      throw new APIError(\"BAD_REQUEST\", { message: \"Paystack client is not configured\" });\n    }\n    return client;\n  };\n\n  return {\n    async initializeTransaction(\n      body: components[\"schemas\"][\"TransactionInitialize\"],\n    ): Promise<components[\"schemas\"][\"TransactionInitializeResponse\"][\"data\"]> {\n      const raw = await requireClient().transaction?.initialize({ body });\n      return unwrapSdkResult<components[\"schemas\"][\"TransactionInitializeResponse\"][\"data\"]>(raw);\n    },\n    async verifyTransaction(reference: string): Promise<unknown> {\n      const raw = await requireClient().transaction?.verify(reference);\n      return unwrapSdkResult(raw);\n    },\n    async chargeAuthorization(body: ChargeAuthorizationPayload): Promise<unknown> {\n      const raw = await requireClient().transaction?.chargeAuthorization({ body });\n      return unwrapSdkResult(raw);\n    },\n    async createCustomer(body: CustomerCreatePayload): Promise<unknown> {\n      const raw = await requireClient().customer?.create({ body });\n      return unwrapSdkResult(raw);\n    },\n    async listProducts(): Promise<components[\"schemas\"][\"ProductListsResponseArray\"][]> {\n      const raw = await requireClient().product?.list({});\n      return unwrapSdkResult<components[\"schemas\"][\"ProductListsResponseArray\"][]>(raw);\n    },\n    async fetchProduct(productId: number): Promise<unknown> {\n      const raw = await requireClient().product?.fetch(productId);\n      return unwrapSdkResult(raw);\n    },\n    async listPlans(): Promise<components[\"schemas\"][\"PlanListResponseArray\"][]> {\n      const raw = await requireClient().plan?.list();\n      return unwrapSdkResult<components[\"schemas\"][\"PlanListResponseArray\"][]>(raw);\n    },\n    async createSubscription(body: CreateSubscriptionPayload): Promise<unknown> {\n      const raw = await requireClient().subscription?.create({ body });\n      return unwrapSdkResult(raw);\n    },\n    async fetchSubscription(subscriptionCode: string): Promise<unknown> {\n      const raw = await requireClient().subscription?.fetch(subscriptionCode);\n      return unwrapSdkResult(raw);\n    },\n    async disableSubscription(body: { code: string; token: string }): Promise<unknown> {\n      const raw = await requireClient().subscription?.disable({ body });\n      return unwrapSdkResult(raw);\n    },\n    async enableSubscription(body: { code: string; token: string }): Promise<unknown> {\n      const raw = await requireClient().subscription?.enable({ body });\n      return unwrapSdkResult(raw);\n    },\n    async manageSubscriptionLink(subscriptionCode: string): Promise<{ link: string }> {\n      const raw = await requireClient().subscription?.manageLink(subscriptionCode);\n      return unwrapSdkResult<{ link: string }>(raw);\n    },\n  };\n}\n","import type { GenericEndpointContext } from \"better-auth\";\n\nimport type {\n  AnyPaystackOptions,\n  PaystackClientLike,\n  PaystackPlan,\n  PaystackProduct,\n  Subscription,\n  PaystackProductResponse,\n} from \"./types\";\nimport { createBillingStore } from \"./billing-store\";\nimport { createPaystackAdapter } from \"./paystack-sdk\";\n\nexport function getPlanSeatAmount(plan: PaystackPlan): number | undefined {\n  if (plan.seatAmount !== undefined) {\n    if (typeof plan.seatAmount === \"number\" && Number.isFinite(plan.seatAmount)) {\n      return plan.seatAmount;\n    }\n    throw new Error(`Invalid seatAmount for plan '${plan.name}'. Expected a finite number.`);\n  }\n\n  if (plan.seatPriceId === undefined || plan.seatPriceId === null || plan.seatPriceId === \"\") {\n    return undefined;\n  }\n\n  const parsed = typeof plan.seatPriceId === \"string\" ? Number(plan.seatPriceId) : plan.seatPriceId;\n  if (typeof parsed === \"number\" && Number.isFinite(parsed)) {\n    return parsed;\n  }\n\n  throw new Error(\n    `Invalid seatPriceId for plan '${plan.name}'. Expected a numeric amount in the smallest currency unit.`,\n  );\n}\n\nexport function calculatePlanAmount(plan: PaystackPlan, quantity: number): number {\n  return (plan.amount ?? 0) + quantity * (getPlanSeatAmount(plan) ?? 0);\n}\n\nexport function isLocalSubscriptionCode(subscriptionCode: string | undefined | null): boolean {\n  return (\n    typeof subscriptionCode === \"string\" &&\n    (subscriptionCode.startsWith(\"LOC_\") || subscriptionCode.startsWith(\"sub_local_\"))\n  );\n}\n\nexport function isLocallyManagedSubscription(\n  subscription: Pick<Subscription, \"paystackSubscriptionCode\" | \"paystackPlanCode\">,\n): boolean {\n  if (isLocalSubscriptionCode(subscription.paystackSubscriptionCode)) {\n    return true;\n  }\n\n  if (\n    typeof subscription.paystackSubscriptionCode === \"string\" &&\n    subscription.paystackSubscriptionCode !== \"\"\n  ) {\n    return false;\n  }\n\n  return (\n    subscription.paystackPlanCode === undefined ||\n    subscription.paystackPlanCode === null ||\n    subscription.paystackPlanCode === \"\"\n  );\n}\n\nexport function assertLocallyManagedSubscription(\n  subscription: Pick<Subscription, \"paystackSubscriptionCode\" | \"paystackPlanCode\">,\n  action: string,\n): void {\n  if (!isLocallyManagedSubscription(subscription)) {\n    throw new Error(\n      `Paystack-managed subscriptions do not support ${action}. Use local billing for seat-based or prorated subscription changes.`,\n    );\n  }\n}\n\nexport async function getPlans(\n  subscriptionOptions: AnyPaystackOptions[\"subscription\"],\n): Promise<PaystackPlan[]> {\n  if (subscriptionOptions?.enabled === true) {\n    return typeof subscriptionOptions.plans === \"function\"\n      ? subscriptionOptions.plans()\n      : subscriptionOptions.plans;\n  }\n  throw new Error(\"Subscriptions are not enabled in the Paystack options.\");\n}\n\nexport const getPlan: (\n  options: AnyPaystackOptions,\n  planId: string,\n) => Promise<PaystackPlan | null> = async (options, planId) => {\n  if (options.subscription?.enabled === true) {\n    const plans = await getPlans(options.subscription);\n    return plans.find((plan) => plan.name === planId) ?? null;\n  }\n  return null;\n};\n\nexport async function getPlanByName(\n  options: AnyPaystackOptions,\n  name: string,\n): Promise<PaystackPlan | null> {\n  if (typeof name !== \"string\" || name.trim() === \"\") {\n    return null;\n  }\n  if (options.subscription?.enabled === true) {\n    const plans = await getPlans(options.subscription);\n    const normalizedName = name.toLowerCase();\n    return (\n      plans.find(\n        (plan) => typeof plan.name === \"string\" && plan.name.toLowerCase() === normalizedName,\n      ) ?? null\n    );\n  }\n  return null;\n}\n\nexport async function getPlanByPriceId(\n  options: AnyPaystackOptions,\n  priceId: string,\n): Promise<PaystackPlan | null> {\n  if (options.subscription?.enabled === true) {\n    const plans = await getPlans(options.subscription);\n    return plans.find((plan) => plan.name === priceId) ?? null;\n  }\n  return null;\n}\n\nexport async function getProducts(\n  productOptions: AnyPaystackOptions[\"products\"],\n): Promise<PaystackProduct[]> {\n  if (productOptions?.products) {\n    return typeof productOptions.products === \"function\"\n      ? await productOptions.products()\n      : productOptions.products;\n  }\n  return [];\n}\n\nexport async function getProductByName(\n  options: AnyPaystackOptions,\n  name: string,\n): Promise<PaystackProduct | null> {\n  return await getProducts(options.products).then((products) =>\n    products !== undefined && products !== null\n      ? (products.find((product) => product.name.toLowerCase() === name.toLowerCase()) ?? null)\n      : null,\n  );\n}\n\nexport function getNextPeriodEnd(startDate: Date, interval: string): Date {\n  const date = new Date(startDate);\n  switch (interval) {\n    case \"daily\":\n      date.setDate(date.getDate() + 1);\n      break;\n    case \"weekly\":\n      date.setDate(date.getDate() + 7);\n      break;\n    case \"monthly\":\n      date.setMonth(date.getMonth() + 1);\n      break;\n    case \"quarterly\":\n      date.setMonth(date.getMonth() + 3);\n      break;\n    case \"biannually\":\n      date.setMonth(date.getMonth() + 6);\n      break;\n    case \"annually\":\n      date.setFullYear(date.getFullYear() + 1);\n      break;\n    default:\n      // Default to monthly if unknown\n      date.setMonth(date.getMonth() + 1);\n  }\n  return date;\n}\n\n/**\n * Validates if the amount meets Paystack's minimum transaction requirements.\n * Amounts should be in the smallest currency unit (e.g., kobo, cents).\n */\nexport function validateMinAmount(amount: number, currency: string): boolean {\n  const minAmounts: Record<string, number> = {\n    NGN: 5000, // 50.00\n    GHS: 10, // 0.10\n    ZAR: 100, // 1.00\n    KES: 300, // 3.00\n    USD: 200, // 2.00\n    XOF: 100, // 1.00\n  };\n  const min = minAmounts[currency.toUpperCase()];\n  return min !== undefined ? amount >= min : true;\n}\n\nexport async function syncProductQuantityFromPaystack(\n  ctx: GenericEndpointContext,\n  productName: string,\n  paystackClient: PaystackClientLike,\n): Promise<void> {\n  const store = createBillingStore(ctx);\n  // Find the local product record (by name or slug)\n  let localProduct = await store.findProductByName(productName);\n\n  localProduct ??= await store.findProductBySlug(productName.toLowerCase().replace(/\\s+/g, \"-\"));\n\n  if (\n    localProduct?.paystackId === undefined ||\n    localProduct.paystackId === null ||\n    localProduct.paystackId === \"\"\n  ) {\n    // No local record with a Paystack ID - fall back to local decrement\n    if (\n      localProduct?.id !== undefined &&\n      localProduct.unlimited !== true &&\n      typeof localProduct.quantity === \"number\" &&\n      localProduct.quantity > 0\n    ) {\n      await store.updateProduct(localProduct.id, {\n        quantity: localProduct.quantity - 1,\n        updatedAt: new Date(),\n      });\n    }\n    return;\n  }\n\n  // Fetch the latest quantity from Paystack\n  try {\n    const paystackProductId = Number(localProduct.paystackId);\n    if (!Number.isFinite(paystackProductId)) {\n      return;\n    }\n    const sdkRes = (await createPaystackAdapter(paystackClient).fetchProduct(\n      paystackProductId,\n    )) as PaystackProductResponse;\n    const remoteQuantity = sdkRes?.quantity;\n\n    if (remoteQuantity !== undefined && localProduct.id !== undefined) {\n      await store.updateProduct(localProduct.id, {\n        quantity: remoteQuantity,\n        updatedAt: new Date(),\n      });\n    }\n  } catch {\n    // If API call fails, fall back to local decrement\n    if (\n      localProduct?.id !== undefined &&\n      localProduct.unlimited !== true &&\n      typeof localProduct.quantity === \"number\" &&\n      localProduct.quantity > 0\n    ) {\n      await store.updateProduct(localProduct.id, {\n        quantity: localProduct.quantity - 1,\n        updatedAt: new Date(),\n      });\n    }\n  }\n}\n\nexport async function decrementProductQuantity(\n  ctx: GenericEndpointContext,\n  productName: string,\n): Promise<void> {\n  const store = createBillingStore(ctx);\n  let product = await store.findProductByName(productName);\n\n  product ??= await store.findProductBySlug(productName.toLowerCase().replace(/\\s+/g, \"-\"));\n\n  if (product !== undefined && product !== null) {\n    if (\n      product.unlimited !== true &&\n      typeof product.quantity === \"number\" &&\n      product.quantity > 0 &&\n      product.id !== undefined\n    ) {\n      await store.updateProduct(product.id, {\n        quantity: product.quantity - 1,\n        updatedAt: new Date(),\n      });\n    }\n  }\n}\n\nexport async function syncSubscriptionSeats(\n  ctx: GenericEndpointContext,\n  organizationId: string,\n  options: AnyPaystackOptions,\n): Promise<void> {\n  if (options.subscription?.enabled !== true) return;\n\n  const store = createBillingStore(ctx);\n  const subscription = await store.findCurrentSubscription(organizationId);\n\n  if (\n    subscription?.paystackSubscriptionCode === undefined ||\n    subscription.paystackSubscriptionCode === null ||\n    subscription.paystackSubscriptionCode === \"\"\n  )\n    return;\n  if (subscription === null || subscription === undefined) return;\n  const plan = await getPlanByName(options, subscription.plan);\n  if (plan === null || plan === undefined) return;\n  const seatAmount = getPlanSeatAmount(plan);\n  if (seatAmount === undefined) return;\n\n  const members = await store.listMembers(organizationId);\n\n  const quantity = members.length;\n\n  try {\n    assertLocallyManagedSubscription(subscription, \"automatic seat sync\");\n\n    // Locally managed subscriptions renew via saved authorizations, so seat count lives in our DB.\n    await store.updateSubscription(subscription.id, {\n      seats: quantity,\n      updatedAt: new Date(),\n    });\n  } catch (e: unknown) {\n    const log = ctx.context.logger;\n    if (log !== undefined && log !== null) {\n      log.error(\"Failed to sync subscription seats\", e);\n    }\n  }\n}\n","import type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\nimport type { AnyPaystackOptions, Session, User } from \"./types\";\n\nexport type BillingReferenceAction =\n  | \"initialize-transaction\"\n  | \"verify-transaction\"\n  | \"list-subscriptions\"\n  | \"list-transactions\"\n  | \"disable-subscription\"\n  | \"enable-subscription\"\n  | \"get-subscription-manage-link\";\n\nconst DEFAULT_BILLING_ORG_ROLES = [\"owner\", \"admin\"] as const;\n\nfunction normalizeBillingRoles(roles: readonly string[]): Set<string> {\n  return new Set(roles.map((value) => value.trim()).filter((value) => value !== \"\"));\n}\n\nexport function getBillingRoles(options: AnyPaystackOptions): readonly string[] {\n  return options.organization?.billingRoles ?? DEFAULT_BILLING_ORG_ROLES;\n}\n\nexport function hasBillingRole(\n  role: unknown,\n  billingRoles: readonly string[] = DEFAULT_BILLING_ORG_ROLES,\n): boolean {\n  const allowedRoles = normalizeBillingRoles(billingRoles);\n  if (Array.isArray(role)) {\n    return role.some((value) => hasBillingRole(value, billingRoles));\n  }\n  if (typeof role !== \"string\") {\n    return false;\n  }\n  return role\n    .split(\",\")\n    .map((value) => value.trim())\n    .some((value) => allowedRoles.has(value));\n}\n\nexport function resolveBillingReferenceId(input: {\n  body?: unknown;\n  query?: unknown;\n  requestUrl?: string;\n  fallbackUserId: string;\n}): string {\n  const body = (input.body ?? {}) as Record<string, unknown>;\n  const query = (input.query ?? {}) as Record<string, unknown>;\n  const requestQueryReferenceId =\n    typeof input.requestUrl === \"string\"\n      ? (new URL(input.requestUrl).searchParams.get(\"referenceId\") ?? undefined)\n      : undefined;\n\n  return (\n    (body.referenceId as string | undefined) ??\n    (query.referenceId as string | undefined) ??\n    requestQueryReferenceId ??\n    input.fallbackUserId\n  );\n}\n\nexport async function authorizeBillingReference(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n  data: {\n    user: User;\n    session: Session;\n    referenceId: string;\n    action: BillingReferenceAction;\n  },\n): Promise<void> {\n  if (data.referenceId === data.user.id) return;\n\n  if (\n    options.subscription?.enabled === true &&\n    typeof options.subscription.authorizeReference === \"function\"\n  ) {\n    const authorized = await options.subscription.authorizeReference(\n      {\n        user: data.user,\n        session: data.session,\n        referenceId: data.referenceId,\n        action: data.action,\n      },\n      ctx,\n    );\n    if (authorized === true) return;\n    throw new APIError(\"UNAUTHORIZED\");\n  }\n\n  if (options.organization?.enabled === true) {\n    const member = await ctx.context.adapter.findOne({\n      model: \"member\",\n      where: [\n        { field: \"userId\", value: data.user.id },\n        { field: \"organizationId\", value: data.referenceId },\n      ],\n    });\n\n    if (\n      member !== null &&\n      member !== undefined &&\n      hasBillingRole((member as { role?: unknown }).role, getBillingRoles(options))\n    ) {\n      return;\n    }\n  }\n\n  throw new APIError(\"UNAUTHORIZED\");\n}\n","import { APIError, createAuthMiddleware, type AuthMiddleware } from \"better-auth/api\";\n\nimport type { PaystackOptions, Session, User } from \"./types\";\nimport {\n  authorizeBillingReference,\n  type BillingReferenceAction,\n  resolveBillingReferenceId,\n} from \"./reference-access\";\n\nexport { hasBillingRole } from \"./reference-access\";\n\nexport const referenceMiddleware = (\n  options: PaystackOptions,\n  action: BillingReferenceAction,\n): AuthMiddleware =>\n  createAuthMiddleware(async (ctx) => {\n    const session = ctx.context.session as {\n      user: User;\n      session: Session;\n    } | null;\n\n    if (session === null || session === undefined) {\n      throw new APIError(\"UNAUTHORIZED\");\n    }\n    const referenceId = resolveBillingReferenceId({\n      body: ctx.body,\n      query: ctx.query,\n      requestUrl: ctx.request?.url,\n      fallbackUserId: session.user.id,\n    });\n\n    await authorizeBillingReference(ctx, options, {\n      user: session.user,\n      session: session.session,\n      referenceId,\n      action,\n    });\n\n    return {\n      context: {\n        ...ctx.context,\n        referenceId,\n      },\n    };\n  });\n","import type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\nimport type { Subscription } from \"./types\";\nimport { createBillingStore } from \"./billing-store\";\n\nexport const getOrganizationSubscription = async (\n  ctx: GenericEndpointContext,\n  organizationId: string,\n): Promise<Subscription | null> => {\n  return createBillingStore(ctx).findCurrentSubscription(organizationId);\n};\n\nexport const checkSeatLimit = async (\n  ctx: GenericEndpointContext,\n  organizationId: string,\n  seatsToAdd = 1,\n): Promise<boolean> => {\n  const subscription = await getOrganizationSubscription(ctx, organizationId);\n\n  if (subscription?.seats === null) {\n    return true; // No explicit seat limit found\n  }\n\n  const members = await createBillingStore(ctx).listMembers(organizationId);\n\n  if (!subscription) {\n    return true; // No subscription, no specific limit enforcement here (or maybe allow depending on config)\n  }\n\n  if (members.length + seatsToAdd > subscription.seats) {\n    throw new APIError(\"FORBIDDEN\", {\n      message: `Organization member limit reached. Used: ${members.length}, Max: ${subscription.seats}`,\n    });\n  }\n\n  return true;\n};\n\nexport const checkTeamLimit = async (\n  ctx: GenericEndpointContext,\n  organizationId: string,\n  maxTeams: number,\n): Promise<boolean> => {\n  const teams = await createBillingStore(ctx).listTeams(organizationId);\n\n  if (teams.length >= maxTeams) {\n    throw new APIError(\"FORBIDDEN\", {\n      message: `Organization team limit reached. Max teams: ${maxTeams}`,\n    });\n  }\n\n  return true;\n};\n","import type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport type { components } from \"@alexasomba/paystack-node\";\n\nimport { createBillingStore } from \"./billing-store\";\nimport { getOrganizationSubscription } from \"./limits\";\nimport { createPaystackAdapter } from \"./paystack-sdk\";\nimport {\n  assertLocallyManagedSubscription,\n  calculatePlanAmount,\n  getPlanByName,\n  getPlanSeatAmount,\n} from \"./utils\";\nimport type {\n  AnyPaystackOptions,\n  PaystackChargeAuthorizationResponse,\n  PaystackCheckoutChannel,\n  PaystackInitializeResult,\n  PaystackPlan,\n  Subscription,\n  User,\n} from \"./types\";\nimport { createProrationMetadata, stringifyPaystackMetadata } from \"./metadata\";\n\nexport type ProratedUpgradeOutcome =\n  | Extract<PaystackInitializeResult, { kind: \"prorated\" }>\n  | {\n      kind: \"checkout\";\n      url: string | undefined;\n      reference: string | undefined;\n      accessCode: string | undefined;\n      redirect: true;\n    };\n\nexport interface TrialLifecycleDecision {\n  trialStart?: Date;\n  trialEnd?: Date;\n  requestedDays: number;\n  requested: boolean;\n  granted: boolean;\n  deniedReason?: \"already_used\";\n}\n\nexport async function scheduleSubscriptionLifecycleChange(\n  ctx: GenericEndpointContext,\n  input: {\n    referenceId: string;\n    plan?: PaystackPlan;\n    scheduleAtPeriodEnd?: boolean;\n    cancelAtPeriodEnd?: boolean;\n  },\n): Promise<Extract<PaystackInitializeResult, { kind: \"scheduled\" }> | null> {\n  if (input.plan !== undefined && input.scheduleAtPeriodEnd === true) {\n    const existingSub = await getOrganizationSubscription(ctx, input.referenceId);\n    if (existingSub?.status === \"active\") {\n      await ctx.context.adapter.update({\n        model: \"subscription\",\n        where: [{ field: \"id\", value: existingSub.id }],\n        update: {\n          pendingPlan: input.plan.name,\n          updatedAt: new Date(),\n        },\n      });\n      return {\n        kind: \"scheduled\",\n        status: \"success\",\n        message: \"Plan change scheduled at period end.\",\n        scheduled: true,\n      };\n    }\n  }\n\n  if (input.cancelAtPeriodEnd === true) {\n    const existingSub = await getOrganizationSubscription(ctx, input.referenceId);\n    if (existingSub?.status === \"active\") {\n      await ctx.context.adapter.update({\n        model: \"subscription\",\n        where: [{ field: \"id\", value: existingSub.id }],\n        update: {\n          cancelAtPeriodEnd: true,\n          updatedAt: new Date(),\n        },\n      });\n\n      return {\n        kind: \"scheduled\",\n        status: \"success\",\n        message: \"Subscription cancellation scheduled at period end.\",\n        scheduled: true,\n      };\n    }\n  }\n\n  return null;\n}\n\nexport async function resolveTrialLifecycle(\n  ctx: GenericEndpointContext,\n  input: {\n    referenceId: string;\n    plan?: PaystackPlan;\n  },\n): Promise<TrialLifecycleDecision> {\n  const requestedDays =\n    input.plan?.freeTrial?.days !== undefined && input.plan.freeTrial.days > 0\n      ? input.plan.freeTrial.days\n      : 0;\n  const requested = requestedDays > 0;\n  if (!requested) {\n    return {\n      requestedDays,\n      requested: false,\n      granted: false,\n    };\n  }\n\n  const previousTrials = await ctx.context.adapter.findMany<Subscription>({\n    model: \"subscription\",\n    where: [{ field: \"referenceId\", value: input.referenceId }],\n  });\n  const hadTrial = previousTrials?.some(\n    (subscription) =>\n      (subscription.trialStart !== undefined && subscription.trialStart !== null) ||\n      (subscription.trialEnd !== undefined && subscription.trialEnd !== null) ||\n      subscription.status === \"trialing\",\n  );\n\n  if (hadTrial === true) {\n    return {\n      requestedDays,\n      requested,\n      granted: false,\n      deniedReason: \"already_used\",\n    };\n  }\n\n  const trialStart = new Date();\n  const trialEnd = new Date();\n  trialEnd.setDate(trialEnd.getDate() + requestedDays);\n\n  return {\n    trialStart,\n    trialEnd,\n    requestedDays,\n    requested,\n    granted: true,\n  };\n}\n\nexport async function resolveCheckoutTargetEmail(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n  input: {\n    email?: string;\n    referenceId: string;\n    user: User;\n  },\n): Promise<string> {\n  const targetEmail = input.email ?? input.user.email;\n\n  if (\n    options.organization?.enabled !== true ||\n    input.referenceId === input.user.id ||\n    input.referenceId === \"\"\n  ) {\n    return targetEmail;\n  }\n\n  const org = await ctx.context.adapter.findOne({\n    model: \"organization\",\n    where: [{ field: \"id\", value: input.referenceId }],\n  });\n  if (org === undefined || org === null) {\n    return targetEmail;\n  }\n\n  const orgWithEmail = org as { email?: string | null };\n  if (\n    orgWithEmail.email !== undefined &&\n    orgWithEmail.email !== null &&\n    orgWithEmail.email !== \"\"\n  ) {\n    return orgWithEmail.email;\n  }\n\n  const ownerMember = await ctx.context.adapter.findOne({\n    model: \"member\",\n    where: [\n      { field: \"organizationId\", value: input.referenceId },\n      { field: \"role\", value: \"owner\" },\n    ],\n  });\n\n  if (ownerMember === undefined || ownerMember === null) {\n    return targetEmail;\n  }\n\n  const ownerUser = (await ctx.context.adapter.findOne({\n    model: \"user\",\n    where: [{ field: \"id\", value: (ownerMember as { userId: string }).userId }],\n  })) as User | null;\n\n  return ownerUser?.email !== undefined && ownerUser.email !== \"\" ? ownerUser.email : targetEmail;\n}\n\nexport async function handleProratedUpgrade(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n  input: {\n    plan: PaystackPlan;\n    referenceId: string;\n    quantity?: number;\n    targetEmail: string;\n    userId: string;\n    finalCurrency: string;\n    callbackURL?: string;\n    allowedSubscriptionChannels?: PaystackCheckoutChannel[];\n  },\n): Promise<ProratedUpgradeOutcome | null> {\n  const store = createBillingStore(ctx);\n  const existingSub = await store.findCurrentSubscription(input.referenceId);\n  if (\n    existingSub?.status !== \"active\" ||\n    existingSub.paystackSubscriptionCode === undefined ||\n    existingSub.paystackSubscriptionCode === null ||\n    existingSub.paystackSubscriptionCode === \"\" ||\n    existingSub.periodEnd === undefined ||\n    existingSub.periodEnd === null ||\n    existingSub.periodStart === undefined ||\n    existingSub.periodStart === null\n  ) {\n    return null;\n  }\n\n  const now = new Date();\n  const periodEnd = new Date(existingSub.periodEnd);\n  const periodStart = new Date(existingSub.periodStart);\n\n  const totalDays = Math.max(\n    1,\n    Math.ceil((periodEnd.getTime() - periodStart.getTime()) / (1000 * 60 * 60 * 24)),\n  );\n  const remainingDays = Math.max(\n    0,\n    Math.ceil((periodEnd.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)),\n  );\n\n  let oldAmount = 0;\n  if (existingSub.plan !== \"\") {\n    const oldPlan =\n      (await getPlanByName(options, existingSub.plan)) ??\n      (await store.findPlanByName(existingSub.plan));\n    if (oldPlan !== undefined && oldPlan !== null) {\n      oldAmount = calculatePlanAmount(oldPlan, existingSub.seats);\n    }\n  }\n\n  let membersCount = 1;\n  let newSeatCount: number;\n  let newAmount: number;\n  try {\n    assertLocallyManagedSubscription(existingSub, \"plan or seat changes\");\n    if (getPlanSeatAmount(input.plan) !== undefined) {\n      const members = await store.listMembers(input.referenceId);\n      membersCount = members.length > 0 ? members.length : 1;\n    }\n    newSeatCount = input.quantity ?? existingSub.seats ?? membersCount;\n    newAmount = calculatePlanAmount(input.plan, newSeatCount);\n  } catch (error: unknown) {\n    throw new APIError(\"BAD_REQUEST\", {\n      message: error instanceof Error ? error.message : \"Invalid seat configuration for plan.\",\n    });\n  }\n\n  const costDifference = newAmount - oldAmount;\n  const prorationMetadata = createProrationMetadata({\n    subscriptionId: existingSub.id,\n    referenceId: input.referenceId,\n    newPlan: input.plan.name.toLowerCase(),\n    oldPlan: existingSub.plan,\n    newSeatCount,\n    remainingDays,\n  });\n  const serializedProrationMetadata = stringifyPaystackMetadata(prorationMetadata);\n  let completedProrationReference: string | undefined;\n\n  if (costDifference > 0 && remainingDays > 0) {\n    const proratedAmount = Math.round((costDifference / totalDays) * remainingDays);\n    if (proratedAmount < 5000) {\n      throw new APIError(\"BAD_REQUEST\", {\n        message:\n          \"Prorated upgrade amount is below Paystack's minimum charge. Schedule the change for period end instead.\",\n        status: 400,\n      });\n    }\n\n    const paystack = createPaystackAdapter(options.paystackClient);\n    if (\n      existingSub.paystackAuthorizationCode !== undefined &&\n      existingSub.paystackAuthorizationCode !== null &&\n      existingSub.paystackAuthorizationCode !== \"\"\n    ) {\n      const sdkRes = (await paystack.chargeAuthorization({\n        email: input.targetEmail,\n        amount: proratedAmount,\n        authorization_code: existingSub.paystackAuthorizationCode,\n        reference: `upg_${existingSub.id}_${Date.now()}_${Math.random().toString(36).substring(7)}`,\n        metadata: serializedProrationMetadata,\n      })) as PaystackChargeAuthorizationResponse;\n\n      if (sdkRes?.status !== \"success\") {\n        throw new APIError(\"BAD_REQUEST\", {\n          message: \"Failed to process prorated charge via saved authorization.\",\n        });\n      }\n\n      await store.createTransaction({\n        reference: sdkRes.reference ?? \"\",\n        paystackId: sdkRes.id !== undefined && sdkRes.id !== null ? String(sdkRes.id) : undefined,\n        referenceId: input.referenceId,\n        userId: input.userId,\n        amount: sdkRes.amount ?? proratedAmount,\n        currency: sdkRes.currency ?? input.finalCurrency,\n        status: \"success\",\n        plan: input.plan.name.toLowerCase(),\n        metadata: serializedProrationMetadata,\n        createdAt: new Date(),\n        updatedAt: new Date(),\n      });\n      completedProrationReference = sdkRes.reference ?? undefined;\n    } else {\n      const initRes = await paystack.initializeTransaction({\n        email: input.targetEmail,\n        amount: proratedAmount,\n        currency: input.finalCurrency,\n        callback_url: input.callbackURL ?? undefined,\n        metadata: serializedProrationMetadata,\n        ...(input.allowedSubscriptionChannels !== undefined\n          ? { channels: input.allowedSubscriptionChannels }\n          : {}),\n      } as components[\"schemas\"][\"TransactionInitialize\"]);\n\n      await store.createTransaction({\n        reference: initRes?.reference ?? \"\",\n        referenceId: input.referenceId,\n        userId: input.userId,\n        amount: proratedAmount,\n        currency: input.finalCurrency,\n        status: \"pending\",\n        plan: input.plan.name.toLowerCase(),\n        metadata: serializedProrationMetadata,\n        createdAt: new Date(),\n        updatedAt: new Date(),\n      });\n\n      return {\n        kind: \"checkout\",\n        url: initRes?.authorization_url,\n        reference: initRes?.reference,\n        accessCode: initRes?.access_code,\n        redirect: true,\n      };\n    }\n  }\n\n  await store.updateSubscription(existingSub.id, {\n    plan: input.plan.name,\n    seats: newSeatCount,\n    ...(completedProrationReference !== undefined\n      ? { paystackTransactionReference: completedProrationReference }\n      : {}),\n    updatedAt: new Date(),\n  });\n\n  return {\n    kind: \"prorated\",\n    status: \"success\",\n    message: \"Subscription successfully upgraded with prorated charge.\",\n    prorated: true,\n  };\n}\n","import type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport type { components } from \"@alexasomba/paystack-node\";\n\nimport { createBillingStore } from \"./billing-store\";\nimport { authorizeBillingReference } from \"./reference-access\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk\";\nimport { getPlans, syncProductQuantityFromPaystack } from \"./utils\";\nimport {\n  getMetadataBoolean,\n  getMetadataNumber,\n  getMetadataString,\n  parsePaystackMetadata,\n} from \"./metadata\";\nimport type {\n  AnyPaystackOptions,\n  PaystackCheckoutChannel,\n  PaystackTransaction,\n  PaystackTransactionResponse,\n  PaystackWebhookPayload,\n  Session,\n  Subscription,\n  User,\n} from \"./types\";\n\nexport type PaystackReconciliationSource = \"webhook\" | \"queue\" | \"admin\" | \"server\" | \"browser\";\n\nexport interface ReconcilePaystackTransactionInput {\n  reference: string;\n  source?: PaystackReconciliationSource;\n  referenceId?: string;\n  actor?: {\n    user: User;\n    session: Session;\n  };\n  throwOnError?: boolean;\n}\n\nexport interface PaystackReconciliationError {\n  code: string;\n  message: string;\n  status?: number;\n}\n\nexport interface PaystackReconciliationSummary {\n  transaction: {\n    found: boolean;\n    updated: boolean;\n    referenceId?: string;\n    previousStatus?: string;\n    status?: string;\n  };\n  subscription: {\n    found: boolean;\n    updated: boolean;\n    id?: string;\n    status?: string;\n    prorationApplied: boolean;\n  };\n  customer: {\n    saved: boolean;\n    referenceId?: string;\n    customerCode?: string;\n    model?: \"user\" | \"organization\";\n  };\n  product: {\n    synced: boolean;\n    name?: string;\n  };\n}\n\nexport interface ReconcilePaystackTransactionSuccess extends PaystackReconciliationSummary {\n  ok: true;\n  source: PaystackReconciliationSource;\n  status: string;\n  reference: string;\n  data: PaystackTransactionResponse;\n  error?: undefined;\n}\n\nexport interface ReconcilePaystackTransactionFailure extends PaystackReconciliationSummary {\n  ok: false;\n  source: PaystackReconciliationSource;\n  status: string;\n  reference: string;\n  data: PaystackTransactionResponse | null;\n  error: PaystackReconciliationError;\n}\n\nexport type ReconcilePaystackTransactionResult =\n  | ReconcilePaystackTransactionSuccess\n  | ReconcilePaystackTransactionFailure;\n\nfunction getAllowedSubscriptionChannels(\n  options: AnyPaystackOptions,\n): PaystackCheckoutChannel[] | undefined {\n  const channels = options.subscription?.allowedPaymentChannels;\n  return Array.isArray(channels) && channels.length > 0 ? channels : undefined;\n}\n\nfunction isAllowedSubscriptionChannel(\n  channel: string | null | undefined,\n  allowedChannels: readonly PaystackCheckoutChannel[] | undefined,\n): boolean {\n  if (allowedChannels === undefined) return true;\n  return channel !== undefined && channel !== null && allowedChannels.includes(channel as never);\n}\n\nfunction createSummary(): PaystackReconciliationSummary {\n  return {\n    transaction: {\n      found: false,\n      updated: false,\n    },\n    subscription: {\n      found: false,\n      updated: false,\n      prorationApplied: false,\n    },\n    customer: {\n      saved: false,\n    },\n    product: {\n      synced: false,\n    },\n  };\n}\n\nfunction getErrorMessage(error: unknown, fallback: string): string {\n  return error instanceof Error && error.message !== \"\" ? error.message : fallback;\n}\n\nfunction createFailureResult(input: {\n  source: PaystackReconciliationSource;\n  status: string;\n  reference: string;\n  data: PaystackTransactionResponse | null;\n  summary: PaystackReconciliationSummary;\n  error: PaystackReconciliationError;\n}): ReconcilePaystackTransactionFailure {\n  return {\n    ok: false,\n    source: input.source,\n    status: input.status,\n    reference: input.reference,\n    data: input.data,\n    error: input.error,\n    ...input.summary,\n  };\n}\n\nfunction throwOrReturnFailure(\n  input: {\n    throwOnError: boolean;\n    apiStatus: \"BAD_REQUEST\" | \"UNAUTHORIZED\";\n  } & Parameters<typeof createFailureResult>[0],\n): ReconcilePaystackTransactionFailure {\n  if (input.throwOnError) {\n    throw new APIError(input.apiStatus, {\n      code: input.error.code,\n      message: input.error.message,\n      status: input.error.status,\n    });\n  }\n\n  return createFailureResult(input);\n}\n\nfunction hasReferenceMismatch(input: {\n  expectedReferenceId?: string;\n  transactionReferenceId?: string | null;\n}): boolean {\n  return (\n    input.expectedReferenceId !== undefined &&\n    input.expectedReferenceId !== \"\" &&\n    input.transactionReferenceId !== undefined &&\n    input.transactionReferenceId !== null &&\n    input.transactionReferenceId !== \"\" &&\n    input.expectedReferenceId !== input.transactionReferenceId\n  );\n}\n\nfunction getNonEmptyString(value: unknown): string | undefined {\n  return typeof value === \"string\" && value !== \"\" ? value : undefined;\n}\n\nexport async function reconcilePaystackTransaction(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n  input: ReconcilePaystackTransactionInput,\n): Promise<ReconcilePaystackTransactionResult> {\n  const source = input.source ?? \"server\";\n  const throwOnError = input.throwOnError === true;\n  const summary = createSummary();\n  const paystack = getPaystackOps(options.paystackClient);\n  let data: PaystackTransactionResponse | undefined;\n\n  try {\n    const verifyRaw = await paystack?.transaction?.verify(input.reference);\n    data = unwrapSdkResult<PaystackTransactionResponse>(verifyRaw);\n  } catch (error: unknown) {\n    ctx.context.logger.error(\"Failed to verify Paystack transaction\", error);\n    return throwOrReturnFailure({\n      throwOnError,\n      apiStatus: \"BAD_REQUEST\",\n      source,\n      status: \"error\",\n      reference: input.reference,\n      data: null,\n      summary,\n      error: {\n        code: \"FAILED_TO_VERIFY_TRANSACTION\",\n        message: getErrorMessage(error, \"Failed to verify transaction\"),\n        status: 400,\n      },\n    });\n  }\n\n  if (data === undefined || data === null) {\n    return throwOrReturnFailure({\n      throwOnError,\n      apiStatus: \"BAD_REQUEST\",\n      source,\n      status: \"error\",\n      reference: input.reference,\n      data: null,\n      summary,\n      error: {\n        code: \"FAILED_TO_VERIFY_TRANSACTION\",\n        message: \"Failed to fetch transaction data from Paystack.\",\n        status: 400,\n      },\n    });\n  }\n\n  const status = data.status ?? \"failed\";\n  const reference = data.reference ?? input.reference;\n  const paystackIdRaw = (data as { id?: number | string | null }).id;\n  const paystackId =\n    paystackIdRaw !== undefined && paystackIdRaw !== null ? String(paystackIdRaw) : undefined;\n  const authorizationCode = (data.authorization as { authorization_code?: string | null } | null)\n    ?.authorization_code;\n  const store = createBillingStore(ctx);\n  const txRecord = await store.findTransactionByReference(reference);\n  summary.transaction.found = txRecord !== null;\n  summary.transaction.previousStatus = txRecord?.status;\n\n  if (\n    hasReferenceMismatch({\n      expectedReferenceId: input.referenceId,\n      transactionReferenceId: txRecord?.referenceId,\n    })\n  ) {\n    return throwOrReturnFailure({\n      throwOnError,\n      apiStatus: \"UNAUTHORIZED\",\n      source,\n      status,\n      reference,\n      data,\n      summary,\n      error: {\n        code: \"REFERENCE_ID_MISMATCH\",\n        message: \"Transaction reference does not belong to the expected billing reference.\",\n        status: 401,\n      },\n    });\n  }\n\n  const referenceId =\n    input.referenceId ??\n    getNonEmptyString(txRecord?.referenceId) ??\n    getNonEmptyString(input.actor?.user.id);\n  summary.transaction.referenceId = referenceId;\n\n  if (\n    input.actor !== undefined &&\n    referenceId !== undefined &&\n    referenceId !== input.actor.user.id\n  ) {\n    try {\n      await authorizeBillingReference(ctx, options, {\n        user: input.actor.user,\n        session: input.actor.session,\n        referenceId,\n        action: \"verify-transaction\",\n      });\n    } catch (error: unknown) {\n      return throwOrReturnFailure({\n        throwOnError,\n        apiStatus: \"UNAUTHORIZED\",\n        source,\n        status,\n        reference,\n        data,\n        summary,\n        error: {\n          code: \"UNAUTHORIZED\",\n          message: getErrorMessage(error, \"Not authorized to reconcile this transaction.\"),\n          status: 401,\n        },\n      });\n    }\n  }\n\n  const transactionUpdate: Partial<PaystackTransaction> & Record<string, unknown> = {\n    status,\n    paystackId,\n    amount: data.amount,\n    currency: data.currency,\n    updatedAt: new Date(),\n  };\n  const updatedTransaction = await store.updateTransactionByReference(reference, transactionUpdate);\n  summary.transaction.updated = updatedTransaction !== null;\n  summary.transaction.status = status;\n\n  if (status !== \"success\") {\n    return {\n      ok: true,\n      source,\n      status,\n      reference,\n      data,\n      ...summary,\n    };\n  }\n\n  const allowedSubscriptionChannels = getAllowedSubscriptionChannels(options);\n  const isSubscriptionFlow =\n    (txRecord?.plan !== undefined && txRecord.plan !== null && txRecord.plan !== \"\") ||\n    Boolean((data as { plan?: unknown }).plan);\n\n  if (\n    isSubscriptionFlow &&\n    isAllowedSubscriptionChannel(data.channel ?? undefined, allowedSubscriptionChannels) === false\n  ) {\n    await store.updateTransactionByReference(reference, {\n      ...transactionUpdate,\n      status: \"failed\",\n    });\n    summary.transaction.updated = true;\n    summary.transaction.status = \"failed\";\n\n    return throwOrReturnFailure({\n      throwOnError,\n      apiStatus: \"BAD_REQUEST\",\n      source,\n      status: \"failed\",\n      reference,\n      data,\n      summary,\n      error: {\n        code: \"SUBSCRIPTION_PAYMENT_CHANNEL_NOT_ALLOWED\",\n        message: `This subscription requires one of: ${allowedSubscriptionChannels?.join(\", \") ?? \"allowed channels\"}.`,\n        status: 400,\n      },\n    });\n  }\n\n  const paystackCustomerCodeFromPaystack = data.customer?.customer_code;\n  if (\n    paystackCustomerCodeFromPaystack !== undefined &&\n    paystackCustomerCodeFromPaystack !== null &&\n    paystackCustomerCodeFromPaystack !== \"\" &&\n    referenceId !== undefined &&\n    referenceId !== \"\"\n  ) {\n    let isOrganization =\n      options.organization?.enabled === true &&\n      typeof referenceId === \"string\" &&\n      referenceId.startsWith(\"org_\");\n    if (isOrganization === false && options.organization?.enabled === true) {\n      const organization = await store.findOrganization(referenceId);\n      isOrganization = organization !== null;\n    }\n\n    await store.saveCustomerCode(referenceId, paystackCustomerCodeFromPaystack, isOrganization);\n    summary.customer.saved = true;\n    summary.customer.referenceId = referenceId;\n    summary.customer.customerCode = paystackCustomerCodeFromPaystack;\n    summary.customer.model = isOrganization ? \"organization\" : \"user\";\n  }\n\n  const transaction = updatedTransaction ?? (await store.findTransactionByReference(reference));\n  if (\n    transaction !== undefined &&\n    transaction !== null &&\n    transaction.product !== undefined &&\n    transaction.product !== null &&\n    transaction.product !== \"\" &&\n    options.paystackClient !== undefined &&\n    options.paystackClient !== null\n  ) {\n    await syncProductQuantityFromPaystack(ctx, transaction.product, options.paystackClient);\n    summary.product.synced = true;\n    summary.product.name = transaction.product;\n  }\n\n  if (options.subscription?.enabled !== true) {\n    return {\n      ok: true,\n      source,\n      status,\n      reference,\n      data,\n      ...summary,\n    };\n  }\n\n  const metadataObj = parsePaystackMetadata(data.metadata);\n  const isTrial = getMetadataBoolean(metadataObj, \"isTrial\");\n  const trialEnd = getMetadataString(metadataObj, \"trialEnd\");\n  const targetPlan = getMetadataString(metadataObj, \"plan\");\n\n  if (metadataObj.type === \"proration\") {\n    const subscriptionId = getMetadataString(metadataObj, \"subscriptionId\");\n    const newPlan = getMetadataString(metadataObj, \"newPlan\");\n    const newSeatCount = getMetadataNumber(metadataObj, \"newSeatCount\");\n\n    if (\n      subscriptionId !== undefined &&\n      subscriptionId !== \"\" &&\n      newPlan !== undefined &&\n      newPlan !== \"\"\n    ) {\n      const updatedSubscription = await store.updateSubscription(subscriptionId, {\n        plan: newPlan,\n        ...(typeof newSeatCount === \"number\" ? { seats: newSeatCount } : {}),\n        paystackTransactionReference: reference,\n        ...(authorizationCode !== undefined && authorizationCode !== null\n          ? { paystackAuthorizationCode: authorizationCode }\n          : {}),\n        updatedAt: new Date(),\n      });\n      summary.subscription.found = updatedSubscription !== null;\n      summary.subscription.updated = updatedSubscription !== null;\n      summary.subscription.id = updatedSubscription?.id ?? subscriptionId;\n      summary.subscription.status = updatedSubscription?.status;\n      summary.subscription.prorationApplied = updatedSubscription !== null;\n    }\n\n    return {\n      ok: true,\n      source,\n      status,\n      reference,\n      data,\n      ...summary,\n    };\n  }\n\n  let paystackSubscriptionCode: string | undefined;\n  const existingSubs = await store.findSubscriptionsByTransactionReference(reference);\n  const targetSub = existingSubs.find(\n    (subscription) =>\n      referenceId === undefined || referenceId === \"\" || subscription.referenceId === referenceId,\n  );\n  summary.subscription.found = targetSub !== undefined;\n  summary.subscription.id = targetSub?.id;\n  summary.subscription.status = targetSub?.status;\n\n  if (isTrial && targetPlan !== undefined && trialEnd !== undefined) {\n    const email = data.customer?.email;\n    const plans = await getPlans(options.subscription);\n    const planConfig = plans.find((plan) => plan.name.toLowerCase() === targetPlan.toLowerCase());\n\n    if (\n      planConfig !== undefined &&\n      planConfig !== null &&\n      (planConfig.planCode === undefined ||\n        planConfig.planCode === null ||\n        planConfig.planCode === \"\")\n    ) {\n      paystackSubscriptionCode = `LOC_${reference}`;\n    } else if (\n      targetSub?.paystackSubscriptionCode !== undefined &&\n      targetSub.paystackSubscriptionCode !== null &&\n      targetSub.paystackSubscriptionCode !== \"\"\n    ) {\n      paystackSubscriptionCode = targetSub.paystackSubscriptionCode;\n    } else if (\n      authorizationCode !== undefined &&\n      authorizationCode !== null &&\n      email !== undefined &&\n      email !== null &&\n      email !== \"\" &&\n      planConfig?.planCode !== undefined &&\n      planConfig.planCode !== null &&\n      planConfig.planCode !== \"\"\n    ) {\n      const subResRaw = await paystack?.subscription?.create({\n        body: {\n          customer: email,\n          plan: planConfig.planCode,\n          authorization: authorizationCode,\n          start_date: trialEnd,\n        },\n      });\n      const subRes =\n        unwrapSdkResult<components[\"schemas\"][\"SubscriptionListResponseArray\"]>(subResRaw);\n      paystackSubscriptionCode = subRes?.subscription_code;\n    }\n  } else if (isTrial === false) {\n    const planCodeFromPaystack = (data as { plan?: { plan_code?: string | null } }).plan?.plan_code;\n    if (\n      planCodeFromPaystack === undefined ||\n      planCodeFromPaystack === null ||\n      planCodeFromPaystack === \"\"\n    ) {\n      paystackSubscriptionCode = `LOC_${reference}`;\n    } else {\n      paystackSubscriptionCode =\n        (data as { subscription?: { subscription_code?: string | null } }).subscription\n          ?.subscription_code ?? undefined;\n    }\n  }\n\n  let updatedSubscription: Subscription | null = null;\n  if (targetSub !== undefined && targetSub !== null) {\n    updatedSubscription = await store.updateSubscription(targetSub.id, {\n      status: isTrial ? \"trialing\" : \"active\",\n      periodStart: new Date(),\n      updatedAt: new Date(),\n      ...(isTrial && trialEnd !== undefined\n        ? {\n            trialStart: new Date(),\n            trialEnd: new Date(trialEnd),\n            periodEnd: new Date(trialEnd),\n          }\n        : {}),\n      ...(paystackSubscriptionCode !== undefined ? { paystackSubscriptionCode } : {}),\n      ...(authorizationCode !== undefined && authorizationCode !== null\n        ? { paystackAuthorizationCode: authorizationCode }\n        : {}),\n    });\n    summary.subscription.updated = updatedSubscription !== null;\n    summary.subscription.id = updatedSubscription?.id ?? targetSub.id;\n    summary.subscription.status = updatedSubscription?.status ?? targetSub.status;\n  }\n\n  if (\n    updatedSubscription !== undefined &&\n    updatedSubscription !== null &&\n    options.subscription?.onSubscriptionComplete !== undefined\n  ) {\n    const plans = await getPlans(options.subscription);\n    const plan = plans.find(\n      (candidate) => candidate.name.toLowerCase() === updatedSubscription.plan.toLowerCase(),\n    );\n    if (plan !== undefined) {\n      await options.subscription.onSubscriptionComplete(\n        {\n          event: data as unknown as PaystackWebhookPayload,\n          subscription: updatedSubscription,\n          plan,\n        },\n        ctx,\n      );\n    }\n  }\n\n  return {\n    ok: true,\n    source,\n    status,\n    reference,\n    data,\n    ...summary,\n  };\n}\n","/* oxlint-disable no-restricted-imports */\nimport { z } from \"zod\";\n\nexport const initializeTransactionBodySchema: z.ZodObject<{\n  plan: z.ZodOptional<z.ZodString>;\n  product: z.ZodOptional<z.ZodString>;\n  amount: z.ZodOptional<z.ZodNumber>;\n  currency: z.ZodOptional<z.ZodString>;\n  email: z.ZodOptional<z.ZodString>;\n  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;\n  referenceId: z.ZodOptional<z.ZodString>;\n  callbackURL: z.ZodOptional<z.ZodString>;\n  quantity: z.ZodOptional<z.ZodNumber>;\n  scheduleAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n  cancelAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n  prorateAndCharge: z.ZodOptional<z.ZodBoolean>;\n}> = z.object({\n  plan: z.string().optional(),\n  product: z.string().optional(),\n  amount: z.number().int().positive().optional(),\n  currency: z.string().optional(),\n  email: z.string().optional(),\n  metadata: z.record(z.string(), z.unknown()).optional(),\n  referenceId: z.string().optional(),\n  callbackURL: z.string().optional(),\n  quantity: z.number().int().positive().optional(),\n  scheduleAtPeriodEnd: z.boolean().optional(),\n  cancelAtPeriodEnd: z.boolean().optional(),\n  prorateAndCharge: z.boolean().optional(),\n});\n","import type { GenericEndpointContext } from \"better-auth\";\n\nimport { createBillingStore } from \"../billing-store\";\nimport { getPlans, getProducts } from \"../utils\";\nimport type { AnyPaystackOptions, PaystackPlan, PaystackProduct } from \"../types\";\n\nexport async function listStoredProducts(ctx: GenericEndpointContext): Promise<PaystackProduct[]> {\n  return createBillingStore(ctx).listProducts();\n}\n\nexport async function listStoredPlans(ctx: GenericEndpointContext): Promise<PaystackPlan[]> {\n  return createBillingStore(ctx).listPlans();\n}\n\nexport async function getConfiguredCatalog(options: AnyPaystackOptions): Promise<{\n  plans: PaystackPlan[];\n  products: PaystackProduct[];\n}> {\n  const plans = options.subscription?.enabled === true ? await getPlans(options.subscription) : [];\n  const products = await getProducts(options.products);\n  return { plans, products };\n}\n","/* oxlint-disable no-restricted-imports */\nimport { z } from \"zod\";\n\nexport const enableDisableBodySchema: z.ZodObject<{\n  referenceId: z.ZodOptional<z.ZodString>;\n  subscriptionCode: z.ZodString;\n  emailToken: z.ZodOptional<z.ZodString>;\n  atPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n}> = z.object({\n  referenceId: z.string().optional(),\n  subscriptionCode: z.string(),\n  emailToken: z.string().optional(),\n  atPeriodEnd: z.boolean().optional(),\n});\n\nexport function decodeBase64UrlToString(value: string): string {\n  const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n  const padded = normalized + \"===\".slice((normalized.length + 3) % 4);\n  const binaryString = atob(padded);\n  const bytes = new Uint8Array(binaryString.length);\n  for (let i = 0; i < binaryString.length; i++) {\n    bytes[i] = binaryString.charCodeAt(i);\n  }\n  return new TextDecoder().decode(bytes);\n}\n\nexport function tryGetEmailTokenFromSubscriptionManageLink(link: string): string | undefined {\n  try {\n    const url = new URL(link);\n    const subscriptionToken = url.searchParams.get(\"subscription_token\");\n    if (subscriptionToken === undefined || subscriptionToken === null || subscriptionToken === \"\")\n      return undefined;\n    const parts = subscriptionToken.split(\".\");\n    if (parts.length < 2) return undefined;\n    const payloadJson = decodeBase64UrlToString(parts[1] ?? \"\");\n    const payload = JSON.parse(payloadJson) as Record<string, unknown>;\n    return typeof payload.email_token === \"string\" ? payload.email_token : undefined;\n  } catch {\n    return undefined;\n  }\n}\n","import type { GenericEndpointContext } from \"better-auth\";\n\nexport function getWebhookRequest(ctx: GenericEndpointContext): Request | undefined {\n  return (\n    (ctx as unknown as { requestClone?: Request }).requestClone ??\n    (ctx as { request?: Request }).request\n  );\n}\n\nexport function getWebhookHeaders(ctx: GenericEndpointContext): Headers | undefined {\n  return (\n    (ctx as GenericEndpointContext & { headers?: Headers }).headers ??\n    (ctx.request as unknown as { headers?: Headers })?.headers\n  );\n}\n\nexport function getWebhookClientIP(\n  ctx: GenericEndpointContext,\n  headers: Headers | undefined,\n): string | undefined {\n  return (\n    headers?.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ??\n    headers?.get(\"x-real-ip\") ??\n    (ctx.request as unknown as { ip?: string }).ip\n  );\n}\n","import { defineErrorCodes } from \"better-auth\";\nimport type { RawError } from \"better-auth\";\n\nimport type { AnyPaystackOptions, PaystackCheckoutChannel } from \"../types\";\n\nexport const PAYSTACK_ERROR_CODES: {\n  SUBSCRIPTION_NOT_FOUND: RawError<\"SUBSCRIPTION_NOT_FOUND\">;\n  SUBSCRIPTION_PLAN_NOT_FOUND: RawError<\"SUBSCRIPTION_PLAN_NOT_FOUND\">;\n  UNABLE_TO_CREATE_CUSTOMER: RawError<\"UNABLE_TO_CREATE_CUSTOMER\">;\n  FAILED_TO_INITIALIZE_TRANSACTION: RawError<\"FAILED_TO_INITIALIZE_TRANSACTION\">;\n  FAILED_TO_VERIFY_TRANSACTION: RawError<\"FAILED_TO_VERIFY_TRANSACTION\">;\n  FAILED_TO_DISABLE_SUBSCRIPTION: RawError<\"FAILED_TO_DISABLE_SUBSCRIPTION\">;\n  FAILED_TO_ENABLE_SUBSCRIPTION: RawError<\"FAILED_TO_ENABLE_SUBSCRIPTION\">;\n  EMAIL_VERIFICATION_REQUIRED: RawError<\"EMAIL_VERIFICATION_REQUIRED\">;\n  SUBSCRIPTION_PAYMENT_CHANNEL_NOT_ALLOWED: RawError<\"SUBSCRIPTION_PAYMENT_CHANNEL_NOT_ALLOWED\">;\n} = defineErrorCodes({\n  SUBSCRIPTION_NOT_FOUND: \"Subscription not found\",\n  SUBSCRIPTION_PLAN_NOT_FOUND: \"Subscription plan not found\",\n  UNABLE_TO_CREATE_CUSTOMER: \"Unable to create customer\",\n  FAILED_TO_INITIALIZE_TRANSACTION: \"Failed to initialize transaction\",\n  FAILED_TO_VERIFY_TRANSACTION: \"Failed to verify transaction\",\n  FAILED_TO_DISABLE_SUBSCRIPTION: \"Failed to disable subscription\",\n  FAILED_TO_ENABLE_SUBSCRIPTION: \"Failed to enable subscription\",\n  EMAIL_VERIFICATION_REQUIRED: \"Email verification is required before you can subscribe to a plan\",\n  SUBSCRIPTION_PAYMENT_CHANNEL_NOT_ALLOWED:\n    \"This subscription only supports specific payment channels\",\n});\n\nexport function getAllowedSubscriptionChannels(\n  options: AnyPaystackOptions,\n): PaystackCheckoutChannel[] | undefined {\n  const channels = options.subscription?.allowedPaymentChannels;\n  return Array.isArray(channels) && channels.length > 0 ? channels : undefined;\n}\n\nexport async function hmacSha512Hex(secret: string, message: string): Promise<string> {\n  const encoder = new TextEncoder();\n  const keyData = encoder.encode(secret);\n  const msgData = encoder.encode(message);\n\n  const crypto = globalThis.crypto;\n  if (crypto !== undefined && crypto !== null && \"subtle\" in crypto) {\n    const subtle = crypto.subtle;\n    const key = await subtle.importKey(\"raw\", keyData, { name: \"HMAC\", hash: \"SHA-512\" }, false, [\n      \"sign\",\n    ]);\n    const signature = await subtle.sign(\"HMAC\", key, msgData);\n    return Array.from(new Uint8Array(signature))\n      .map((b) => b.toString(16).padStart(2, \"0\"))\n      .join(\"\");\n  }\n\n  const { createHmac } = await import(\"node:crypto\");\n  return createHmac(\"sha512\", secret).update(message).digest(\"hex\");\n}\n","import { HIDE_METADATA } from \"better-auth\";\nimport { APIError, getSessionFromCtx, originCheck, sessionMiddleware } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/api\";\n/* oxlint-disable no-restricted-imports */\nimport { z } from \"zod\";\nimport type { components } from \"@alexasomba/paystack-node\";\nimport type {\n  GenericEndpointContext,\n  MiddlewareInputContext,\n  MiddlewareOptions,\n  StrictEndpoint,\n} from \"better-auth\";\n\nimport type {\n  InputPaystackProduct,\n  PaystackTransaction,\n  AnyPaystackOptions,\n  PaystackProduct,\n  Subscription,\n  Member,\n  PaystackOrganization,\n  PaystackPlan,\n  PaystackWebhookPayload,\n  User,\n  PaystackUser,\n  PaystackCheckoutChannel,\n  PaystackInitializeResult,\n} from \"./types\";\nimport {\n  createCheckoutMetadata,\n  hasPaystackMetadata,\n  parsePaystackMetadata,\n  stringifyPaystackMetadata,\n} from \"./metadata\";\nimport {\n  syncProductQuantityFromPaystack,\n  getPlanByName,\n  getPlans,\n  getProductByName,\n  getPlanSeatAmount,\n  calculatePlanAmount,\n  isLocalSubscriptionCode,\n} from \"./utils\";\nimport { referenceMiddleware } from \"./middleware\";\nimport { authorizeBillingReference } from \"./reference-access\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk\";\nimport { createBillingStore } from \"./billing-store\";\nimport {\n  handleProratedUpgrade,\n  resolveCheckoutTargetEmail,\n  resolveTrialLifecycle,\n  scheduleSubscriptionLifecycleChange,\n} from \"./subscription-lifecycle\";\nimport { reconcilePaystackTransaction } from \"./reconciliation\";\nimport { initializeTransactionBodySchema } from \"./route-modules/checkout\";\nimport { getConfiguredCatalog, listStoredPlans, listStoredProducts } from \"./route-modules/catalog\";\nimport {\n  enableDisableBodySchema,\n  tryGetEmailTokenFromSubscriptionManageLink,\n} from \"./route-modules/subscriptions\";\nimport { getWebhookClientIP, getWebhookHeaders, getWebhookRequest } from \"./route-modules/webhook\";\nimport {\n  getAllowedSubscriptionChannels,\n  hmacSha512Hex,\n  PAYSTACK_ERROR_CODES,\n} from \"./route-modules/shared\";\n\nexport const paystackWebhook = <P extends string = \"/webhook\">(\n  options: AnyPaystackOptions,\n  path: P = \"/webhook\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    metadata: {\n      openapi: {\n        operationId: string;\n      };\n      scope: \"server\";\n    };\n    cloneRequest: true;\n    disableBody: true;\n  },\n  {\n    received: boolean;\n  }\n> => {\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"POST\",\n      metadata: {\n        ...HIDE_METADATA,\n        openapi: {\n          operationId: \"handlePaystackWebhook\",\n        },\n      },\n      cloneRequest: true,\n      disableBody: true,\n    },\n    async (ctx) => {\n      const request = getWebhookRequest(ctx as GenericEndpointContext);\n      if (request === undefined || request === null) {\n        throw new APIError(\"BAD_REQUEST\", {\n          message: \"Request object is missing from context\",\n        });\n      }\n      const payload = await request.text();\n      const headers = getWebhookHeaders(ctx as GenericEndpointContext);\n      const signature = headers?.get(\"x-paystack-signature\");\n\n      if (options.webhook?.verifyIP === true) {\n        const trustedIPs = options.webhook.trustedIPs ?? [\n          \"52.31.139.75\",\n          \"52.49.173.169\",\n          \"52.214.14.220\",\n        ];\n        const clientIP = getWebhookClientIP(ctx as GenericEndpointContext, headers);\n\n        if (\n          clientIP !== undefined &&\n          clientIP !== null &&\n          trustedIPs.includes(clientIP) === false\n        ) {\n          throw new APIError(\"UNAUTHORIZED\", {\n            message: `Forbidden IP: ${clientIP}`,\n            status: 401,\n          });\n        }\n      }\n\n      if (signature === undefined || signature === null || signature === \"\") {\n        throw new APIError(\"UNAUTHORIZED\", {\n          message: \"Missing x-paystack-signature header\",\n          status: 401,\n        });\n      }\n\n      const webhookSecret =\n        options.webhook?.secret ?? options.paystackWebhookSecret ?? options.secretKey;\n      const expected = await hmacSha512Hex(webhookSecret, payload);\n      if (expected !== signature) {\n        throw new APIError(\"UNAUTHORIZED\", {\n          message: \"Invalid Paystack webhook signature\",\n          status: 401,\n        });\n      }\n\n      const event = JSON.parse(payload) as PaystackWebhookPayload;\n      const eventName = event.event;\n      const data = event.data;\n\n      // Core Transaction Status Sync (Applies to both one-time and recurring)\n      if (eventName === \"charge.success\") {\n        const reference = (data as { reference?: string | null })?.reference;\n        const paystackIdRaw = (data as { id?: number | string | null })?.id;\n        const paystackId =\n          paystackIdRaw !== undefined && paystackIdRaw !== null ? String(paystackIdRaw) : undefined;\n\n        if (reference !== undefined && reference !== null && reference !== \"\") {\n          try {\n            await ctx.context.adapter.update({\n              model: \"paystackTransaction\",\n              update: {\n                status: \"success\",\n                paystackId,\n                updatedAt: new Date(),\n              },\n              where: [{ field: \"reference\", value: reference }],\n            });\n          } catch (e) {\n            ctx.context.logger.warn(\"Failed to update transaction status for charge.success\", e);\n          }\n\n          // Sync product quantity from Paystack after successful charge\n          try {\n            const transaction = await ctx.context.adapter.findOne<PaystackTransaction>({\n              model: \"paystackTransaction\",\n              where: [{ field: \"reference\", value: reference }],\n            });\n            if (\n              transaction !== undefined &&\n              transaction !== null &&\n              transaction.product !== undefined &&\n              transaction.product !== null &&\n              transaction.product !== \"\"\n            ) {\n              if (options.paystackClient !== undefined && options.paystackClient !== null) {\n                await syncProductQuantityFromPaystack(\n                  ctx,\n                  transaction.product,\n                  options.paystackClient,\n                );\n              }\n            }\n          } catch (e) {\n            ctx.context.logger.warn(\"Failed to sync product quantity\", e);\n          }\n        }\n      }\n\n      if ((eventName as string) === \"charge.failure\") {\n        const reference = (data as { reference?: string })?.reference;\n        if (reference !== undefined && reference !== null && reference !== \"\") {\n          try {\n            await ctx.context.adapter.update({\n              model: \"paystackTransaction\",\n              update: {\n                status: \"failed\",\n                updatedAt: new Date(),\n              },\n              where: [{ field: \"reference\", value: reference }],\n            });\n          } catch (e) {\n            ctx.context.logger.warn(\"Failed to update transaction status for charge.failure\", e);\n          }\n        }\n      }\n\n      // Best-effort local state sync for subscription lifecycle.\n      if (options.subscription?.enabled === true) {\n        try {\n          if (eventName === \"subscription.create\") {\n            const subscriptionData =\n              data as unknown as components[\"schemas\"][\"SubscriptionListResponseArray\"];\n            const subscriptionCode = subscriptionData.subscription_code ?? \"\";\n            const customerCode = (\n              subscriptionData.customer as { customer_code?: string | null } | undefined\n            )?.customer_code;\n            const planCode = (subscriptionData.plan as { plan_code?: string | null } | undefined)\n              ?.plan_code;\n\n            const metadataObj = parsePaystackMetadata(\n              (subscriptionData as unknown as { metadata?: unknown }).metadata,\n            );\n            const referenceIdFromMetadata =\n              typeof metadataObj.referenceId === \"string\" ? metadataObj.referenceId : undefined;\n            let planNameFromMetadata =\n              typeof metadataObj.plan === \"string\" ? metadataObj.plan : undefined;\n            if (typeof planNameFromMetadata === \"string\") {\n              planNameFromMetadata = planNameFromMetadata.toLowerCase();\n            }\n\n            const plans = await getPlans(options.subscription);\n            const planFromCode =\n              planCode !== undefined && planCode !== null && planCode !== \"\"\n                ? plans.find((p) => p.planCode === planCode)\n                : undefined;\n            const planPart = planFromCode?.name ?? planNameFromMetadata;\n            const planName =\n              planPart !== undefined && planPart !== null && planPart !== \"\"\n                ? planPart.toLowerCase()\n                : undefined;\n\n            if (\n              subscriptionCode !== undefined &&\n              subscriptionCode !== null &&\n              subscriptionCode !== \"\"\n            ) {\n              const where: { field: string; value: string | number | boolean | null }[] = [];\n              if (\n                referenceIdFromMetadata !== undefined &&\n                referenceIdFromMetadata !== null &&\n                referenceIdFromMetadata !== \"\"\n              ) {\n                where.push({ field: \"referenceId\", value: referenceIdFromMetadata });\n              } else if (\n                customerCode !== undefined &&\n                customerCode !== null &&\n                customerCode !== \"\"\n              ) {\n                where.push({ field: \"paystackCustomerCode\", value: customerCode });\n              }\n              if (planName !== undefined && planName !== null && planName !== \"\") {\n                where.push({ field: \"plan\", value: planName });\n              }\n\n              if (where.length > 0) {\n                const matches = await ctx.context.adapter.findMany<Subscription>({\n                  model: \"subscription\",\n                  where: where as unknown as {\n                    field: string;\n                    value: string | number | boolean | null;\n                  }[],\n                });\n                const subscription = matches?.[0];\n                if (subscription !== undefined && subscription !== null) {\n                  await ctx.context.adapter.update({\n                    model: \"subscription\",\n                    update: {\n                      paystackSubscriptionCode: subscriptionCode,\n                      status: \"active\",\n                      updatedAt: new Date(),\n                      periodEnd:\n                        subscriptionData.next_payment_date !== undefined &&\n                        subscriptionData.next_payment_date !== null\n                          ? new Date(subscriptionData.next_payment_date)\n                          : undefined,\n                    },\n                    where: [{ field: \"id\", value: subscription.id }],\n                  });\n\n                  const plan =\n                    planFromCode ??\n                    (planName !== undefined && planName !== null && planName !== \"\"\n                      ? await getPlanByName(options, planName)\n                      : undefined);\n                  if (plan !== undefined && plan !== null) {\n                    await options.subscription.onSubscriptionComplete?.(\n                      {\n                        event,\n                        subscription: {\n                          ...subscription,\n                          paystackSubscriptionCode: subscriptionCode,\n                          status: \"active\",\n                        },\n                        plan,\n                      },\n                      ctx as GenericEndpointContext,\n                    );\n                    await options.subscription.onSubscriptionCreated?.(\n                      {\n                        event,\n                        subscription: {\n                          ...subscription,\n                          paystackSubscriptionCode: subscriptionCode,\n                          status: \"active\",\n                        },\n                        plan,\n                      },\n                      ctx as GenericEndpointContext,\n                    );\n                  }\n                }\n              }\n            }\n          }\n\n          if (eventName === \"subscription.disable\" || eventName === \"subscription.not_renew\") {\n            const subscriptionData =\n              data as unknown as components[\"schemas\"][\"SubscriptionListResponseArray\"];\n            const subscriptionCode = subscriptionData.subscription_code ?? \"\";\n            if (subscriptionCode !== \"\") {\n              const existing = await ctx.context.adapter.findOne<Subscription>({\n                model: \"subscription\",\n                where: [{ field: \"paystackSubscriptionCode\", value: subscriptionCode }],\n              });\n\n              let newStatus = \"canceled\";\n              const nextPaymentDate = subscriptionData.next_payment_date;\n              const periodEnd =\n                nextPaymentDate !== undefined && nextPaymentDate !== null && nextPaymentDate !== \"\"\n                  ? new Date(nextPaymentDate)\n                  : existing?.periodEnd !== undefined && existing.periodEnd !== null\n                    ? new Date(existing.periodEnd)\n                    : undefined;\n\n              if (periodEnd !== undefined && periodEnd.getTime() > Date.now()) {\n                newStatus = \"active\";\n              }\n\n              await ctx.context.adapter.update({\n                model: \"subscription\",\n                update: {\n                  status: newStatus,\n                  cancelAtPeriodEnd: true,\n                  ...(periodEnd ? { periodEnd } : {}),\n                  updatedAt: new Date(),\n                },\n                where: [{ field: \"paystackSubscriptionCode\", value: subscriptionCode }],\n              });\n\n              if (existing !== null && existing !== undefined) {\n                await options.subscription.onSubscriptionCancel?.(\n                  { event, subscription: { ...existing, status: \"canceled\" } as Subscription },\n                  ctx as GenericEndpointContext,\n                );\n              }\n            }\n          }\n\n          // Handle plan changes on renewal\n          if (eventName === \"charge.success\" || eventName === \"invoice.update\") {\n            const subData = (data as { subscription?: { subscription_code?: string | null } })\n              ?.subscription;\n            const subscriptionCodeRaw =\n              subData?.subscription_code ??\n              (data as { subscription_code?: string | null })?.subscription_code;\n            const subscriptionCode =\n              subscriptionCodeRaw !== undefined &&\n              subscriptionCodeRaw !== null &&\n              subscriptionCodeRaw !== \"\"\n                ? subscriptionCodeRaw\n                : undefined;\n\n            if (subscriptionCode !== undefined) {\n              const existingSub = await ctx.context.adapter.findOne<Subscription>({\n                model: \"subscription\",\n                where: [{ field: \"paystackSubscriptionCode\", value: subscriptionCode }],\n              });\n\n              if (\n                existingSub !== undefined &&\n                existingSub !== null &&\n                existingSub.pendingPlan !== undefined &&\n                existingSub.pendingPlan !== null &&\n                existingSub.pendingPlan !== \"\"\n              ) {\n                await ctx.context.adapter.update({\n                  model: \"subscription\",\n                  update: {\n                    plan: existingSub.pendingPlan,\n                    pendingPlan: null,\n                    updatedAt: new Date(),\n                  },\n                  where: [{ field: \"id\", value: existingSub.id }],\n                });\n              }\n            }\n          }\n        } catch (_e: unknown) {\n          ctx.context.logger.error(\"Failed to sync Paystack webhook event\", _e);\n        }\n      }\n\n      await options.onEvent?.(event);\n      return ctx.json({ received: true });\n    },\n  );\n};\n\nexport const initializeTransaction = <P extends string = \"/initialize-transaction\">(\n  options: AnyPaystackOptions,\n  path: P = \"/initialize-transaction\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        plan: z.ZodOptional<z.ZodString>;\n        product: z.ZodOptional<z.ZodString>;\n        amount: z.ZodOptional<z.ZodNumber>;\n        currency: z.ZodOptional<z.ZodString>;\n        email: z.ZodOptional<z.ZodString>;\n        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;\n        referenceId: z.ZodOptional<z.ZodString>;\n        callbackURL: z.ZodOptional<z.ZodString>;\n        quantity: z.ZodOptional<z.ZodNumber>;\n        scheduleAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n        cancelAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n        prorateAndCharge: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  PaystackInitializeResult | undefined\n> => {\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares =\n    subscriptionOptions?.enabled === true\n      ? [sessionMiddleware, originCheck, referenceMiddleware(options, \"initialize-transaction\")]\n      : [sessionMiddleware, originCheck];\n\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"POST\",\n      body: initializeTransactionBodySchema,\n      use: useMiddlewares,\n    },\n    async (ctx) => {\n      const paystack = getPaystackOps(options.paystackClient);\n      const {\n        plan: planName,\n        product: productName,\n        amount: bodyAmount,\n        currency,\n        email,\n        metadata: extraMetadata,\n        callbackURL,\n        quantity,\n        scheduleAtPeriodEnd,\n        cancelAtPeriodEnd,\n        prorateAndCharge,\n      } = ctx.body;\n\n      // 1. Validate Callback URL validation (same as before)\n      if (callbackURL !== undefined && callbackURL !== null && callbackURL !== \"\") {\n        const checkTrusted = () => {\n          try {\n            if ((callbackURL as string | undefined)?.startsWith(\"/\") === true) return true;\n            const baseUrl =\n              ((ctx.context as Record<string, unknown>)?.baseURL as string | undefined) ??\n              (ctx.request as unknown as { url?: string })?.url ??\n              \"\";\n            if (baseUrl === \"\") return false;\n            const baseOrigin = new URL(baseUrl).origin;\n            return new URL(callbackURL).origin === baseOrigin;\n          } catch {\n            return false;\n          }\n        };\n        if (checkTrusted() === false) {\n          throw new APIError(\"FORBIDDEN\", {\n            message: \"callbackURL is not a trusted origin.\",\n            status: 403,\n          });\n        }\n      }\n\n      // 2. Get User & Session\n      const session = await getSessionFromCtx(ctx);\n      if (session === undefined || session === null) throw new APIError(\"UNAUTHORIZED\");\n      const user = session.user;\n\n      // 3. Email Verification Check (only if subscription options enforce it)\n      if (\n        subscriptionOptions?.enabled === true &&\n        subscriptionOptions.requireEmailVerification === true &&\n        user.emailVerified !== true\n      ) {\n        throw new APIError(\"BAD_REQUEST\", {\n          code: \"EMAIL_VERIFICATION_REQUIRED\",\n          message: PAYSTACK_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED.message,\n        });\n      }\n\n      // 4. Determine Payment Mode: Subscription (Plan) vs Product vs One-Time (Amount)\n      let plan: PaystackPlan | undefined;\n      let product: PaystackProduct | InputPaystackProduct | undefined;\n\n      if (planName !== undefined && planName !== null && planName !== \"\") {\n        if (subscriptionOptions?.enabled !== true) {\n          throw new APIError(\"BAD_REQUEST\", { message: \"Subscriptions are not enabled.\" });\n        }\n        plan = (await getPlanByName(options, planName)) ?? undefined;\n        if (plan === undefined || plan === null) {\n          try {\n            // Fallback: Check database for synced plans when that model exists.\n            const nativePlan = await ctx.context.adapter.findOne<PaystackPlan>({\n              model: \"paystackPlan\",\n              where: [{ field: \"name\", value: planName }],\n            });\n            if (nativePlan !== undefined && nativePlan !== null) {\n              plan = nativePlan;\n            } else {\n              const nativePlanByCode = await ctx.context.adapter.findOne<PaystackPlan>({\n                model: \"paystackPlan\",\n                where: [{ field: \"planCode\", value: planName }],\n              });\n              plan = nativePlanByCode ?? undefined;\n            }\n          } catch {\n            plan = undefined;\n          }\n        }\n        if (plan === undefined || plan === null) {\n          throw new APIError(\"BAD_REQUEST\", {\n            code: \"SUBSCRIPTION_PLAN_NOT_FOUND\",\n            message: PAYSTACK_ERROR_CODES.SUBSCRIPTION_PLAN_NOT_FOUND.message,\n            status: 400,\n          });\n        }\n      } else if (productName !== undefined && productName !== null && productName !== \"\") {\n        if (typeof productName === \"string\") {\n          product = (await getProductByName(options, productName)) ?? undefined;\n          // Fallback: Check database for synced products\n          product ??=\n            (await ctx.context.adapter.findOne<PaystackProduct>({\n              model: \"paystackProduct\",\n              where: [{ field: \"name\", value: productName }],\n            })) ?? undefined;\n        }\n        if (product === undefined || product === null) {\n          throw new APIError(\"BAD_REQUEST\", {\n            message: `Product '${productName}' not found.`,\n            status: 400,\n          });\n        }\n      } else if (bodyAmount === undefined || bodyAmount === null) {\n        throw new APIError(\"BAD_REQUEST\", {\n          message: \"Either 'plan', 'product', or 'amount' is required to initialize a transaction.\",\n          status: 400,\n        });\n      }\n\n      let amount =\n        bodyAmount ??\n        (product as PaystackProduct)?.price ??\n        (product as InputPaystackProduct)?.amount;\n      const finalCurrency =\n        currency ??\n        (product as PaystackProduct)?.currency ??\n        (product as InputPaystackProduct)?.currency ??\n        plan?.currency ??\n        \"NGN\";\n\n      const referenceIdFromCtx = (ctx.context as Record<string, unknown>).referenceId as\n        | string\n        | undefined;\n      const referenceId =\n        ctx.body.referenceId ?? referenceIdFromCtx ?? (session.user as { id: string }).id;\n\n      const scheduledChange = await scheduleSubscriptionLifecycleChange(ctx, {\n        referenceId,\n        plan,\n        scheduleAtPeriodEnd,\n        cancelAtPeriodEnd,\n      });\n      if (scheduledChange !== null) {\n        return ctx.json(scheduledChange);\n      }\n\n      // Calculate final amount considering seats if applicable\n      if (plan !== undefined) {\n        try {\n          if (getPlanSeatAmount(plan) !== undefined) {\n            const members = await ctx.context.adapter.findMany<Member>({\n              model: \"member\",\n              where: [{ field: \"organizationId\", value: referenceId }],\n            });\n            const seatCount = members.length > 0 ? members.length : 1;\n            const quantityToUse = quantity ?? seatCount;\n            amount = calculatePlanAmount(plan, quantityToUse);\n          }\n        } catch (error: unknown) {\n          throw new APIError(\"BAD_REQUEST\", {\n            message:\n              error instanceof Error ? error.message : \"Invalid seat configuration for plan.\",\n          });\n        }\n      }\n\n      let url: string | undefined;\n      let reference: string | undefined;\n      let accessCode: string | undefined;\n\n      const trial = await resolveTrialLifecycle(ctx, { referenceId, plan });\n      const { trialStart, trialEnd } = trial;\n\n      try {\n        const targetEmail = await resolveCheckoutTargetEmail(ctx, options, {\n          email,\n          referenceId,\n          user: user as User,\n        });\n\n        const allowedSubscriptionChannels = plan\n          ? getAllowedSubscriptionChannels(options)\n          : undefined;\n\n        // Construct Metadata\n        const metadata = stringifyPaystackMetadata(\n          createCheckoutMetadata({\n            referenceId,\n            userId: user.id,\n            plan: plan !== undefined ? plan.name.toLowerCase() : undefined,\n            product: product !== undefined ? product.name.toLowerCase() : undefined,\n            extra: extraMetadata,\n            trial: {\n              isTrial: trialStart !== undefined,\n              requested: trial.requested,\n              granted: trial.granted,\n              deniedReason: trial.deniedReason,\n              endsAt: trialEnd,\n            },\n          }),\n        );\n\n        const initBody: {\n          email: string;\n          callback_url?: string;\n          metadata?: string;\n          currency: string;\n          quantity?: number;\n          amount?: number;\n          plan?: string;\n          channels?: PaystackCheckoutChannel[];\n          [key: string]: unknown;\n        } = {\n          email: targetEmail,\n          callback_url: callbackURL ?? undefined,\n          metadata,\n          // If plan/product exists, use its currency; otherwise fallback to provided or default\n          currency: finalCurrency,\n          quantity,\n        };\n\n        if (allowedSubscriptionChannels !== undefined) {\n          initBody.channels = allowedSubscriptionChannels;\n        }\n\n        // Handle prorateAndCharge for existing active subscriptions\n        if (plan !== undefined && prorateAndCharge === true) {\n          const proration = await handleProratedUpgrade(ctx, options, {\n            plan,\n            referenceId,\n            quantity,\n            targetEmail,\n            userId: user.id,\n            finalCurrency,\n            callbackURL,\n            allowedSubscriptionChannels,\n          });\n\n          if (proration?.kind === \"checkout\") {\n            return ctx.json({\n              kind: \"checkout\",\n              url: proration.url ?? \"\",\n              reference: proration.reference ?? \"\",\n              accessCode: proration.accessCode ?? \"\",\n              redirect: proration.redirect,\n            } satisfies PaystackInitializeResult);\n          }\n\n          if (proration?.kind === \"prorated\") {\n            return ctx.json({\n              kind: \"prorated\",\n              status: proration.status,\n              message: proration.message,\n              prorated: proration.prorated,\n            } satisfies PaystackInitializeResult);\n          }\n        }\n\n        if (plan !== undefined) {\n          // Subscription Flow\n          if (trialStart !== undefined) {\n            // Trial Flow: Authorize card with minimum amount, don't start sub yet\n            initBody.amount = 5000; // 50 NGN (minimum allowed)\n          } else {\n            // Standard Flow\n            initBody.plan = plan.planCode;\n            // SDK might use different field names, but keeping DX consistency\n            (initBody as Record<string, unknown>).invoice_limit = plan.invoiceLimit;\n\n            let finalAmount: number;\n            if (amount !== undefined && amount !== null) {\n              finalAmount = amount;\n              initBody.quantity = 1;\n            } else {\n              finalAmount = (plan.amount ?? 0) * (quantity ?? 1);\n            }\n            initBody.amount = Math.max(Math.round(finalAmount), 5000);\n          }\n        } else {\n          // One-Time Payment Flow\n          if (amount === undefined || amount === null)\n            throw new APIError(\"BAD_REQUEST\", {\n              message: \"Amount is required for one-time payments\",\n            });\n          initBody.amount = Math.round(amount);\n        }\n\n        const initRaw = await paystack?.transaction?.initialize({\n          body: initBody as components[\"schemas\"][\"TransactionInitialize\"],\n        });\n        const sdkRes =\n          unwrapSdkResult<components[\"schemas\"][\"TransactionInitializeResponse\"][\"data\"]>(initRaw);\n\n        url = sdkRes?.authorization_url;\n        reference = sdkRes?.reference;\n        accessCode = sdkRes?.access_code;\n      } catch (error: unknown) {\n        ctx.context.logger.error(\"Failed to initialize Paystack transaction\", error);\n        const errorMessage =\n          error instanceof Error\n            ? error.message\n            : PAYSTACK_ERROR_CODES.FAILED_TO_INITIALIZE_TRANSACTION.message;\n        throw new APIError(\"BAD_REQUEST\", {\n          code: \"FAILED_TO_INITIALIZE_TRANSACTION\",\n          message: errorMessage,\n        });\n      }\n\n      // 6. Record Transaction & Subscription\n      await ctx.context.adapter.create({\n        model: \"paystackTransaction\",\n        data: {\n          reference: reference ?? \"\",\n          referenceId,\n          userId: user.id,\n          amount: amount ?? 0,\n          currency: plan?.currency ?? currency ?? \"NGN\",\n          status: \"pending\",\n          plan: plan !== undefined ? plan.name.toLowerCase() : undefined,\n          product: product !== undefined ? product.name.toLowerCase() : undefined,\n          metadata: hasPaystackMetadata(extraMetadata)\n            ? stringifyPaystackMetadata(extraMetadata)\n            : undefined,\n          createdAt: new Date(),\n          updatedAt: new Date(),\n        },\n      });\n\n      if (plan !== undefined) {\n        let storedCustomerCode = (user as PaystackUser).paystackCustomerCode;\n        if (options.organization?.enabled === true && referenceId !== user.id) {\n          const org = await ctx.context.adapter.findOne({\n            model: \"organization\",\n            where: [{ field: \"id\", value: referenceId }],\n          });\n          if (org !== undefined && org !== null) {\n            const paystackOrg = org as PaystackOrganization;\n            if (\n              paystackOrg.paystackCustomerCode !== undefined &&\n              paystackOrg.paystackCustomerCode !== null &&\n              paystackOrg.paystackCustomerCode !== \"\"\n            ) {\n              storedCustomerCode = paystackOrg.paystackCustomerCode;\n            }\n          }\n        }\n\n        const newSubscription = await ctx.context.adapter.create<Subscription>({\n          model: \"subscription\",\n          data: {\n            plan: plan.name.toLowerCase(),\n            referenceId,\n            userId: user.id,\n            paystackCustomerCode: storedCustomerCode ?? \"\",\n            paystackSubscriptionCode: \"\",\n            paystackPlanCode: plan.planCode,\n            paystackAuthorizationCode: \"\",\n            paystackTransactionReference: reference ?? \"\",\n            status: trialStart !== undefined ? \"trialing\" : \"incomplete\",\n            seats: quantity ?? 1,\n            periodStart: new Date(),\n            periodEnd: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // Default 30 days\n            cancelAtPeriodEnd: false,\n            trialStart,\n            trialEnd,\n            createdAt: new Date(),\n            updatedAt: new Date(),\n          },\n        });\n\n        // Call trial start hook if trial was granted\n        if (\n          trialStart !== undefined &&\n          newSubscription !== undefined &&\n          newSubscription !== null &&\n          plan.freeTrial?.onTrialStart !== undefined\n        ) {\n          await plan.freeTrial.onTrialStart(newSubscription);\n        }\n      }\n\n      return ctx.json({\n        kind: \"checkout\",\n        url: url ?? \"\",\n        reference: reference ?? \"\",\n        accessCode: accessCode ?? \"\",\n        redirect: true,\n      } satisfies PaystackInitializeResult);\n    },\n  );\n};\n\n// Aliases for Client DX Parity\nexport const createSubscription = <P extends string = \"/create-subscription\">(\n  options: AnyPaystackOptions,\n  path: P = \"/create-subscription\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        plan: z.ZodOptional<z.ZodString>;\n        product: z.ZodOptional<z.ZodString>;\n        amount: z.ZodOptional<z.ZodNumber>;\n        currency: z.ZodOptional<z.ZodString>;\n        email: z.ZodOptional<z.ZodString>;\n        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;\n        referenceId: z.ZodOptional<z.ZodString>;\n        callbackURL: z.ZodOptional<z.ZodString>;\n        quantity: z.ZodOptional<z.ZodNumber>;\n        scheduleAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n        cancelAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n        prorateAndCharge: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  PaystackInitializeResult | undefined\n> => initializeTransaction(options, path);\n\nexport const upgradeSubscription = <P extends string = \"/upgrade-subscription\">(\n  options: AnyPaystackOptions,\n  path: P = \"/upgrade-subscription\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        plan: z.ZodOptional<z.ZodString>;\n        product: z.ZodOptional<z.ZodString>;\n        amount: z.ZodOptional<z.ZodNumber>;\n        currency: z.ZodOptional<z.ZodString>;\n        email: z.ZodOptional<z.ZodString>;\n        metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;\n        referenceId: z.ZodOptional<z.ZodString>;\n        callbackURL: z.ZodOptional<z.ZodString>;\n        quantity: z.ZodOptional<z.ZodNumber>;\n        scheduleAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n        cancelAtPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n        prorateAndCharge: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  PaystackInitializeResult | undefined\n> => initializeTransaction(options, path);\n\nexport const cancelSubscription = <P extends string = \"/cancel-subscription\">(\n  options: AnyPaystackOptions,\n  path: P = \"/cancel-subscription\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        referenceId: z.ZodOptional<z.ZodString>;\n        subscriptionCode: z.ZodString;\n        emailToken: z.ZodOptional<z.ZodString>;\n        atPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    status: string;\n  }\n> => disablePaystackSubscription(options, path);\n\nexport const restoreSubscription = <P extends string = \"/restore-subscription\">(\n  options: AnyPaystackOptions,\n  path: P = \"/restore-subscription\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        referenceId: z.ZodOptional<z.ZodString>;\n        subscriptionCode: z.ZodString;\n        emailToken: z.ZodOptional<z.ZodString>;\n        atPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    status: string;\n  }\n> => enablePaystackSubscription(options, path);\n\nexport const verifyTransaction = <P extends string = \"/verify-transaction\">(\n  options: AnyPaystackOptions,\n  path: P = \"/verify-transaction\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        reference: z.ZodString;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    status: string;\n    reference: string;\n    data: {\n      id: number;\n      domain: string;\n      status: string;\n      reference: string;\n      receipt_number: string | null;\n      amount: number;\n      message: string | null;\n      gateway_response: string;\n      channel: string;\n      currency: string;\n      ip_address: string | null;\n      metadata: (string | Record<string, never> | number) | null;\n      log: {\n        start_time: number;\n        time_spent: number;\n        attempts: number;\n        errors: number;\n        success: boolean;\n        mobile: boolean;\n        input: unknown[];\n        history: {\n          type: string;\n          message: string;\n          time: number;\n        }[];\n      } | null;\n      fees: number | null;\n      fees_split: unknown;\n      authorization: {\n        authorization_code?: string;\n        bin?: string | null;\n        last4?: string;\n        exp_month?: string;\n        exp_year?: string;\n        channel?: string;\n        card_type?: string;\n        bank?: string;\n        country_code?: string;\n        brand?: string;\n        reusable?: boolean;\n        signature?: string;\n        account_name?: string | null;\n        receiver_bank_account_number?: string | null;\n        receiver_bank?: string | null;\n      };\n      customer: {\n        id: number;\n        first_name: string | null;\n        last_name: string | null;\n        email: string;\n        customer_code: string;\n        phone: string | null;\n        metadata: Record<string, never> | null;\n        risk_action: string;\n        international_format_phone?: string | null;\n      };\n      plan: (string | Record<string, never>) | null;\n      split: Record<string, never> | null;\n      order_id: unknown;\n      paidAt: string | null;\n      createdAt: string;\n      requested_amount: number;\n      pos_transaction_data: unknown;\n      source: unknown;\n      fees_breakdown: unknown;\n      connect: unknown;\n      transaction_date: string;\n      plan_object: {\n        id?: number;\n        name?: string;\n        plan_code?: string;\n        description?: unknown;\n        amount?: number;\n        interval?: string;\n        send_invoices?: boolean;\n        send_sms?: boolean;\n        currency?: string;\n      };\n      subaccount: Record<string, never> | null;\n    };\n  }\n> => {\n  const verifyBodySchema = z.object({\n    reference: z.string(),\n  });\n\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares =\n    subscriptionOptions?.enabled === true\n      ? [sessionMiddleware, originCheck, referenceMiddleware(options, \"verify-transaction\")]\n      : [sessionMiddleware, originCheck];\n\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"POST\",\n      body: verifyBodySchema,\n      use: useMiddlewares,\n    },\n    async (ctx) => {\n      const session = await getSessionFromCtx(ctx);\n      const result = await reconcilePaystackTransaction(ctx as GenericEndpointContext, options, {\n        reference: ctx.body.reference,\n        source: \"browser\",\n        actor:\n          session !== undefined && session !== null\n            ? {\n                user: session.user as User,\n                session: session.session,\n              }\n            : undefined,\n        throwOnError: true,\n      });\n\n      if (!result.ok || result.data === null) {\n        throw new APIError(\"BAD_REQUEST\", {\n          code: result.error?.code ?? \"FAILED_TO_VERIFY_TRANSACTION\",\n          message:\n            result.error?.message ?? PAYSTACK_ERROR_CODES.FAILED_TO_VERIFY_TRANSACTION.message,\n          status: result.error?.status,\n        });\n      }\n\n      return ctx.json({\n        status: result.status,\n        reference: result.reference,\n        data: result.data,\n      });\n    },\n  );\n};\n\nexport const listSubscriptions = <P extends string = \"/list-subscriptions\">(\n  options: AnyPaystackOptions,\n  path: P = \"/list-subscriptions\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"GET\";\n    query: z.ZodObject<\n      {\n        referenceId: z.ZodOptional<z.ZodString>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    subscriptions: Subscription[];\n  }\n> => {\n  const listQuerySchema = z.object({\n    referenceId: z.string().optional(),\n  });\n\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares =\n    subscriptionOptions?.enabled === true\n      ? [sessionMiddleware, originCheck, referenceMiddleware(options, \"list-subscriptions\")]\n      : [sessionMiddleware, originCheck];\n\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"GET\",\n      query: listQuerySchema,\n      use: useMiddlewares,\n    },\n    async (ctx) => {\n      if (subscriptionOptions?.enabled !== true) {\n        throw new APIError(\"BAD_REQUEST\", {\n          message: \"Subscriptions are not enabled in the Paystack options.\",\n        });\n      }\n      const session = await getSessionFromCtx(ctx);\n      if (session === undefined || session === null) throw new APIError(\"UNAUTHORIZED\");\n      const store = createBillingStore(ctx);\n      const referenceIdPart = (ctx.context as Record<string, unknown>).referenceId as\n        | string\n        | undefined;\n      const queryRefId =\n        ctx.query?.referenceId ??\n        (typeof ctx.request?.url === \"string\"\n          ? (new URL(ctx.request.url).searchParams.get(\"referenceId\") ?? undefined)\n          : undefined);\n      const userId = (session.user as { id: string }).id;\n      if (queryRefId !== undefined && queryRefId !== userId && referenceIdPart !== queryRefId) {\n        await authorizeBillingReference(ctx, options, {\n          user: session.user as User,\n          session: session.session,\n          referenceId: queryRefId,\n          action: \"list-subscriptions\",\n        });\n      }\n      const referenceId = queryRefId ?? referenceIdPart ?? userId;\n      const res = await store.findSubscriptionsByReference(referenceId);\n      return ctx.json({ subscriptions: res });\n    },\n  );\n};\n\nexport const listTransactions = <P extends string = \"/list-transactions\">(\n  options: AnyPaystackOptions,\n  path: P = \"/list-transactions\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"GET\";\n    query: z.ZodObject<\n      {\n        referenceId: z.ZodOptional<z.ZodString>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    transactions: PaystackTransaction[];\n  }\n> => {\n  const listQuerySchema = z.object({\n    referenceId: z.string().optional(),\n  });\n\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares =\n    subscriptionOptions?.enabled === true\n      ? [sessionMiddleware, originCheck, referenceMiddleware(options, \"list-transactions\")]\n      : [sessionMiddleware, originCheck];\n\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"GET\",\n      query: listQuerySchema,\n      use: useMiddlewares,\n    },\n    async (ctx) => {\n      const session = await getSessionFromCtx(ctx);\n      if (session === undefined || session === null) throw new APIError(\"UNAUTHORIZED\");\n      const store = createBillingStore(ctx);\n      const referenceIdPart = (ctx.context as Record<string, unknown>).referenceId as\n        | string\n        | undefined;\n      const queryRefId =\n        ctx.query?.referenceId ??\n        (typeof ctx.request?.url === \"string\"\n          ? (new URL(ctx.request.url).searchParams.get(\"referenceId\") ?? undefined)\n          : undefined);\n      const userId = (session.user as { id: string }).id;\n      if (queryRefId !== undefined && queryRefId !== userId && referenceIdPart !== queryRefId) {\n        await authorizeBillingReference(ctx, options, {\n          user: session.user as User,\n          session: session.session,\n          referenceId: queryRefId,\n          action: \"list-transactions\",\n        });\n      }\n      const referenceId = queryRefId ?? referenceIdPart ?? userId;\n      const transactions = await store.listTransactions(referenceId);\n      return ctx.json({ transactions });\n    },\n  );\n};\n\nexport const disablePaystackSubscription = <P extends string = \"/disable-subscription\">(\n  options: AnyPaystackOptions,\n  path: P = \"/disable-subscription\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        referenceId: z.ZodOptional<z.ZodString>;\n        subscriptionCode: z.ZodString;\n        emailToken: z.ZodOptional<z.ZodString>;\n        atPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    status: string;\n  }\n> => {\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares =\n    subscriptionOptions?.enabled === true\n      ? [sessionMiddleware, originCheck, referenceMiddleware(options, \"disable-subscription\")]\n      : [sessionMiddleware, originCheck];\n\n  return createAuthEndpoint(\n    path,\n    { method: \"POST\", body: enableDisableBodySchema, use: useMiddlewares },\n    async (ctx) => {\n      const { subscriptionCode, atPeriodEnd } = ctx.body;\n      const paystack = getPaystackOps(options.paystackClient);\n      try {\n        const subCode = subscriptionCode;\n        if (isLocalSubscriptionCode(subCode)) {\n          const sub = await ctx.context.adapter.findOne<Subscription>({\n            model: \"subscription\",\n            where: [{ field: \"paystackSubscriptionCode\", value: subscriptionCode }],\n          });\n\n          if (sub !== null && sub !== undefined) {\n            await ctx.context.adapter.update({\n              model: \"subscription\",\n              update: {\n                status: atPeriodEnd === false ? \"canceled\" : \"active\",\n                cancelAtPeriodEnd: atPeriodEnd !== false,\n                updatedAt: new Date(),\n              },\n              where: [{ field: \"id\", value: sub.id }],\n            });\n            return ctx.json({ status: \"success\" });\n          }\n          throw new APIError(\"BAD_REQUEST\", { message: \"Subscription not found\" });\n        }\n\n        let emailToken = ctx.body.emailToken;\n        let nextPaymentDate: string | undefined;\n\n        try {\n          const raw = await paystack?.subscription?.fetch(subscriptionCode);\n          const fetchRes =\n            unwrapSdkResult<components[\"schemas\"][\"SubscriptionListResponseArray\"]>(raw);\n\n          if (fetchRes !== undefined && fetchRes !== null) {\n            emailToken ??= fetchRes.email_token ?? undefined;\n            nextPaymentDate = fetchRes.next_payment_date ?? undefined;\n          }\n        } catch {\n          // ignore fetch failure\n        }\n\n        if (emailToken === undefined || emailToken === null || emailToken === \"\") {\n          try {\n            const raw = await paystack?.subscription?.manageLink(subscriptionCode);\n            const linkRes = unwrapSdkResult<{ link: string }>(raw);\n            const link = linkRes?.link;\n            if (link !== undefined && link !== null && link !== \"\") {\n              emailToken = tryGetEmailTokenFromSubscriptionManageLink(link);\n            }\n          } catch {\n            // ignore\n          }\n        }\n\n        if (emailToken === undefined || emailToken === null || emailToken === \"\") {\n          throw new Error(\"Could not retrieve email_token for subscription disable.\");\n        }\n\n        await paystack?.subscription?.disable({\n          body: { code: subscriptionCode, token: emailToken },\n        });\n\n        const periodEnd =\n          nextPaymentDate !== undefined && nextPaymentDate !== null && nextPaymentDate !== \"\"\n            ? new Date(nextPaymentDate)\n            : undefined;\n\n        const sub = await ctx.context.adapter.findOne<Subscription>({\n          model: \"subscription\",\n          where: [{ field: \"paystackSubscriptionCode\", value: subscriptionCode }],\n        });\n\n        if (sub !== undefined && sub !== null) {\n          await ctx.context.adapter.update({\n            model: \"subscription\",\n            update: {\n              status: atPeriodEnd === false ? \"canceled\" : \"active\",\n              cancelAtPeriodEnd: atPeriodEnd !== false,\n              periodEnd,\n              updatedAt: new Date(),\n            },\n            where: [{ field: \"id\", value: sub.id }],\n          });\n        } else {\n          ctx.context.logger.warn(\n            `Could not find subscription with code ${subscriptionCode} to disable`,\n          );\n        }\n\n        return ctx.json({ status: \"success\" });\n      } catch (error: unknown) {\n        ctx.context.logger.error(\"Failed to disable subscription\", error);\n        const errorMessage =\n          error instanceof Error\n            ? error.message\n            : PAYSTACK_ERROR_CODES.FAILED_TO_DISABLE_SUBSCRIPTION.message;\n        throw new APIError(\"BAD_REQUEST\", {\n          code: \"FAILED_TO_DISABLE_SUBSCRIPTION\",\n          message: errorMessage,\n        });\n      }\n    },\n  );\n};\n\nexport const enablePaystackSubscription = <P extends string = \"/enable-subscription\">(\n  options: AnyPaystackOptions,\n  path: P = \"/enable-subscription\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"POST\";\n    body: z.ZodObject<\n      {\n        referenceId: z.ZodOptional<z.ZodString>;\n        subscriptionCode: z.ZodString;\n        emailToken: z.ZodOptional<z.ZodString>;\n        atPeriodEnd: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    status: string;\n  }\n> => {\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares =\n    subscriptionOptions?.enabled === true\n      ? [sessionMiddleware, originCheck, referenceMiddleware(options, \"enable-subscription\")]\n      : [sessionMiddleware, originCheck];\n\n  return createAuthEndpoint(\n    path,\n    { method: \"POST\", body: enableDisableBodySchema, use: useMiddlewares },\n    async (ctx) => {\n      const { subscriptionCode } = ctx.body;\n      const paystack = getPaystackOps(options.paystackClient);\n      try {\n        let emailToken = ctx.body.emailToken;\n        if (emailToken === undefined || emailToken === null || emailToken === \"\") {\n          try {\n            const raw = await paystack?.subscription?.fetch(subscriptionCode);\n            const fetchRes =\n              unwrapSdkResult<components[\"schemas\"][\"SubscriptionListResponseArray\"]>(raw);\n            if (fetchRes !== undefined && fetchRes !== null) {\n              emailToken = fetchRes.email_token ?? undefined;\n            }\n          } catch {\n            // ignore\n          }\n        }\n\n        if (emailToken === undefined || emailToken === null || emailToken === \"\") {\n          try {\n            const raw = await paystack?.subscription?.manageLink(subscriptionCode);\n            const linkRes = unwrapSdkResult<{ link: string }>(raw);\n            const link = linkRes?.link;\n            if (link !== undefined && link !== null && link !== \"\") {\n              emailToken = tryGetEmailTokenFromSubscriptionManageLink(link);\n            }\n          } catch {\n            // ignore\n          }\n        }\n\n        if (emailToken === undefined || emailToken === null || emailToken === \"\") {\n          throw new APIError(\"BAD_REQUEST\", {\n            message: \"Could not retrieve email_token for subscription enable.\",\n          });\n        }\n\n        await paystack?.subscription?.enable({\n          body: { code: subscriptionCode, token: emailToken },\n        });\n\n        // Update local status immediately\n        await ctx.context.adapter.update({\n          model: \"subscription\",\n          update: {\n            status: \"active\",\n            updatedAt: new Date(),\n          },\n          where: [{ field: \"paystackSubscriptionCode\", value: subscriptionCode }],\n        });\n\n        return ctx.json({ status: \"success\" });\n      } catch (error: unknown) {\n        ctx.context.logger.error(\"Failed to enable subscription\", error);\n        const errorMessage =\n          error instanceof Error\n            ? error.message\n            : PAYSTACK_ERROR_CODES.FAILED_TO_ENABLE_SUBSCRIPTION.message;\n        throw new APIError(\"BAD_REQUEST\", {\n          code: \"FAILED_TO_ENABLE_SUBSCRIPTION\",\n          message: errorMessage,\n        });\n      }\n    },\n  );\n};\n\nexport const getSubscriptionManageLink = <P extends string = \"/subscription-manage-link\">(\n  options: AnyPaystackOptions,\n  path: P = \"/subscription-manage-link\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"GET\";\n    query: z.ZodObject<\n      {\n        subscriptionCode: z.ZodString;\n      },\n      z.core.$strip\n    >;\n    use: (\n      | ((\n          getValue: (ctx: GenericEndpointContext) => string | string[],\n        ) => (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<void>)\n      | ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<unknown>)\n    )[];\n  },\n  {\n    link: string | null;\n  }\n> => {\n  const manageLinkQuerySchema = z.object({\n    subscriptionCode: z.string(),\n  });\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheck,\n          referenceMiddleware(options, \"get-subscription-manage-link\"),\n        ]\n      : [sessionMiddleware, originCheck];\n\n  const handler = async (ctx: GenericEndpointContext) => {\n    const { subscriptionCode } = ctx.query;\n\n    if (isLocalSubscriptionCode(subscriptionCode as string)) {\n      return ctx.json({ link: null, message: \"Local subscriptions cannot be managed on Paystack\" });\n    }\n\n    const paystack = getPaystackOps(options.paystackClient);\n    try {\n      const raw = await paystack?.subscription?.manageLink(subscriptionCode as string);\n      const res = unwrapSdkResult<{ link: string }>(raw);\n      return ctx.json({ link: res?.link || null });\n    } catch (error: unknown) {\n      ctx.context.logger.error(\"Failed to get subscription manage link\", error);\n      const errorMessage =\n        error instanceof Error ? error.message : \"Failed to get subscription manage link\";\n      throw new APIError(\"BAD_REQUEST\", {\n        message: errorMessage,\n      });\n    }\n  };\n\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"GET\",\n      query: manageLinkQuerySchema,\n      use: useMiddlewares,\n    },\n    handler,\n  );\n};\n\nexport const listProducts = <P extends string = \"/list-products\">(\n  _options: AnyPaystackOptions,\n  path: P = \"/list-products\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"GET\";\n    metadata: {\n      openapi: {\n        operationId: string;\n      };\n    };\n  },\n  {\n    products: PaystackProduct[];\n  }\n> => {\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"GET\",\n      metadata: {\n        openapi: {\n          operationId: \"listPaystackProducts\",\n        },\n      },\n    },\n    async (ctx) => {\n      const products = await listStoredProducts(ctx);\n      return ctx.json({ products });\n    },\n  );\n};\n\nexport const listPlans = <P extends string = \"/list-plans\">(\n  _options: AnyPaystackOptions,\n  path: P = \"/list-plans\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"GET\";\n    metadata: {\n      scope: \"server\";\n    };\n    use: ((inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<{\n      session: {\n        session: Record<string, unknown> & {\n          id: string;\n          createdAt: Date;\n          updatedAt: Date;\n          userId: string;\n          expiresAt: Date;\n          token: string;\n          ipAddress?: string | null | undefined;\n          userAgent?: string | null | undefined;\n        };\n        user: Record<string, unknown> & {\n          id: string;\n          createdAt: Date;\n          updatedAt: Date;\n          email: string;\n          emailVerified: boolean;\n          name: string;\n          image?: string | null | undefined;\n        };\n      };\n    }>)[];\n  },\n  {\n    plans: PaystackPlan[];\n  }\n> => {\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"GET\",\n      metadata: { ...HIDE_METADATA },\n      use: [sessionMiddleware],\n    },\n    async (ctx) => {\n      try {\n        const plans = await listStoredPlans(ctx);\n        return ctx.json({ plans });\n      } catch (error: unknown) {\n        ctx.context.logger.error(\"Failed to list plans\", error);\n        const errorMessage = error instanceof Error ? error.message : \"Failed to list plans\";\n        throw new APIError(\"BAD_REQUEST\", {\n          message: errorMessage,\n        });\n      }\n    },\n  );\n};\n\nexport const getConfig = <P extends string = \"/get-config\">(\n  options: AnyPaystackOptions,\n  path: P = \"/get-config\" as P,\n): StrictEndpoint<\n  P,\n  {\n    method: \"GET\";\n    metadata: {\n      openapi: {\n        operationId: string;\n      };\n    };\n  },\n  {\n    plans: PaystackPlan[];\n    products: PaystackProduct[];\n  }\n> => {\n  return createAuthEndpoint(\n    path,\n    {\n      method: \"GET\",\n      metadata: {\n        openapi: {\n          operationId: \"getPaystackConfig\",\n        },\n      },\n    },\n    async (ctx: GenericEndpointContext) => {\n      return ctx.json(await getConfiguredCatalog(options));\n    },\n  );\n};\n\nexport { PAYSTACK_ERROR_CODES };\n","import { mergeSchema, type BetterAuthPluginDBSchema, type DBFieldAttribute } from \"better-auth/db\";\n\nimport type { PaystackOptions } from \"./types\";\n\ntype PluginSchemaTable<TableName extends string, FieldName extends string> = Record<\n  TableName,\n  {\n    fields: Record<FieldName, DBFieldAttribute>;\n    disableMigration?: boolean;\n    modelName?: string;\n  }\n>;\n\ntype TransactionsSchema = PluginSchemaTable<\n  \"paystackTransaction\",\n  | \"reference\"\n  | \"paystackId\"\n  | \"referenceId\"\n  | \"userId\"\n  | \"amount\"\n  | \"currency\"\n  | \"status\"\n  | \"plan\"\n  | \"product\"\n  | \"metadata\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\ntype SubscriptionsSchema = PluginSchemaTable<\n  \"subscription\",\n  | \"plan\"\n  | \"referenceId\"\n  | \"paystackCustomerCode\"\n  | \"paystackSubscriptionCode\"\n  | \"paystackTransactionReference\"\n  | \"paystackAuthorizationCode\"\n  | \"paystackEmailToken\"\n  | \"status\"\n  | \"periodStart\"\n  | \"periodEnd\"\n  | \"trialStart\"\n  | \"trialEnd\"\n  | \"cancelAtPeriodEnd\"\n  | \"groupId\"\n  | \"seats\"\n  | \"pendingPlan\"\n>;\n\ntype UserSchema = PluginSchemaTable<\"user\", \"paystackCustomerCode\">;\n\ntype OrganizationSchema = PluginSchemaTable<\"organization\", \"paystackCustomerCode\" | \"email\">;\n\ntype ProductsSchema = PluginSchemaTable<\n  \"paystackProduct\",\n  | \"name\"\n  | \"description\"\n  | \"price\"\n  | \"currency\"\n  | \"quantity\"\n  | \"unlimited\"\n  | \"paystackId\"\n  | \"slug\"\n  | \"metadata\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\ntype PlansSchema = PluginSchemaTable<\n  \"paystackPlan\",\n  | \"name\"\n  | \"description\"\n  | \"amount\"\n  | \"currency\"\n  | \"interval\"\n  | \"planCode\"\n  | \"paystackId\"\n  | \"metadata\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\nexport type PaystackPluginSchema = SubscriptionsSchema &\n  TransactionsSchema &\n  UserSchema &\n  OrganizationSchema &\n  ProductsSchema &\n  PlansSchema;\n\nconst transactionsSchema: TransactionsSchema = {\n  paystackTransaction: {\n    fields: {\n      reference: {\n        type: \"string\",\n        required: true,\n        unique: true,\n      },\n      paystackId: {\n        type: \"string\",\n        required: false,\n      },\n      referenceId: {\n        type: \"string\",\n        required: true,\n        index: true,\n      },\n      userId: {\n        type: \"string\",\n        required: true,\n        index: true,\n      },\n      amount: {\n        type: \"number\",\n        required: true,\n      },\n      currency: {\n        type: \"string\",\n        required: true,\n      },\n      status: {\n        type: \"string\",\n        required: true,\n      },\n      plan: {\n        type: \"string\",\n        required: false,\n      },\n      product: {\n        type: \"string\",\n        required: false,\n      },\n      metadata: {\n        type: \"string\",\n        required: false,\n      },\n      createdAt: {\n        type: \"date\",\n        required: true,\n      },\n      updatedAt: {\n        type: \"date\",\n        required: true,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const transactions: typeof transactionsSchema = transactionsSchema;\n\nconst subscriptionsSchema: SubscriptionsSchema = {\n  subscription: {\n    fields: {\n      plan: {\n        type: \"string\",\n        required: true,\n        index: true,\n      },\n      referenceId: {\n        type: \"string\",\n        required: true,\n        index: true,\n      },\n      paystackCustomerCode: {\n        type: \"string\",\n        required: false,\n        index: true,\n      },\n      paystackSubscriptionCode: {\n        type: \"string\",\n        required: false,\n        unique: true,\n      },\n      paystackTransactionReference: {\n        type: \"string\",\n        required: false,\n        index: true,\n      },\n      paystackAuthorizationCode: {\n        type: \"string\",\n        required: false,\n      },\n      paystackEmailToken: {\n        type: \"string\",\n        required: false,\n      },\n      status: {\n        type: \"string\",\n        defaultValue: \"incomplete\",\n      },\n      periodStart: {\n        type: \"date\",\n        required: false,\n      },\n      periodEnd: {\n        type: \"date\",\n        required: false,\n      },\n      trialStart: {\n        type: \"date\",\n        required: false,\n      },\n      trialEnd: {\n        type: \"date\",\n        required: false,\n      },\n      cancelAtPeriodEnd: {\n        type: \"boolean\",\n        required: false,\n        defaultValue: false,\n      },\n      groupId: {\n        type: \"string\",\n        required: false,\n      },\n      seats: {\n        type: \"number\",\n        required: false,\n      },\n      pendingPlan: {\n        type: \"string\",\n        required: false,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const subscriptions: typeof subscriptionsSchema = subscriptionsSchema;\n\nconst userSchema: UserSchema = {\n  user: {\n    fields: {\n      paystackCustomerCode: {\n        type: \"string\",\n        required: false,\n        index: true,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const user: typeof userSchema = userSchema;\n\nconst organizationSchema: OrganizationSchema = {\n  organization: {\n    fields: {\n      paystackCustomerCode: {\n        type: \"string\",\n        required: false,\n        index: true,\n      },\n      email: {\n        type: \"string\",\n        required: false,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const organization: typeof organizationSchema = organizationSchema;\n\nconst productsSchema: ProductsSchema = {\n  paystackProduct: {\n    fields: {\n      name: {\n        type: \"string\",\n        required: true,\n      },\n      description: {\n        type: \"string\",\n        required: false,\n      },\n      price: {\n        type: \"number\",\n        required: true,\n      },\n      currency: {\n        type: \"string\",\n        required: true,\n      },\n      quantity: {\n        type: \"number\",\n        required: false,\n        defaultValue: 0,\n      },\n      unlimited: {\n        type: \"boolean\",\n        required: false,\n        defaultValue: true,\n      },\n      paystackId: {\n        type: \"string\",\n        required: false,\n        unique: true,\n      },\n      slug: {\n        type: \"string\",\n        required: true,\n        unique: true,\n      },\n      metadata: {\n        type: \"string\",\n        required: false,\n      },\n      createdAt: {\n        type: \"date\",\n        required: true,\n      },\n      updatedAt: {\n        type: \"date\",\n        required: true,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const products: typeof productsSchema = productsSchema;\n\nconst plansSchema: PlansSchema = {\n  paystackPlan: {\n    fields: {\n      name: {\n        type: \"string\",\n        required: true,\n      },\n      description: {\n        type: \"string\",\n        required: false,\n      },\n      amount: {\n        type: \"number\",\n        required: true,\n      },\n      currency: {\n        type: \"string\",\n        required: true,\n      },\n      interval: {\n        type: \"string\",\n        required: true,\n      },\n      planCode: {\n        type: \"string\",\n        required: true,\n        unique: true,\n      },\n      paystackId: {\n        type: \"string\",\n        required: true,\n        unique: true,\n      },\n      metadata: {\n        type: \"string\",\n        required: false,\n      },\n      createdAt: {\n        type: \"date\",\n        required: true,\n      },\n      updatedAt: {\n        type: \"date\",\n        required: true,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const plans: typeof plansSchema = plansSchema;\n\nconst paystackPluginSchemaDefinition: PaystackPluginSchema = {\n  ...subscriptions,\n  ...transactions,\n  ...user,\n  ...organization,\n  ...products,\n  ...plans,\n} satisfies BetterAuthPluginDBSchema;\n\nexport const paystackPluginSchema: typeof paystackPluginSchemaDefinition =\n  paystackPluginSchemaDefinition;\n\nexport const getSchema = (options: PaystackOptions): BetterAuthPluginDBSchema => {\n  let baseSchema: BetterAuthPluginDBSchema;\n  const optionSchema = options.schema as Parameters<typeof mergeSchema>[1];\n\n  if (options.subscription?.enabled === true) {\n    baseSchema = {\n      ...subscriptions,\n      ...transactions,\n      ...user,\n      ...products,\n      ...plans,\n    };\n  } else {\n    baseSchema = {\n      ...user,\n      ...transactions,\n      ...products,\n      ...plans,\n    };\n  }\n\n  // Add organization schema if organization support is enabled\n  if (options.organization?.enabled === true) {\n    baseSchema = {\n      ...baseSchema,\n      ...organization,\n    };\n  }\n\n  if (\n    options.schema !== undefined &&\n    options.subscription?.enabled !== true &&\n    \"subscription\" in options.schema\n  ) {\n    const { subscription: _subscription, ...restSchema } = optionSchema ?? {};\n    return mergeSchema(baseSchema, restSchema);\n  }\n\n  return mergeSchema(baseSchema, optionSchema);\n};\n","import { APIError } from \"better-auth/api\";\nimport type { GenericEndpointContext } from \"better-auth\";\n\nimport { createBillingStore } from \"./billing-store\";\nimport { createPaystackAdapter } from \"./paystack-sdk\";\nimport { getNextPeriodEnd, getPlans, validateMinAmount } from \"./utils\";\nimport { createRenewalMetadata, stringifyPaystackMetadata } from \"./metadata\";\nimport type {\n  AnyPaystackOptions,\n  ChargeRecurringSubscriptionInput,\n  ChargeRecurringSubscriptionResult,\n  PaystackSyncResult,\n  PaystackChargeAuthorizationResponse,\n} from \"./types\";\n\nexport async function syncPaystackProducts(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n): Promise<PaystackSyncResult> {\n  const paystack = createPaystackAdapter(options.paystackClient);\n  const store = createBillingStore(ctx);\n  try {\n    const productsData = await paystack.listProducts();\n\n    if (!Array.isArray(productsData)) {\n      return { status: \"success\", count: 0 };\n    }\n\n    for (const product of productsData) {\n      const paystackId = String(product.id);\n      const productFields = {\n        name: product.name ?? \"\",\n        description: product.description ?? \"\",\n        price: product.price ?? 0,\n        currency: product.currency ?? \"\",\n        quantity: product.quantity ?? 0,\n        unlimited:\n          product.unlimited !== undefined &&\n          product.unlimited !== null &&\n          product.unlimited !== false,\n        paystackId,\n        slug:\n          (product as { slug?: string }).slug ??\n          product.name?.toLowerCase().replace(/\\s+/g, \"-\") ??\n          \"\",\n        metadata: stringifyPaystackMetadata((product as { metadata?: unknown }).metadata),\n        updatedAt: new Date(),\n      };\n\n      await store.upsertProductByPaystackId(paystackId, {\n        ...productFields,\n        createdAt: new Date(),\n      });\n    }\n\n    return { status: \"success\", count: productsData.length };\n  } catch (error: unknown) {\n    ctx.context.logger.error(\"Failed to sync products\", error);\n    const errorMessage = error instanceof Error ? error.message : \"Failed to sync products\";\n    throw new APIError(\"BAD_REQUEST\", {\n      message: errorMessage,\n    });\n  }\n}\n\nexport async function syncPaystackPlans(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n): Promise<PaystackSyncResult> {\n  const paystack = createPaystackAdapter(options.paystackClient);\n  const store = createBillingStore(ctx);\n  try {\n    const plansData = await paystack.listPlans();\n\n    if (!Array.isArray(plansData)) {\n      return { status: \"success\", count: 0 };\n    }\n\n    for (const plan of plansData) {\n      const paystackId = String(plan.id);\n      const planData = {\n        name: plan.name ?? \"\",\n        description: typeof plan.description === \"string\" ? plan.description : \"\",\n        amount: plan.amount ?? 0,\n        currency: plan.currency ?? \"\",\n        interval: plan.interval ?? \"\",\n        planCode: plan.plan_code ?? \"\",\n        paystackId,\n        metadata: stringifyPaystackMetadata((plan as { metadata?: unknown }).metadata),\n        updatedAt: new Date(),\n      };\n\n      await store.upsertPlanByPaystackId(paystackId, {\n        ...planData,\n        createdAt: new Date(),\n      });\n    }\n\n    return { status: \"success\", count: plansData.length };\n  } catch (error: unknown) {\n    ctx.context.logger.error(\"Failed to sync plans\", error);\n    const errorMessage = error instanceof Error ? error.message : \"Failed to sync plans\";\n    throw new APIError(\"BAD_REQUEST\", {\n      message: errorMessage,\n    });\n  }\n}\n\nexport async function chargeSubscriptionRenewal(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n  input: ChargeRecurringSubscriptionInput,\n): Promise<ChargeRecurringSubscriptionResult> {\n  const { subscriptionId, amount: bodyAmount } = input;\n  const store = createBillingStore(ctx);\n  const subscription = await store.findSubscriptionById(subscriptionId);\n\n  if (subscription === undefined || subscription === null) {\n    throw new APIError(\"NOT_FOUND\", { message: \"Subscription not found\" });\n  }\n\n  if (\n    subscription.paystackAuthorizationCode === undefined ||\n    subscription.paystackAuthorizationCode === null ||\n    subscription.paystackAuthorizationCode === \"\"\n  ) {\n    throw new APIError(\"BAD_REQUEST\", {\n      message: \"No authorization code found for this subscription\",\n    });\n  }\n\n  const plans = await getPlans(options.subscription);\n  const plan = plans.find(\n    (candidate) => candidate.name.toLowerCase() === subscription.plan.toLowerCase(),\n  );\n\n  if (plan === undefined || plan === null) {\n    throw new APIError(\"NOT_FOUND\", { message: \"Plan not found\" });\n  }\n\n  const amount = bodyAmount ?? plan.amount;\n  if (amount === undefined || amount === null) {\n    throw new APIError(\"BAD_REQUEST\", { message: \"Plan amount is not defined\" });\n  }\n\n  let email: string | undefined;\n  let billingUserId = subscription.userId;\n  const referenceId = subscription.referenceId;\n  if (referenceId !== undefined && referenceId !== null && referenceId !== \"\") {\n    const user = await store.findUser(referenceId);\n    if (user !== undefined && user !== null) {\n      email = user.email;\n      billingUserId = user.id;\n    } else if (options.organization?.enabled === true) {\n      const ownerMember = await store.findOrganizationOwner(referenceId);\n      if (ownerMember !== undefined && ownerMember !== null) {\n        const ownerUser = await store.findUser(ownerMember.userId);\n        email = ownerUser?.email;\n        billingUserId = ownerUser?.id ?? ownerMember.userId;\n      }\n    }\n  }\n\n  if (email === undefined || email === null || email === \"\") {\n    throw new APIError(\"NOT_FOUND\", { message: \"User email not found\" });\n  }\n\n  const finalCurrency = plan.currency ?? \"NGN\";\n  if (!validateMinAmount(amount, finalCurrency)) {\n    throw new APIError(\"BAD_REQUEST\", {\n      message: `Amount ${amount} is less than the minimum required for ${finalCurrency}.`,\n      status: 400,\n    });\n  }\n\n  const paystack = createPaystackAdapter(options.paystackClient);\n  const renewalMetadata = createRenewalMetadata({\n    subscriptionId,\n    referenceId,\n  });\n  const serializedRenewalMetadata = stringifyPaystackMetadata(renewalMetadata);\n\n  const chargeData = await paystack.chargeAuthorization({\n    email,\n    amount,\n    authorization_code: subscription.paystackAuthorizationCode,\n    reference: `rec_${subscription.id}_${Date.now()}`,\n    metadata: serializedRenewalMetadata,\n  });\n\n  const typedChargeData = chargeData as PaystackChargeAuthorizationResponse;\n  if (typedChargeData?.status === \"success\" && typedChargeData.reference !== undefined) {\n    const now = new Date();\n    const nextPeriodEnd = getNextPeriodEnd(now, plan.interval ?? \"monthly\");\n\n    await store.createTransaction({\n      reference: typedChargeData.reference,\n      paystackId:\n        typedChargeData.id !== undefined && typedChargeData.id !== null\n          ? String(typedChargeData.id)\n          : undefined,\n      referenceId,\n      userId: billingUserId,\n      amount: typedChargeData.amount,\n      currency: typedChargeData.currency,\n      status: \"success\",\n      plan: plan.name.toLowerCase(),\n      metadata: serializedRenewalMetadata,\n      createdAt: now,\n      updatedAt: now,\n    });\n\n    await store.updateSubscription(subscription.id, {\n      periodStart: now,\n      periodEnd: nextPeriodEnd,\n      updatedAt: now,\n      paystackTransactionReference: typedChargeData.reference,\n    });\n\n    return { status: \"success\", data: typedChargeData };\n  }\n\n  return { status: \"failed\", data: typedChargeData };\n}\n","import type { CustomerCreatePayload } from \"@alexasomba/paystack-node\";\nimport {\n  defineErrorCodes,\n  type AuthContext,\n  type BetterAuthPlugin,\n  type GenericEndpointContext,\n} from \"better-auth\";\nimport { defu } from \"defu\";\n\nimport {\n  disablePaystackSubscription,\n  enablePaystackSubscription,\n  initializeTransaction,\n  listSubscriptions,\n  listTransactions,\n  paystackWebhook,\n  verifyTransaction,\n  getConfig,\n  getSubscriptionManageLink,\n  PAYSTACK_ERROR_CODES,\n  createSubscription,\n  upgradeSubscription,\n  cancelSubscription,\n  restoreSubscription,\n  listProducts,\n  listPlans,\n} from \"./routes\";\nimport { getSchema } from \"./schema\";\nimport { checkSeatLimit, checkTeamLimit, getOrganizationSubscription } from \"./limits\";\nimport { getPlanByName, syncSubscriptionSeats } from \"./utils\";\nimport type {\n  PaystackClientLike,\n  PaystackOptions,\n  PaystackCustomerResponse,\n  AnyPaystackOptions,\n  User,\n} from \"./types\";\nimport { createPaystackAdapter } from \"./paystack-sdk\";\nimport { PACKAGE_VERSION } from \"./version\";\nimport { createBillingStoreFromAdapter } from \"./billing-store\";\nimport { stringifyPaystackMetadata } from \"./metadata\";\n\nexport {\n  createCheckoutMetadata,\n  createProrationMetadata,\n  createRenewalMetadata,\n  getMetadataBoolean,\n  getMetadataNumber,\n  getMetadataString,\n  hasPaystackMetadata,\n  parsePaystackMetadata,\n  stringifyPaystackMetadata,\n} from \"./metadata\";\nexport type { PaystackMetadata } from \"./metadata\";\nexport type { PaystackInitializeResult } from \"./types\";\n\ndeclare module \"better-auth\" {\n  interface BetterAuthPluginRegistry<AuthOptions, Options> {\n    paystack: {\n      creator: typeof paystack;\n    };\n  }\n}\n\nconst INTERNAL_ERROR_CODES: ReturnType<typeof defineErrorCodes> = defineErrorCodes(\n  Object.fromEntries(\n    Object.entries(PAYSTACK_ERROR_CODES).map(([key, value]) => [\n      key,\n      typeof value === \"string\" ? value : (value as { message: string }).message,\n    ]),\n  ),\n);\n\ntype BetterAuthEndpoint = NonNullable<BetterAuthPlugin[\"endpoints\"]>[string];\n\ninterface PaystackPluginEndpoints extends Record<string, BetterAuthEndpoint> {\n  initializeTransaction: ReturnType<typeof initializeTransaction>;\n  verifyTransaction: ReturnType<typeof verifyTransaction>;\n  listSubscriptions: ReturnType<typeof listSubscriptions>;\n  paystackWebhook: ReturnType<typeof paystackWebhook>;\n  listTransactions: ReturnType<typeof listTransactions>;\n  getConfig: ReturnType<typeof getConfig>;\n  disableSubscription: ReturnType<typeof disablePaystackSubscription>;\n  enableSubscription: ReturnType<typeof enablePaystackSubscription>;\n  getSubscriptionManageLink: ReturnType<typeof getSubscriptionManageLink>;\n  subscriptionManageLink: ReturnType<typeof getSubscriptionManageLink>;\n  createSubscription: ReturnType<typeof createSubscription>;\n  upgradeSubscription: ReturnType<typeof upgradeSubscription>;\n  cancelSubscription: ReturnType<typeof cancelSubscription>;\n  restoreSubscription: ReturnType<typeof restoreSubscription>;\n  listProducts: ReturnType<typeof listProducts>;\n  listPlans: ReturnType<typeof listPlans>;\n}\n\ntype PaystackHookHandler = (...args: unknown[]) => unknown;\n\ninterface PaystackPluginInitResult {\n  options: {\n    databaseHooks: Record<string, unknown> & {\n      organization: {\n        create: {\n          after: PaystackHookHandler;\n        };\n      };\n    };\n  };\n}\n\ntype PaystackPluginInit = ((ctx: AuthContext) => PaystackPluginInitResult) &\n  NonNullable<BetterAuthPlugin[\"init\"]>;\n\ntype PaystackPluginInstance<O extends AnyPaystackOptions> = Omit<\n  BetterAuthPlugin,\n  \"id\" | \"version\" | \"endpoints\" | \"schema\" | \"init\" | \"$ERROR_CODES\" | \"options\"\n> & {\n  id: \"paystack\";\n  version: typeof PACKAGE_VERSION;\n  endpoints: PaystackPluginEndpoints;\n  schema: ReturnType<typeof getSchema>;\n  init: PaystackPluginInit;\n  $ERROR_CODES: typeof INTERNAL_ERROR_CODES;\n  options: NoInfer<O>;\n};\n\nconst createPaystackPlugin = <\n  TPaystackClient extends PaystackClientLike = PaystackClientLike,\n  O extends PaystackOptions<TPaystackClient> = PaystackOptions<TPaystackClient>,\n>(\n  options: O,\n): PaystackPluginInstance<O> => {\n  const routeOptions = {\n    ...(options as unknown as AnyPaystackOptions),\n    webhook: {\n      ...options.webhook,\n      secret: options.webhook?.secret ?? options.paystackWebhookSecret,\n    },\n  } satisfies AnyPaystackOptions;\n  return {\n    id: \"paystack\",\n    version: PACKAGE_VERSION as typeof PACKAGE_VERSION,\n    endpoints: {\n      initializeTransaction: initializeTransaction(\n        routeOptions,\n        \"/paystack/initialize-transaction\",\n      ),\n      verifyTransaction: verifyTransaction(routeOptions, \"/paystack/verify-transaction\"),\n      listSubscriptions: listSubscriptions(routeOptions, \"/paystack/list-subscriptions\"),\n      paystackWebhook: paystackWebhook(routeOptions, \"/paystack/webhook\"),\n      listTransactions: listTransactions(routeOptions, \"/paystack/list-transactions\"),\n      getConfig: getConfig(routeOptions, \"/paystack/config\"),\n      disableSubscription: disablePaystackSubscription(\n        routeOptions,\n        \"/paystack/disable-subscription\",\n      ),\n      enableSubscription: enablePaystackSubscription(routeOptions, \"/paystack/enable-subscription\"),\n      getSubscriptionManageLink: getSubscriptionManageLink(\n        routeOptions,\n        \"/paystack/subscription-manage-link\",\n      ),\n      subscriptionManageLink: getSubscriptionManageLink(\n        routeOptions,\n        \"/paystack/subscription/manage-link\",\n      ),\n      createSubscription: createSubscription(routeOptions, \"/paystack/create-subscription\"),\n      upgradeSubscription: upgradeSubscription(routeOptions, \"/paystack/upgrade-subscription\"),\n      cancelSubscription: cancelSubscription(routeOptions, \"/paystack/cancel-subscription\"),\n      restoreSubscription: restoreSubscription(routeOptions, \"/paystack/restore-subscription\"),\n      listProducts: listProducts(routeOptions, \"/paystack/list-products\"),\n      listPlans: listPlans(routeOptions, \"/paystack/list-plans\"),\n    },\n    schema: getSchema(options),\n    init: ((ctx: AuthContext) => {\n      const organizationPluginAvailable = ctx.hasPlugin(\"organization\");\n      if (options.organization?.enabled === true && !organizationPluginAvailable) {\n        ctx.logger.error(\n          \"Paystack organization billing is enabled, but the Better Auth organization plugin was not found. Organization billing hooks will be skipped.\",\n        );\n      }\n\n      return {\n        options: {\n          databaseHooks: {\n            user: {\n              create: {\n                async after(\n                  user: { id: string; email?: string | null; name?: string | null },\n                  hookCtx?: GenericEndpointContext | null,\n                ) {\n                  if (\n                    !hookCtx ||\n                    options.createCustomerOnSignUp !== true ||\n                    user.email === null ||\n                    user.email === undefined ||\n                    user.email === \"\"\n                  )\n                    return;\n\n                  try {\n                    const sdkRes = (await createPaystackAdapter(\n                      options.paystackClient as PaystackClientLike,\n                    ).createCustomer({\n                      email: user.email,\n                      first_name: user.name ?? undefined,\n                      metadata: stringifyPaystackMetadata({ userId: user.id }),\n                    })) as PaystackCustomerResponse;\n                    const customerCode = sdkRes?.customer_code;\n\n                    if (\n                      customerCode !== undefined &&\n                      customerCode !== null &&\n                      customerCode !== \"\"\n                    ) {\n                      await createBillingStoreFromAdapter(ctx.adapter).saveCustomerCode(\n                        user.id,\n                        customerCode,\n                        false,\n                      );\n\n                      if (typeof options.onCustomerCreate === \"function\") {\n                        await options.onCustomerCreate(\n                          {\n                            paystackCustomer: sdkRes,\n                            user: {\n                              ...(user as User),\n                              paystackCustomerCode: customerCode,\n                            },\n                          },\n                          hookCtx,\n                        );\n                      }\n                    }\n                  } catch (error: unknown) {\n                    ctx.logger.error(\"Failed to create Paystack customer for user\", error);\n                  }\n                },\n              },\n            },\n            organization:\n              options.organization?.enabled === true && organizationPluginAvailable\n                ? {\n                    create: {\n                      async after(\n                        org: { id: string; name: string; email?: string | null },\n                        hookCtx: GenericEndpointContext | null,\n                      ) {\n                        try {\n                          const extraCreateParams =\n                            typeof options.organization?.getCustomerCreateParams === \"function\"\n                              ? await (\n                                  options.organization.getCustomerCreateParams as (\n                                    org: Record<string, unknown>,\n                                    hookCtx: GenericEndpointContext,\n                                  ) => Promise<Record<string, unknown>>\n                                )(org as Record<string, unknown>, hookCtx!)\n                              : {};\n\n                          let targetEmail = org.email;\n                          if (targetEmail === undefined || targetEmail === null) {\n                            const store = createBillingStoreFromAdapter(ctx.adapter);\n                            const ownerMember = await store.findOrganizationOwner(org.id);\n                            if (ownerMember !== null && ownerMember !== undefined) {\n                              const ownerUser = await store.findUser(ownerMember.userId);\n                              targetEmail = ownerUser?.email;\n                            }\n                          }\n\n                          if (targetEmail === undefined || targetEmail === null) return;\n\n                          const params = defu(\n                            {\n                              email: targetEmail,\n                              first_name: org.name,\n                              metadata: stringifyPaystackMetadata({ organizationId: org.id }),\n                            },\n                            extraCreateParams,\n                          );\n                          const sdkRes = (await createPaystackAdapter(\n                            options.paystackClient as PaystackClientLike,\n                          ).createCustomer(\n                            params as CustomerCreatePayload,\n                          )) as PaystackCustomerResponse;\n                          const customerCode = sdkRes?.customer_code as string | undefined;\n\n                          if (\n                            customerCode !== undefined &&\n                            customerCode !== null &&\n                            customerCode !== \"\" &&\n                            sdkRes !== undefined &&\n                            sdkRes !== null\n                          ) {\n                            await createBillingStoreFromAdapter(ctx.adapter).saveCustomerCode(\n                              org.id,\n                              customerCode,\n                              true,\n                            );\n\n                            if (typeof options.organization?.onCustomerCreate === \"function\") {\n                              await options.organization.onCustomerCreate(\n                                {\n                                  paystackCustomer: sdkRes,\n                                  organization: {\n                                    ...org,\n                                    paystackCustomerCode: customerCode,\n                                  },\n                                },\n                                hookCtx!,\n                              );\n                            }\n                          }\n                        } catch (error: unknown) {\n                          ctx.logger.error(\n                            \"Failed to create Paystack customer for organization\",\n                            error,\n                          );\n                        }\n                      },\n                    },\n                  }\n                : undefined,\n            member: organizationPluginAvailable\n              ? {\n                  create: {\n                    before: async (\n                      member: { organizationId: string },\n                      ctx: GenericEndpointContext | null | undefined,\n                    ) => {\n                      if (\n                        options.subscription?.enabled === true &&\n                        member.organizationId &&\n                        ctx !== null &&\n                        ctx !== undefined\n                      ) {\n                        await checkSeatLimit(ctx, member.organizationId);\n                      }\n                    },\n                    after: async (\n                      member: { organizationId: string | undefined },\n                      ctx: GenericEndpointContext | null | undefined,\n                    ) => {\n                      if (\n                        options.subscription?.enabled === true &&\n                        typeof member?.organizationId === \"string\" &&\n                        ctx\n                      ) {\n                        await syncSubscriptionSeats(ctx, member.organizationId, routeOptions);\n                      }\n                    },\n                  },\n                  delete: {\n                    after: async (\n                      member: { organizationId: string | undefined },\n                      ctx: GenericEndpointContext | null | undefined,\n                    ) => {\n                      if (\n                        options.subscription?.enabled === true &&\n                        typeof member?.organizationId === \"string\" &&\n                        ctx\n                      ) {\n                        await syncSubscriptionSeats(ctx, member.organizationId, routeOptions);\n                      }\n                    },\n                  },\n                }\n              : undefined,\n            invitation: organizationPluginAvailable\n              ? {\n                  create: {\n                    before: async (\n                      invitation: { organizationId: string },\n                      ctx: GenericEndpointContext | null | undefined,\n                    ) => {\n                      if (\n                        options.subscription?.enabled === true &&\n                        invitation.organizationId &&\n                        ctx !== null &&\n                        ctx !== undefined\n                      ) {\n                        await checkSeatLimit(ctx, invitation.organizationId);\n                      }\n                    },\n                    after: async (\n                      invitation: { organizationId: string | undefined },\n                      ctx: GenericEndpointContext | null | undefined,\n                    ) => {\n                      if (\n                        options.subscription?.enabled === true &&\n                        typeof invitation?.organizationId === \"string\" &&\n                        ctx\n                      ) {\n                        await syncSubscriptionSeats(ctx, invitation.organizationId, routeOptions);\n                      }\n                    },\n                  },\n                  delete: {\n                    after: async (\n                      invitation: { organizationId: string | undefined },\n                      ctx: GenericEndpointContext | null | undefined,\n                    ) => {\n                      if (\n                        options.subscription?.enabled === true &&\n                        typeof invitation?.organizationId === \"string\" &&\n                        ctx\n                      ) {\n                        await syncSubscriptionSeats(ctx, invitation.organizationId, routeOptions);\n                      }\n                    },\n                  },\n                }\n              : undefined,\n            team: organizationPluginAvailable\n              ? {\n                  create: {\n                    before: async (\n                      team: { organizationId: string },\n                      ctx: GenericEndpointContext | null | undefined,\n                    ) => {\n                      if (options.subscription?.enabled === true && team.organizationId && ctx) {\n                        const subscription = await getOrganizationSubscription(\n                          ctx,\n                          team.organizationId,\n                        );\n                        if (subscription !== null && subscription !== undefined) {\n                          const plan = await getPlanByName(routeOptions, subscription.plan);\n                          const limits = plan?.limits;\n                          const maxTeams = limits?.teams as number | undefined;\n\n                          if (typeof maxTeams === \"number\") {\n                            await checkTeamLimit(ctx, team.organizationId, maxTeams);\n                          }\n                        }\n                      }\n                    },\n                  },\n                }\n              : undefined,\n          },\n        },\n      };\n    }) as PaystackPluginInit,\n    $ERROR_CODES: INTERNAL_ERROR_CODES,\n    options: options as NoInfer<O>,\n  } satisfies BetterAuthPlugin;\n};\n\nexport const paystack: typeof createPaystackPlugin = createPaystackPlugin;\n\nexport type PaystackPlugin<\n  TPaystackClient extends PaystackClientLike = PaystackClientLike,\n  O extends PaystackOptions<TPaystackClient> = PaystackOptions<TPaystackClient>,\n> = ReturnType<typeof paystack<TPaystackClient, O>>;\n\nexport { chargeSubscriptionRenewal, syncPaystackPlans, syncPaystackProducts } from \"./operations\";\nexport { reconcilePaystackTransaction } from \"./reconciliation\";\nexport type {\n  PaystackReconciliationError,\n  PaystackReconciliationSource,\n  PaystackReconciliationSummary,\n  ReconcilePaystackTransactionFailure,\n  ReconcilePaystackTransactionInput,\n  ReconcilePaystackTransactionResult,\n  ReconcilePaystackTransactionSuccess,\n} from \"./reconciliation\";\nexport type {\n  Subscription,\n  SubscriptionOptions,\n  PaystackPlan,\n  PaystackOptions,\n  PaystackProduct,\n  PaystackTransactionResponse,\n  PaystackClientLike,\n  ChargeRecurringSubscriptionResult,\n  PaystackSyncResult,\n} from \"./types\";\n"],"mappings":"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"}