UNPKG

better-auth-paystack

Version:

Production-ready Paystack billing plugin for Better Auth. Supports subscriptions, one-time payments, organization billing, secure webhooks and more

1 lines • 329 kB
{"version":3,"file":"index.mjs","names":["NodeBuffer","z","getAllowedSubscriptionChannels","subCode"],"sources":["../src/models.ts","../src/billing-store.ts","../src/paystack-sdk.ts","../src/customer.ts","../src/utils.ts","../src/limits.ts","../src/credential-crypto.ts","../src/payment-credentials.ts","../src/reference-access.ts","../src/subscription-fulfillment.ts","../src/reconciliation.ts","../src/reference-middleware.ts","../src/route-modules/callback-url.ts","../src/route-modules/catalog.ts","../src/route-modules/checkout.ts","../src/route-modules/shared.ts","../src/route-modules/subscriptions.ts","../src/route-modules/webhook.ts","../src/subscription-lifecycle.ts","../src/routes.ts","../src/schema.ts","../src/operations.ts","../src/migrations.ts","../src/index.ts"],"sourcesContent":["/** Provider-owned Better Auth model names. Keep these centralized so a provider\n * model cannot accidentally fall back to Better Auth's generic billing tables. */\nexport const PAYSTACK_MODELS = {\n  customer: \"paystackCustomer\",\n  paymentCredential: \"paystackPaymentCredential\",\n  subscription: \"paystackSubscription\",\n  transaction: \"paystackTransaction\",\n  product: \"paystackProduct\",\n  plan: \"paystackPlan\",\n  webhookEvent: \"paystackWebhookEvent\",\n} as const;\n\nexport const LEGACY_PAYSTACK_MODELS = {\n  subscription: \"subscription\",\n} as const;\n","import type { GenericEndpointContext } from \"better-auth\";\n\nimport { PAYSTACK_MODELS } from \"./models.ts\";\nimport type {\n  Member,\n  PaystackCustomer,\n  PaystackOrganization,\n  PaystackPlan,\n  PaystackProduct,\n  PaystackTransaction,\n  PaystackWebhookEventRecord,\n  Subscription,\n  User,\n} from \"./types.ts\";\n\nexport type BillingStoreAdapter = Pick<\n  GenericEndpointContext[\"context\"][\"adapter\"],\n  \"create\" | \"delete\" | \"deleteMany\" | \"findMany\" | \"findOne\" | \"update\" | \"updateMany\"\n>;\ntype Adapter = BillingStoreAdapter;\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(\n    referenceId: string,\n    groupId?: string | null,\n  ): Promise<Subscription | null>;\n  retireCompetingSubscriptions(\n    referenceId: string,\n    groupId: string | null,\n    exceptId: string,\n  ): Promise<void>;\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  findCustomerByReference(\n    referenceType: \"user\" | \"organization\",\n    referenceId: string,\n  ): Promise<PaystackCustomer | null>;\n  findCustomerByCode(customerCode: string): Promise<PaystackCustomer | null>;\n  saveCustomer(\n    referenceType: \"user\" | \"organization\",\n    referenceId: string,\n    customerCode: string,\n    email?: string | null,\n  ): Promise<PaystackCustomer>;\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  createWebhookEvent(\n    data: Omit<PaystackWebhookEventRecord, \"id\">,\n  ): Promise<PaystackWebhookEventRecord>;\n  findWebhookEvent(eventId: string): Promise<PaystackWebhookEventRecord | null>;\n  updateWebhookEvent(\n    eventId: string,\n    update: Partial<PaystackWebhookEventRecord> & Record<string, unknown>,\n  ): Promise<PaystackWebhookEventRecord | 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    email?: string | null,\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    try {\n      return (await adapter.findOne<T>({ model, where })) ?? null;\n    } catch {\n      // Adapters such as the in-memory adapter create provider tables lazily.\n      return null;\n    }\n  };\n\n  const findMany = async <T>(model: string, where?: WhereClause): Promise<T[]> => {\n    try {\n      return (await adapter.findMany<T>({ model, ...(where ? { where } : {}) })) ?? [];\n    } catch {\n      return [];\n    }\n  };\n\n  return {\n    findSubscriptionById: (id) =>\n      findOne<Subscription>(PAYSTACK_MODELS.subscription, [{ field: \"id\", value: id }]),\n    findSubscriptionByCode: (subscriptionCode) =>\n      findOne<Subscription>(PAYSTACK_MODELS.subscription, [\n        { field: \"subscriptionCode\", value: subscriptionCode },\n      ]),\n    findSubscriptionsByReference: (referenceId) =>\n      findMany<Subscription>(PAYSTACK_MODELS.subscription, [\n        { field: \"referenceId\", value: referenceId },\n      ]),\n    async findCurrentSubscription(referenceId, groupId) {\n      const subscriptions = await this.findSubscriptionsByReference(referenceId);\n      const scoped =\n        groupId === undefined\n          ? subscriptions\n          : subscriptions.filter((subscription) =>\n              groupId === null\n                ? subscription.groupId === undefined ||\n                  subscription.groupId === null ||\n                  subscription.groupId === \"\"\n                : subscription.groupId === groupId,\n            );\n      return sortSubscriptionsForCurrent(scoped)[0] ?? null;\n    },\n    async retireCompetingSubscriptions(referenceId, groupId, exceptId) {\n      const subscriptions = await this.findSubscriptionsByReference(referenceId);\n      const selected = subscriptions.find((subscription) => subscription.id === exceptId);\n      const competitors = subscriptions.filter(\n        (subscription) =>\n          subscription.id !== exceptId &&\n          (selected === undefined ||\n            new Date(subscription.createdAt).getTime() <= new Date(selected.createdAt).getTime()) &&\n          (subscription.status === \"active\" || subscription.status === \"trialing\") &&\n          (groupId === null\n            ? subscription.groupId === undefined ||\n              subscription.groupId === null ||\n              subscription.groupId === \"\"\n            : subscription.groupId === groupId),\n      );\n      const now = new Date();\n      for (const subscription of competitors) {\n        await this.updateSubscription(subscription.id, {\n          status: \"canceled\",\n          cancelAtPeriodEnd: false,\n          canceledAt: now,\n          endedAt: now,\n          updatedAt: now,\n        });\n      }\n    },\n    findSubscriptionsByTransactionReference: (reference) =>\n      findMany<Subscription>(PAYSTACK_MODELS.subscription, [\n        { field: \"transactionReference\", value: reference },\n      ]),\n    createSubscription: async (data) =>\n      await adapter.create({\n        model: PAYSTACK_MODELS.subscription,\n        data: data as Omit<Subscription, \"id\">,\n      }),\n    updateSubscription: (id, update) =>\n      adapter.update<Subscription>({\n        model: PAYSTACK_MODELS.subscription,\n        update,\n        where: [{ field: \"id\", value: id }],\n      }),\n    updateSubscriptionByCode: (subscriptionCode, update) =>\n      adapter.update<Subscription>({\n        model: PAYSTACK_MODELS.subscription,\n        update,\n        where: [{ field: \"subscriptionCode\", value: subscriptionCode }],\n      }),\n    createTransaction: async (data) =>\n      await adapter.create({\n        model: PAYSTACK_MODELS.transaction,\n        data: data as Omit<PaystackTransaction, \"id\">,\n      }),\n    findTransactionByReference: (reference) =>\n      findOne<PaystackTransaction>(PAYSTACK_MODELS.transaction, [\n        { field: \"reference\", value: reference },\n      ]),\n    updateTransactionByReference: (reference, update) =>\n      adapter.update<PaystackTransaction>({\n        model: PAYSTACK_MODELS.transaction,\n        update,\n        where: [{ field: \"reference\", value: reference }],\n      }),\n    createWebhookEvent: (data) =>\n      adapter.create({\n        model: PAYSTACK_MODELS.webhookEvent,\n        data,\n      }),\n    findWebhookEvent: (eventId) =>\n      adapter.findOne<PaystackWebhookEventRecord>({\n        model: PAYSTACK_MODELS.webhookEvent,\n        where: [{ field: \"eventId\", value: eventId }],\n      }),\n    updateWebhookEvent: (eventId, update) =>\n      adapter.update<PaystackWebhookEventRecord>({\n        model: PAYSTACK_MODELS.webhookEvent,\n        update,\n        where: [{ field: \"eventId\", value: eventId }],\n      }),\n    async listTransactions(referenceId) {\n      const transactions = await findMany<PaystackTransaction>(PAYSTACK_MODELS.transaction, [\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>(PAYSTACK_MODELS.product);\n      return products.sort((a, b) => a.name.localeCompare(b.name));\n    },\n    findProductByName: (name) =>\n      findOne<PaystackProduct>(PAYSTACK_MODELS.product, [{ field: \"name\", value: name }]),\n    findProductBySlug: (slug) =>\n      findOne<PaystackProduct>(PAYSTACK_MODELS.product, [{ field: \"slug\", value: slug }]),\n    async updateProduct(id, update) {\n      await adapter.update({\n        model: PAYSTACK_MODELS.product,\n        update,\n        where: [{ field: \"id\", value: id }],\n      });\n    },\n    async upsertProductByPaystackId(paystackId, data) {\n      const existing = await findOne<PaystackProduct>(PAYSTACK_MODELS.product, [\n        { field: \"paystackId\", value: paystackId },\n      ]);\n      if (existing?.id !== undefined) {\n        const { createdAt: _createdAt, ...update } = data;\n        await adapter.update({\n          model: PAYSTACK_MODELS.product,\n          update,\n          where: [{ field: \"id\", value: String(existing.id) }],\n        });\n        return;\n      }\n      await adapter.create({ model: PAYSTACK_MODELS.product, data });\n    },\n    listPlans: () => findMany<PaystackPlan>(PAYSTACK_MODELS.plan),\n    findPlanByName: (name) =>\n      findOne<PaystackPlan>(PAYSTACK_MODELS.plan, [{ field: \"name\", value: name }]),\n    findPlanByCode: (planCode) =>\n      findOne<PaystackPlan>(PAYSTACK_MODELS.plan, [{ field: \"planCode\", value: planCode }]),\n    async upsertPlanByPaystackId(paystackId, data) {\n      const existing = await findOne<PaystackPlan>(PAYSTACK_MODELS.plan, [\n        { field: \"paystackId\", value: paystackId },\n      ]);\n      if (existing?.id !== undefined) {\n        const { createdAt: _createdAt, ...update } = data;\n        await adapter.update({\n          model: PAYSTACK_MODELS.plan,\n          update,\n          where: [{ field: \"id\", value: existing.id }],\n        });\n        return;\n      }\n      await adapter.create({ model: PAYSTACK_MODELS.plan, 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    findCustomerByReference: (referenceType, referenceId) =>\n      findOne<PaystackCustomer>(PAYSTACK_MODELS.customer, [\n        { field: \"referenceKey\", value: `${referenceType}:${referenceId}` },\n      ]),\n    findCustomerByCode: (customerCode) =>\n      findOne<PaystackCustomer>(PAYSTACK_MODELS.customer, [\n        { field: \"customerCode\", value: customerCode },\n      ]),\n    async saveCustomer(referenceType, referenceId, customerCode, email) {\n      const referenceKey = `${referenceType}:${referenceId}`;\n      const existing = await findOne<PaystackCustomer>(PAYSTACK_MODELS.customer, [\n        { field: \"referenceKey\", value: referenceKey },\n      ]);\n      const now = new Date();\n      const hasEmail = email !== undefined && email !== null && email !== \"\";\n      if (existing) {\n        const updated = await adapter.update<PaystackCustomer>({\n          model: PAYSTACK_MODELS.customer,\n          update: { customerCode, ...(hasEmail ? { email } : {}), updatedAt: now },\n          where: [{ field: \"id\", value: existing.id }],\n        });\n        return (\n          updated ?? { ...existing, customerCode, email: email ?? existing.email, updatedAt: now }\n        );\n      }\n      return adapter.create({\n        model: PAYSTACK_MODELS.customer,\n        data: {\n          referenceType,\n          referenceId,\n          referenceKey,\n          customerCode,\n          ...(hasEmail ? { email } : {}),\n          createdAt: now,\n          updatedAt: now,\n        },\n      });\n    },\n    async saveCustomerCode(referenceId, customerCode, isOrganization, email) {\n      await this.saveCustomer(\n        isOrganization ? \"organization\" : \"user\",\n        referenceId,\n        customerCode,\n        email,\n      );\n    },\n  };\n}\n","import {\n  PaystackError,\n  PaystackResponse,\n  type CustomerCreatePayload,\n  type CustomerUpdatePayload,\n} from \"@alexasomba/paystack-node\";\nimport type { components } from \"@alexasomba/paystack-node\";\nimport { APIError } from \"better-auth/api\";\n\nimport type { PaystackClientLike } from \"./types.ts\";\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(e.status === 404 ? \"NOT_FOUND\" : \"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  fetchCustomer(emailOrCode: string): Promise<unknown>;\n  updateCustomer(\n    emailOrCode: string,\n    body: CustomerUpdatePayload & { email?: string },\n  ): 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 fetchCustomer(emailOrCode: string): Promise<unknown> {\n      const raw = await requireClient().customer?.fetch(emailOrCode);\n      return unwrapSdkResult(raw);\n    },\n    async updateCustomer(\n      emailOrCode: string,\n      body: CustomerUpdatePayload & { email?: string },\n    ): Promise<unknown> {\n      const raw = await requireClient().customer?.update(emailOrCode, {\n        body: body,\n      });\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 { createBillingStoreFromAdapter } from \"./billing-store.ts\";\nimport { parsePaystackMetadata, stringifyPaystackMetadata } from \"./metadata.ts\";\nimport { createPaystackAdapter } from \"./paystack-sdk.ts\";\nimport type { PaystackClientLike, PaystackCustomerResponse } from \"./types.ts\";\n\ninterface Logger {\n  error(message: string, error?: unknown): void;\n}\ntype Adapter = Parameters<typeof createBillingStoreFromAdapter>[0];\n\ninterface BillingReference {\n  id: string;\n  type: \"user\" | \"organization\";\n  email: string;\n  name?: string | null;\n  emailVerified?: boolean;\n  paystackCustomerCode?: string | null;\n}\n\nfunction isNotFound(error: unknown): boolean {\n  if (error === null || typeof error !== \"object\") return false;\n  const candidate = error as Record<string, unknown>;\n  return candidate.status === 404 || candidate.statusCode === 404;\n}\n\nfunction customerCode(customer: unknown): string | undefined {\n  if (customer === null || typeof customer !== \"object\") return undefined;\n  const code = (customer as Record<string, unknown>).customer_code;\n  return typeof code === \"string\" && code !== \"\" ? code : undefined;\n}\n\nfunction ownsCustomer(customer: unknown, reference: BillingReference): boolean {\n  if (customer === null || typeof customer !== \"object\") return false;\n  const metadata = parsePaystackMetadata((customer as Record<string, unknown>).metadata);\n  const expectedIdKey = reference.type === \"user\" ? \"userId\" : \"organizationId\";\n  const otherIdKey = reference.type === \"user\" ? \"organizationId\" : \"userId\";\n  return (\n    metadata[expectedIdKey] === reference.id &&\n    metadata[otherIdKey] === undefined &&\n    (metadata.customerType === undefined || metadata.customerType === reference.type)\n  );\n}\n\nfunction hasOwner(customer: unknown): boolean {\n  if (customer === null || typeof customer !== \"object\") return false;\n  const metadata = parsePaystackMetadata((customer as Record<string, unknown>).metadata);\n  return (\n    typeof metadata.userId === \"string\" ||\n    typeof metadata.organizationId === \"string\" ||\n    typeof metadata.customerType === \"string\"\n  );\n}\n\nfunction ownershipMetadata(reference: BillingReference, existing?: unknown): string | undefined {\n  return stringifyPaystackMetadata({\n    ...parsePaystackMetadata(existing),\n    customerType: reference.type,\n    ...(reference.type === \"user\" ? { userId: reference.id } : { organizationId: reference.id }),\n  });\n}\n\nexport async function resolvePaystackCustomer(input: {\n  adapter: Adapter;\n  client: PaystackClientLike;\n  logger: Logger;\n  reference: BillingReference;\n  createParams?: Record<string, unknown>;\n}): Promise<{ customer: PaystackCustomerResponse; created: boolean } | null> {\n  const { adapter, client, logger, reference } = input;\n  const store = createBillingStoreFromAdapter(adapter);\n  const persisted = await store.findCustomerByReference(reference.type, reference.id);\n  let legacyCode: string | undefined;\n  try {\n    const legacy = await adapter.findOne<{ paystackCustomerCode?: string | null }>({\n      model: reference.type,\n      where: [{ field: \"id\", value: reference.id }],\n      select: [\"paystackCustomerCode\"],\n    });\n    legacyCode = legacy?.paystackCustomerCode ?? undefined;\n  } catch {\n    // The legacy column is optional after the v4 schema migration.\n  }\n  const existingCode = reference.paystackCustomerCode ?? persisted?.customerCode ?? legacyCode;\n  if (typeof existingCode === \"string\" && existingCode !== \"\") {\n    if (persisted === null) {\n      await store.saveCustomer(reference.type, reference.id, existingCode, reference.email);\n    }\n    return null;\n  }\n\n  const sdk = createPaystackAdapter(client);\n  let existing: PaystackCustomerResponse | null = null;\n  if (typeof client.customer?.fetch === \"function\") {\n    try {\n      existing =\n        ((await sdk.fetchCustomer(reference.email)) as PaystackCustomerResponse | undefined) ??\n        null;\n    } catch (error: unknown) {\n      if (!isNotFound(error)) {\n        logger.error(\"Failed to look up Paystack customer; customer creation was skipped\", error);\n        return null;\n      }\n    }\n  }\n\n  if (existing !== null) {\n    const code = customerCode(existing);\n    if (code === undefined) {\n      logger.error(\"Paystack customer lookup returned no customer code\");\n      return null;\n    }\n\n    const owned = ownsCustomer(existing, reference);\n    const canClaimLegacy =\n      reference.type === \"user\" && reference.emailVerified === true && !hasOwner(existing);\n    if (!owned && !canClaimLegacy) {\n      logger.error(\"Paystack customer belongs to another billing reference\");\n      return null;\n    }\n\n    const existingMetadata = (existing as unknown as Record<string, unknown>).metadata;\n    if (canClaimLegacy || parsePaystackMetadata(existingMetadata).customerType !== reference.type) {\n      await sdk.updateCustomer(code, {\n        metadata: ownershipMetadata(reference, existingMetadata),\n      });\n    }\n    await store.saveCustomer(reference.type, reference.id, code, reference.email);\n    return { customer: existing, created: false };\n  }\n\n  const customer = (await sdk.createCustomer({\n    ...input.createParams,\n    email: reference.email,\n    first_name: reference.name ?? undefined,\n    metadata: ownershipMetadata(reference),\n  })) as PaystackCustomerResponse;\n  const code = customerCode(customer);\n  if (code === undefined) return null;\n  await store.saveCustomer(reference.type, reference.id, code, reference.email);\n  return { customer, created: true };\n}\n","import type { GenericEndpointContext } from \"better-auth\";\n\nimport { createBillingStore } from \"./billing-store.ts\";\nimport { createPaystackAdapter } from \"./paystack-sdk.ts\";\nimport type {\n  AnyPaystackOptions,\n  PaystackClientLike,\n  PaystackPlan,\n  PaystackProduct,\n  Subscription,\n  PaystackProductResponse,\n} from \"./types.ts\";\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 normalizeSubscriptionGroup(group: string | undefined | null): string | null {\n  const normalized = group?.trim().toLowerCase();\n  return normalized === undefined || normalized === \"\" ? null : normalized;\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, \"subscriptionCode\" | \"planCode\">,\n): boolean {\n  if (isLocalSubscriptionCode(subscription.subscriptionCode)) {\n    return true;\n  }\n\n  if (typeof subscription.subscriptionCode === \"string\" && subscription.subscriptionCode !== \"\") {\n    return false;\n  }\n\n  return (\n    subscription.planCode === undefined ||\n    subscription.planCode === null ||\n    subscription.planCode === \"\"\n  );\n}\n\nexport function assertLocallyManagedSubscription(\n  subscription: Pick<Subscription, \"subscriptionCode\" | \"planCode\">,\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 subscriptions = (await store.findSubscriptionsByReference(organizationId)).filter(\n    (subscription) => subscription.status === \"active\" || subscription.status === \"trialing\",\n  );\n  const seatSubscriptions: Subscription[] = [];\n  for (const candidate of subscriptions) {\n    const candidatePlan = await getPlanByName(options, candidate.plan);\n    if (candidatePlan !== null && getPlanSeatAmount(candidatePlan) !== undefined) {\n      seatSubscriptions.push(candidate);\n    }\n  }\n  const members = await store.listMembers(organizationId);\n  const quantity = members.length;\n  for (const subscription of seatSubscriptions) {\n    if (\n      subscription.subscriptionCode === undefined ||\n      subscription.subscriptionCode === null ||\n      subscription.subscriptionCode === \"\"\n    )\n      continue;\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      ctx.context.logger.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 { createBillingStore } from \"./billing-store.ts\";\nimport type { AnyPaystackOptions, Subscription } from \"./types.ts\";\nimport { getPlanByName } from \"./utils.ts\";\n\nexport const getOrganizationSubscription = async (\n  ctx: GenericEndpointContext,\n  organizationId: string,\n  groupId?: string | null,\n): Promise<Subscription | null> => {\n  return createBillingStore(ctx).findCurrentSubscription(organizationId, groupId);\n};\n\nexport const checkSeatLimit = async (\n  ctx: GenericEndpointContext,\n  organizationId: string,\n  seatsToAdd = 1,\n): Promise<boolean> => {\n  const store = createBillingStore(ctx);\n  const subscriptions = (await store.findSubscriptionsByReference(organizationId)).filter(\n    (subscription) => subscription.status === \"active\" || subscription.status === \"trialing\",\n  );\n  const seatLimit = subscriptions.reduce<number | undefined>(\n    (maximum, subscription) =>\n      typeof subscription.seats === \"number\"\n        ? Math.max(maximum ?? subscription.seats, subscription.seats)\n        : maximum,\n    undefined,\n  );\n  const members = await store.listMembers(organizationId);\n\n  if (seatLimit === undefined) {\n    return true; // No subscription, no specific limit enforcement here (or maybe allow depending on config)\n  }\n\n  if (members.length + seatsToAdd > seatLimit) {\n    throw new APIError(\"FORBIDDEN\", {\n      message: `Organization member limit reached. Used: ${members.length}, Max: ${seatLimit}`,\n    });\n  }\n\n  return true;\n};\n\nexport async function getOrganizationEntitlements(\n  ctx: GenericEndpointContext,\n  organizationId: string,\n  options: AnyPaystackOptions,\n): Promise<{ limits: Record<string, number>; features: string[] }> {\n  const subscriptions = (\n    await createBillingStore(ctx).findSubscriptionsByReference(organizationId)\n  ).filter(\n    (subscription) => subscription.status === \"active\" || subscription.status === \"trialing\",\n  );\n  const limits: Record<string, number> = {};\n  const features = new Set<string>();\n  for (const subscription of subscriptions) {\n    const plan = await getPlanByName(options, subscription.plan);\n    for (const [name, value] of Object.entries(plan?.limits ?? {})) {\n      if (typeof value === \"number\" && Number.isFinite(value)) {\n        limits[name] = Math.max(limits[name] ?? value, value);\n      }\n    }\n    for (const feature of plan?.features ?? []) features.add(feature);\n  }\n  return { limits, features: [...features] };\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 { Buffer as NodeBuffer } from \"node:buffer\";\nimport { createCipheriv, createDecipheriv, createHash, randomBytes } from \"node:crypto\";\n\nconst ALGORITHM = \"aes-256-gcm\";\nconst VERSION = \"v1\";\nconst IV_LENGTH = 12;\n\nfunction deriveKey(secret: string): Uint8Array {\n  if (typeof secret !== \"string\" || secret.trim() === \"\") {\n    throw new Error(\"A non-empty credential encryption key is required\");\n  }\n  return createHash(\"sha256\").update(secret, \"utf8\").digest();\n}\n\nexport function encryptPaystackCredential(value: string, secret: string): string {\n  if (value === \"\") throw new Error(\"Cannot encrypt an empty Paystack credential\");\n  const iv = randomBytes(IV_LENGTH);\n  const cipher = createCipheriv(ALGORITHM, deriveKey(secret), iv);\n  const ciphertext = NodeBuffer.concat([cipher.update(value, \"utf8\"), cipher.final()]);\n  const authTag = cipher.getAuthTag();\n  return [VERSION, iv.toString(\"hex\"), authTag.toString(\"hex\"), ciphertext.toString(\"hex\")].join(\n    \":\",\n  );\n}\n\nexport function decryptPaystackCredential(encrypted: string, secret: string): string {\n  const parts = encrypted.split(\":\");\n  if (parts.length !== 4 || parts[0] !== VERSION) {\n    throw new Error(\"Invalid Paystack credential ciphertext\");\n  }\n  const [, ivHex, authTagHex, ciphertextHex] = parts;\n  const iv = NodeBuffer.from(ivHex, \"hex\");\n  const authTag = NodeBuffer.from(authTagHex, \"hex\");\n  const ciphertext = NodeBuffer.from(ciphertextHex, \"hex\");\n  if (iv.length !== IV_LENGTH || authTag.length !== 16 || ciphertext.length === 0) {\n    throw new Error(\"Invalid Paystack credential ciphertext\");\n  }\n  const decipher = createDecipheriv(ALGORITHM, deriveKey(secret), iv);\n  decipher.setAuthTag(authTag);\n  return NodeBuffer.concat([decipher.update(ciphertext), decipher.final()]).toString(\"utf8\");\n}\n\nexport function resolveCredentialEncryptionKey(options: {\n  secretKey: string;\n  credentialEncryptionKey?: string;\n}): string {\n  const key = options.credentialEncryptionKey ?? options.secretKey;\n  if (typeof key !== \"string\" || key.trim() === \"\") {\n    throw new Error(\"credentialEncryptionKey or secretKey must be a non-empty string\");\n  }\n  return key;\n}\n","import type { createBillingStoreFromAdapter } from \"./billing-store.ts\";\nimport {\n  decryptPaystackCredential,\n  encryptPaystackCredential,\n  resolveCredentialEncryptionKey,\n} from \"./credential-crypto.ts\";\nimport { PAYSTACK_MODELS } from \"./models.ts\";\nimport type { PaystackOptions } from \"./types.ts\";\n\ntype Adapter = Parameters<typeof createBillingStoreFromAdapter>[0];\n\ninterface StoredPaymentCredential {\n  id: string;\n  subscriptionId: string;\n  authorizationCodeEncrypted?: string | null;\n  emailTokenEncrypted?: string | null;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface PaystackPaymentCredentialValues {\n  authorizationCode?: string | null;\n  emailToken?: string | null;\n}\n\nexport async function readPaystackPaymentCredentials(\n  adapter: Adapter,\n  options: PaystackOptions,\n  subscriptionId: string,\n): Promise<PaystackPaymentCredentialValues | null> {\n  let row: StoredPaymentCredential | null;\n  try {\n    row = await adapter.findOne<StoredPaymentCredential>({\n      model: PAYSTACK_MODELS.paymentCredential,\n      where: [{ field: \"subscriptionId\", value: subscriptionId }],\n    });\n  } catch {\n    return null;\n  }\n  if (!row) return null;\n  const key = resolveCredentialEncryptionKey(options);\n  const authorizationCodeEncrypted = row.authorizationCodeEncrypted;\n  const emailTokenEncrypted = row.emailTokenEncrypted;\n  return {\n    authorizationCode:\n      typeof authorizationCodeEncrypted === \"string\" && authorizationCodeEncrypted !== \"\"\n        ? decryptPaystackCredential(authorizationCodeEncrypted, key)\n        : undefined,\n    emailToken:\n      typeof emailTokenEncrypted === \"string\" && emailTokenEncrypted !== \"\"\n        ? decryptPaystackCredential(emailTokenEncrypted, key)\n        : undefined,\n  };\n}\n\nexport async function savePaystackPaymentCredentials(\n  adapter: Adapter,\n  options: PaystackOptions,\n  subscriptionId: string,\n  values: PaystackPaymentCredentialValues,\n): Promise<void> {\n  const authorizationCode = values.authorizationCode ?? undefined;\n  const emailToken = values.emailToken ?? undefined;\n  if (authorizationCode === undefined && emailToken === undefined) return;\n  const key = resolveCredentialEncryptionKey(options);\n  const now = new Date();\n  let existing: StoredPaymentCredential | null = null;\n  try {\n    existing = await adapter.findOne<StoredPaymentCredential>({\n      model: PAYSTACK_MODELS.paymentCredential,\n      where: [{ field: \"subscriptionId\", value: subscriptionId }],\n    });\n  } catch {\n    // Some adapters create provider tables lazily on first write.\n  }\n  const update = {\n    ...(authorizationCode !== undefined\n      ? { authorizationCodeEncrypted: encryptPaystackCredential(authorizationCode, key) }\n      : {}),\n    ...(emailToken !== undefined\n      ? { emailTokenEncrypted: encryptPaystackCredential(emailToken, key) }\n      : {}),\n    updatedAt: now,\n  };\n  if (existing !== null) {\n    await adapter.update({\n      model: PAYSTACK_MODELS.paymentCredential,\n      update,\n      where: [{ field: \"id\", value: existing.id }],\n    });\n    return;\n  }\n  await adapter.create({\n    model: PAYSTACK_MODELS.paymentCredential,\n    data: {\n      subscriptionId,\n      ...update,\n      createdAt: now,\n    },\n  });\n}\n\nexport async function findStoredPaystackPaymentCredential(\n  adapter: Adapter,\n  subscriptionId: string,\n): Promise<StoredPaymentCredential | null> {\n  try {\n    return (\n      (await adapter.findOne<StoredPaymentCredential>({\n        model: PAYSTACK_MODELS.paymentCredential,\n        where: [{ field: \"subscriptionId\", value: subscriptionId }],\n      })) ?? null\n    );\n  } catch {\n    return null;\n  }\n}\n","import type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\nimport type { AnyPaystackOptions, Session, User } from \"./types.ts\";\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 { createHash, randomUUID } from \"node:crypto\";\n\nimport type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport * as z from \"zod/v4\";\n\nimport { createBillingStore } from \"./billing-store.ts\";\nimport { PAYSTACK_MODELS } from \"./models.ts\";\nimport type {\n  AnyPaystackOptions,\n  PaystackPlan,\n  PaystackWebhookPayload,\n  PaystackWebhookEventRecord,\n  Subscription,\n} from \"./types.ts\";\n\nconst progressSchema = z.object({\n  version: z.literal(1),\n  completed: z.array(z.enum([\"complete\", \"update\", \"trialStart\"])),\n  remoteCreationSubmitted: z.boolean().optional(),\n  remoteSubscriptionCode: z.string().optional(),\n});\ninterface Claim {\n  eventId: string;\n  status: string;\n  progress: z.infer<typeof progressSchema>;\n}\nconst unavailable = () =>\n  new APIError(\"SERVICE_UNAVAILABLE\", {\n    message: \"Subscription fulfillment is pending. Retry verification.\",\n  });\n\n/** Persist delivery intent before activation, sharing one lease across verification transports. */\nexport async function claimSubscriptionFulfillment(\n  ctx: GenericEndpointContext,\n  reference: string,\n  subscription: Subscription,\n  phase = \"subscription-fulfillment\",\n): Promise<Claim | null> {\n  const store = createBillingStore(ctx);\n  const eventId = `${phase}:${createHash(\"sha256\")\n    .update(JSON.stringify([reference, subscription.id]))\n    .digest(\"hex\")}`;\n  const findRecord = () =>\n    ctx.context.adapter.findOne<PaystackWebhookEventRecord>({\n      model: PAYSTACK_MODELS.webhookEvent,\n      where: [{ field: \"eventId\", value: eventId }],\n    });\n  let record = await findRecord();\n  if (record === null) {\n    // Existing entitlements predate this delivery journal; do not replay historical callbacks.\n    if (subscription.status !== \"incomplete\") return null;\n    try {\n      record = await store.createWebhookEvent({\n        eventId,\n        eventType: \"subscription.fulfillment\",\n        reference,\n        status: \"pending\",\n        payload: JSON.stringify({ version: 1, completed: [] }),\n        createdAt: new Date(),\n        updatedAt: new Date(),\n      });\n    } catch (error) {\n      record = await findRecord();\n      if (record === null) throw error;\n    }\n  }\n  if (record.status === \"processed\") return null;\n  if (\n    record.status.startsWith(\"processing:\") &&\n    Date.now() - new Date(record.updatedAt).getTime() < 300_000\n  )\n    throw unavailable();\n  const progress = progressSchema.parse(JSON.parse(record.payload));\n  const status = `processing:${randomUUID()}`;\n  const claimed = await ctx.context.adapter.update({\n    model: PAYSTACK_MODELS.webhookEvent,\n    where: [\n      { field: \"eventId\", value: eventId },\n      { field: \"status\", value: record.status },\n      { field: \"updatedAt\", value: record.updatedAt },\n    ],\n    update: { status, updatedAt: new Date() },\n  });\n  if (claimed === null) throw unavailable();\n  return { eventId, status, progress };\n}\n\nexport async function deliverTrialStart(\n  ctx: GenericEndpointContext,\n  claim: Claim,\n  subscription: Subscription,\n  plan: PaystackPlan | undefined,\n): Promise<void> {\n  if (!claim.progress.completed.includes(\"trialStart\")) {\n    await checkpoint(ctx, claim);\n    await plan?.freeTrial?.onTrialStart?.(subscription);\n    claim.progress.completed.push(\"trialStart\");\n    await checkpoint(ctx, claim);\n  }\n  await checkpoint(ctx, claim, true);\n}\n\nexport async function reserveRemoteTrialSubscription(\n  ctx: GenericEndpointContext,\n  claim: Claim,\n  create: () => Promise<string | undefined>,\n): Promise<string> {\n  if (claim.progress.remoteSubscriptionCode !== undefined)\n    return claim.progress.remoteSubscriptionCode;\n  if (claim.progress.remoteCreationSubmitted === true)\n    throw new APIError(\"SERVICE_UNAVAILABLE\", {\n      message:\n        \"Remote trial subscription creation is unresolved. Reconcile the existing provider subscription before retrying.\",\n    });\n  claim.progress.remoteCreationSubmitted = true;\n  await checkpoint(ctx, claim);\n  const code = await create();\n  if (code === undefined || code === \"\") throw unavailable();\n  claim.progress.remoteSubscriptionCode = code;\n  await checkpoint(ctx, claim);\n  return code;\n}\n\nasync function checkpoint(\n  ctx: GenericEndpointContext,\n  claim: Claim,\n  processed = false,\n): Promise<void> {\n  const updated = await ctx.context.adapter.update({\n    model: PAYSTACK_MODELS.webhookEvent,\n    where: [\n      { field: \"eventId\", value: claim.eventId },\n      { field: \"status\", value: claim.status },\n    ],\n    update: {\n      payload: JSON.stringify(claim.progress),\n      updatedAt: new Date(),\n      ...(processed ? { status: \"processed\", processedAt: new Date() } : {}),\n    },\n  });\n  if (updated === null) throw unavailable();\n}\n\nexport async function deliverSubscriptionFulfillment(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n  claim: Claim,\n  subscription: Subscription,\n  plan: PaystackPlan | undefined,\n  event: PaystackWebhookPayload,\n): Promise<void> {\n  if (plan !== undefined) {\n    const callbacks = {\n      complete: options.subscription?.onSubscriptionComplete,\n      update: options.subscription?.onSubscriptionUpdate,\n    };\n    for (const name of [\"complete\", \"update\"] as const) {\n      if (claim.progress.completed.includes(name)) continue;\n      // Refresh ownership before invoking application code. Hooks must still be idempotent:\n      // a process can stop after its side effect and before this journal checkpoint.\n      await checkpoint(ctx, claim);\n      await callbacks[name]?.({ event, subscription, plan }, ctx);\n      claim.progress.completed.push(name);\n      await checkpoint(ctx, claim);\n    }\n  }\n  await checkpoint(ctx, claim, true);\n}\n\nexport async function releaseSubscriptionFulfillment(\n  ctx: GenericEndpointContext,\n  claim: Claim,\n): Promise<void> {\n  await ctx.context.adapter.update({\n    model: PAYSTACK_MODELS.webhookEvent,\n    where: [\n      { field: \"eventId\", value: claim.eventId },\n      { field: \"status\", value: claim.status },\n    ],\n    update: { status: \"pending\", updatedAt: new Date() },\n  });\n}\n","import type { components } from \"@alexasomba/paystack-node\";\nimport type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\nimport { createBillingStore } from \"./billing-store.ts\";\nimport {\n  getMetadataBoolean,\n  getMetadataNumber,\n  getMetadataString,\n  parsePaystackMetadata,\n} from \"./metadata.ts\";\nimport { PAYSTACK_MODELS } from \"./models.ts\";\nimport { savePaystackPaymentCredentials } from \"./payment-credentials.ts\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk.ts\";\nimport { authorizeBillingReference } from \"./reference-access.ts\";\nimport {\n  claimSubscriptionFulfillment,\n  deliverSubscriptionFulfillment,\n  releaseSubscriptionFulfillment,\n  reserveRemoteTrialSubscription,\n} from \"./subscription-fulfillment.ts\";\nimport type {\n  AnyPaystackOptions,\n  PaystackCheckoutChannel,\n  PaystackTransaction,\n  PaystackTransactionResponse,\n  PaystackWebhookPayload,\n  Session,\n  Subscription,\n  User,\n} from \"./types.ts\";\nimport { getPlans, syncProductQuantityFromPaystack } from \"./utils.ts\";\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 = 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  if (\n    data.reference !== reference ||\n    (txRecord !== null && typeof txRecord.amount === \"number\" && txRecord.amount !== data.amount) ||\n    (txRecord !== null &&\n      typeof txRecord.currency === \"string\" &&\n      txRecord.currency !== data.currency)\n  ) {\n    return throwOrReturnFailure({\n      throwOnError,\n      apiStatus: \"BAD_REQUEST\",\n      source,\n      status,\n      reference,\n      data,\n      summary,\n      error: {\n        code: \"PAYMENT_INTENT_MISMATCH\",\n        message: \"Verified payment does not match the stored reference, amount, and currency.\",\n        status: 400,\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(\n      referenceId,\n      paystackCustomerCodeFromPaystack,\n      isOrganization,\n      data.customer?.email,\n    );\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 originalSubscription = await store.findSubscriptionById(subscriptionId);\n      if (\n        !originalSubscription ||\n        originalSubscription.status === \"canceled\" ||\n        originalSubscription.transactionReference === reference\n      )\n        return { ok: true, source, status, reference, data, ...summary };\n      const updatedSubscription = await store.updateSubscription(subscriptionId, {\n        plan: newPlan,\n        ...(typeof newSeatCount === \"number\" ? { seats: newSeatCount } : {}),\n        transactionReference: reference,\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      if (\n        updatedSubscription !== null &&\n        authorizationCode !== undefined &&\n        authorizationCode !== null &&\n        authorizationCode !== \"\"\n      ) {\n        await savePaystackPaymentCredentials(ctx.context.adapter, options, updatedSubscription.id, {\n          authorizationCode,\n        });\n      }\n    }\n\n    return {\n      ok: true,\n      source,\n      status,\n      reference,\n      data,\n      ...summary,\n    };\n  }\n\n  let subscriptionCode: 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  // Terminal entitlements are never reactivated by a payment replay.\n  if (!targetSub || ![\"incomplete\", \"active\", \"trialing\"].includes(targetSub.status)) {\n    return { ok: true, source, status, reference, data, ...summary };\n  }\n  const claim = await claimSubscriptionFulfillment(ctx, reference, targetSub);\n  if (claim === null) return { ok: true, source, status, reference, data, ...summary };\n  try {\n    if (targetSub.status !== \"incomplete\") {\n      if (\n        authorizationCode !== undefined &&\n        authorizationCode !== null &&\n        authorizationCode !== \"\"\n      ) {\n        await savePaystackPaymentCredentials(ctx.context.adapter, options, targetSub.id, {\n          authorizationCode,\n        });\n      }\n      await store.retireCompetingSubscriptions(\n        targetSub.referenceId,\n        targetSub.groupId ?? null,\n        targetSub.id,\n      );\n      const plans = await getPlans(options.subscription);\n      const plan = plans.find(\n        (candidate) => candidate.name.toLowerCase() === targetSub.plan.toLowerCase(),\n      );\n      await deliverSubscriptionFulfillment(\n        ctx,\n        options,\n        claim,\n        targetSub,\n        plan,\n        data as unknown as PaystackWebhookPayload,\n      );\n      return { ok: true, source, status, reference, data, ...summary };\n    }\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        subscriptionCode = `LOC_${reference}`;\n      } else if (\n        targetSub?.subscriptionCode !== undefined &&\n        targetSub.subscriptionCode !== null &&\n        targetSub.subscriptionCode !== \"\"\n      ) {\n        subscriptionCode = targetSub.subscriptionCode;\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 planCode = planConfig.planCode;\n        subscriptionCode = await reserveRemoteTrialSubscription(ctx, claim, async () => {\n          const subResRaw = await paystack?.subscription?.create({\n            body: {\n              customer: email,\n              plan: planCode,\n              authorization: authorizationCode,\n              start_date: trialEnd,\n            },\n          });\n          const subRes =\n            unwrapSdkResult<components[\"schemas\"][\"SubscriptionListResponseArray\"]>(subResRaw);\n          return subRes?.subscription_code;\n        });\n      }\n    } else if (isTrial === false) {\n      const planCodeFromPaystack = (data as { plan?: { plan_code?: string | null } }).plan\n        ?.plan_code;\n      if (\n        planCodeFromPaystack === undefined ||\n        planCodeFromPaystack === null ||\n        planCodeFromPaystack === \"\"\n      ) {\n        subscriptionCode = `LOC_${reference}`;\n      } else {\n        subscriptionCode =\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      const plans = await getPlans(options.subscription);\n      const resolvedPlan = plans.find(\n        (candidate) => candidate.name.toLowerCase() === targetSub.plan.toLowerCase(),\n      );\n      updatedSubscription = await ctx.context.adapter.update<Subscription>({\n        model: PAYSTACK_MODELS.subscription,\n        where: [\n          { field: \"id\", value: targetSub.id },\n          { field: \"status\", value: \"incomplete\" },\n          { field: \"transactionReference\", value: reference },\n        ],\n        update: {\n          status: isTrial ? \"trialing\" : \"active\",\n          billingInterval: resolvedPlan?.interval ?? targetSub.billingInterval ?? null,\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          ...(subscriptionCode !== undefined ? { subscriptionCode } : {}),\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      if (\n        authorizationCode !== undefined &&\n        authorizationCode !== null &&\n        authorizationCode !== \"\" &&\n        updatedSubscription !== null\n      ) {\n        await savePaystackPaymentCredentials(ctx.context.adapter, options, updatedSubscription.id, {\n          authorizationCode,\n        });\n      }\n      if (\n        updatedSubscription !== null &&\n        (updatedSubscription.status === \"active\" || updatedSubscription.status === \"trialing\")\n      ) {\n        await store.retireCompetingSubscriptions(\n          updatedSubscription.referenceId,\n          updatedSubscription.groupId ?? null,\n          updatedSubscription.id,\n        );\n      }\n    }\n\n    if (updatedSubscription !== undefined && updatedSubscription !== null) {\n      const plans = await getPlans(options.subscription);\n      const plan = plans.find(\n        (candidate) => candidate.name.toLowerCase() === updatedSubscription.plan.toLowerCase(),\n      );\n      await deliverSubscriptionFulfillment(\n        ctx,\n        options,\n        claim,\n        updatedSubscription,\n        plan,\n        data as unknown as PaystackWebhookPayload,\n      );\n    } else {\n      throw new APIError(\"SERVICE_UNAVAILABLE\", {\n        message: \"Subscription activation is pending. Retry verification.\",\n      });\n    }\n\n    return {\n      ok: true,\n      source,\n      status,\n      reference,\n      data,\n      ...summary,\n    };\n  } catch (error) {\n    await releaseSubscriptionFulfillment(ctx, claim);\n    throw error;\n  }\n}\n","import { APIError, createAuthMiddleware, type AuthMiddleware } from \"better-auth/api\";\n\nimport {\n  authorizeBillingReference,\n  type BillingReferenceAction,\n  resolveBillingReferenceId,\n} from \"./reference-access.ts\";\nimport type { PaystackOptions } from \"./types.ts\";\n\nexport { hasBillingRole } from \"./reference-access.ts\";\n\nexport const referenceMiddleware = (\n  options: PaystackOptions,\n  action: BillingReferenceAction,\n): AuthMiddleware =>\n  createAuthMiddleware(async (ctx) => {\n    const session = ctx.context.session;\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","/** Accept only absolute HTTP(S) URLs or root-relative paths on the Better Auth origin. */\nfunction hasControlCharacters(value: string): boolean {\n  for (const character of value) {\n    const codePoint = character.codePointAt(0);\n    if (\n      codePoint !== undefined &&\n      (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f))\n    ) {\n      return true;\n    }\n  }\n  return false;\n}\n\nexport function isTrustedCallbackURL(callbackURL: string, baseURL: string): boolean {\n  if (\n    callbackURL.startsWith(\"//\") ||\n    callbackURL.includes(\"\\\\\") ||\n    hasControlCharacters(callbackURL)\n  ) {\n    return false;\n  }\n  try {\n    const base = new URL(baseURL);\n    const isAbsoluteHttpURL = /^https?:\\/\\//i.test(callbackURL);\n    if (!isAbsoluteHttpURL && !callbackURL.startsWith(\"/\")) return false;\n    const callback = new URL(callbackURL, base);\n    return (\n      (callback.protocol === \"http:\" || callback.protocol === \"https:\") &&\n      callback.origin === base.origin &&\n      callback.username === \"\" &&\n      callback.password === \"\"\n    );\n  } catch {\n    return false;\n  }\n}\n","import type { GenericEndpointContext } from \"better-auth\";\n\nimport { createBillingStore } from \"../billing-store.ts\";\nimport type { AnyPaystackOptions, PaystackPlan, PaystackProduct } from \"../types.ts\";\nimport { getPlans, getProducts } from \"../utils.ts\";\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 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  subscriptionId: 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  confirmTrialTokenizationCharge: 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  subscriptionId: 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  confirmTrialTokenizationCharge: z.boolean().optional(),\n});\n","import { defineErrorCodes } from \"better-auth\";\nimport type { RawError } from \"better-auth\";\n\nimport type { AnyPaystackOptions, PaystackCheckoutChannel } from \"../types.ts\";\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","/* 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 type { components } from \"@alexasomba/paystack-node\";\nimport type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\nimport { createBillingStore } from \"./billing-store.ts\";\nimport { getOrganizationSubscription } from \"./limits.ts\";\nimport { createProrationMetadata, stringifyPaystackMetadata } from \"./metadata.ts\";\nimport { PAYSTACK_MODELS } from \"./models.ts\";\nimport { readPaystackPaymentCredentials } from \"./payment-credentials.ts\";\nimport { createPaystackAdapter } from \"./paystack-sdk.ts\";\nimport type {\n  AnyPaystackOptions,\n  PaystackChargeAuthorizationResponse,\n  PaystackCheckoutChannel,\n  PaystackInitializeResult,\n  PaystackPlan,\n  Subscription,\n  User,\n  PaystackSubscriptionOperation,\n  PaystackSubscriptionOperationPhase,\n} from \"./types.ts\";\nimport {\n  assertLocallyManagedSubscription,\n  calculatePlanAmount,\n  getPlanByName,\n  getPlanSeatAmount,\n  normalizeSubscriptionGroup,\n} from \"./utils.ts\";\n\n/** Keep reservation context invocation-local, including concurrent requests through one plugin. */\nexport async function runSubscriptionOperation<TResult extends PaystackInitializeResult>(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions | undefined,\n  operation: PaystackSubscriptionOperation,\n  run: (\n    providerReference: string | undefined,\n    setPhase: (phase: PaystackSubscriptionOperationPhase) => void,\n  ) => Promise<TResult>,\n): Promise<TResult> {\n  const hooks = options?.subscription?.operationHooks;\n  if (hooks === undefined) return run(undefined, () => undefined);\n  const decision = await hooks.before(operation, ctx);\n  if (decision.kind === \"replay\") {\n    const validKind =\n      operation.kind === \"schedule\"\n        ? decision.result.kind === \"scheduled\"\n        : operation.kind === \"initialize\"\n          ? decision.result.kind === \"checkout\"\n          : operation.kind === \"local-change\"\n            ? decision.result.kind === \"prorated\"\n            : decision.result.kind === \"checkout\" || decision.result.kind === \"prorated\";\n    if (!validKind)\n      throw new APIError(\"BAD_REQUEST\", {\n        message: \"Operation replay does not match the validated operation kind.\",\n      });\n    return decision.result as TResult;\n  }\n  if (decision.kind === \"block\") {\n    throw new APIError(\"CONFLICT\", {\n      message: decision.message ?? \"Subscription operation is blocked.\",\n    });\n  }\n  if (\n    decision.kind !== \"proceed\" ||\n    typeof decision.providerReference !== \"string\" ||\n    decision.providerReference.trim() === \"\"\n  ) {\n    throw new APIError(\"BAD_REQUEST\", {\n      message: \"Operation hook must reserve a provider reference.\",\n    });\n  }\n  const invocation = {\n    ...operation,\n    providerReference: decision.providerReference,\n    context: decision.context,\n  };\n  let phase: PaystackSubscriptionOperationPhase =\n    operation.kind === \"schedule\" || operation.kind === \"local-change\" ? \"persistence\" : \"provider\";\n  try {\n    const result = await run(decision.providerReference, (next) => {\n      phase = next;\n    });\n    phase = \"completion\";\n    await hooks.after?.({ ...invocation, result }, ctx);\n    return result;\n  } catch (error: unknown) {\n    try {\n      await hooks.onError?.({ ...invocation, phase, error }, ctx);\n    } catch {\n      ctx.context.logger.error(\"Paystack operation error hook failed\", { phase });\n    }\n    throw error;\n  }\n}\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    userId?: string;\n    referenceId: string;\n    subscriptionId?: string;\n    plan?: PaystackPlan;\n    scheduleAtPeriodEnd?: boolean;\n    cancelAtPeriodEnd?: boolean;\n  },\n  options?: AnyPaystackOptions,\n): Promise<Extract<PaystackInitializeResult, { kind: \"scheduled\" }> | null> {\n  const groupId = normalizeSubscriptionGroup(input.plan?.group);\n  if (input.plan !== undefined && input.scheduleAtPeriodEnd === true) {\n    const existingSub =\n      input.subscriptionId === undefined\n        ? await getOrganizationSubscription(ctx, input.referenceId, groupId)\n        : await createBillingStore(ctx).findSubscriptionById(input.subscriptionId);\n    if (existingSub?.status === \"active\") {\n      return runSubscriptionOperation<Extract<PaystackInitializeResult, { kind: \"scheduled\" }>>(\n        ctx,\n        options,\n        {\n          actor: { id: input.userId ?? existingSub.userId },\n          referenceId: input.referenceId,\n          kind: \"schedule\",\n          subscription: existingSub,\n          intent: {\n            plan: input.plan?.name ?? existingSub.plan,\n            interval: input.plan?.interval ?? existingSub.billingInterval ?? undefined,\n            groupId,\n            scheduleAtPeriodEnd: input.scheduleAtPeriodEnd,\n            cancelAtPeriodEnd: input.cancelAtPeriodEnd,\n          },\n        },\n        async () => {\n          await ctx.context.adapter.update({\n            model: PAYSTACK_MODELS.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  }\n\n  if (input.cancelAtPeriodEnd === true) {\n    const existingSub =\n      input.subscriptionId === undefined\n        ? await getOrganizationSubscription(\n            ctx,\n            input.referenceId,\n            input.plan === undefined ? undefined : groupId,\n          )\n        : await createBillingStore(ctx).findSubscriptionById(input.subscriptionId);\n    if (existingSub?.status === \"active\") {\n      return runSubscriptionOperation<Extract<PaystackInitializeResult, { kind: \"scheduled\" }>>(\n        ctx,\n        options,\n        {\n          actor: { id: input.userId ?? existingSub.userId },\n          referenceId: input.referenceId,\n          kind: \"schedule\",\n          subscription: existingSub,\n          intent: {\n            plan: input.plan?.name ?? existingSub.plan,\n            interval: input.plan?.interval ?? existingSub.billingInterval ?? undefined,\n            groupId,\n            scheduleAtPeriodEnd: input.scheduleAtPeriodEnd,\n            cancelAtPeriodEnd: input.cancelAtPeriodEnd,\n          },\n        },\n        async () => {\n          await ctx.context.adapter.update({\n            model: PAYSTACK_MODELS.subscription,\n            where: [{ field: \"id\", value: existingSub.id }],\n            update: {\n              cancelAtPeriodEnd: true,\n              cancelAt: existingSub.periodEnd ?? null,\n              canceledAt: new Date(),\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  }\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: PAYSTACK_MODELS.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<User>({\n    model: \"user\",\n    where: [{ field: \"id\", value: (ownerMember as { userId: string }).userId }],\n  });\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    subscriptionId?: 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 =\n    input.subscriptionId === undefined\n      ? await store.findCurrentSubscription(\n          input.referenceId,\n          normalizeSubscriptionGroup(input.plan.group),\n        )\n      : await store.findSubscriptionById(input.subscriptionId);\n  if (\n    existingSub?.status !== \"active\" ||\n    existingSub.subscriptionCode === undefined ||\n    existingSub.subscriptionCode === null ||\n    existingSub.subscriptionCode === \"\" ||\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 ?? 1);\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  const proratedAmount = Math.round((costDifference / totalDays) * remainingDays);\n  const hasCharge = costDifference > 0 && remainingDays > 0;\n  if (hasCharge && 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  const credentials = hasCharge\n    ? await readPaystackPaymentCredentials(ctx.context.adapter, options, existingSub.id)\n    : null;\n  const hasAuthorization =\n    credentials?.authorizationCode !== undefined &&\n    credentials.authorizationCode !== null &&\n    credentials.authorizationCode !== \"\";\n  return runSubscriptionOperation<Exclude<PaystackInitializeResult, { kind: \"scheduled\" }>>(\n    ctx,\n    options,\n    {\n      actor: { id: input.userId ?? existingSub.userId },\n      referenceId: input.referenceId,\n      kind: hasCharge\n        ? hasAuthorization\n          ? \"proration-charge\"\n          : \"proration-initialize\"\n        : \"local-change\",\n      subscription: existingSub,\n      intent: {\n        plan: input.plan.name.toLowerCase(),\n        amount: hasCharge ? proratedAmount : 0,\n        currency: input.finalCurrency,\n        interval: input.plan.interval,\n        quantity: newSeatCount,\n        groupId: normalizeSubscriptionGroup(input.plan.group),\n        callbackURL: input.callbackURL,\n      },\n    },\n    async (providerReference, setPhase) => {\n      let completedProrationReference: string | undefined;\n\n      if (costDifference > 0 && remainingDays > 0) {\n        const paystack = createPaystackAdapter(options.paystackClient);\n        if (\n          credentials?.authorizationCode !== undefined &&\n          credentials.authorizationCode !== null &&\n          credentials.authorizationCode !== \"\"\n        ) {\n          const sdkRes = (await paystack.chargeAuthorization({\n            email: input.targetEmail,\n            amount: proratedAmount,\n            authorization_code: credentials.authorizationCode,\n            reference:\n              providerReference ??\n              `upg_${existingSub.id}_${Date.now()}_${Math.random().toString(36).substring(7)}`,\n            metadata: serializedProrationMetadata,\n          })) as PaystackChargeAuthorizationResponse;\n\n          if (providerReference !== undefined && sdkRes?.reference !== providerReference) {\n            throw new APIError(\"BAD_REQUEST\", {\n              message: \"Provider reference does not match reserved operation.\",\n            });\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          setPhase(\"persistence\");\n          await store.createTransaction({\n            reference: sdkRes.reference ?? \"\",\n            paystackId:\n              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            ...(providerReference !== undefined ? { reference: providerReference } : {}),\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          if (providerReference !== undefined && initRes?.reference !== providerReference) {\n            throw new APIError(\"BAD_REQUEST\", {\n              message: \"Provider reference does not match reserved operation.\",\n            });\n          }\n          setPhase(\"persistence\");\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      setPhase(\"persistence\");\n      await store.updateSubscription(existingSub.id, {\n        plan: input.plan.name,\n        seats: newSeatCount,\n        ...(completedProrationReference !== undefined\n          ? { transactionReference: 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  );\n}\n","import { randomUUID, createHash } from \"node:crypto\";\n\nimport type { components } from \"@alexasomba/paystack-node\";\nimport { HIDE_METADATA } from \"better-auth\";\nimport type { GenericEndpointContext, StrictEndpoint } from \"better-auth\";\nimport {\n  APIError,\n  getSessionFromCtx,\n  type AuthMiddleware,\n  originCheckMiddleware,\n  sessionMiddleware,\n} from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/api\";\n/* oxlint-disable no-restricted-imports */\nimport { z } from \"zod\";\n\nimport { createBillingStore } from \"./billing-store.ts\";\nimport {\n  createCheckoutMetadata,\n  hasPaystackMetadata,\n  parsePaystackMetadata,\n  stringifyPaystackMetadata,\n} from \"./metadata.ts\";\nimport { PAYSTACK_MODELS } from \"./models.ts\";\nimport {\n  readPaystackPaymentCredentials,\n  savePaystackPaymentCredentials,\n} from \"./payment-credentials.ts\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk.ts\";\nimport { reconcilePaystackTransaction } from \"./reconciliation.ts\";\nimport { authorizeBillingReference } from \"./reference-access.ts\";\nimport { referenceMiddleware } from \"./reference-middleware.ts\";\nimport { isTrustedCallbackURL } from \"./route-modules/callback-url.ts\";\nimport {\n  getConfiguredCatalog,\n  listStoredPlans,\n  listStoredProducts,\n} from \"./route-modules/catalog.ts\";\nimport { initializeTransactionBodySchema } from \"./route-modules/checkout.ts\";\nimport {\n  getAllowedSubscriptionChannels,\n  hmacSha512Hex,\n  PAYSTACK_ERROR_CODES,\n} from \"./route-modules/shared.ts\";\nimport {\n  enableDisableBodySchema,\n  tryGetEmailTokenFromSubscriptionManageLink,\n} from \"./route-modules/subscriptions.ts\";\nimport {\n  getWebhookClientIP,\n  getWebhookHeaders,\n  getWebhookRequest,\n} from \"./route-modules/webhook.ts\";\nimport {\n  claimSubscriptionFulfillment,\n  deliverTrialStart,\n  releaseSubscriptionFulfillment,\n} from \"./subscription-fulfillment.ts\";\nimport {\n  handleProratedUpgrade,\n  resolveCheckoutTargetEmail,\n  resolveTrialLifecycle,\n  scheduleSubscriptionLifecycleChange,\n  runSubscriptionOperation,\n} from \"./subscription-lifecycle.ts\";\nimport type {\n  InputPaystackProduct,\n  PaystackTransaction,\n  AnyPaystackOptions,\n  PaystackProduct,\n  Subscription,\n  Member,\n  PaystackPlan,\n  PaystackWebhookPayload,\n  User,\n  PaystackCheckoutChannel,\n  PaystackInitializeResult,\n} from \"./types.ts\";\nimport {\n  syncProductQuantityFromPaystack,\n  getPlanByName,\n  getPlans,\n  getProductByName,\n  getPlanSeatAmount,\n  calculatePlanAmount,\n  isLocalSubscriptionCode,\n  normalizeSubscriptionGroup,\n} from \"./utils.ts\";\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 expected = await hmacSha512Hex(options.secretKey, 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      const reference = (data as { reference?: string | null })?.reference;\n      const eventId = createHash(\"sha256\").update(payload).digest(\"hex\");\n      const store = createBillingStore(ctx);\n      let claimStatus: string | undefined;\n      try {\n        let existingEvent = await store.findWebhookEvent(eventId);\n        if (existingEvent?.status === \"processed\") return ctx.json({ received: true });\n        if (existingEvent === null) {\n          try {\n            existingEvent = await store.createWebhookEvent({\n              eventId,\n              eventType: eventName,\n              reference: reference ?? null,\n              payload,\n              status: \"pending\",\n              createdAt: new Date(),\n              updatedAt: new Date(),\n            });\n          } catch (error) {\n            existingEvent = await store.findWebhookEvent(eventId);\n            if (!existingEvent) throw error;\n          }\n        }\n        if (existingEvent.status === \"processed\") return ctx.json({ received: true });\n        if (\n          existingEvent.status.startsWith(\"processing:\") &&\n          new Date(existingEvent.updatedAt).getTime() > Date.now() - 5 * 60_000\n        )\n          throw new Error(\"Webhook is already processing; retry later.\");\n        claimStatus = `processing:${randomUUID()}`;\n        const claimed = await ctx.context.adapter.update({\n          model: PAYSTACK_MODELS.webhookEvent,\n          where: [\n            { field: \"eventId\", value: eventId },\n            { field: \"status\", value: existingEvent.status },\n            { field: \"updatedAt\", value: existingEvent.updatedAt },\n          ],\n          update: { status: claimStatus, updatedAt: new Date() },\n        });\n        if (claimed === null) throw new Error(\"Webhook claim was lost; retry later.\");\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\n              ? String(paystackIdRaw)\n              : 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              throw e;\n            }\n\n            if (options.subscription?.enabled === true) {\n              const pendingTrial = await ctx.context.adapter.findOne<Subscription>({\n                model: PAYSTACK_MODELS.subscription,\n                where: [{ field: \"transactionReference\", value: reference }],\n              });\n              if (\n                pendingTrial !== null &&\n                [\"incomplete\", \"trialing\"].includes(pendingTrial.status) &&\n                pendingTrial.trialStart !== undefined &&\n                pendingTrial.trialStart !== null\n              ) {\n                const trialClaim = await claimSubscriptionFulfillment(\n                  ctx,\n                  reference,\n                  pendingTrial,\n                  \"trial-start\",\n                );\n                if (trialClaim !== null) {\n                  try {\n                    const startedTrial =\n                      pendingTrial.status === \"trialing\"\n                        ? pendingTrial\n                        : await ctx.context.adapter.update<Subscription>({\n                            model: PAYSTACK_MODELS.subscription,\n                            where: [\n                              { field: \"id\", value: pendingTrial.id },\n                              { field: \"status\", value: \"incomplete\" },\n                              { field: \"transactionReference\", value: reference },\n                            ],\n                            update: { status: \"trialing\", updatedAt: new Date() },\n                          });\n                    if (startedTrial === null)\n                      throw new Error(\"Trial activation changed concurrently; retry later.\");\n                    const trialPlan = await getPlanByName(options, pendingTrial.plan);\n                    await deliverTrialStart(ctx, trialClaim, startedTrial, trialPlan ?? undefined);\n                  } catch (error) {\n                    await releaseSubscriptionFulfillment(ctx, trialClaim);\n                    throw error;\n                  }\n                }\n              }\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              throw 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              throw e;\n            }\n            if (options.subscription?.enabled === true) {\n              const pendingTrial = await ctx.context.adapter.findOne<Subscription>({\n                model: PAYSTACK_MODELS.subscription,\n                where: [{ field: \"transactionReference\", value: reference }],\n              });\n              if (\n                pendingTrial?.status === \"incomplete\" &&\n                pendingTrial.trialStart !== undefined &&\n                pendingTrial.trialStart !== null\n              ) {\n                const endedAt = new Date();\n                await ctx.context.adapter.update({\n                  model: PAYSTACK_MODELS.subscription,\n                  where: [{ field: \"id\", value: pendingTrial.id }],\n                  update: { status: \"canceled\", endedAt, updatedAt: endedAt },\n                });\n              }\n            }\n          }\n        }\n\n        if ((eventName as string) === \"invoice.payment_failed\") {\n          const invoice = data as {\n            subscription?: { subscription_code?: string | null };\n            subscription_code?: string | null;\n          };\n          const subscriptionCode =\n            invoice.subscription?.subscription_code ?? invoice.subscription_code;\n          if (\n            subscriptionCode !== null &&\n            subscriptionCode !== undefined &&\n            subscriptionCode !== \"\"\n          ) {\n            const existing = await ctx.context.adapter.findOne<Subscription>({\n              model: PAYSTACK_MODELS.subscription,\n              where: [{ field: \"subscriptionCode\", value: subscriptionCode }],\n            });\n            if (existing && existing.status !== \"canceled\" && existing.status !== \"past_due\") {\n              const pastDue = { ...existing, status: \"past_due\", updatedAt: new Date() };\n              await ctx.context.adapter.update({\n                model: PAYSTACK_MODELS.subscription,\n                where: [{ field: \"id\", value: existing.id }],\n                update: { status: pastDue.status, updatedAt: pastDue.updatedAt },\n              });\n              const plan = await getPlanByName(options, existing.plan);\n              if (plan) {\n                await options.subscription?.onSubscriptionUpdate?.(\n                  { event, subscription: pastDue, plan },\n                  ctx as GenericEndpointContext,\n                );\n              }\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 groupIdFromMetadata =\n                typeof metadataObj.groupId === \"string\"\n                  ? normalizeSubscriptionGroup(metadataObj.groupId)\n                  : normalizeSubscriptionGroup(planFromCode?.group);\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: \"customerCode\", 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: PAYSTACK_MODELS.subscription,\n                    where: where,\n                  });\n                  const subscription = matches?.find((candidate) =>\n                    candidate.status !== \"canceled\" &&\n                    (candidate.subscriptionCode === subscriptionCode ||\n                      candidate.status === \"incomplete\" ||\n                      (candidate.status === \"trialing\" &&\n                        (candidate.subscriptionCode === undefined ||\n                          candidate.subscriptionCode === null ||\n                          candidate.subscriptionCode === \"\"))) &&\n                    groupIdFromMetadata === null\n                      ? candidate.groupId === undefined ||\n                        candidate.groupId === null ||\n                        candidate.groupId === \"\"\n                      : candidate.groupId === groupIdFromMetadata,\n                  );\n                  if (subscription !== undefined && subscription !== null) {\n                    const plan =\n                      planFromCode ??\n                      (planName !== undefined && planName !== null && planName !== \"\"\n                        ? await getPlanByName(options, planName)\n                        : undefined);\n                    const now = new Date();\n                    const persistedSubscription: Subscription = {\n                      ...subscription,\n                      subscriptionCode,\n                      status: \"active\",\n                      billingInterval: plan?.interval ?? subscription.billingInterval ?? null,\n                      periodEnd:\n                        subscriptionData.next_payment_date !== undefined &&\n                        subscriptionData.next_payment_date !== null\n                          ? new Date(subscriptionData.next_payment_date)\n                          : subscription.periodEnd,\n                      updatedAt: now,\n                    };\n                    await ctx.context.adapter.update({\n                      model: PAYSTACK_MODELS.subscription,\n                      update: {\n                        subscriptionCode: persistedSubscription.subscriptionCode,\n                        status: persistedSubscription.status,\n                        billingInterval: persistedSubscription.billingInterval,\n                        periodEnd: persistedSubscription.periodEnd,\n                        updatedAt: persistedSubscription.updatedAt,\n                      },\n                      where: [{ field: \"id\", value: subscription.id }],\n                    });\n                    await createBillingStore(ctx).retireCompetingSubscriptions(\n                      subscription.referenceId,\n                      subscription.groupId ?? null,\n                      subscription.id,\n                    );\n\n                    if (plan !== undefined && plan !== null) {\n                      const callbackData = { event, subscription: persistedSubscription, plan };\n                      for (const callback of [\n                        options.subscription.onSubscriptionComplete,\n                        options.subscription.onSubscriptionCreated,\n                        options.subscription.onSubscriptionUpdate,\n                      ]) {\n                        try {\n                          await callback?.(callbackData, ctx as GenericEndpointContext);\n                        } catch (error) {\n                          ctx.context.logger.error(\"Paystack subscription callback failed\", error);\n                          throw error;\n                        }\n                      }\n                      if (subscription.status === \"trialing\") {\n                        try {\n                          await plan.freeTrial?.onTrialEnd?.(persistedSubscription);\n                        } catch (error) {\n                          ctx.context.logger.error(\"Paystack trial end callback failed\", error);\n                          throw error;\n                        }\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: PAYSTACK_MODELS.subscription,\n                  where: [{ field: \"subscriptionCode\", value: subscriptionCode }],\n                });\n\n                let newStatus = \"canceled\";\n                const nextPaymentDate = subscriptionData.next_payment_date;\n                const periodEnd =\n                  nextPaymentDate !== undefined &&\n                  nextPaymentDate !== null &&\n                  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                const now = new Date();\n                const persistedSubscription =\n                  existing === null || existing === undefined\n                    ? undefined\n                    : ({\n                        ...existing,\n                        status: newStatus,\n                        cancelAtPeriodEnd: newStatus === \"active\",\n                        cancelAt: newStatus === \"active\" ? (periodEnd ?? null) : null,\n                        canceledAt: now,\n                        endedAt: newStatus === \"canceled\" ? now : null,\n                        ...(periodEnd ? { periodEnd } : {}),\n                        updatedAt: now,\n                      } as Subscription);\n                await ctx.context.adapter.update({\n                  model: PAYSTACK_MODELS.subscription,\n                  update: {\n                    status: newStatus,\n                    cancelAtPeriodEnd: newStatus === \"active\",\n                    cancelAt: newStatus === \"active\" ? (periodEnd ?? null) : null,\n                    canceledAt: now,\n                    endedAt: newStatus === \"canceled\" ? now : null,\n                    ...(periodEnd ? { periodEnd } : {}),\n                    updatedAt: now,\n                  },\n                  where: [{ field: \"subscriptionCode\", value: subscriptionCode }],\n                });\n\n                if (persistedSubscription !== undefined) {\n                  try {\n                    await options.subscription.onSubscriptionCancel?.(\n                      { event, subscription: persistedSubscription },\n                      ctx as GenericEndpointContext,\n                    );\n                  } catch (error) {\n                    ctx.context.logger.error(\"Paystack subscription cancel callback failed\", error);\n                  }\n                  const plan = await getPlanByName(options, persistedSubscription.plan);\n                  if (plan !== undefined && plan !== null) {\n                    try {\n                      await options.subscription.onSubscriptionUpdate?.(\n                        { event, subscription: persistedSubscription, plan },\n                        ctx as GenericEndpointContext,\n                      );\n                    } catch (error) {\n                      ctx.context.logger.error(\n                        \"Paystack subscription update callback failed\",\n                        error,\n                      );\n                    }\n                    if (existing?.status === \"trialing\" && newStatus === \"canceled\") {\n                      try {\n                        await plan.freeTrial?.onTrialExpired?.(persistedSubscription);\n                      } catch (error) {\n                        ctx.context.logger.error(\"Paystack trial expiry callback failed\", error);\n                      }\n                    }\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: PAYSTACK_MODELS.subscription,\n                  where: [{ field: \"subscriptionCode\", value: subscriptionCode }],\n                });\n\n                if (existingSub?.status === \"past_due\") {\n                  const recovered = { ...existingSub, status: \"active\", updatedAt: new Date() };\n                  await ctx.context.adapter.update({\n                    model: PAYSTACK_MODELS.subscription,\n                    update: { status: recovered.status, updatedAt: recovered.updatedAt },\n                    where: [{ field: \"id\", value: existingSub.id }],\n                  });\n                  const plan = await getPlanByName(options, existingSub.plan);\n                  if (plan) {\n                    await options.subscription.onSubscriptionUpdate?.(\n                      { event, subscription: recovered, plan },\n                      ctx as GenericEndpointContext,\n                    );\n                  }\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: PAYSTACK_MODELS.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            throw _e;\n          }\n        }\n\n        await options.onEvent?.(event);\n        const completed = await ctx.context.adapter.update({\n          model: PAYSTACK_MODELS.webhookEvent,\n          where: [\n            { field: \"eventId\", value: eventId },\n            { field: \"status\", value: claimStatus },\n          ],\n          update: { status: \"processed\", processedAt: new Date(), updatedAt: new Date() },\n        });\n        if (completed === null) throw new Error(\"Webhook processing lease was lost.\");\n        return ctx.json({ received: true });\n      } catch (error) {\n        if (claimStatus !== undefined)\n          await ctx.context.adapter.update({\n            model: PAYSTACK_MODELS.webhookEvent,\n            where: [\n              { field: \"eventId\", value: eventId },\n              { field: \"status\", value: claimStatus },\n            ],\n            update: { status: \"pending\", updatedAt: new Date() },\n          });\n        ctx.context.logger.error(\n          \"Paystack webhook processing failed; delivery must be retried\",\n          error,\n        );\n        throw new APIError(\"SERVICE_UNAVAILABLE\", {\n          message: \"Webhook processing failed; retry delivery.\",\n        });\n      }\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        subscriptionId: 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        confirmTrialTokenizationCharge: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: AuthMiddleware[];\n  },\n  PaystackInitializeResult | undefined\n> => {\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares: AuthMiddleware[] =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheckMiddleware,\n          referenceMiddleware(options, \"initialize-transaction\"),\n        ]\n      : [sessionMiddleware, originCheckMiddleware];\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        subscriptionId,\n        confirmTrialTokenizationCharge,\n      } = ctx.body;\n\n      // 1. Validate Callback URL validation (same as before)\n      if (callbackURL !== undefined && callbackURL !== null && callbackURL !== \"\") {\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 (!isTrustedCallbackURL(callbackURL, baseUrl)) {\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        plan !== undefined\n          ? plan.amount\n          : product\n            ? ((product as PaystackProduct).price ?? (product as InputPaystackProduct).amount)\n            : bodyAmount;\n      const finalCurrency =\n        plan !== undefined || product\n          ? ((product as PaystackProduct)?.currency ??\n            (product as InputPaystackProduct)?.currency ??\n            plan?.currency ??\n            \"NGN\")\n          : (currency ?? \"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      const groupId = normalizeSubscriptionGroup(plan?.group);\n      if (subscriptionId !== undefined) {\n        const selectedSubscription =\n          await createBillingStore(ctx).findSubscriptionById(subscriptionId);\n        if (\n          selectedSubscription === null ||\n          selectedSubscription.referenceId !== referenceId ||\n          normalizeSubscriptionGroup(selectedSubscription.groupId) !== groupId\n        ) {\n          throw new APIError(\"BAD_REQUEST\", {\n            message: \"Subscription does not belong to the authorized reference and plan group.\",\n          });\n        }\n      }\n\n      const scheduledChange = await scheduleSubscriptionLifecycleChange(\n        ctx,\n        {\n          userId: user.id,\n          referenceId,\n          subscriptionId,\n          plan,\n          scheduleAtPeriodEnd,\n          cancelAtPeriodEnd,\n        },\n        options,\n      );\n      if (scheduledChange !== null) {\n        return ctx.json(scheduledChange);\n      }\n\n      let validatedQuantity = quantity ?? 1;\n      if (product && amount !== undefined) amount *= quantity ?? 1;\n      if (amount !== undefined && (!Number.isSafeInteger(amount) || amount <= 0))\n        throw new APIError(\"BAD_REQUEST\", {\n          message: \"Catalog amount must be a positive safe integer.\",\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            validatedQuantity = quantityToUse;\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      const trialTokenizationCharge = trial.granted\n        ? getTrialTokenizationCharge(plan, finalCurrency)\n        : undefined;\n      if (trial.granted && confirmTrialTokenizationCharge !== true) {\n        throw new APIError(\"BAD_REQUEST\", {\n          code: \"TRIAL_TOKENIZATION_CHARGE_CONFIRMATION_REQUIRED\",\n          message: `This Paystack trial requires a one-time tokenization charge of ${trialTokenizationCharge} minor units in ${finalCurrency}. Tell the customer the exact charge and retry with confirmTrialTokenizationCharge: true after they accept it.`,\n        });\n      }\n\n      const normalizeInitializationError = (error: unknown): APIError => {\n        ctx.context.logger.error(\"Failed to initialize Paystack transaction\", error);\n        return new APIError(\"BAD_REQUEST\", {\n          code: \"FAILED_TO_INITIALIZE_TRANSACTION\",\n          message:\n            error instanceof Error\n              ? error.message\n              : PAYSTACK_ERROR_CODES.FAILED_TO_INITIALIZE_TRANSACTION.message,\n        });\n      };\n      const prepared = await (async () => {\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            groupId,\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            subscriptionId,\n            quantity,\n            targetEmail,\n            userId: user.id,\n            finalCurrency,\n            callbackURL,\n            allowedSubscriptionChannels,\n          });\n\n          if (proration?.kind === \"checkout\") {\n            return {\n              earlyResult: {\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\n          if (proration?.kind === \"prorated\") {\n            return {\n              earlyResult: {\n                kind: \"prorated\",\n                status: proration.status,\n                message: proration.message,\n                prorated: proration.prorated,\n              } satisfies PaystackInitializeResult,\n            };\n          }\n        }\n\n        if (plan !== undefined) {\n          // Subscription Flow\n          if (trialStart !== undefined) {\n            // Paystack requires a small paid transaction to tokenize authorization before a local trial.\n            initBody.amount = trialTokenizationCharge;\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        return { initBody };\n      })().catch((error: unknown) => {\n        if (options.subscription?.operationHooks === undefined)\n          throw normalizeInitializationError(error);\n        throw error;\n      });\n      if (prepared.earlyResult !== undefined) return ctx.json(prepared.earlyResult);\n      const initBody = prepared.initBody;\n      const operation =\n        plan !== undefined && options.subscription?.operationHooks !== undefined\n          ? {\n              actor: { id: user.id },\n              referenceId,\n              kind: \"initialize\" as const,\n              subscription:\n                subscriptionId !== undefined\n                  ? await createBillingStore(ctx).findSubscriptionById(subscriptionId)\n                  : await createBillingStore(ctx).findCurrentSubscription(referenceId, groupId),\n              intent: {\n                plan: plan.name.toLowerCase(),\n                amount: initBody.amount,\n                currency: finalCurrency,\n                interval: plan.interval,\n                quantity: validatedQuantity,\n                groupId,\n                callbackURL,\n                trialStart,\n                trialEnd,\n              },\n            }\n          : undefined;\n      const execute = async (\n        providerReference: string | undefined,\n        setPhase: (phase: \"provider\" | \"persistence\" | \"completion\") => void,\n      ): Promise<PaystackInitializeResult> => {\n        if (providerReference !== undefined) initBody.reference = providerReference;\n        try {\n          const initRaw = await paystack?.transaction?.initialize({\n            body: initBody as components[\"schemas\"][\"TransactionInitialize\"],\n          });\n          const sdkRes =\n            unwrapSdkResult<components[\"schemas\"][\"TransactionInitializeResponse\"][\"data\"]>(\n              initRaw,\n            );\n\n          if (providerReference !== undefined && sdkRes?.reference !== providerReference) {\n            throw new APIError(\"BAD_REQUEST\", {\n              message: \"Provider reference does not match reserved operation.\",\n            });\n          }\n          url = sdkRes?.authorization_url;\n          reference = sdkRes?.reference;\n          accessCode = sdkRes?.access_code;\n        } catch (error: unknown) {\n          throw normalizeInitializationError(error);\n        }\n        setPhase(\"persistence\");\n        // 6. Record Transaction & Subscription\n        await ctx.context.adapter.create({\n          model: PAYSTACK_MODELS.transaction,\n          data: {\n            reference: reference ?? \"\",\n            referenceId,\n            userId: user.id,\n            amount: initBody.amount ?? 0,\n            currency: finalCurrency,\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          const store = createBillingStore(ctx);\n          const customer = await store.findCustomerByReference(\n            referenceId === user.id ? \"user\" : \"organization\",\n            referenceId,\n          );\n          let customerCode = customer?.customerCode;\n          if (customerCode === undefined) {\n            try {\n              const legacy = await ctx.context.adapter.findOne<{\n                paystackCustomerCode?: string | null;\n              }>({\n                model: referenceId === user.id ? \"user\" : \"organization\",\n                where: [{ field: \"id\", value: referenceId }],\n                select: [\"paystackCustomerCode\"],\n              });\n              customerCode = legacy?.paystackCustomerCode ?? undefined;\n              if (customerCode !== undefined && customerCode !== null && customerCode !== \"\") {\n                await store.saveCustomer(\n                  referenceId === user.id ? \"user\" : \"organization\",\n                  referenceId,\n                  customerCode,\n                );\n              }\n            } catch {\n              // Legacy customer columns are optional after the migration.\n            }\n          }\n\n          await ctx.context.adapter.create<Subscription>({\n            model: PAYSTACK_MODELS.subscription,\n            data: {\n              plan: plan.name.toLowerCase(),\n              groupId,\n              referenceId,\n              userId: user.id,\n              customerCode,\n              subscriptionCode: undefined,\n              planCode: plan.planCode,\n              transactionReference: reference ?? \"\",\n              // Access remains incomplete until the tokenization charge succeeds.\n              status: \"incomplete\",\n              billingInterval: plan.interval ?? null,\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\n        return ctx.json({\n          kind: \"checkout\",\n          url: url ?? \"\",\n          reference: reference ?? \"\",\n          accessCode: accessCode ?? \"\",\n          redirect: true,\n          ...(trial.granted && trialTokenizationCharge !== undefined\n            ? {\n                trial: {\n                  days: trial.requestedDays,\n                  tokenizationCharge: { amount: trialTokenizationCharge, currency: finalCurrency },\n                },\n              }\n            : {}),\n        } satisfies PaystackInitializeResult);\n      };\n      return operation !== undefined\n        ? runSubscriptionOperation(ctx, options, operation, execute)\n        : execute(undefined, () => undefined);\n    },\n  );\n};\n\nfunction getTrialTokenizationCharge(plan: PaystackPlan | undefined, currency: string): number {\n  const configured = plan?.freeTrial?.tokenizationCharge;\n  if (configured !== undefined) {\n    if (!Number.isSafeInteger(configured) || configured <= 0) {\n      throw new APIError(\"BAD_REQUEST\", {\n        code: \"INVALID_TRIAL_TOKENIZATION_CHARGE\",\n        message: \"freeTrial.tokenizationCharge must be a positive safe integer in minor units.\",\n      });\n    }\n    return configured;\n  }\n  const documentedMinimums: Record<string, number> = {\n    NGN: 5_000,\n    GHS: 10,\n    ZAR: 100,\n    KES: 300,\n    USD: 200,\n  };\n  const amount = documentedMinimums[currency.toUpperCase()];\n  if (amount === undefined) {\n    throw new APIError(\"BAD_REQUEST\", {\n      code: \"TRIAL_TOKENIZATION_CHARGE_REQUIRED\",\n      message: `Configure freeTrial.tokenizationCharge in minor units for ${currency}.`,\n    });\n  }\n  return amount;\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        subscriptionId: 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        confirmTrialTokenizationCharge: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: AuthMiddleware[];\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        subscriptionId: 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        confirmTrialTokenizationCharge: z.ZodOptional<z.ZodBoolean>;\n      },\n      z.core.$strip\n    >;\n    use: AuthMiddleware[];\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: AuthMiddleware[];\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: AuthMiddleware[];\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: AuthMiddleware[];\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: AuthMiddleware[] =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheckMiddleware,\n          referenceMiddleware(options, \"verify-transaction\"),\n        ]\n      : [sessionMiddleware, originCheckMiddleware];\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: AuthMiddleware[];\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: AuthMiddleware[] =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheckMiddleware,\n          referenceMiddleware(options, \"list-subscriptions\"),\n        ]\n      : [sessionMiddleware, originCheckMiddleware];\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: AuthMiddleware[];\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: AuthMiddleware[] =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheckMiddleware,\n          referenceMiddleware(options, \"list-transactions\"),\n        ]\n      : [sessionMiddleware, originCheckMiddleware];\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: AuthMiddleware[];\n  },\n  {\n    status: string;\n  }\n> => {\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares: AuthMiddleware[] =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheckMiddleware,\n          referenceMiddleware(options, \"disable-subscription\"),\n        ]\n      : [sessionMiddleware, originCheckMiddleware];\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: PAYSTACK_MODELS.subscription,\n            where: [{ field: \"subscriptionCode\", value: subscriptionCode }],\n          });\n\n          if (sub !== null && sub !== undefined) {\n            const now = new Date();\n            const immediate = atPeriodEnd === false;\n            await ctx.context.adapter.update({\n              model: PAYSTACK_MODELS.subscription,\n              update: {\n                status: immediate ? \"canceled\" : \"active\",\n                cancelAtPeriodEnd: !immediate,\n                cancelAt: immediate ? null : (sub.periodEnd ?? null),\n                canceledAt: now,\n                endedAt: immediate ? now : null,\n                updatedAt: now,\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        const storedSubscription =\n          await createBillingStore(ctx).findSubscriptionByCode(subscriptionCode);\n        const storedCredentials = storedSubscription\n          ? await readPaystackPaymentCredentials(\n              ctx.context.adapter,\n              options,\n              storedSubscription.id,\n            )\n          : null;\n        let emailToken = ctx.body.emailToken ?? storedCredentials?.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        if (storedSubscription) {\n          await savePaystackPaymentCredentials(\n            ctx.context.adapter,\n            options,\n            storedSubscription.id,\n            {\n              emailToken,\n            },\n          );\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: PAYSTACK_MODELS.subscription,\n          where: [{ field: \"subscriptionCode\", value: subscriptionCode }],\n        });\n\n        if (sub !== undefined && sub !== null) {\n          const now = new Date();\n          const immediate = atPeriodEnd === false;\n          await ctx.context.adapter.update({\n            model: PAYSTACK_MODELS.subscription,\n            update: {\n              status: immediate ? \"canceled\" : \"active\",\n              cancelAtPeriodEnd: !immediate,\n              cancelAt: immediate ? null : (periodEnd ?? sub.periodEnd ?? null),\n              canceledAt: now,\n              endedAt: immediate ? now : null,\n              periodEnd,\n              updatedAt: now,\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: AuthMiddleware[];\n  },\n  {\n    status: string;\n  }\n> => {\n  const subscriptionOptions = options.subscription;\n  const useMiddlewares: AuthMiddleware[] =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheckMiddleware,\n          referenceMiddleware(options, \"enable-subscription\"),\n        ]\n      : [sessionMiddleware, originCheckMiddleware];\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        const storedSubscription =\n          await createBillingStore(ctx).findSubscriptionByCode(subscriptionCode);\n        const storedCredentials = storedSubscription\n          ? await readPaystackPaymentCredentials(\n              ctx.context.adapter,\n              options,\n              storedSubscription.id,\n            )\n          : null;\n        let emailToken = ctx.body.emailToken ?? storedCredentials?.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        if (storedSubscription) {\n          await savePaystackPaymentCredentials(\n            ctx.context.adapter,\n            options,\n            storedSubscription.id,\n            {\n              emailToken,\n            },\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: PAYSTACK_MODELS.subscription,\n          update: {\n            status: \"active\",\n            cancelAtPeriodEnd: false,\n            cancelAt: null,\n            canceledAt: null,\n            endedAt: null,\n            updatedAt: new Date(),\n          },\n          where: [{ field: \"subscriptionCode\", 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: AuthMiddleware[];\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: AuthMiddleware[] =\n    subscriptionOptions?.enabled === true\n      ? [\n          sessionMiddleware,\n          originCheckMiddleware,\n          referenceMiddleware(options, \"get-subscription-manage-link\"),\n        ]\n      : [sessionMiddleware, originCheckMiddleware];\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: AuthMiddleware[];\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.ts\";\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 WebhookEventsSchema = PluginSchemaTable<\n  \"paystackWebhookEvent\",\n  | \"eventId\"\n  | \"eventType\"\n  | \"reference\"\n  | \"payload\"\n  | \"status\"\n  | \"processedAt\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\ntype SubscriptionsSchema = PluginSchemaTable<\n  \"paystackSubscription\",\n  | \"plan\"\n  | \"referenceId\"\n  | \"userId\"\n  | \"customerCode\"\n  | \"subscriptionCode\"\n  | \"transactionReference\"\n  | \"planCode\"\n  | \"status\"\n  | \"periodStart\"\n  | \"periodEnd\"\n  | \"trialStart\"\n  | \"trialEnd\"\n  | \"cancelAtPeriodEnd\"\n  | \"cancelAt\"\n  | \"canceledAt\"\n  | \"endedAt\"\n  | \"billingInterval\"\n  | \"groupId\"\n  | \"seats\"\n  | \"pendingPlan\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\ntype CustomerSchema = PluginSchemaTable<\n  \"paystackCustomer\",\n  | \"referenceType\"\n  | \"referenceId\"\n  | \"referenceKey\"\n  | \"customerCode\"\n  | \"email\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\ntype PaymentCredentialsSchema = PluginSchemaTable<\n  \"paystackPaymentCredential\",\n  | \"subscriptionId\"\n  | \"authorizationCodeEncrypted\"\n  | \"emailTokenEncrypted\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\ntype UserSchema = PluginSchemaTable<\"user\", never>;\n\ntype OrganizationSchema = PluginSchemaTable<\"organization\", \"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  | \"group\"\n  | \"planCode\"\n  | \"paystackId\"\n  | \"metadata\"\n  | \"createdAt\"\n  | \"updatedAt\"\n>;\n\nexport type PaystackPluginSchema = SubscriptionsSchema &\n  TransactionsSchema &\n  CustomerSchema &\n  PaymentCredentialsSchema &\n  UserSchema &\n  OrganizationSchema &\n  ProductsSchema &\n  PlansSchema &\n  WebhookEventsSchema;\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  paystackSubscription: {\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      userId: {\n        type: \"string\",\n        required: true,\n        index: true,\n      },\n      customerCode: {\n        type: \"string\",\n        required: false,\n        index: true,\n      },\n      subscriptionCode: {\n        type: \"string\",\n        required: false,\n        unique: true,\n      },\n      transactionReference: {\n        type: \"string\",\n        required: false,\n        index: true,\n      },\n      planCode: {\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      cancelAt: {\n        type: \"date\",\n        required: false,\n      },\n      canceledAt: {\n        type: \"date\",\n        required: false,\n      },\n      endedAt: {\n        type: \"date\",\n        required: false,\n      },\n      billingInterval: {\n        type: \"string\",\n        required: 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      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 subscriptions: typeof subscriptionsSchema = subscriptionsSchema;\n\nconst customersSchema: CustomerSchema = {\n  paystackCustomer: {\n    fields: {\n      referenceType: { type: \"string\", required: true },\n      referenceId: { type: \"string\", required: true, index: true },\n      // Better Auth schema generation cannot express a portable composite unique\n      // index, so this provider-owned key enforces (type, id) uniqueness.\n      referenceKey: { type: \"string\", required: true, unique: true },\n      customerCode: { type: \"string\", required: true, unique: true },\n      email: { type: \"string\", required: false },\n      createdAt: { type: \"date\", required: true },\n      updatedAt: { type: \"date\", required: true },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const customers: typeof customersSchema = customersSchema;\n\nconst paymentCredentialsSchema: PaymentCredentialsSchema = {\n  paystackPaymentCredential: {\n    fields: {\n      subscriptionId: { type: \"string\", required: true, unique: true, index: true },\n      authorizationCodeEncrypted: { type: \"string\", required: false },\n      emailTokenEncrypted: { type: \"string\", required: false },\n      createdAt: { type: \"date\", required: true },\n      updatedAt: { type: \"date\", required: true },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const paymentCredentials: typeof paymentCredentialsSchema = paymentCredentialsSchema;\n\nconst userSchema: UserSchema = {\n  user: {\n    fields: {},\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const user: typeof userSchema = userSchema;\n\nconst organizationSchema: OrganizationSchema = {\n  organization: {\n    fields: {\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      group: {\n        type: \"string\",\n        required: false,\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 webhookEventsSchema: WebhookEventsSchema = {\n  paystackWebhookEvent: {\n    fields: {\n      eventId: {\n        type: \"string\",\n        required: true,\n        unique: true,\n      },\n      eventType: {\n        type: \"string\",\n        required: true,\n        index: true,\n      },\n      reference: {\n        type: \"string\",\n        required: false,\n        index: true,\n      },\n      payload: {\n        type: \"string\",\n        required: true,\n      },\n      status: {\n        type: \"string\",\n        required: true,\n        defaultValue: \"pending\",\n        index: true,\n      },\n      processedAt: {\n        type: \"date\",\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 webhookEvents: typeof webhookEventsSchema = webhookEventsSchema;\n\nconst paystackPluginSchemaDefinition: PaystackPluginSchema = {\n  ...subscriptions,\n  ...transactions,\n  ...customers,\n  ...paymentCredentials,\n  ...user,\n  ...organization,\n  ...products,\n  ...plans,\n  ...webhookEvents,\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      ...customers,\n      ...paymentCredentials,\n      ...user,\n      ...products,\n      ...plans,\n      ...webhookEvents,\n    };\n  } else {\n    baseSchema = {\n      ...user,\n      ...transactions,\n      ...customers,\n      ...paymentCredentials,\n      ...products,\n      ...plans,\n      ...webhookEvents,\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 (options.schema !== undefined && \"subscription\" in options.schema) {\n    const { subscription: _subscription, ...restSchema } = optionSchema ?? {};\n    return mergeSchema(baseSchema, restSchema);\n  }\n\n  return mergeSchema(baseSchema, optionSchema);\n};\n","import type { GenericEndpointContext } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\n\nimport { createBillingStore } from \"./billing-store.ts\";\nimport { createRenewalMetadata, stringifyPaystackMetadata } from \"./metadata.ts\";\nimport { readPaystackPaymentCredentials } from \"./payment-credentials.ts\";\nimport { createPaystackAdapter } from \"./paystack-sdk.ts\";\nimport type {\n  AnyPaystackOptions,\n  ChargeRecurringSubscriptionInput,\n  ChargeRecurringSubscriptionResult,\n  PaystackSyncResult,\n  PaystackChargeAuthorizationResponse,\n} from \"./types.ts\";\nimport { calculatePlanAmount } from \"./utils.ts\";\nimport { getNextPeriodEnd, getPlans, validateMinAmount } from \"./utils.ts\";\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 } = 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  const credentials = await readPaystackPaymentCredentials(\n    ctx.context.adapter,\n    options,\n    subscription.id,\n  );\n  if (\n    credentials?.authorizationCode === undefined ||\n    credentials.authorizationCode === null ||\n    credentials.authorizationCode === \"\"\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 = calculatePlanAmount(plan, subscription.seats ?? 1);\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: credentials.authorizationCode,\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      transactionReference: typedChargeData.reference,\n    });\n\n    return { status: \"success\", data: typedChargeData };\n  }\n\n  return { status: \"failed\", data: typedChargeData };\n}\n","import type { GenericEndpointContext } from \"better-auth\";\n\nimport type { createBillingStoreFromAdapter } from \"./billing-store.ts\";\nimport { LEGACY_PAYSTACK_MODELS, PAYSTACK_MODELS } from \"./models.ts\";\nimport { savePaystackPaymentCredentials } from \"./payment-credentials.ts\";\nimport type { AnyPaystackOptions } from \"./types.ts\";\n\ntype Adapter = Parameters<typeof createBillingStoreFromAdapter>[0];\ntype LegacyRecord = Record<string, unknown> & { id?: string | number };\n\nexport interface PaystackSchemaMigrationFailure {\n  kind: \"subscription\" | \"customer\" | \"credential\";\n  id: string;\n  message: string;\n}\n\nexport interface PaystackSchemaMigrationReport {\n  status: \"complete\" | \"partial\";\n  subscriptions: { migrated: number; skipped: number; failed: number };\n  customers: { migrated: number; skipped: number; failed: number };\n  credentials: { migrated: number; skipped: number; failed: number };\n  skipped: number;\n  failures: PaystackSchemaMigrationFailure[];\n}\n\nfunction asString(value: unknown): string | undefined {\n  return typeof value === \"string\" && value !== \"\" ? value : undefined;\n}\n\nfunction asIdentifier(value: unknown): string | undefined {\n  if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n  return asString(value);\n}\n\nfunction asDate(value: unknown, fallback: Date): Date {\n  if (value instanceof Date) return value;\n  if (typeof value === \"string\" || typeof value === \"number\") {\n    const date = new Date(value);\n    if (!Number.isNaN(date.getTime())) return date;\n  }\n  return fallback;\n}\n\nfunction asOptionalDate(value: unknown): Date | null | undefined {\n  if (value === null) return null;\n  if (value === undefined) return undefined;\n  if (value instanceof Date) return value;\n  if (typeof value === \"string\" || typeof value === \"number\") {\n    const date = new Date(value);\n    if (!Number.isNaN(date.getTime())) return date;\n  }\n  return undefined;\n}\n\nasync function findManySafely(adapter: Adapter, model: string): Promise<LegacyRecord[]> {\n  try {\n    return (await adapter.findMany<LegacyRecord>({ model })) ?? [];\n  } catch {\n    // The legacy table may already have been removed in a fresh installation.\n    return [];\n  }\n}\n\nfunction migrationData(legacy: LegacyRecord): Record<string, unknown> {\n  const now = new Date();\n  const referenceId = asIdentifier(legacy.referenceId) ?? asIdentifier(legacy.userId) ?? \"\";\n  const id = asIdentifier(legacy.id);\n  return {\n    ...(id !== undefined ? { id } : {}),\n    plan: asString(legacy.plan) ?? \"\",\n    referenceId,\n    userId: asIdentifier(legacy.userId) ?? referenceId,\n    customerCode:\n      asString(legacy.customerCode) ?? asString(legacy.paystackCustomerCode) ?? undefined,\n    subscriptionCode:\n      asString(legacy.subscriptionCode) ?? asString(legacy.paystackSubscriptionCode) ?? undefined,\n    transactionReference:\n      asString(legacy.transactionReference) ??\n      asString(legacy.paystackTransactionReference) ??\n      undefined,\n    planCode: asString(legacy.planCode) ?? asString(legacy.paystackPlanCode) ?? undefined,\n    status: asString(legacy.status) ?? \"incomplete\",\n    periodStart: asDate(legacy.periodStart, now),\n    periodEnd: asOptionalDate(legacy.periodEnd),\n    trialStart: asOptionalDate(legacy.trialStart),\n    trialEnd: asOptionalDate(legacy.trialEnd),\n    cancelAtPeriodEnd: legacy.cancelAtPeriodEnd === true,\n    cancelAt: asOptionalDate(legacy.cancelAt),\n    canceledAt: asOptionalDate(legacy.canceledAt),\n    endedAt: asOptionalDate(legacy.endedAt),\n    billingInterval: asString(legacy.billingInterval) ?? undefined,\n    groupId: asString(legacy.groupId) ?? undefined,\n    seats: typeof legacy.seats === \"number\" ? legacy.seats : undefined,\n    pendingPlan: asString(legacy.pendingPlan) ?? undefined,\n    createdAt: asDate(legacy.createdAt, now),\n    updatedAt: asDate(legacy.updatedAt, now),\n  };\n}\n\nasync function migrateCustomer(\n  adapter: Adapter,\n  referenceType: \"user\" | \"organization\",\n  legacy: LegacyRecord,\n  report: PaystackSchemaMigrationReport,\n): Promise<void> {\n  const customerCode = asString(legacy.paystackCustomerCode) ?? asString(legacy.customerCode);\n  const referenceId = asIdentifier(legacy.id);\n  if (customerCode === undefined || referenceId === undefined) return;\n  const referenceKey = `${referenceType}:${referenceId}`;\n  try {\n    const existing = await adapter.findOne<LegacyRecord>({\n      model: PAYSTACK_MODELS.customer,\n      where: [{ field: \"referenceKey\", value: referenceKey }],\n    });\n    if (existing) {\n      report.customers.skipped += 1;\n      report.skipped += 1;\n      return;\n    }\n    const now = new Date();\n    const email = asString(legacy.email);\n    await adapter.create({\n      model: PAYSTACK_MODELS.customer,\n      data: {\n        referenceType,\n        referenceId,\n        referenceKey,\n        customerCode,\n        ...(email !== undefined ? { email } : {}),\n        createdAt: asDate(legacy.createdAt, now),\n        updatedAt: asDate(legacy.updatedAt, now),\n      },\n    });\n    report.customers.migrated += 1;\n  } catch (error) {\n    report.customers.failed += 1;\n    report.failures.push({\n      kind: \"customer\",\n      id: referenceKey,\n      message: error instanceof Error ? error.message : \"Failed to migrate customer\",\n    });\n  }\n}\n\nexport async function migratePaystackSubscriptionSchema(\n  ctx: GenericEndpointContext,\n  options: AnyPaystackOptions,\n): Promise<PaystackSchemaMigrationReport> {\n  const adapter = ctx.context.adapter;\n  const report: PaystackSchemaMigrationReport = {\n    status: \"complete\",\n    subscriptions: { migrated: 0, skipped: 0, failed: 0 },\n    customers: { migrated: 0, skipped: 0, failed: 0 },\n    credentials: { migrated: 0, skipped: 0, failed: 0 },\n    skipped: 0,\n    failures: [],\n  };\n\n  for (const referenceType of [\"user\", \"organization\"] as const) {\n    const records = await findManySafely(adapter, referenceType);\n    for (const record of records) await migrateCustomer(adapter, referenceType, record, report);\n  }\n\n  const legacySubscriptions = await findManySafely(adapter, LEGACY_PAYSTACK_MODELS.subscription);\n  for (const legacy of legacySubscriptions) {\n    const id = asIdentifier(legacy.id);\n    if (id === undefined) continue;\n    try {\n      const existing = await adapter.findOne<LegacyRecord>({\n        model: PAYSTACK_MODELS.subscription,\n        where: [{ field: \"id\", value: id }],\n      });\n      if (existing) {\n        report.subscriptions.skipped += 1;\n        report.skipped += 1;\n      } else {\n        await adapter.create({\n          model: PAYSTACK_MODELS.subscription,\n          data: migrationData(legacy),\n          forceAllowId: true,\n        });\n        report.subscriptions.migrated += 1;\n      }\n    } catch (error) {\n      report.subscriptions.failed += 1;\n      report.failures.push({\n        kind: \"subscription\",\n        id,\n        message: error instanceof Error ? error.message : \"Failed to migrate subscription\",\n      });\n    }\n\n    const authorizationCode =\n      asString(legacy.authorizationCode) ?? asString(legacy.paystackAuthorizationCode);\n    const emailToken = asString(legacy.emailToken) ?? asString(legacy.paystackEmailToken);\n    if (authorizationCode !== undefined || emailToken !== undefined) {\n      try {\n        const existingCredential = await adapter.findOne<LegacyRecord>({\n          model: PAYSTACK_MODELS.paymentCredential,\n          where: [{ field: \"subscriptionId\", value: id }],\n        });\n        if (existingCredential) {\n          report.credentials.skipped += 1;\n          report.skipped += 1;\n        } else {\n          await savePaystackPaymentCredentials(adapter, options, id, {\n            authorizationCode,\n            emailToken,\n          });\n          report.credentials.migrated += 1;\n        }\n      } catch (error) {\n        report.credentials.failed += 1;\n        report.failures.push({\n          kind: \"credential\",\n          id,\n          message: error instanceof Error ? error.message : \"Failed to migrate credential\",\n        });\n      }\n    }\n  }\n\n  report.status = report.failures.length > 0 ? \"partial\" : \"complete\";\n  return report;\n}\n","import {\n  defineErrorCodes,\n  type AuthContext,\n  type BetterAuthPlugin,\n  type GenericEndpointContext,\n} from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport { defu } from \"defu\";\n\nimport { createBillingStoreFromAdapter, type BillingStoreAdapter } from \"./billing-store.ts\";\nimport { resolvePaystackCustomer } from \"./customer.ts\";\nimport { checkSeatLimit, checkTeamLimit, getOrganizationEntitlements } from \"./limits.ts\";\nimport { createPaystackAdapter } from \"./paystack-sdk.ts\";\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.ts\";\nimport { getSchema } from \"./schema.ts\";\nimport type { PaystackClientLike, PaystackOptions, AnyPaystackOptions, User } from \"./types.ts\";\nimport { syncSubscriptionSeats } from \"./utils.ts\";\nimport { PACKAGE_VERSION } from \"./version.ts\";\n\nexport {\n  createCheckoutMetadata,\n  createProrationMetadata,\n  createRenewalMetadata,\n  getMetadataBoolean,\n  getMetadataNumber,\n  getMetadataString,\n  hasPaystackMetadata,\n  parsePaystackMetadata,\n  stringifyPaystackMetadata,\n} from \"./metadata.ts\";\nexport type { PaystackMetadata } from \"./metadata.ts\";\nexport type { PaystackInitializeResult } from \"./types.ts\";\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\n/**\n * Must stay a `type` rather than an `interface`.\n *\n * `BetterAuthPlugin[\"endpoints\"]` is `{ [key: string]: Endpoint }`, and only object literal\n * *type aliases* get TypeScript's implicit index signature — interfaces do not. Declaring\n * this as `interface ... extends Record<string, Endpoint>` satisfies that constraint but\n * gives the plugin a real string index signature. Better Auth merges every plugin's\n * endpoints into `auth.api`, so that signature spreads across the whole API surface and,\n * under `noUncheckedIndexedAccess`, makes *every* `auth.api.*` call possibly `undefined`.\n */\n// oxlint-disable-next-line typescript/consistent-type-definitions\ntype PaystackPluginEndpoints = {\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 PaystackPluginInitContext = Pick<AuthContext, \"hasPlugin\" | \"logger\"> & {\n  adapter: BillingStoreAdapter;\n};\n\ntype PaystackPluginInit = ((ctx: PaystackPluginInitContext) => 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: options.webhook,\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: PaystackPluginInitContext) => {\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: {\n                    id: string;\n                    email?: string | null;\n                    name?: string | null;\n                    emailVerified?: boolean;\n                  },\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 result = await resolvePaystackCustomer({\n                      adapter: ctx.adapter,\n                      client: options.paystackClient as PaystackClientLike,\n                      logger: ctx.logger,\n                      reference: {\n                        id: user.id,\n                        type: \"user\",\n                        email: user.email,\n                        name: user.name,\n                        emailVerified: user.emailVerified,\n                        paystackCustomerCode: (user as Record<string, unknown>)\n                          .paystackCustomerCode as string | null | undefined,\n                      },\n                    });\n                    const customerCode = result?.customer.customer_code;\n\n                    if (\n                      result?.created === true &&\n                      typeof customerCode === \"string\" &&\n                      typeof options.onCustomerCreate === \"function\"\n                    ) {\n                      await options.onCustomerCreate(\n                        {\n                          paystackCustomer: result.customer,\n                          user: {\n                            ...(user as User),\n                            paystackCustomerCode: customerCode,\n                          },\n                        },\n                        hookCtx,\n                      );\n                    }\n                  } catch (error: unknown) {\n                    ctx.logger.error(\"Failed to create Paystack customer for user\", error);\n                  }\n                },\n              },\n              update: {\n                async after(user: { id: string; email?: string | null }) {\n                  const customerCode = (\n                    await createBillingStoreFromAdapter(ctx.adapter).findCustomerByReference(\n                      \"user\",\n                      user.id,\n                    )\n                  )?.customerCode;\n                  if (\n                    typeof customerCode !== \"string\" ||\n                    customerCode === \"\" ||\n                    typeof user.email !== \"string\" ||\n                    user.email === \"\"\n                  )\n                    return;\n                  try {\n                    await createPaystackAdapter(options.paystackClient).updateCustomer(\n                      customerCode,\n                      { email: user.email },\n                    );\n                  } catch (error: unknown) {\n                    ctx.logger.error(\"Failed to synchronize Paystack customer email\", 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, 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 result = await resolvePaystackCustomer({\n                            adapter: ctx.adapter,\n                            client: options.paystackClient as PaystackClientLike,\n                            logger: ctx.logger,\n                            reference: {\n                              id: org.id,\n                              type: \"organization\",\n                              email: targetEmail,\n                              name: org.name,\n                              paystackCustomerCode: (\n                                org as { paystackCustomerCode?: string | null }\n                              ).paystackCustomerCode,\n                            },\n                            createParams: defu({}, extraCreateParams),\n                          });\n                          const customerCode = result?.customer.customer_code;\n\n                          if (\n                            result?.created === true &&\n                            typeof customerCode === \"string\" &&\n                            typeof options.organization?.onCustomerCreate === \"function\"\n                          ) {\n                            await options.organization.onCustomerCreate(\n                              {\n                                paystackCustomer: result.customer,\n                                organization: {\n                                  ...org,\n                                  paystackCustomerCode: customerCode,\n                                },\n                              },\n                              hookCtx!,\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                    update: {\n                      async after(\n                        org: {\n                          id: string;\n                          name?: string | null;\n                          email?: string | null;\n                        },\n                        hookCtx?: GenericEndpointContext | null,\n                      ) {\n                        const persisted = await createBillingStoreFromAdapter(\n                          ctx.adapter,\n                        ).findOrganization(org.id);\n                        const customerCode = (\n                          await createBillingStoreFromAdapter(ctx.adapter).findCustomerByReference(\n                            \"organization\",\n                            org.id,\n                          )\n                        )?.customerCode;\n                        if (typeof customerCode !== \"string\" || customerCode === \"\") return;\n                        try {\n                          const configured =\n                            typeof options.organization?.getCustomerCreateParams === \"function\" &&\n                            hookCtx\n                              ? await options.organization.getCustomerCreateParams(\n                                  {\n                                    id: org.id,\n                                    name: org.name ?? persisted?.name ?? \"\",\n                                    email:\n                                      org.email ??\n                                      (persisted as typeof persisted & { email?: string | null })\n                                        ?.email,\n                                  },\n                                  hookCtx,\n                                )\n                              : {};\n                          const configuredEmail =\n                            typeof configured.email === \"string\" && configured.email !== \"\"\n                              ? configured.email\n                              : undefined;\n                          await createPaystackAdapter(options.paystackClient).updateCustomer(\n                            customerCode,\n                            {\n                              ...(configuredEmail !== undefined ||\n                              (typeof org.email === \"string\" && org.email !== \"\")\n                                ? { email: configuredEmail ?? org.email ?? undefined }\n                                : {}),\n                              ...(typeof org.name === \"string\" && org.name !== \"\"\n                                ? { first_name: org.name }\n                                : {}),\n                            },\n                          );\n                        } catch (error: unknown) {\n                          ctx.logger.error(\n                            \"Failed to synchronize Paystack organization customer\",\n                            error,\n                          );\n                        }\n                      },\n                    },\n                    delete: {\n                      async before(org: { id: string }) {\n                        const store = createBillingStoreFromAdapter(ctx.adapter);\n                        const subscriptions = await store.findSubscriptionsByReference(org.id);\n                        if (\n                          subscriptions.some(\n                            (subscription) =>\n                              subscription.status === \"active\" ||\n                              subscription.status === \"trialing\",\n                          )\n                        ) {\n                          throw new APIError(\"BAD_REQUEST\", {\n                            message:\n                              \"Organization cannot be deleted while it has an active subscription\",\n                          });\n                        }\n\n                        const customerCode = (\n                          await store.findCustomerByReference(\"organization\", org.id)\n                        )?.customerCode;\n                        if (typeof customerCode !== \"string\" || customerCode === \"\") return;\n                        try {\n                          const customer = (await createPaystackAdapter(\n                            options.paystackClient,\n                          ).fetchCustomer(customerCode)) as {\n                            subscriptions?: { status?: string }[];\n                          };\n                          if (\n                            customer.subscriptions?.some(\n                              (subscription) =>\n                                subscription.status === \"active\" ||\n                                subscription.status === \"trialing\",\n                            ) === true\n                          ) {\n                            throw new APIError(\"BAD_REQUEST\", {\n                              message:\n                                \"Organization cannot be deleted while it has an active subscription\",\n                            });\n                          }\n                        } catch (error: unknown) {\n                          if (error instanceof APIError) throw error;\n                          ctx.logger.error(\n                            \"Failed to check Paystack subscriptions before organization deletion\",\n                            error,\n                          );\n                          throw new APIError(\"BAD_REQUEST\", {\n                            message:\n                              \"Organization deletion could not verify its Paystack subscriptions\",\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 entitlements = await getOrganizationEntitlements(\n                          ctx,\n                          team.organizationId,\n                          routeOptions,\n                        );\n                        const maxTeams = entitlements.limits.teams;\n                        if (typeof maxTeams === \"number\") {\n                          await checkTeamLimit(ctx, team.organizationId, maxTeams);\n                        }\n                      }\n                    },\n                  },\n                }\n              : undefined,\n          },\n        },\n      };\n    }) as PaystackPluginInit,\n    $ERROR_CODES: INTERNAL_ERROR_CODES,\n    options: options,\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 {\n  chargeSubscriptionRenewal,\n  syncPaystackPlans,\n  syncPaystackProducts,\n} from \"./operations.ts\";\nexport { getOrganizationEntitlements } from \"./limits.ts\";\nexport { reconcilePaystackTransaction } from \"./reconciliation.ts\";\nexport { migratePaystackSubscriptionSchema } from \"./migrations.ts\";\nexport type {\n  PaystackReconciliationError,\n  PaystackReconciliationSource,\n  PaystackReconciliationSummary,\n  ReconcilePaystackTransactionFailure,\n  ReconcilePaystackTransactionInput,\n  ReconcilePaystackTransactionResult,\n  ReconcilePaystackTransactionSuccess,\n} from \"./reconciliation.ts\";\nexport type {\n  Subscription,\n  PaystackSubscription,\n  PaystackCustomer,\n  PaystackPaymentCredential,\n  SubscriptionOptions,\n  PaystackSubscriptionOperation,\n  PaystackSubscriptionOperationDecision,\n  PaystackSubscriptionOperationPhase,\n  PaystackSubscriptionOperationHooks,\n  PaystackPlan,\n  PaystackOptions,\n  PaystackProduct,\n  PaystackTransaction,\n  PaystackTransactionResponse,\n  PaystackClientLike,\n  ChargeRecurringSubscriptionResult,\n  PaystackSyncResult,\n  PaystackWebhookEventRecord,\n} from \"./types.ts\";\nexport type {\n  PaystackSchemaMigrationFailure,\n  PaystackSchemaMigrationReport,\n} from \"./migrations.ts\";\n"],"mappings":"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"}