@alexasomba/better-auth-paystack 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -66
- package/dist/client.d.mts +5 -12
- package/dist/client.d.mts.map +1 -1
- package/dist/client.mjs +4 -1
- package/dist/client.mjs.map +1 -1
- package/dist/{index-DWhjFOp2.d.mts → index-Bz5N0iP1.d.mts} +139 -52
- package/dist/index-Bz5N0iP1.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +266 -349
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -13
- package/dist/index-DWhjFOp2.d.mts.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["logger","metadata: any","where: Array<{ field: string; value: any }>","e: any","paystack","user","url: string | undefined","reference: string | undefined","accessCode: string | undefined","initBody: any","error: any","verifyRes: any","baseSchema: BetterAuthPluginDBSchema","user","e: any"],"sources":["../node_modules/.pnpm/@better-auth+core@1.4.7_@better-auth+utils@0.3.0_@better-fetch+fetch@1.1.21_better-call_d24665956e428978271bbb947eda0893/node_modules/@better-auth/core/dist/env-DbssmzoK.mjs","../node_modules/.pnpm/@better-auth+core@1.4.7_@better-auth+utils@0.3.0_@better-fetch+fetch@1.1.21_better-call_d24665956e428978271bbb947eda0893/node_modules/@better-auth/core/dist/utils-NloIXYE0.mjs","../node_modules/.pnpm/@better-auth+core@1.4.7_@better-auth+utils@0.3.0_@better-fetch+fetch@1.1.21_better-call_d24665956e428978271bbb947eda0893/node_modules/@better-auth/core/dist/async_hooks/index.mjs","../node_modules/.pnpm/@better-auth+core@1.4.7_@better-auth+utils@0.3.0_@better-fetch+fetch@1.1.21_better-call_d24665956e428978271bbb947eda0893/node_modules/@better-auth/core/dist/context-DblZrIwO.mjs","../node_modules/.pnpm/@better-auth+core@1.4.7_@better-auth+utils@0.3.0_@better-fetch+fetch@1.1.21_better-call_d24665956e428978271bbb947eda0893/node_modules/@better-auth/core/dist/api/index.mjs","../src/utils.ts","../src/middleware.ts","../src/paystack-sdk.ts","../src/routes.ts","../src/schema.ts","../src/index.ts"],"sourcesContent":["//#region src/env/env-impl.ts\nconst _envShim = Object.create(null);\nconst _getEnv = (useShim) => globalThis.process?.env || globalThis.Deno?.env.toObject() || globalThis.__env__ || (useShim ? _envShim : globalThis);\nconst env = new Proxy(_envShim, {\n\tget(_, prop) {\n\t\treturn _getEnv()[prop] ?? _envShim[prop];\n\t},\n\thas(_, prop) {\n\t\treturn prop in _getEnv() || prop in _envShim;\n\t},\n\tset(_, prop, value) {\n\t\tconst env$1 = _getEnv(true);\n\t\tenv$1[prop] = value;\n\t\treturn true;\n\t},\n\tdeleteProperty(_, prop) {\n\t\tif (!prop) return false;\n\t\tconst env$1 = _getEnv(true);\n\t\tdelete env$1[prop];\n\t\treturn true;\n\t},\n\townKeys() {\n\t\tconst env$1 = _getEnv(true);\n\t\treturn Object.keys(env$1);\n\t}\n});\nfunction toBoolean(val) {\n\treturn val ? val !== \"false\" : false;\n}\nconst nodeENV = typeof process !== \"undefined\" && process.env && process.env.NODE_ENV || \"\";\n/** Detect if `NODE_ENV` environment variable is `production` */\nconst isProduction = nodeENV === \"production\";\n/** Detect if `NODE_ENV` environment variable is `dev` or `development` */\nconst isDevelopment = () => nodeENV === \"dev\" || nodeENV === \"development\";\n/** Detect if `NODE_ENV` environment variable is `test` */\nconst isTest = () => nodeENV === \"test\" || toBoolean(env.TEST);\n/**\n* Get environment variable with fallback\n*/\nfunction getEnvVar(key, fallback) {\n\tif (typeof process !== \"undefined\" && process.env) return process.env[key] ?? fallback;\n\tif (typeof Deno !== \"undefined\") return Deno.env.get(key) ?? fallback;\n\tif (typeof Bun !== \"undefined\") return Bun.env[key] ?? fallback;\n\treturn fallback;\n}\n/**\n* Get boolean environment variable\n*/\nfunction getBooleanEnvVar(key, fallback = true) {\n\tconst value = getEnvVar(key);\n\tif (!value) return fallback;\n\treturn value !== \"0\" && value.toLowerCase() !== \"false\" && value !== \"\";\n}\n/**\n* Common environment variables used in Better Auth\n*/\nconst ENV = Object.freeze({\n\tget BETTER_AUTH_SECRET() {\n\t\treturn getEnvVar(\"BETTER_AUTH_SECRET\");\n\t},\n\tget AUTH_SECRET() {\n\t\treturn getEnvVar(\"AUTH_SECRET\");\n\t},\n\tget BETTER_AUTH_TELEMETRY() {\n\t\treturn getEnvVar(\"BETTER_AUTH_TELEMETRY\");\n\t},\n\tget BETTER_AUTH_TELEMETRY_ID() {\n\t\treturn getEnvVar(\"BETTER_AUTH_TELEMETRY_ID\");\n\t},\n\tget NODE_ENV() {\n\t\treturn getEnvVar(\"NODE_ENV\", \"development\");\n\t},\n\tget PACKAGE_VERSION() {\n\t\treturn getEnvVar(\"PACKAGE_VERSION\", \"0.0.0\");\n\t},\n\tget BETTER_AUTH_TELEMETRY_ENDPOINT() {\n\t\treturn getEnvVar(\"BETTER_AUTH_TELEMETRY_ENDPOINT\", \"https://telemetry.better-auth.com/v1/track\");\n\t}\n});\n\n//#endregion\n//#region src/env/color-depth.ts\nconst COLORS_2 = 1;\nconst COLORS_16 = 4;\nconst COLORS_256 = 8;\nconst COLORS_16m = 24;\nconst TERM_ENVS = {\n\teterm: COLORS_16,\n\tcons25: COLORS_16,\n\tconsole: COLORS_16,\n\tcygwin: COLORS_16,\n\tdtterm: COLORS_16,\n\tgnome: COLORS_16,\n\thurd: COLORS_16,\n\tjfbterm: COLORS_16,\n\tkonsole: COLORS_16,\n\tkterm: COLORS_16,\n\tmlterm: COLORS_16,\n\tmosh: COLORS_16m,\n\tputty: COLORS_16,\n\tst: COLORS_16,\n\t\"rxvt-unicode-24bit\": COLORS_16m,\n\tterminator: COLORS_16m,\n\t\"xterm-kitty\": COLORS_16m\n};\nconst CI_ENVS_MAP = new Map(Object.entries({\n\tAPPVEYOR: COLORS_256,\n\tBUILDKITE: COLORS_256,\n\tCIRCLECI: COLORS_16m,\n\tDRONE: COLORS_256,\n\tGITEA_ACTIONS: COLORS_16m,\n\tGITHUB_ACTIONS: COLORS_16m,\n\tGITLAB_CI: COLORS_256,\n\tTRAVIS: COLORS_256\n}));\nconst TERM_ENVS_REG_EXP = [\n\t/ansi/,\n\t/color/,\n\t/linux/,\n\t/direct/,\n\t/^con[0-9]*x[0-9]/,\n\t/^rxvt/,\n\t/^screen/,\n\t/^xterm/,\n\t/^vt100/,\n\t/^vt220/\n];\nfunction getColorDepth() {\n\tif (getEnvVar(\"FORCE_COLOR\") !== void 0) switch (getEnvVar(\"FORCE_COLOR\")) {\n\t\tcase \"\":\n\t\tcase \"1\":\n\t\tcase \"true\": return COLORS_16;\n\t\tcase \"2\": return COLORS_256;\n\t\tcase \"3\": return COLORS_16m;\n\t\tdefault: return COLORS_2;\n\t}\n\tif (getEnvVar(\"NODE_DISABLE_COLORS\") !== void 0 && getEnvVar(\"NODE_DISABLE_COLORS\") !== \"\" || getEnvVar(\"NO_COLOR\") !== void 0 && getEnvVar(\"NO_COLOR\") !== \"\" || getEnvVar(\"TERM\") === \"dumb\") return COLORS_2;\n\tif (getEnvVar(\"TMUX\")) return COLORS_16m;\n\tif (\"TF_BUILD\" in env && \"AGENT_NAME\" in env) return COLORS_16;\n\tif (\"CI\" in env) {\n\t\tfor (const { 0: envName, 1: colors } of CI_ENVS_MAP) if (envName in env) return colors;\n\t\tif (getEnvVar(\"CI_NAME\") === \"codeship\") return COLORS_256;\n\t\treturn COLORS_2;\n\t}\n\tif (\"TEAMCITY_VERSION\" in env) return /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.exec(getEnvVar(\"TEAMCITY_VERSION\")) !== null ? COLORS_16 : COLORS_2;\n\tswitch (getEnvVar(\"TERM_PROGRAM\")) {\n\t\tcase \"iTerm.app\":\n\t\t\tif (!getEnvVar(\"TERM_PROGRAM_VERSION\") || /^[0-2]\\./.exec(getEnvVar(\"TERM_PROGRAM_VERSION\")) !== null) return COLORS_256;\n\t\t\treturn COLORS_16m;\n\t\tcase \"HyperTerm\":\n\t\tcase \"MacTerm\": return COLORS_16m;\n\t\tcase \"Apple_Terminal\": return COLORS_256;\n\t}\n\tif (getEnvVar(\"COLORTERM\") === \"truecolor\" || getEnvVar(\"COLORTERM\") === \"24bit\") return COLORS_16m;\n\tif (getEnvVar(\"TERM\")) {\n\t\tif (/truecolor/.exec(getEnvVar(\"TERM\")) !== null) return COLORS_16m;\n\t\tif (/^xterm-256/.exec(getEnvVar(\"TERM\")) !== null) return COLORS_256;\n\t\tconst termEnv = getEnvVar(\"TERM\").toLowerCase();\n\t\tif (TERM_ENVS[termEnv]) return TERM_ENVS[termEnv];\n\t\tif (TERM_ENVS_REG_EXP.some((term) => term.exec(termEnv) !== null)) return COLORS_16;\n\t}\n\tif (getEnvVar(\"COLORTERM\")) return COLORS_16;\n\treturn COLORS_2;\n}\n\n//#endregion\n//#region src/env/logger.ts\nconst TTY_COLORS = {\n\treset: \"\\x1B[0m\",\n\tbright: \"\\x1B[1m\",\n\tdim: \"\\x1B[2m\",\n\tundim: \"\\x1B[22m\",\n\tunderscore: \"\\x1B[4m\",\n\tblink: \"\\x1B[5m\",\n\treverse: \"\\x1B[7m\",\n\thidden: \"\\x1B[8m\",\n\tfg: {\n\t\tblack: \"\\x1B[30m\",\n\t\tred: \"\\x1B[31m\",\n\t\tgreen: \"\\x1B[32m\",\n\t\tyellow: \"\\x1B[33m\",\n\t\tblue: \"\\x1B[34m\",\n\t\tmagenta: \"\\x1B[35m\",\n\t\tcyan: \"\\x1B[36m\",\n\t\twhite: \"\\x1B[37m\"\n\t},\n\tbg: {\n\t\tblack: \"\\x1B[40m\",\n\t\tred: \"\\x1B[41m\",\n\t\tgreen: \"\\x1B[42m\",\n\t\tyellow: \"\\x1B[43m\",\n\t\tblue: \"\\x1B[44m\",\n\t\tmagenta: \"\\x1B[45m\",\n\t\tcyan: \"\\x1B[46m\",\n\t\twhite: \"\\x1B[47m\"\n\t}\n};\nconst levels = [\n\t\"debug\",\n\t\"info\",\n\t\"success\",\n\t\"warn\",\n\t\"error\"\n];\nfunction shouldPublishLog(currentLogLevel, logLevel) {\n\treturn levels.indexOf(logLevel) >= levels.indexOf(currentLogLevel);\n}\nconst levelColors = {\n\tinfo: TTY_COLORS.fg.blue,\n\tsuccess: TTY_COLORS.fg.green,\n\twarn: TTY_COLORS.fg.yellow,\n\terror: TTY_COLORS.fg.red,\n\tdebug: TTY_COLORS.fg.magenta\n};\nconst formatMessage = (level, message, colorsEnabled) => {\n\tconst timestamp = (/* @__PURE__ */ new Date()).toISOString();\n\tif (colorsEnabled) return `${TTY_COLORS.dim}${timestamp}${TTY_COLORS.reset} ${levelColors[level]}${level.toUpperCase()}${TTY_COLORS.reset} ${TTY_COLORS.bright}[Better Auth]:${TTY_COLORS.reset} ${message}`;\n\treturn `${timestamp} ${level.toUpperCase()} [Better Auth]: ${message}`;\n};\nconst createLogger = (options) => {\n\tconst enabled = options?.disabled !== true;\n\tconst logLevel = options?.level ?? \"error\";\n\tconst colorsEnabled = options?.disableColors !== void 0 ? !options.disableColors : getColorDepth() !== 1;\n\tconst LogFunc = (level, message, args = []) => {\n\t\tif (!enabled || !shouldPublishLog(logLevel, level)) return;\n\t\tconst formattedMessage = formatMessage(level, message, colorsEnabled);\n\t\tif (!options || typeof options.log !== \"function\") {\n\t\t\tif (level === \"error\") console.error(formattedMessage, ...args);\n\t\t\telse if (level === \"warn\") console.warn(formattedMessage, ...args);\n\t\t\telse console.log(formattedMessage, ...args);\n\t\t\treturn;\n\t\t}\n\t\toptions.log(level === \"success\" ? \"info\" : level, message, ...args);\n\t};\n\treturn {\n\t\t...Object.fromEntries(levels.map((level) => [level, (...[message, ...args]) => LogFunc(level, message, args)])),\n\t\tget level() {\n\t\t\treturn logLevel;\n\t\t}\n\t};\n};\nconst logger = createLogger();\n\n//#endregion\nexport { shouldPublishLog as a, env as c, isDevelopment as d, isProduction as f, logger as i, getBooleanEnvVar as l, nodeENV as m, createLogger as n, getColorDepth as o, isTest as p, levels as r, ENV as s, TTY_COLORS as t, getEnvVar as u };","import { i as logger } from \"./env-DbssmzoK.mjs\";\nimport { createRandomStringGenerator } from \"@better-auth/utils/random\";\n\n//#region src/utils/error-codes.ts\nfunction defineErrorCodes(codes) {\n\treturn codes;\n}\n\n//#endregion\n//#region src/utils/id.ts\nconst generateId = (size) => {\n\treturn createRandomStringGenerator(\"a-z\", \"A-Z\", \"0-9\")(size || 32);\n};\n\n//#endregion\n//#region src/utils/json.ts\nfunction safeJSONParse(data) {\n\tfunction reviver(_, value) {\n\t\tif (typeof value === \"string\") {\n\t\t\tif (/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$/.test(value)) {\n\t\t\t\tconst date = new Date(value);\n\t\t\t\tif (!isNaN(date.getTime())) return date;\n\t\t\t}\n\t\t}\n\t\treturn value;\n\t}\n\ttry {\n\t\tif (typeof data !== \"string\") return data;\n\t\treturn JSON.parse(data, reviver);\n\t} catch (e) {\n\t\tlogger.error(\"Error parsing JSON\", { error: e });\n\t\treturn null;\n\t}\n}\n\n//#endregion\n//#region src/utils/string.ts\nfunction capitalizeFirstLetter(str) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n//#endregion\nexport { defineErrorCodes as i, safeJSONParse as n, generateId as r, capitalizeFirstLetter as t };","//#region src/async_hooks/index.ts\nconst AsyncLocalStoragePromise = import(\n\t/* @vite-ignore */\n\t/* webpackIgnore: true */\n\t\"node:async_hooks\"\n).then((mod) => mod.AsyncLocalStorage).catch((err) => {\n\tif (\"AsyncLocalStorage\" in globalThis) return globalThis.AsyncLocalStorage;\n\tif (typeof window !== \"undefined\") return null;\n\tconsole.warn(\"[better-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected.\");\n\tconsole.warn(\"[better-auth] Please read more about this warning at https://better-auth.com/docs/installation#mount-handler\");\n\tconsole.warn(\"[better-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag\");\n\tthrow err;\n});\nasync function getAsyncLocalStorage() {\n\tconst mod = await AsyncLocalStoragePromise;\n\tif (mod === null) throw new Error(\"getAsyncLocalStorage is only available in server code\");\n\telse return mod;\n}\n\n//#endregion\nexport { getAsyncLocalStorage };","import { getAsyncLocalStorage } from \"@better-auth/core/async_hooks\";\n\n//#region src/context/endpoint-context.ts\nlet currentContextAsyncStorage = null;\nconst ensureAsyncStorage$2 = async () => {\n\tif (!currentContextAsyncStorage) currentContextAsyncStorage = new (await (getAsyncLocalStorage()))();\n\treturn currentContextAsyncStorage;\n};\n/**\n* This is for internal use only. Most users should use `getCurrentAuthContext` instead.\n*\n* It is exposed for advanced use cases where you need direct access to the AsyncLocalStorage instance.\n*/\nasync function getCurrentAuthContextAsyncLocalStorage() {\n\treturn ensureAsyncStorage$2();\n}\nasync function getCurrentAuthContext() {\n\tconst context = (await ensureAsyncStorage$2()).getStore();\n\tif (!context) throw new Error(\"No auth context found. Please make sure you are calling this function within a `runWithEndpointContext` callback.\");\n\treturn context;\n}\nasync function runWithEndpointContext(context, fn) {\n\treturn (await ensureAsyncStorage$2()).run(context, fn);\n}\n\n//#endregion\n//#region src/context/request-state.ts\nlet requestStateAsyncStorage = null;\nconst ensureAsyncStorage$1 = async () => {\n\tif (!requestStateAsyncStorage) requestStateAsyncStorage = new (await (getAsyncLocalStorage()))();\n\treturn requestStateAsyncStorage;\n};\nasync function getRequestStateAsyncLocalStorage() {\n\treturn ensureAsyncStorage$1();\n}\nasync function hasRequestState() {\n\treturn (await ensureAsyncStorage$1()).getStore() !== void 0;\n}\nasync function getCurrentRequestState() {\n\tconst store = (await ensureAsyncStorage$1()).getStore();\n\tif (!store) throw new Error(\"No request state found. Please make sure you are calling this function within a `runWithRequestState` callback.\");\n\treturn store;\n}\nasync function runWithRequestState(store, fn) {\n\treturn (await ensureAsyncStorage$1()).run(store, fn);\n}\nfunction defineRequestState(initFn) {\n\tconst ref = Object.freeze({});\n\treturn {\n\t\tget ref() {\n\t\t\treturn ref;\n\t\t},\n\t\tasync get() {\n\t\t\tconst store = await getCurrentRequestState();\n\t\t\tif (!store.has(ref)) {\n\t\t\t\tconst initialValue = await initFn();\n\t\t\t\tstore.set(ref, initialValue);\n\t\t\t\treturn initialValue;\n\t\t\t}\n\t\t\treturn store.get(ref);\n\t\t},\n\t\tasync set(value) {\n\t\t\t(await getCurrentRequestState()).set(ref, value);\n\t\t}\n\t};\n}\n\n//#endregion\n//#region src/context/transaction.ts\nlet currentAdapterAsyncStorage = null;\nconst ensureAsyncStorage = async () => {\n\tif (!currentAdapterAsyncStorage) currentAdapterAsyncStorage = new (await (getAsyncLocalStorage()))();\n\treturn currentAdapterAsyncStorage;\n};\n/**\n* This is for internal use only. Most users should use `getCurrentAdapter` instead.\n*\n* It is exposed for advanced use cases where you need direct access to the AsyncLocalStorage instance.\n*/\nconst getCurrentDBAdapterAsyncLocalStorage = async () => {\n\treturn ensureAsyncStorage();\n};\nconst getCurrentAdapter = async (fallback) => {\n\treturn ensureAsyncStorage().then((als) => {\n\t\treturn als.getStore() || fallback;\n\t}).catch(() => {\n\t\treturn fallback;\n\t});\n};\nconst runWithAdapter = async (adapter, fn) => {\n\tlet called = true;\n\treturn ensureAsyncStorage().then((als) => {\n\t\tcalled = true;\n\t\treturn als.run(adapter, fn);\n\t}).catch((err) => {\n\t\tif (!called) return fn();\n\t\tthrow err;\n\t});\n};\nconst runWithTransaction = async (adapter, fn) => {\n\tlet called = true;\n\treturn ensureAsyncStorage().then((als) => {\n\t\tcalled = true;\n\t\treturn adapter.transaction(async (trx) => {\n\t\t\treturn als.run(trx, fn);\n\t\t});\n\t}).catch((err) => {\n\t\tif (!called) return fn();\n\t\tthrow err;\n\t});\n};\n\n//#endregion\nexport { defineRequestState as a, hasRequestState as c, getCurrentAuthContextAsyncLocalStorage as d, runWithEndpointContext as f, runWithTransaction as i, runWithRequestState as l, getCurrentDBAdapterAsyncLocalStorage as n, getCurrentRequestState as o, runWithAdapter as r, getRequestStateAsyncLocalStorage as s, getCurrentAdapter as t, getCurrentAuthContext as u };","import { f as runWithEndpointContext } from \"../context-DblZrIwO.mjs\";\nimport { createEndpoint, createMiddleware } from \"better-call\";\n\n//#region src/api/index.ts\nconst optionsMiddleware = createMiddleware(async () => {\n\t/**\n\t* This will be passed on the instance of\n\t* the context. Used to infer the type\n\t* here.\n\t*/\n\treturn {};\n});\nconst createAuthMiddleware = createMiddleware.create({ use: [optionsMiddleware, createMiddleware(async () => {\n\treturn {};\n})] });\nconst use = [optionsMiddleware];\nfunction createAuthEndpoint(pathOrOptions, handlerOrOptions, handlerOrNever) {\n\tconst path = typeof pathOrOptions === \"string\" ? pathOrOptions : void 0;\n\tconst options = typeof handlerOrOptions === \"object\" ? handlerOrOptions : pathOrOptions;\n\tconst handler = typeof handlerOrOptions === \"function\" ? handlerOrOptions : handlerOrNever;\n\tif (path) return createEndpoint(path, {\n\t\t...options,\n\t\tuse: [...options?.use || [], ...use]\n\t}, async (ctx) => runWithEndpointContext(ctx, () => handler(ctx)));\n\treturn createEndpoint({\n\t\t...options,\n\t\tuse: [...options?.use || [], ...use]\n\t}, async (ctx) => runWithEndpointContext(ctx, () => handler(ctx)));\n}\n\n//#endregion\nexport { createAuthEndpoint, createAuthMiddleware, optionsMiddleware };","import type { PaystackOptions } from \"./types\";\n\nexport async function getPlans(subscriptionOptions: PaystackOptions[\"subscription\"]) {\n if (subscriptionOptions?.enabled) {\n return typeof subscriptionOptions.plans === \"function\"\n ? await subscriptionOptions.plans()\n : subscriptionOptions.plans;\n }\n throw new Error(\"Subscriptions are not enabled in the Paystack options.\");\n}\n\nexport async function getPlanByName(options: PaystackOptions<any>, name: string) {\n return await getPlans(options.subscription).then((plans) =>\n plans?.find((plan) => plan.name.toLowerCase() === name.toLowerCase()),\n );\n}\n","import { createAuthMiddleware } from \"@better-auth/core/api\";\nimport { logger } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport type { SubscriptionOptions } from \"./types\";\n\nexport const referenceMiddleware = (\n subscriptionOptions: SubscriptionOptions,\n action:\n | \"initialize-transaction\"\n | \"verify-transaction\"\n | \"list-subscriptions\"\n | \"disable-subscription\"\n | \"enable-subscription\",\n) =>\n createAuthMiddleware(async (ctx) => {\n const session = ctx.context.session as any;\n if (!session) {\n throw new APIError(\"UNAUTHORIZED\");\n }\n const referenceId =\n ctx.body?.referenceId || ctx.query?.referenceId || session.user.id;\n\n if (referenceId !== session.user.id && !subscriptionOptions.authorizeReference) {\n logger.error(\n `Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your paystack plugin config.`,\n );\n throw new APIError(\"BAD_REQUEST\", {\n message:\n \"Passing referenceId isn't allowed without subscription.authorizeReference.\",\n });\n }\n\n if (referenceId !== session.user.id && subscriptionOptions.authorizeReference) {\n const authorized = await subscriptionOptions.authorizeReference(\n {\n user: session.user,\n session,\n referenceId,\n action,\n },\n ctx,\n );\n if (!authorized) {\n throw new APIError(\"UNAUTHORIZED\");\n }\n }\n\n return {\n context: {\n referenceId,\n },\n };\n });\n","import type { PaystackClientLike, PaystackOpenApiFetchResponse } from \"./types\";\n\nfunction isOpenApiFetchResponse(value: any): value is PaystackOpenApiFetchResponse {\n return (\n value &&\n typeof value === \"object\" &&\n (\"data\" in value || \"error\" in value || \"response\" in value)\n );\n}\n\nexport function unwrapSdkResult<T = any>(result: any): T {\n if (isOpenApiFetchResponse(result)) {\n if (result.error) {\n throw result.error;\n }\n return result.data as T;\n }\n return (result?.data ?? result) as T;\n}\n\nexport function getPaystackOps(paystackClient: PaystackClientLike | any) {\n return {\n customerCreate: async (params: any) => {\n if (paystackClient?.customer_create) {\n return paystackClient.customer_create({ body: params });\n }\n return paystackClient?.customer?.create?.(params);\n },\n transactionInitialize: async (body: any) => {\n if (paystackClient?.transaction_initialize) {\n return paystackClient.transaction_initialize({ body });\n }\n return paystackClient?.transaction?.initialize?.(body);\n },\n transactionVerify: async (reference: string) => {\n if (paystackClient?.transaction_verify) {\n return paystackClient.transaction_verify({\n params: { path: { reference } },\n });\n }\n return paystackClient?.transaction?.verify?.(reference);\n },\n subscriptionDisable: async (body: { code: string; token: string }) => {\n if (paystackClient?.subscription_disable) {\n return paystackClient.subscription_disable({ body });\n }\n return paystackClient?.subscription?.disable?.(body);\n },\n subscriptionEnable: async (body: { code: string; token: string }) => {\n if (paystackClient?.subscription_enable) {\n return paystackClient.subscription_enable({ body });\n }\n return paystackClient?.subscription?.enable?.(body);\n },\n subscriptionFetch: async (idOrCode: string) => {\n if (paystackClient?.subscription_fetch) {\n try {\n return await paystackClient.subscription_fetch({\n params: { path: { code: idOrCode } },\n });\n } catch {\n return paystackClient.subscription_fetch({\n params: { path: { id_or_code: idOrCode } },\n });\n }\n }\n return paystackClient?.subscription?.fetch?.(idOrCode);\n },\n subscriptionManageLink: async (code: string) => {\n if (paystackClient?.subscription_manage_link) {\n return paystackClient.subscription_manage_link({\n params: { path: { code } },\n });\n }\n return paystackClient?.subscription?.manage?.link?.(code);\n },\n };\n}\n","import { createAuthEndpoint } from \"@better-auth/core/api\";\nimport { defineErrorCodes } from \"@better-auth/core/utils\";\nimport type { GenericEndpointContext } from \"better-auth\";\nimport { HIDE_METADATA } from \"better-auth\";\nimport {\n APIError,\n getSessionFromCtx,\n originCheck,\n sessionMiddleware,\n} from \"better-auth/api\";\nimport * as z from \"zod/v4\";\nimport type { InputSubscription, PaystackOptions, Subscription } from \"./types\";\nimport { getPlanByName, getPlans } from \"./utils\";\nimport { referenceMiddleware } from \"./middleware\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk\";\n\ntype AnyPaystackOptions = PaystackOptions<any>;\n\nconst PAYSTACK_ERROR_CODES = 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:\n \"Email verification is required before you can subscribe to a plan\",\n});\n\nasync 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 subtle = (globalThis.crypto as any)?.subtle;\n if (subtle) {\n const key = await subtle.importKey(\n \"raw\",\n keyData,\n { name: \"HMAC\", hash: \"SHA-512\" },\n 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\nexport const paystackWebhook = (options: AnyPaystackOptions) => {\n return createAuthEndpoint(\n \"/paystack/webhook\",\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 = (ctx as any).requestClone ?? ctx.request;\n const payload = await request.text();\n const headers = (ctx as any).headers ?? (ctx.request as any)?.headers;\n const signature = headers?.get(\"x-paystack-signature\") as\n | string\n | null\n | undefined;\n\n if (!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.paystackWebhookSecret, 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 any;\n\n // Best-effort local state sync for subscription lifecycle.\n if (options.subscription?.enabled) {\n const eventName = String(event?.event ?? \"\");\n const data = event?.data as any;\n try {\n if (eventName === \"subscription.create\") {\n const subscriptionCode =\n data?.subscription_code ??\n data?.subscription?.subscription_code ??\n data?.code;\n const customerCode =\n data?.customer?.customer_code ??\n data?.customer_code ??\n data?.customer?.code;\n const planCode =\n data?.plan?.plan_code ?? data?.plan_code ?? data?.plan;\n\n let metadata: any = data?.metadata;\n if (typeof metadata === \"string\") {\n try {\n metadata = JSON.parse(metadata);\n } catch {\n // ignore\n }\n }\n\n const referenceIdFromMetadata =\n typeof metadata === \"object\" && metadata\n ? (metadata.referenceId as string | undefined)\n : undefined;\n\n let planNameFromMetadata =\n typeof metadata === \"object\" && metadata\n ? (metadata.plan as string | undefined)\n : undefined;\n if (typeof planNameFromMetadata === \"string\") {\n planNameFromMetadata = planNameFromMetadata.toLowerCase();\n }\n\n const plans = await getPlans(options.subscription);\n const planFromCode = planCode\n ? plans.find((p) => p.planCode && p.planCode === planCode)\n : undefined;\n const planName = (planFromCode?.name ?? planNameFromMetadata)?.toLowerCase();\n\n if (subscriptionCode) {\n const where: Array<{ field: string; value: any }> = [];\n if (referenceIdFromMetadata) {\n where.push({ field: \"referenceId\", value: referenceIdFromMetadata });\n } else if (customerCode) {\n where.push({ field: \"paystackCustomerCode\", value: customerCode });\n }\n if (planName) {\n where.push({ field: \"plan\", value: planName });\n }\n\n if (where.length > 0) {\n const matches = await ctx.context.adapter.findMany<Subscription>({\n model: \"subscription\",\n where,\n });\n const subscription = matches?.[0];\n if (subscription) {\n await ctx.context.adapter.update({\n model: \"subscription\",\n update: {\n paystackSubscriptionCode: subscriptionCode,\n status: \"active\",\n updatedAt: new Date(),\n },\n where: [{ field: \"id\", value: subscription.id }],\n });\n\n const plan = planFromCode ?? (planName ? await getPlanByName(options, planName) : undefined);\n if (plan) {\n await options.subscription.onSubscriptionComplete?.(\n { event, subscription: { ...subscription, paystackSubscriptionCode: subscriptionCode, status: \"active\" }, plan },\n ctx as any,\n );\n }\n }\n }\n }\n }\n\n if (eventName === \"subscription.disable\" || eventName === \"subscription.not_renew\") {\n const subscriptionCode =\n data?.subscription_code ??\n data?.subscription?.subscription_code ??\n data?.code;\n if (subscriptionCode) {\n await ctx.context.adapter.update({\n model: \"subscription\",\n update: {\n status: \"canceled\",\n updatedAt: new Date(),\n },\n where: [\n { field: \"paystackSubscriptionCode\", value: subscriptionCode },\n ],\n });\n }\n }\n } catch (e: any) {\n ctx.context.logger.error(\"Failed to sync Paystack webhook event\", e);\n }\n }\n\n await options.onEvent?.(event);\n return ctx.json({ received: true });\n },\n );\n};\n\n\nconst initializeTransactionBodySchema = z.object({\n plan: z.string(),\n referenceId: z.string().optional(),\n callbackURL: z.string().optional(),\n});\n\nexport const initializeTransaction = (options: AnyPaystackOptions) => {\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"initialize-transaction\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/transaction/initialize\",\n {\n method: \"POST\",\n body: initializeTransactionBodySchema,\n use: useMiddlewares,\n },\n async (ctx) => {\n const paystack = getPaystackOps(options.paystackClient);\n if (!subscriptionOptions?.enabled) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Subscriptions are not enabled in the Paystack options.\",\n });\n }\n\n if (ctx.body.callbackURL) {\n const isTrustedOriginFn = (ctx.context as any)?.isTrustedOrigin as\n | ((value: string, opts?: { allowRelativePaths?: boolean }) => boolean)\n | undefined;\n\n const trusted = isTrustedOriginFn\n ? isTrustedOriginFn(ctx.body.callbackURL, { allowRelativePaths: true })\n : (() => {\n try {\n if (ctx.body.callbackURL.startsWith(\"/\")) return true;\n const baseUrl =\n (ctx.context as any)?.baseURL ??\n (ctx.request as any)?.url ??\n \"\";\n if (!baseUrl) return false;\n const baseOrigin = new URL(baseUrl).origin;\n return new URL(ctx.body.callbackURL).origin === baseOrigin;\n } catch {\n return false;\n }\n })();\n\n if (!trusted) {\n throw new APIError(\"FORBIDDEN\", {\n message: \"callbackURL is not a trusted origin.\",\n status: 403,\n });\n }\n }\n\n const session = await getSessionFromCtx(ctx);\n if (!session) throw new APIError(\"UNAUTHORIZED\");\n const user = session.user;\n const referenceIdFromCtx = (ctx.context as any).referenceId as\n | string\n | undefined;\n const referenceId =\n ctx.body.referenceId || referenceIdFromCtx || (session.user as any).id;\n\n if (subscriptionOptions.requireEmailVerification && !user.emailVerified) {\n throw new APIError(\"BAD_REQUEST\", {\n code: \"EMAIL_VERIFICATION_REQUIRED\",\n message: PAYSTACK_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED,\n });\n }\n\n const plan = await getPlanByName(options, ctx.body.plan);\n if (!plan) {\n throw new APIError(\"BAD_REQUEST\", {\n code: \"SUBSCRIPTION_PLAN_NOT_FOUND\",\n message: PAYSTACK_ERROR_CODES.SUBSCRIPTION_PLAN_NOT_FOUND,\n });\n }\n\n if (!plan.planCode && !plan.amount) {\n throw new APIError(\"BAD_REQUEST\", {\n message:\n \"Paystack transaction initialization requires either plan.planCode (Paystack plan code) or plan.amount (smallest unit).\",\n });\n }\n\n let url: string | undefined;\n let reference: string | undefined;\n let accessCode: string | undefined;\n try {\n const metadata = JSON.stringify({\n referenceId,\n userId: user.id,\n plan: plan.name.toLowerCase(),\n });\n\n const initBody: any = {\n email: user.email,\n callback_url: ctx.body.callbackURL,\n currency: plan.currency,\n plan: plan.planCode,\n invoice_limit: plan.invoiceLimit,\n metadata,\n };\n\n // Paystack docs: when `plan` is provided, it invalidates `amount`.\n if (!plan.planCode && plan.amount) {\n initBody.amount = String(plan.amount);\n }\n\n const initRaw = await paystack.transactionInitialize(initBody);\n const initRes = unwrapSdkResult<any>(initRaw);\n const data =\n initRes && typeof initRes === \"object\" && \"status\" in initRes && \"data\" in initRes\n ? (initRes as any).data\n : initRes?.data ?? initRes;\n url = data?.authorization_url;\n reference = data?.reference;\n accessCode = data?.access_code;\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to initialize Paystack transaction\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_INITIALIZE_TRANSACTION\",\n message:\n error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_INITIALIZE_TRANSACTION,\n });\n }\n\n const paystackCustomerCode = (user as any).paystackCustomerCode;\n\n await ctx.context.adapter.create<InputSubscription, Subscription>({\n model: \"subscription\",\n data: {\n plan: plan.name.toLowerCase(),\n referenceId,\n paystackCustomerCode,\n paystackTransactionReference: reference,\n status: \"incomplete\",\n },\n });\n\n return ctx.json({\n url,\n reference,\n accessCode,\n redirect: true,\n });\n },\n );\n};\n\nexport const verifyTransaction = (options: AnyPaystackOptions) => {\n const verifyBodySchema = z.object({\n reference: z.string(),\n });\n\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"verify-transaction\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/transaction/verify\",\n {\n method: \"POST\",\n body: verifyBodySchema,\n use: useMiddlewares,\n },\n async (ctx) => {\n const paystack = getPaystackOps(options.paystackClient);\n let verifyRes: any;\n try {\n const verifyRaw = await paystack.transactionVerify(ctx.body.reference);\n verifyRes = unwrapSdkResult<any>(verifyRaw);\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to verify Paystack transaction\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_VERIFY_TRANSACTION\",\n message:\n error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_VERIFY_TRANSACTION,\n });\n }\n const data =\n verifyRes && typeof verifyRes === \"object\" && \"status\" in verifyRes && \"data\" in verifyRes\n ? (verifyRes as any).data\n : verifyRes?.data ?? verifyRes;\n const status = data?.status;\n const reference = data?.reference ?? ctx.body.reference;\n\n if (status === \"success\") {\n try {\n const session = await getSessionFromCtx(ctx);\n const referenceIdFromCtx = (ctx.context as any).referenceId as\n | string\n | undefined;\n const referenceId = referenceIdFromCtx ?? (session?.user as any)?.id;\n\n await ctx.context.adapter.update({\n model: \"subscription\",\n update: {\n status: \"active\",\n periodStart: new Date(),\n updatedAt: new Date(),\n },\n where: [\n { field: \"paystackTransactionReference\", value: reference },\n ...(referenceId ? [{ field: \"referenceId\", value: referenceId }] : []),\n ],\n });\n } catch (e: any) {\n ctx.context.logger.error(\n \"Failed to update subscription after transaction verification\",\n e,\n );\n }\n }\n\n return ctx.json({\n status,\n reference,\n data,\n });\n },\n );\n};\n\nexport const listSubscriptions = (options: AnyPaystackOptions) => {\n const listQuerySchema = z.object({\n referenceId: z.string().optional(),\n });\n\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"list-subscriptions\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/subscription/list-local\",\n {\n method: \"GET\",\n query: listQuerySchema,\n use: useMiddlewares,\n },\n async (ctx) => {\n if (!subscriptionOptions?.enabled) {\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) throw new APIError(\"UNAUTHORIZED\");\n const referenceId =\n ((ctx.context as any).referenceId as string | undefined) ??\n (ctx.query?.referenceId as string | undefined) ??\n ((session.user as any).id as string);\n const res = await ctx.context.adapter.findMany<Subscription>({\n model: \"subscription\",\n where: [{ field: \"referenceId\", value: referenceId }],\n });\n return ctx.json({ subscriptions: res });\n },\n );\n};\n\nconst enableDisableBodySchema = z.object({\n referenceId: z.string().optional(),\n subscriptionCode: z.string(),\n emailToken: z.string().optional(),\n});\n\nfunction decodeBase64UrlToString(value: string): string {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = normalized + \"===\".slice((normalized.length + 3) % 4);\n if (typeof (globalThis as any).atob === \"function\") {\n return (globalThis as any).atob(padded);\n }\n // Node fallback\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return Buffer.from(padded, \"base64\").toString(\"utf8\");\n}\n\nfunction tryGetEmailTokenFromSubscriptionManageLink(link: string): string | undefined {\n try {\n const url = new URL(link);\n const subscriptionToken = url.searchParams.get(\"subscription_token\");\n if (!subscriptionToken) 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 any;\n return typeof payload?.email_token === \"string\" ? payload.email_token : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport const disablePaystackSubscription = (options: AnyPaystackOptions) => {\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"disable-subscription\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/subscription/disable\",\n { method: \"POST\", body: enableDisableBodySchema, use: useMiddlewares },\n async (ctx) => {\n const { subscriptionCode } = ctx.body;\n const paystack = getPaystackOps(options.paystackClient);\n try {\n let emailToken = ctx.body.emailToken;\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionFetch(subscriptionCode);\n const fetchRes = unwrapSdkResult<any>(raw);\n const data =\n fetchRes && typeof fetchRes === \"object\" && \"status\" in fetchRes && \"data\" in fetchRes\n ? (fetchRes as any).data\n : fetchRes?.data ?? fetchRes;\n emailToken = data?.email_token;\n } catch {\n // ignore; try manage-link fallback below\n }\n }\n\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionManageLink(subscriptionCode);\n const linkRes = unwrapSdkResult<any>(raw);\n const data =\n linkRes && typeof linkRes === \"object\" && \"status\" in linkRes && \"data\" in linkRes\n ? (linkRes as any).data\n : linkRes?.data ?? linkRes;\n const link = data?.link;\n if (typeof link === \"string\") {\n emailToken = tryGetEmailTokenFromSubscriptionManageLink(link);\n }\n } catch {\n // ignore\n }\n }\n\n if (!emailToken) {\n throw new APIError(\"BAD_REQUEST\", {\n message:\n \"Missing emailToken. Provide it explicitly or ensure your server can fetch it from Paystack using the subscription code.\",\n });\n }\n\n const raw = await paystack.subscriptionDisable({\n code: subscriptionCode,\n token: emailToken,\n });\n const result = unwrapSdkResult<any>(raw);\n return ctx.json({ result });\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to disable Paystack subscription\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_DISABLE_SUBSCRIPTION\",\n message:\n error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_DISABLE_SUBSCRIPTION,\n });\n }\n },\n );\n};\n\nexport const enablePaystackSubscription = (options: AnyPaystackOptions) => {\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"enable-subscription\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/subscription/enable\",\n { method: \"POST\", body: enableDisableBodySchema, use: useMiddlewares },\n async (ctx) => {\n const { subscriptionCode } = ctx.body;\n const paystack = getPaystackOps(options.paystackClient);\n try {\n let emailToken = ctx.body.emailToken;\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionFetch(subscriptionCode);\n const fetchRes = unwrapSdkResult<any>(raw);\n const data =\n fetchRes && typeof fetchRes === \"object\" && \"status\" in fetchRes && \"data\" in fetchRes\n ? (fetchRes as any).data\n : fetchRes?.data ?? fetchRes;\n emailToken = data?.email_token;\n } catch {\n // ignore; try manage-link fallback below\n }\n }\n\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionManageLink(subscriptionCode);\n const linkRes = unwrapSdkResult<any>(raw);\n const data =\n linkRes && typeof linkRes === \"object\" && \"status\" in linkRes && \"data\" in linkRes\n ? (linkRes as any).data\n : linkRes?.data ?? linkRes;\n const link = data?.link;\n if (typeof link === \"string\") {\n emailToken = tryGetEmailTokenFromSubscriptionManageLink(link);\n }\n } catch {\n // ignore\n }\n }\n\n if (!emailToken) {\n throw new APIError(\"BAD_REQUEST\", {\n message:\n \"Missing emailToken. Provide it explicitly or ensure your server can fetch it from Paystack using the subscription code.\",\n });\n }\n\n const raw = await paystack.subscriptionEnable({\n code: subscriptionCode,\n token: emailToken,\n });\n const result = unwrapSdkResult<any>(raw);\n return ctx.json({ result });\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to enable Paystack subscription\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_ENABLE_SUBSCRIPTION\",\n message:\n error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_ENABLE_SUBSCRIPTION,\n });\n }\n },\n );\n};\n\nexport { PAYSTACK_ERROR_CODES };\n","import type { BetterAuthPluginDBSchema } from \"@better-auth/core/db\";\nimport { mergeSchema } from \"better-auth/db\";\nimport type { PaystackOptions } from \"./types\";\n\nexport const subscriptions = {\n subscription: {\n fields: {\n plan: {\n type: \"string\",\n required: true,\n },\n referenceId: {\n type: \"string\",\n required: true,\n },\n paystackCustomerCode: {\n type: \"string\",\n required: false,\n },\n paystackSubscriptionCode: {\n type: \"string\",\n required: false,\n },\n paystackTransactionReference: {\n type: \"string\",\n required: false,\n },\n status: {\n type: \"string\",\n defaultValue: \"incomplete\",\n },\n periodStart: {\n type: \"date\",\n required: false,\n },\n periodEnd: {\n type: \"date\",\n required: false,\n },\n trialStart: {\n type: \"date\",\n required: false,\n },\n trialEnd: {\n type: \"date\",\n required: false,\n },\n cancelAtPeriodEnd: {\n type: \"boolean\",\n required: false,\n defaultValue: false,\n },\n groupId: {\n type: \"string\",\n required: false,\n },\n seats: {\n type: \"number\",\n required: false,\n },\n },\n },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const user = {\n user: {\n fields: {\n paystackCustomerCode: {\n type: \"string\",\n required: false,\n },\n },\n },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const getSchema = (options: PaystackOptions<any>) => {\n let baseSchema: BetterAuthPluginDBSchema;\n\n if (options.subscription?.enabled) {\n baseSchema = {\n ...subscriptions,\n ...user,\n };\n } else {\n baseSchema = {\n ...user,\n };\n }\n\n if (\n options.schema &&\n !options.subscription?.enabled &&\n \"subscription\" in options.schema\n ) {\n const { subscription: _subscription, ...restSchema } = options.schema as any;\n return mergeSchema(baseSchema, restSchema);\n }\n\n return mergeSchema(baseSchema, options.schema);\n};\n","import { defineErrorCodes } from \"@better-auth/core/utils\";\nimport type { BetterAuthPlugin } from \"better-auth\";\nimport type { GenericEndpointContext } from \"better-auth\";\nimport { defu } from \"defu\";\nimport {\n disablePaystackSubscription,\n enablePaystackSubscription,\n initializeTransaction,\n listSubscriptions,\n paystackWebhook,\n verifyTransaction,\n PAYSTACK_ERROR_CODES,\n} from \"./routes\";\nimport { getSchema } from \"./schema\";\nimport type {\n PaystackNodeClient,\n PaystackClientLike,\n PaystackOptions,\n PaystackPlan,\n Subscription,\n SubscriptionOptions,\n} from \"./types\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk\";\n\nconst INTERNAL_ERROR_CODES = defineErrorCodes({\n ...PAYSTACK_ERROR_CODES,\n});\n\nexport const paystack = <\n TPaystackClient extends PaystackClientLike = PaystackNodeClient,\n O extends PaystackOptions<TPaystackClient> = PaystackOptions<TPaystackClient>,\n>(\n options: O,\n) => {\n const baseEndpoints = {\n paystackWebhook: paystackWebhook(options),\n } satisfies NonNullable<BetterAuthPlugin[\"endpoints\"]>;\n\n const subscriptionEnabledEndpoints = {\n ...baseEndpoints,\n initializeTransaction: initializeTransaction(options),\n verifyTransaction: verifyTransaction(options),\n listSubscriptions: listSubscriptions(options),\n disablePaystackSubscription: disablePaystackSubscription(options),\n enablePaystackSubscription: enablePaystackSubscription(options),\n } satisfies NonNullable<BetterAuthPlugin[\"endpoints\"]>;\n\n type EndpointsForOptions = O extends { subscription: { enabled: true } }\n ? typeof subscriptionEnabledEndpoints\n : typeof baseEndpoints;\n\n const endpoints = (\n options.subscription?.enabled\n ? subscriptionEnabledEndpoints\n : baseEndpoints\n ) as EndpointsForOptions;\n\n return {\n id: \"paystack\",\n endpoints,\n init(ctx) {\n return {\n options: {\n databaseHooks: {\n user: {\n create: {\n async after(user, hookCtx?: GenericEndpointContext | null) {\n if (!hookCtx || !options.createCustomerOnSignUp) return;\n\n try {\n const firstName = user.name?.split(\" \")[0];\n const lastName = user.name?.split(\" \").slice(1).join(\" \") || undefined;\n\n const extraCreateParams = options.getCustomerCreateParams\n ? await options.getCustomerCreateParams(user as any, hookCtx as any)\n : {};\n\n const params = defu(\n {\n email: user.email,\n first_name: firstName,\n last_name: lastName,\n metadata: { userId: user.id },\n },\n extraCreateParams,\n );\n const paystack = getPaystackOps(options.paystackClient);\n const raw = await paystack.customerCreate(params);\n const res = unwrapSdkResult<any>(raw);\n const paystackCustomer =\n res && typeof res === \"object\" && \"status\" in res && \"data\" in res\n ? (res as any).data\n : res?.data ?? res;\n const customerCode = paystackCustomer?.customer_code;\n\n if (!customerCode) return;\n\n await (hookCtx as any).context.internalAdapter.updateUser(user.id, {\n paystackCustomerCode: customerCode,\n });\n\n await options.onCustomerCreate?.(\n {\n paystackCustomer,\n user: {\n ...(user as any),\n paystackCustomerCode: customerCode,\n },\n },\n hookCtx as any,\n );\n } catch (e: any) {\n (hookCtx as any).context.logger.error(\n `Failed to create Paystack customer: ${e?.message || \"Unknown error\"}`,\n e,\n );\n }\n },\n },\n },\n },\n },\n };\n },\n schema: getSchema(options),\n $ERROR_CODES: INTERNAL_ERROR_CODES,\n } satisfies BetterAuthPlugin;\n};\n\ntype PaystackClientFromOptions<O extends PaystackOptions<any>> =\n O extends PaystackOptions<infer TClient> ? TClient : PaystackNodeClient;\n\nexport type PaystackPlugin<O extends PaystackOptions<any> = PaystackOptions> = ReturnType<\n typeof paystack<PaystackClientFromOptions<O>, O>\n>;\n\nexport type { Subscription, SubscriptionOptions, PaystackPlan, PaystackOptions };\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/utils.ts","../src/middleware.ts","../src/paystack-sdk.ts","../src/routes.ts","../src/schema.ts","../src/index.ts"],"sourcesContent":["import type { PaystackOptions } from \"./types\";\n\nexport async function getPlans(subscriptionOptions: PaystackOptions[\"subscription\"]) {\n if (subscriptionOptions?.enabled) {\n return typeof subscriptionOptions.plans === \"function\"\n ? await subscriptionOptions.plans()\n : subscriptionOptions.plans;\n }\n throw new Error(\"Subscriptions are not enabled in the Paystack options.\");\n}\n\nexport async function getPlanByName(options: PaystackOptions<any>, name: string) {\n return await getPlans(options.subscription).then((plans) =>\n plans?.find((plan) => plan.name.toLowerCase() === name.toLowerCase()),\n );\n}\n\nexport async function getProducts(productOptions: PaystackOptions[\"products\"]) {\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(options: PaystackOptions<any>, name: string) {\n return await getProducts(options.products).then((products) =>\n products?.find((product) => product.name.toLowerCase() === name.toLowerCase()),\n );\n}\n","import { createAuthMiddleware } from \"@better-auth/core/api\";\nimport { logger } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport type { SubscriptionOptions } from \"./types\";\n\nexport const referenceMiddleware = (\n subscriptionOptions: SubscriptionOptions,\n action:\n | \"initialize-transaction\"\n | \"verify-transaction\"\n | \"list-subscriptions\"\n | \"list-transactions\"\n | \"disable-subscription\"\n | \"enable-subscription\"\n | \"get-subscription-manage-link\",\n) =>\n createAuthMiddleware(async (ctx) => {\n const session = ctx.context.session as any;\n if (!session) {\n throw new APIError(\"UNAUTHORIZED\");\n }\n const referenceId =\n ctx.body?.referenceId || ctx.query?.referenceId || session.user.id;\n\n if (referenceId !== session.user.id && !subscriptionOptions.authorizeReference) {\n logger.error(\n `Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your paystack plugin config.`,\n );\n throw new APIError(\"BAD_REQUEST\", {\n message:\n \"Passing referenceId isn't allowed without subscription.authorizeReference.\",\n });\n }\n\n if (referenceId !== session.user.id && subscriptionOptions.authorizeReference) {\n const authorized = await subscriptionOptions.authorizeReference(\n {\n user: session.user,\n session,\n referenceId,\n action,\n },\n ctx,\n );\n if (!authorized) {\n throw new APIError(\"UNAUTHORIZED\");\n }\n }\n\n return {\n context: {\n referenceId,\n },\n };\n });\n","import type { PaystackClientLike, PaystackOpenApiFetchResponse } from \"./types\";\n\nfunction isOpenApiFetchResponse(value: any): value is PaystackOpenApiFetchResponse {\n return (\n value &&\n typeof value === \"object\" &&\n (\"data\" in value || \"error\" in value || \"response\" in value)\n );\n}\n\nexport function unwrapSdkResult<T = any>(result: any): T {\n if (isOpenApiFetchResponse(result)) {\n if (result.error) {\n throw result.error;\n }\n return result.data as T;\n }\n return (result?.data ?? result) as T;\n}\n\nexport function getPaystackOps(paystackClient: PaystackClientLike | any) {\n return {\n customerCreate: async (params: any) => {\n if (paystackClient?.customer_create) {\n return paystackClient.customer_create({ body: params });\n }\n return paystackClient?.customer?.create?.(params);\n },\n transactionInitialize: async (body: any) => {\n if (paystackClient?.transaction_initialize) {\n return paystackClient.transaction_initialize({ body });\n }\n return paystackClient?.transaction?.initialize?.(body);\n },\n transactionVerify: async (reference: string) => {\n if (paystackClient?.transaction_verify) {\n return paystackClient.transaction_verify({\n params: { path: { reference } },\n });\n }\n return paystackClient?.transaction?.verify?.(reference);\n },\n subscriptionDisable: async (body: { code: string; token: string }) => {\n if (paystackClient?.subscription_disable) {\n return paystackClient.subscription_disable({ body });\n }\n return paystackClient?.subscription?.disable?.(body);\n },\n subscriptionEnable: async (body: { code: string; token: string }) => {\n if (paystackClient?.subscription_enable) {\n return paystackClient.subscription_enable({ body });\n }\n return paystackClient?.subscription?.enable?.(body);\n },\n subscriptionFetch: async (idOrCode: string) => {\n if (paystackClient?.subscription_fetch) {\n try {\n return await paystackClient.subscription_fetch({\n params: { path: { code: idOrCode } },\n });\n } catch {\n return paystackClient.subscription_fetch({\n params: { path: { id_or_code: idOrCode } },\n });\n }\n }\n return paystackClient?.subscription?.fetch?.(idOrCode);\n },\n subscriptionManageLink: async (code: string) => {\n if (paystackClient?.subscription_manage_link) {\n return paystackClient.subscription_manage_link({\n params: { path: { code } },\n });\n }\n return paystackClient?.subscription?.manage?.link?.(code);\n },\n };\n}\n","import { createAuthEndpoint } from \"@better-auth/core/api\";\nimport { defineErrorCodes } from \"@better-auth/core/utils\";\nimport type { GenericEndpointContext } from \"better-auth\";\nimport { HIDE_METADATA } from \"better-auth\";\nimport {\n APIError,\n getSessionFromCtx,\n originCheck,\n sessionMiddleware,\n} from \"better-auth/api\";\nimport * as z from \"zod/v4\";\nimport type { InputPaystackTransaction, InputSubscription, PaystackOptions, PaystackTransaction, Subscription } from \"./types\";\nimport { getPlanByName, getPlans, getProductByName, getProducts } from \"./utils\";\nimport { referenceMiddleware } from \"./middleware\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk\";\n\ntype AnyPaystackOptions = PaystackOptions<any>;\n\nconst PAYSTACK_ERROR_CODES = 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:\n \"Email verification is required before you can subscribe to a plan\",\n});\n\nasync 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 subtle = (globalThis.crypto as any)?.subtle;\n if (subtle) {\n const key = await subtle.importKey(\n \"raw\",\n keyData,\n { name: \"HMAC\", hash: \"SHA-512\" },\n 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\nexport const paystackWebhook = (options: AnyPaystackOptions) => {\n return createAuthEndpoint(\n \"/paystack/webhook\",\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 = (ctx as any).requestClone ?? ctx.request;\n const payload = await request.text();\n const headers = (ctx as any).headers ?? (ctx.request as any)?.headers;\n const signature = headers?.get(\"x-paystack-signature\") as\n | string\n | null\n | undefined;\n\n if (!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.paystackWebhookSecret, 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 any;\n\n // Best-effort local state sync for subscription lifecycle.\n if (options.subscription?.enabled) {\n const eventName = String(event?.event ?? \"\");\n const data = event?.data as any;\n try {\n if (eventName === \"charge.success\") {\n const reference = data?.reference;\n const paystackId = data?.id ? String(data.id) : undefined;\n if (reference) {\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 }\n }\n\n if (eventName === \"subscription.create\") {\n const subscriptionCode =\n data?.subscription_code ??\n data?.subscription?.subscription_code ??\n data?.code;\n const customerCode =\n data?.customer?.customer_code ??\n data?.customer_code ??\n data?.customer?.code;\n const planCode =\n data?.plan?.plan_code ?? data?.plan_code ?? data?.plan;\n\n let metadata: any = data?.metadata;\n if (typeof metadata === \"string\") {\n try {\n metadata = JSON.parse(metadata);\n } catch {\n // ignore\n }\n }\n\n const referenceIdFromMetadata =\n typeof metadata === \"object\" && metadata\n ? (metadata.referenceId as string | undefined)\n : undefined;\n\n let planNameFromMetadata =\n typeof metadata === \"object\" && metadata\n ? (metadata.plan as string | undefined)\n : undefined;\n if (typeof planNameFromMetadata === \"string\") {\n planNameFromMetadata = planNameFromMetadata.toLowerCase();\n }\n\n const plans = await getPlans(options.subscription);\n const planFromCode = planCode\n ? plans.find((p) => p.planCode && p.planCode === planCode)\n : undefined;\n const planName = (planFromCode?.name ?? planNameFromMetadata)?.toLowerCase();\n\n if (subscriptionCode) {\n const where: Array<{ field: string; value: any }> = [];\n if (referenceIdFromMetadata) {\n where.push({ field: \"referenceId\", value: referenceIdFromMetadata });\n } else if (customerCode) {\n where.push({ field: \"paystackCustomerCode\", value: customerCode });\n }\n if (planName) {\n where.push({ field: \"plan\", value: planName });\n }\n\n if (where.length > 0) {\n const matches = await ctx.context.adapter.findMany<Subscription>({\n model: \"subscription\",\n where,\n });\n const subscription = matches?.[0];\n if (subscription) {\n await ctx.context.adapter.update({\n model: \"subscription\",\n update: {\n paystackSubscriptionCode: subscriptionCode,\n status: \"active\",\n updatedAt: new Date(),\n },\n where: [{ field: \"id\", value: subscription.id }],\n });\n\n const plan = planFromCode ?? (planName ? await getPlanByName(options, planName) : undefined);\n if (plan) {\n await options.subscription.onSubscriptionComplete?.(\n { event, subscription: { ...subscription, paystackSubscriptionCode: subscriptionCode, status: \"active\" }, plan },\n ctx as any,\n );\n }\n }\n }\n }\n }\n\n if (eventName === \"subscription.disable\" || eventName === \"subscription.not_renew\") {\n const subscriptionCode =\n data?.subscription_code ??\n data?.subscription?.subscription_code ??\n data?.code;\n if (subscriptionCode) {\n await ctx.context.adapter.update({\n model: \"subscription\",\n update: {\n status: \"canceled\",\n updatedAt: new Date(),\n },\n where: [\n { field: \"paystackSubscriptionCode\", value: subscriptionCode },\n ],\n });\n }\n }\n } catch (e: any) {\n ctx.context.logger.error(\"Failed to sync Paystack webhook event\", e);\n }\n }\n\n await options.onEvent?.(event);\n return ctx.json({ received: true });\n },\n );\n};\n\n\nconst initializeTransactionBodySchema = z.object({\n plan: z.string().optional(),\n product: z.string().optional(),\n amount: z.number().optional(), // Amount in smallest currency unit (e.g., kobo)\n currency: z.string().optional(),\n email: z.string().optional(),\n metadata: z.record(z.string(), z.any()).optional(),\n referenceId: z.string().optional(),\n callbackURL: z.string().optional(),\n});\n\nexport const initializeTransaction = (options: AnyPaystackOptions) => {\n const subscriptionOptions = options.subscription;\n // If subscriptions are enabled, use full middleware stack; otherwise just basics.\n // However, for one-time payments, we might not strictly need subscription middleware\n // checking for existing subs, but let's keep it consistent for now.\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"initialize-transaction\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/transaction/initialize\",\n {\n method: \"POST\",\n body: initializeTransactionBodySchema,\n use: useMiddlewares,\n },\n async (ctx) => {\n const paystack = getPaystackOps(options.paystackClient);\n const { plan: planName, product: productName, amount: bodyAmount, currency, email, metadata: extraMetadata, callbackURL } = ctx.body;\n\n // 1. Validate Callback URL validation (same as before)\n if (callbackURL) {\n const checkTrusted = () => {\n try {\n if (!callbackURL) return false;\n if (callbackURL.startsWith(\"/\")) return true;\n const baseUrl =\n (ctx.context as any)?.baseURL ??\n (ctx.request as any)?.url ??\n \"\";\n if (!baseUrl) return false;\n const baseOrigin = new URL(baseUrl).origin;\n return new URL(callbackURL).origin === baseOrigin;\n } catch {\n return false;\n }\n };\n if (!checkTrusted()) {\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) throw new APIError(\"UNAUTHORIZED\");\n const user = session.user;\n \n // 3. Email Verification Check (only if subscription options enforce it)\n if (subscriptionOptions?.enabled && subscriptionOptions.requireEmailVerification && !user.emailVerified) {\n throw new APIError(\"BAD_REQUEST\", {\n code: \"EMAIL_VERIFICATION_REQUIRED\",\n message: PAYSTACK_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED,\n });\n }\n\n // 4. Determine Payment Mode: Subscription (Plan) vs Product vs One-Time (Amount)\n let plan: ReturnType<typeof getPlanByName> extends Promise<infer U> ? U : never;\n let product: ReturnType<typeof getProductByName> extends Promise<infer U> ? U : never;\n \n if (planName) {\n if (!subscriptionOptions?.enabled) {\n throw new APIError(\"BAD_REQUEST\", { message: \"Subscriptions are not enabled.\" });\n }\n plan = await getPlanByName(options, planName);\n if (!plan) {\n throw new APIError(\"BAD_REQUEST\", {\n code: \"SUBSCRIPTION_PLAN_NOT_FOUND\",\n message: PAYSTACK_ERROR_CODES.SUBSCRIPTION_PLAN_NOT_FOUND,\n });\n }\n } else if (productName) {\n product = await getProductByName(options, productName);\n if (!product) {\n throw new APIError(\"BAD_REQUEST\", {\n message: `Product '${productName}' not found.`,\n });\n }\n } else if (!bodyAmount) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Either 'plan', 'product', or 'amount' is required to initialize a transaction.\",\n });\n }\n\n const amount = bodyAmount || product?.amount;\n const finalCurrency = currency || product?.currency || plan?.currency || \"NGN\";\n\n // 5. Prepare Payload\n const referenceIdFromCtx = (ctx.context as any).referenceId as string | undefined;\n const referenceId = ctx.body.referenceId || referenceIdFromCtx || (session.user as any).id;\n\n let url: string | undefined;\n let reference: string | undefined;\n let accessCode: string | undefined;\n\n try {\n // Construct Metadata\n const metadata = JSON.stringify({\n referenceId,\n userId: user.id,\n plan: plan?.name.toLowerCase(), // Undefined for one-time\n product: product?.name.toLowerCase(),\n ...extraMetadata,\n });\n\n const initBody: any = {\n email: email || user.email,\n callback_url: callbackURL,\n metadata,\n // If plan/product exists, use its currency; otherwise fallback to provided or default\n currency: finalCurrency, \n };\n\n if (plan) {\n // Subscription Flow\n initBody.plan = plan.planCode;\n initBody.invoice_limit = plan.invoiceLimit;\n // If plan has no code but has amount (e.g. local plans?), Paystack usually needs amount\n if (!plan.planCode && plan.amount) {\n initBody.amount = plan.amount;\n }\n } else {\n // One-Time Payment Flow\n if (!amount) throw new Error(\"Amount is required for one-time payments\");\n initBody.amount = amount;\n }\n\n const initRaw = await paystack.transactionInitialize(initBody);\n const initRes = unwrapSdkResult<any>(initRaw);\n let data =\n initRes && typeof initRes === \"object\" && \"status\" in initRes && \"data\" in initRes\n ? (initRes as any).data\n : initRes?.data ?? initRes;\n \n if (data && typeof data === \"object\" && \"status\" in data && \"data\" in data) {\n data = data.data;\n }\n url = data?.authorization_url;\n reference = data?.reference;\n accessCode = data?.access_code;\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to initialize Paystack transaction\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_INITIALIZE_TRANSACTION\",\n message: error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_INITIALIZE_TRANSACTION,\n });\n }\n\n // 6. Record Transaction & Subscription\n const paystackCustomerCode = (user as any).paystackCustomerCode;\n \n await ctx.context.adapter.create<InputPaystackTransaction, PaystackTransaction>({\n model: \"paystackTransaction\",\n data: {\n reference: reference!,\n referenceId,\n userId: user.id,\n amount: plan?.amount || amount!,\n currency: plan?.currency || currency || \"NGN\",\n status: \"pending\",\n plan: plan?.name.toLowerCase(),\n metadata: extraMetadata ? JSON.stringify(extraMetadata) : undefined,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n });\n\n if (plan) {\n await ctx.context.adapter.create<InputSubscription, Subscription>({\n model: \"subscription\",\n data: {\n plan: plan.name.toLowerCase(),\n referenceId,\n paystackCustomerCode,\n paystackTransactionReference: reference,\n status: \"incomplete\",\n },\n });\n }\n\n return ctx.json({\n url,\n reference,\n accessCode,\n redirect: true,\n });\n },\n );\n};\n\nexport const verifyTransaction = (options: AnyPaystackOptions) => {\n const verifyBodySchema = z.object({\n reference: z.string(),\n });\n\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"verify-transaction\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/transaction/verify\",\n {\n method: \"POST\",\n body: verifyBodySchema,\n use: useMiddlewares,\n },\n async (ctx) => {\n const paystack = getPaystackOps(options.paystackClient);\n let verifyRes: any;\n try {\n const verifyRaw = await paystack.transactionVerify(ctx.body.reference);\n verifyRes = unwrapSdkResult<any>(verifyRaw);\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to verify Paystack transaction\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_VERIFY_TRANSACTION\",\n message:\n error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_VERIFY_TRANSACTION,\n });\n }\n let data =\n verifyRes && typeof verifyRes === \"object\" && \"status\" in verifyRes && \"data\" in verifyRes\n ? (verifyRes as any).data\n : verifyRes?.data ?? verifyRes;\n \n if (data && typeof data === \"object\" && \"status\" in data && \"data\" in data) {\n data = data.data;\n }\n const status = data?.status;\n const reference = data?.reference ?? ctx.body.reference;\n const paystackId = data?.id ? String(data.id) : undefined;\n\n if (status === \"success\") {\n try {\n const session = await getSessionFromCtx(ctx);\n const referenceIdFromCtx = (ctx.context as any).referenceId as\n | string\n | undefined;\n const referenceId = referenceIdFromCtx ?? (session?.user as any)?.id;\n\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\n await ctx.context.adapter.update({\n model: \"subscription\",\n update: {\n status: \"active\",\n periodStart: new Date(),\n updatedAt: new Date(),\n },\n where: [\n { field: \"paystackTransactionReference\", value: reference },\n ...(referenceId ? [{ field: \"referenceId\", value: referenceId }] : []),\n ],\n });\n } catch (e: any) {\n ctx.context.logger.error(\n \"Failed to update transaction/subscription after verification\",\n e,\n );\n }\n } else if (status === \"failed\" || status === \"abandoned\") {\n try {\n await ctx.context.adapter.update({\n model: \"paystackTransaction\",\n update: {\n status,\n updatedAt: new Date(),\n },\n where: [{ field: \"reference\", value: reference }],\n });\n } catch (e: any) {\n ctx.context.logger.error(\"Failed to update transaction status\", e);\n }\n }\n\n return ctx.json({\n status,\n reference,\n data,\n });\n },\n );\n};\n\nexport const listSubscriptions = (options: AnyPaystackOptions) => {\n const listQuerySchema = z.object({\n referenceId: z.string().optional(),\n });\n\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"list-subscriptions\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/subscription/list-local\",\n {\n method: \"GET\",\n query: listQuerySchema,\n use: useMiddlewares,\n },\n async (ctx) => {\n if (!subscriptionOptions?.enabled) {\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) throw new APIError(\"UNAUTHORIZED\");\n const referenceId =\n ((ctx.context as any).referenceId as string | undefined) ??\n (ctx.query?.referenceId as string | undefined) ??\n ((session.user as any).id as string);\n const res = await ctx.context.adapter.findMany<Subscription>({\n model: \"subscription\",\n where: [{ field: \"referenceId\", value: referenceId }],\n });\n return ctx.json({ subscriptions: res });\n },\n );\n};\n\nexport const listTransactions = (options: AnyPaystackOptions) => {\n const listQuerySchema = z.object({\n referenceId: z.string().optional(),\n });\n\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"list-transactions\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/transaction/list\",\n {\n method: \"GET\",\n query: listQuerySchema,\n use: useMiddlewares,\n },\n async (ctx) => {\n const session = await getSessionFromCtx(ctx);\n if (!session) throw new APIError(\"UNAUTHORIZED\");\n const referenceId =\n ((ctx.context as any).referenceId as string | undefined) ??\n (ctx.query?.referenceId as string | undefined) ??\n ((session.user as any).id as string);\n const res = await ctx.context.adapter.findMany<PaystackTransaction>({\n model: \"paystackTransaction\",\n where: [{ field: \"referenceId\", value: referenceId }],\n });\n // Sort by createdAt desc locally if adapter doesn't support it well, \n // but Better Auth adapters usually return in insertion order.\n // Let's sort to be sure.\n const sorted = res.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n return ctx.json({ transactions: sorted });\n },\n );\n};\n\nconst enableDisableBodySchema = z.object({\n referenceId: z.string().optional(),\n subscriptionCode: z.string(),\n emailToken: z.string().optional(),\n});\n\nfunction decodeBase64UrlToString(value: string): string {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = normalized + \"===\".slice((normalized.length + 3) % 4);\n if (typeof (globalThis as any).atob === \"function\") {\n return (globalThis as any).atob(padded);\n }\n // Node fallback\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return Buffer.from(padded, \"base64\").toString(\"utf8\");\n}\n\nfunction tryGetEmailTokenFromSubscriptionManageLink(link: string): string | undefined {\n try {\n const url = new URL(link);\n const subscriptionToken = url.searchParams.get(\"subscription_token\");\n if (!subscriptionToken) 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 any;\n return typeof payload?.email_token === \"string\" ? payload.email_token : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport const disablePaystackSubscription = (options: AnyPaystackOptions) => {\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"disable-subscription\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/subscription/disable\",\n { method: \"POST\", body: enableDisableBodySchema, use: useMiddlewares },\n async (ctx) => {\n const { subscriptionCode } = ctx.body;\n const paystack = getPaystackOps(options.paystackClient);\n try {\n let emailToken = ctx.body.emailToken;\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionFetch(subscriptionCode);\n const fetchRes = unwrapSdkResult<any>(raw);\n const data =\n fetchRes && typeof fetchRes === \"object\" && \"status\" in fetchRes && \"data\" in fetchRes\n ? (fetchRes as any).data\n : fetchRes?.data ?? fetchRes;\n emailToken = data?.email_token;\n } catch {\n // ignore; try manage-link fallback below\n }\n }\n\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionManageLink(subscriptionCode);\n const linkRes = unwrapSdkResult<any>(raw);\n const data =\n linkRes && typeof linkRes === \"object\" && \"status\" in linkRes && \"data\" in linkRes\n ? (linkRes as any).data\n : linkRes?.data ?? linkRes;\n const link = data?.link;\n if (typeof link === \"string\") {\n emailToken = tryGetEmailTokenFromSubscriptionManageLink(link);\n }\n } catch {\n // ignore\n }\n }\n\n if (!emailToken) {\n throw new APIError(\"BAD_REQUEST\", {\n message:\n \"Missing emailToken. Provide it explicitly or ensure your server can fetch it from Paystack using the subscription code.\",\n });\n }\n\n const raw = await paystack.subscriptionDisable({\n code: subscriptionCode,\n token: emailToken,\n });\n const result = unwrapSdkResult<any>(raw);\n return ctx.json({ result });\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to disable Paystack subscription\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_DISABLE_SUBSCRIPTION\",\n message:\n error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_DISABLE_SUBSCRIPTION,\n });\n }\n },\n );\n};\n\nexport const enablePaystackSubscription = (options: AnyPaystackOptions) => {\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"enable-subscription\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/subscription/enable\",\n { method: \"POST\", body: enableDisableBodySchema, use: useMiddlewares },\n async (ctx) => {\n const { subscriptionCode } = ctx.body;\n const paystack = getPaystackOps(options.paystackClient);\n try {\n let emailToken = ctx.body.emailToken;\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionFetch(subscriptionCode);\n const fetchRes = unwrapSdkResult<any>(raw);\n const data =\n fetchRes && typeof fetchRes === \"object\" && \"status\" in fetchRes && \"data\" in fetchRes\n ? (fetchRes as any).data\n : fetchRes?.data ?? fetchRes;\n emailToken = data?.email_token;\n } catch {\n // ignore; try manage-link fallback below\n }\n }\n\n if (!emailToken) {\n try {\n const raw = await paystack.subscriptionManageLink(subscriptionCode);\n const linkRes = unwrapSdkResult<any>(raw);\n const data =\n linkRes && typeof linkRes === \"object\" && \"status\" in linkRes && \"data\" in linkRes\n ? (linkRes as any).data\n : linkRes?.data ?? linkRes;\n const link = data?.link;\n if (typeof link === \"string\") {\n emailToken = tryGetEmailTokenFromSubscriptionManageLink(link);\n }\n } catch {\n // ignore\n }\n }\n\n if (!emailToken) {\n throw new APIError(\"BAD_REQUEST\", {\n message:\n \"Missing emailToken. Provide it explicitly or ensure your server can fetch it from Paystack using the subscription code.\",\n });\n }\n\n const raw = await paystack.subscriptionEnable({\n code: subscriptionCode,\n token: emailToken,\n });\n const result = unwrapSdkResult<any>(raw);\n return ctx.json({ result });\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to enable Paystack subscription\", error);\n throw new APIError(\"BAD_REQUEST\", {\n code: \"FAILED_TO_ENABLE_SUBSCRIPTION\",\n message:\n error?.message || PAYSTACK_ERROR_CODES.FAILED_TO_ENABLE_SUBSCRIPTION,\n });\n }\n },\n );\n};\n\n\nconst subscriptionCodeSchema = z.object({\n subscriptionCode: z.string(),\n});\n\nexport const getSubscriptionManageLink = (options: AnyPaystackOptions) => {\n const subscriptionOptions = options.subscription;\n const useMiddlewares = subscriptionOptions?.enabled\n ? [sessionMiddleware, originCheck, referenceMiddleware(subscriptionOptions, \"get-subscription-manage-link\")]\n : [sessionMiddleware, originCheck];\n\n return createAuthEndpoint(\n \"/paystack/subscription/manage-link\",\n { \n method: \"GET\", \n query: subscriptionCodeSchema, \n use: useMiddlewares \n },\n async (ctx) => {\n const { subscriptionCode } = ctx.query;\n const paystack = getPaystackOps(options.paystackClient);\n try {\n const raw = await paystack.subscriptionManageLink(subscriptionCode);\n const linkRes = unwrapSdkResult<any>(raw);\n const data =\n linkRes && typeof linkRes === \"object\" && \"status\" in linkRes && \"data\" in linkRes\n ? (linkRes as any).data\n : linkRes?.data ?? linkRes;\n \n return ctx.json({ link: data?.link });\n } catch (error: any) {\n ctx.context.logger.error(\"Failed to get Paystack subscription manage link\", error);\n throw new APIError(\"BAD_REQUEST\", {\n message: error?.message || \"Failed to fetch subscription management link\",\n });\n }\n },\n );\n};\n\nexport const getConfig = (options: AnyPaystackOptions) => {\n return createAuthEndpoint(\n \"/paystack/get-config\",\n {\n method: \"GET\",\n metadata: {\n openapi: {\n operationId: \"getPaystackConfig\",\n },\n },\n },\n async (ctx) => {\n const [plans, products] = await Promise.all([\n options.subscription?.enabled ? getPlans(options.subscription) : Promise.resolve([]),\n getProducts(options.products),\n ]);\n return ctx.json({ plans, products });\n },\n );\n};\n\nexport { PAYSTACK_ERROR_CODES };\n\n","import type { BetterAuthPluginDBSchema } from \"@better-auth/core/db\";\nimport { mergeSchema } from \"better-auth/db\";\nimport type { PaystackOptions } from \"./types\";\n\nexport const transactions = {\n paystackTransaction: {\n fields: {\n reference: {\n type: \"string\",\n required: true,\n },\n paystackId: {\n type: \"string\",\n required: false,\n },\n referenceId: {\n type: \"string\",\n required: true,\n },\n userId: {\n type: \"string\",\n required: 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 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 subscriptions = {\n subscription: {\n fields: {\n plan: {\n type: \"string\",\n required: true,\n },\n referenceId: {\n type: \"string\",\n required: true,\n },\n paystackCustomerCode: {\n type: \"string\",\n required: false,\n },\n paystackSubscriptionCode: {\n type: \"string\",\n required: false,\n },\n paystackTransactionReference: {\n type: \"string\",\n required: false,\n },\n status: {\n type: \"string\",\n defaultValue: \"incomplete\",\n },\n periodStart: {\n type: \"date\",\n required: false,\n },\n periodEnd: {\n type: \"date\",\n required: false,\n },\n trialStart: {\n type: \"date\",\n required: false,\n },\n trialEnd: {\n type: \"date\",\n required: false,\n },\n cancelAtPeriodEnd: {\n type: \"boolean\",\n required: false,\n defaultValue: false,\n },\n groupId: {\n type: \"string\",\n required: false,\n },\n seats: {\n type: \"number\",\n required: false,\n },\n },\n },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const user = {\n user: {\n fields: {\n paystackCustomerCode: {\n type: \"string\",\n required: false,\n },\n },\n },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const getSchema = (options: PaystackOptions<any>) => {\n let baseSchema: BetterAuthPluginDBSchema;\n\n if (options.subscription?.enabled) {\n baseSchema = {\n ...subscriptions,\n ...transactions,\n ...user,\n };\n } else {\n baseSchema = {\n ...user,\n ...transactions,\n };\n }\n\n if (\n options.schema &&\n !options.subscription?.enabled &&\n \"subscription\" in options.schema\n ) {\n const { subscription: _subscription, ...restSchema } = options.schema as any;\n return mergeSchema(baseSchema, restSchema);\n }\n\n return mergeSchema(baseSchema, options.schema);\n};\n","import { defineErrorCodes } from \"@better-auth/core/utils\";\nimport type { BetterAuthPlugin } from \"better-auth\";\nimport type { GenericEndpointContext } from \"better-auth\";\nimport { defu } from \"defu\";\nimport {\n disablePaystackSubscription,\n enablePaystackSubscription,\n initializeTransaction,\n listSubscriptions,\n listTransactions,\n paystackWebhook,\n verifyTransaction,\n getConfig,\n getSubscriptionManageLink,\n PAYSTACK_ERROR_CODES,\n} from \"./routes\";\nimport { getSchema } from \"./schema\";\nimport type {\n PaystackNodeClient,\n PaystackClientLike,\n PaystackOptions,\n PaystackPlan,\n Subscription,\n SubscriptionOptions,\n PaystackProduct,\n} from \"./types\";\nimport { getPaystackOps, unwrapSdkResult } from \"./paystack-sdk\";\n\nconst INTERNAL_ERROR_CODES = defineErrorCodes({\n ...PAYSTACK_ERROR_CODES,\n});\n\nexport const paystack = <\n TPaystackClient extends PaystackClientLike = PaystackNodeClient,\n O extends PaystackOptions<TPaystackClient> = PaystackOptions<TPaystackClient>,\n>(\n options: O,\n) => {\n type GenericEndpoints = NonNullable<BetterAuthPlugin[\"endpoints\"]>;\n const endpoints = {\n paystackWebhook: paystackWebhook(options),\n listTransactions: listTransactions(options),\n getConfig: getConfig(options),\n initializeTransaction: initializeTransaction(options),\n verifyTransaction: verifyTransaction(options),\n listSubscriptions: listSubscriptions(options),\n disablePaystackSubscription: disablePaystackSubscription(options),\n enablePaystackSubscription: enablePaystackSubscription(options),\n getSubscriptionManageLink: getSubscriptionManageLink(options),\n } satisfies GenericEndpoints;\n\n type EndpointsForOptions = typeof endpoints;\n\n return {\n id: \"paystack\",\n endpoints,\n init(ctx) {\n return {\n options: {\n databaseHooks: {\n user: {\n create: {\n async after(user, hookCtx?: GenericEndpointContext | null) {\n if (!hookCtx || !options.createCustomerOnSignUp) return;\n\n try {\n const firstName = user.name?.split(\" \")[0];\n const lastName = user.name?.split(\" \").slice(1).join(\" \") || undefined;\n\n const extraCreateParams = options.getCustomerCreateParams\n ? await options.getCustomerCreateParams(user as any, hookCtx as any)\n : {};\n\n const params = defu(\n {\n email: user.email,\n first_name: firstName,\n last_name: lastName,\n metadata: { userId: user.id },\n },\n extraCreateParams,\n );\n const paystack = getPaystackOps(options.paystackClient);\n const raw = await paystack.customerCreate(params);\n const res = unwrapSdkResult<any>(raw);\n const paystackCustomer =\n res && typeof res === \"object\" && \"status\" in res && \"data\" in res\n ? (res as any).data\n : res?.data ?? res;\n const customerCode = paystackCustomer?.customer_code;\n\n if (!customerCode) return;\n\n await (hookCtx as any).context.internalAdapter.updateUser(user.id, {\n paystackCustomerCode: customerCode,\n });\n\n await options.onCustomerCreate?.(\n {\n paystackCustomer,\n user: {\n ...(user as any),\n paystackCustomerCode: customerCode,\n },\n },\n hookCtx as any,\n );\n } catch (e: any) {\n (hookCtx as any).context.logger.error(\n `Failed to create Paystack customer: ${e?.message || \"Unknown error\"}`,\n e,\n );\n }\n },\n },\n },\n },\n },\n };\n },\n schema: getSchema(options),\n $ERROR_CODES: INTERNAL_ERROR_CODES,\n } satisfies BetterAuthPlugin;\n};\n\nexport type PaystackPlugin<O extends PaystackOptions<any> = PaystackOptions> = ReturnType<\n typeof paystack<any, O>\n>;\n\nexport type { Subscription, SubscriptionOptions, PaystackPlan, PaystackOptions, PaystackProduct };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexasomba/better-auth-paystack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Community Better Auth plugin for Paystack (by alexasomba)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "alexasomba",
|
|
@@ -36,26 +36,25 @@
|
|
|
36
36
|
"better-auth": ">=1.3.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@alexasomba/paystack-browser": "^1.1.6",
|
|
40
39
|
"@alexasomba/paystack-node": "^1.1.6",
|
|
41
|
-
"better-call": "^1.1
|
|
40
|
+
"better-call": "^1.2.1",
|
|
42
41
|
"defu": "^6.1.4",
|
|
43
|
-
"zod": "^4.
|
|
42
|
+
"zod": "^4.3.6"
|
|
44
43
|
},
|
|
45
44
|
"optionalDependencies": {
|
|
46
|
-
"@rollup/rollup-linux-x64-gnu": "4.
|
|
45
|
+
"@rollup/rollup-linux-x64-gnu": "^4.57.1"
|
|
47
46
|
},
|
|
48
47
|
"devDependencies": {
|
|
49
48
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
50
|
-
"@better-auth/core": "^1.4.
|
|
51
|
-
"@rollup/rollup-linux-x64-gnu": "4.
|
|
52
|
-
"@types/node": "^
|
|
53
|
-
"@vitest/coverage-v8": "^4.0.
|
|
54
|
-
"better-auth": "^1.4.
|
|
55
|
-
"publint": "^0.3.
|
|
56
|
-
"tsdown": "^0.
|
|
49
|
+
"@better-auth/core": "^1.4.18",
|
|
50
|
+
"@rollup/rollup-linux-x64-gnu": "^4.57.1",
|
|
51
|
+
"@types/node": "^22.19.7",
|
|
52
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
53
|
+
"better-auth": "^1.4.18",
|
|
54
|
+
"publint": "^0.3.17",
|
|
55
|
+
"tsdown": "^0.20.1",
|
|
57
56
|
"typescript": "^5.9.3",
|
|
58
|
-
"vitest": "^4.0.
|
|
57
|
+
"vitest": "^4.0.18"
|
|
59
58
|
},
|
|
60
59
|
"scripts": {
|
|
61
60
|
"build": "tsdown",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DWhjFOp2.d.mts","names":["GenericEndpointContext","InferOptionSchema","Session","User","createPaystack","subscriptions","user","PaystackNodeClient","ReturnType","PaystackOpenApiFetchResponse","T","Response","PaystackApiResult","Promise","PaystackClientLike","NoInfer","AuthSession","Record","PaystackPlan","Subscription","Date","SubscriptionOptions","PaystackOptions","TPaystackClient","InputSubscription","Omit"],"sources":["../src/schema.ts","../src/types.d.ts","../src/index.ts"],"sourcesContent":["import type { GenericEndpointContext, InferOptionSchema, Session, User } from \"better-auth\";\nimport type { createPaystack } from \"@alexasomba/paystack-node\";\nimport type { subscriptions, user } from \"./schema\";\nexport type PaystackNodeClient = ReturnType<typeof createPaystack>;\nexport type PaystackOpenApiFetchResponse<T = unknown> = {\n data?: T;\n error?: unknown;\n response?: Response;\n};\nexport type PaystackApiResult<T = unknown> = Promise<T | PaystackOpenApiFetchResponse<T>>;\nexport type PaystackClientLike = {\n customer_create?: (init?: {\n body?: any;\n } | undefined) => PaystackApiResult<any>;\n transaction_initialize?: (init?: {\n body?: any;\n } | undefined) => PaystackApiResult<any>;\n transaction_verify?: (init: {\n params: {\n path: {\n reference: string;\n };\n };\n }) => PaystackApiResult<any>;\n subscription_fetch?: (init: any) => PaystackApiResult<any>;\n subscription_disable?: (init?: {\n body?: {\n code: string;\n token: string;\n };\n } | undefined) => PaystackApiResult<any>;\n subscription_enable?: (init?: {\n body?: {\n code: string;\n token: string;\n };\n } | undefined) => PaystackApiResult<any>;\n subscription_manage_link?: (init: {\n params: {\n path: {\n code: string;\n };\n };\n }) => PaystackApiResult<any>;\n customer?: {\n create?: (params: any) => Promise<any>;\n };\n transaction?: {\n initialize?: (params: any) => Promise<any>;\n verify?: (reference: string) => Promise<any>;\n };\n subscription?: {\n fetch?: (idOrCode: string) => Promise<any>;\n disable?: (params: any) => Promise<any>;\n enable?: (params: any) => Promise<any>;\n manage?: {\n link?: (code: string) => Promise<any>;\n };\n };\n};\ntype NoInfer<T> = [T][T extends any ? 0 : never];\nexport type AuthSession = {\n user: User;\n session: Session;\n} & Record<string, any>;\nexport type PaystackPlan = {\n /** Human name stored in DB (lowercased). */\n name: string;\n /** Paystack plan code (if you use Paystack plans). */\n planCode?: string | undefined;\n /** Amount in the smallest currency unit (e.g. kobo). */\n amount?: number | undefined;\n /** Currency ISO code (e.g. NGN). */\n currency?: string | undefined;\n /** Paystack interval keyword (when using Paystack plans). */\n interval?: \"daily\" | \"weekly\" | \"monthly\" | \"quarterly\" | \"biannually\" | \"annually\" | undefined;\n /** Optional invoice limit; Paystack uses `invoice_limit` during init. */\n invoiceLimit?: number | undefined;\n /** Arbitrary limits (stored/consumed by your app). */\n limits?: Record<string, unknown> | undefined;\n /** Optional free trial config, if your app supports it. */\n freeTrial?: {\n days: number;\n } | undefined;\n};\nexport interface Subscription {\n id: string;\n plan: string;\n referenceId: string;\n paystackCustomerCode?: string | undefined;\n paystackSubscriptionCode?: string | undefined;\n paystackTransactionReference?: string | undefined;\n status: \"active\" | \"canceled\" | \"incomplete\" | \"incomplete_expired\" | \"paused\" | \"trialing\" | \"unpaid\";\n periodStart?: Date | undefined;\n periodEnd?: Date | undefined;\n trialStart?: Date | undefined;\n trialEnd?: Date | undefined;\n cancelAtPeriodEnd?: boolean | undefined;\n groupId?: string | undefined;\n seats?: number | undefined;\n}\nexport type SubscriptionOptions = {\n plans: PaystackPlan[] | (() => PaystackPlan[] | Promise<PaystackPlan[]>);\n requireEmailVerification?: boolean | undefined;\n authorizeReference?: ((data: {\n user: User;\n session: AuthSession;\n referenceId: string;\n action: \"initialize-transaction\" | \"verify-transaction\" | \"list-subscriptions\" | \"disable-subscription\" | \"enable-subscription\";\n }, ctx: GenericEndpointContext) => Promise<boolean>) | undefined;\n onSubscriptionComplete?: ((data: {\n event: any;\n subscription: Subscription;\n plan: PaystackPlan;\n }, ctx: GenericEndpointContext) => Promise<void>) | undefined;\n onSubscriptionUpdate?: ((data: {\n event: any;\n subscription: Subscription;\n }, ctx: GenericEndpointContext) => Promise<void>) | undefined;\n onSubscriptionDelete?: ((data: {\n event: any;\n subscription: Subscription;\n }, ctx: GenericEndpointContext) => Promise<void>) | undefined;\n};\nexport interface PaystackOptions<TPaystackClient extends PaystackClientLike = PaystackNodeClient> {\n /** Paystack SDK instance (recommended: `@alexasomba/paystack-node` via `createPaystack({ secretKey })`). */\n paystackClient: NoInfer<TPaystackClient>;\n /** Paystack webhook secret used to verify `x-paystack-signature`. */\n paystackWebhookSecret: string;\n /** Enable customer creation on Better Auth sign up. */\n createCustomerOnSignUp?: boolean | undefined;\n onCustomerCreate?: ((data: {\n paystackCustomer: any;\n user: User & {\n paystackCustomerCode: string;\n };\n }, ctx: GenericEndpointContext) => Promise<void>) | undefined;\n getCustomerCreateParams?: ((user: User, ctx: GenericEndpointContext) => Promise<Record<string, any>>) | undefined;\n subscription?: ({\n enabled: false;\n } | ({\n enabled: true;\n } & SubscriptionOptions)) | undefined;\n onEvent?: ((event: any) => Promise<void>) | undefined;\n schema?: InferOptionSchema<typeof subscriptions & typeof user> | undefined;\n}\nexport interface InputSubscription extends Omit<Subscription, \"id\"> {\n}\nexport {};\n//# sourceMappingURL=types.d.ts.map"],"mappings":"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"}
|