@alexasomba/better-auth-paystack 0.0.4

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 ADDED
@@ -0,0 +1,218 @@
1
+ # Better Auth Paystack Plugin
2
+
3
+ Better Auth plugin that integrates Paystack for customer creation, checkout, and Paystack-native subscription flows.
4
+
5
+ ## Features
6
+
7
+ - Optional Paystack customer creation on sign up (`createCustomerOnSignUp`)
8
+ - Paystack checkout via transaction initialize + verify (redirect-first)
9
+ - Paystack webhook signature verification (`x-paystack-signature`, HMAC-SHA512)
10
+ - Local subscription records stored in your Better Auth database
11
+ - Subscription management endpoints using Paystack’s email-token flows (`/subscription/enable` + `/subscription/disable`)
12
+ - Reference ID support (user by default; org/team via `referenceId` + `authorizeReference`)
13
+
14
+ ## Installation
15
+
16
+ ### Install packages
17
+
18
+ ```bash
19
+ npm install better-auth @alexasomba/better-auth-paystack
20
+ ```
21
+
22
+ If you want strict typing and the recommended server SDK client:
23
+
24
+ ```bash
25
+ npm install @alexasomba/paystack-node
26
+ ```
27
+
28
+ If your app has separate client + server bundles, install the plugin in both.
29
+
30
+ ### Configure the server plugin
31
+
32
+ ```ts
33
+ import { betterAuth } from "better-auth";
34
+ import { paystack } from "@alexasomba/better-auth-paystack";
35
+ import { createPaystack } from "@alexasomba/paystack-node";
36
+
37
+ const paystackClient = createPaystack({
38
+ secretKey: process.env.PAYSTACK_SECRET_KEY!,
39
+ });
40
+
41
+ export const auth = betterAuth({
42
+ plugins: [
43
+ paystack({
44
+ paystackClient,
45
+ paystackWebhookSecret: process.env.PAYSTACK_WEBHOOK_SECRET!,
46
+ createCustomerOnSignUp: true,
47
+ subscription: {
48
+ enabled: true,
49
+ plans: [
50
+ {
51
+ name: "starter",
52
+ amount: 500000,
53
+ currency: "NGN",
54
+ // If you use Paystack Plans, prefer planCode + (optional) invoiceLimit.
55
+ // planCode: "PLN_...",
56
+ // invoiceLimit: 12,
57
+ },
58
+ ],
59
+ authorizeReference: async ({ user, referenceId, action }, ctx) => {
60
+ // Allow only the current user by default; authorize org/team IDs here.
61
+ // return await canUserManageOrg(user.id, referenceId)
62
+ return referenceId === user.id;
63
+ },
64
+ },
65
+ }),
66
+ ],
67
+ });
68
+ ```
69
+
70
+ ### Configure the client plugin
71
+
72
+ ```ts
73
+ import { createAuthClient } from "better-auth/client";
74
+ import { paystackClient } from "@alexasomba/better-auth-paystack/client";
75
+
76
+ export const client = createAuthClient({
77
+ plugins: [paystackClient({ subscription: true })],
78
+ });
79
+ ```
80
+
81
+ ### Migrate / generate schema
82
+
83
+ The plugin adds fields/tables to your Better Auth database. Run the Better Auth CLI migration/generate step you already use in your project.
84
+
85
+ ## Webhooks
86
+
87
+ ### Endpoint URL
88
+
89
+ The plugin exposes a webhook endpoint at:
90
+
91
+ ```
92
+ {AUTH_BASE}/paystack/webhook
93
+ ```
94
+
95
+ Where `{AUTH_BASE}` is your Better Auth server base path (commonly `/api/auth`).
96
+
97
+ ### Signature verification
98
+
99
+ Paystack sends `x-paystack-signature` which is an HMAC-SHA512 of the raw payload signed with your secret key. The plugin verifies this using `paystackWebhookSecret`.
100
+
101
+ ### Recommended events
102
+
103
+ At minimum, enable the events your app depends on. For subscription flows, Paystack documents these as relevant:
104
+
105
+ - `charge.success`
106
+ - `subscription.create`
107
+ - `subscription.disable`
108
+ - `subscription.not_renew`
109
+
110
+ The plugin forwards all webhook payloads to `onEvent` (if provided) after signature verification.
111
+
112
+ ## Usage
113
+
114
+ ### Defining plans
115
+
116
+ Plans are referenced by their `name` (stored lowercased). For Paystack-native subscriptions you can either:
117
+
118
+ - Use `planCode` (Paystack plan code). When `planCode` is provided, Paystack invalidates `amount` during transaction initialization.
119
+ - Or use `amount` (smallest currency unit) for simple payments.
120
+
121
+ ### Frontend checkout (redirect)
122
+
123
+ This flow matches Paystack’s transaction initialize/verify APIs:
124
+
125
+ 1. Call `POST {AUTH_BASE}/paystack/transaction/initialize`
126
+ 2. Redirect the user to the returned Paystack `url`
127
+ 3. On your callback route/page, call `GET {AUTH_BASE}/paystack/transaction/verify?reference=...`
128
+
129
+ Example (framework-agnostic):
130
+
131
+ ```ts
132
+ // Start checkout
133
+ const initRes = await fetch("/api/auth/paystack/transaction/initialize", {
134
+ method: "POST",
135
+ headers: { "content-type": "application/json" },
136
+ body: JSON.stringify({
137
+ plan: "starter",
138
+ callbackURL: `${window.location.origin}/billing/paystack/callback`,
139
+ // Optional for org/team billing (requires authorizeReference)
140
+ // referenceId: "org_123",
141
+ }),
142
+ });
143
+
144
+ const init = await initRes.json();
145
+ // { url, reference, accessCode, redirect: true }
146
+ if (init?.url) window.location.href = init.url;
147
+
148
+ // On your callback page/route
149
+ const reference = new URLSearchParams(window.location.search).get("reference");
150
+ if (reference) {
151
+ await fetch(
152
+ `/api/auth/paystack/transaction/verify?reference=${encodeURIComponent(reference)}`,
153
+ );
154
+ }
155
+ ```
156
+
157
+ ### Inline modal checkout (optional)
158
+
159
+ If you prefer an inline checkout experience, initialize the transaction the same way and use `@alexasomba/paystack-browser` in your UI. This plugin does not render UI — it only provides server endpoints.
160
+
161
+ ### Listing local subscriptions
162
+
163
+ List subscription rows stored by this plugin:
164
+
165
+ `GET {AUTH_BASE}/paystack/subscription/list-local`
166
+
167
+ You can optionally pass `referenceId` as a query param (requires `authorizeReference` when it’s not the current user):
168
+
169
+ `GET {AUTH_BASE}/paystack/subscription/list-local?referenceId=org_123`
170
+
171
+ ### Enabling / disabling a subscription
172
+
173
+ Paystack requires both the subscription code and the email token.
174
+
175
+ For convenience, the plugin lets you omit `emailToken` and will attempt to fetch it from Paystack using the subscription code (via Subscription fetch, with a fallback to Manage Link).
176
+
177
+ - `POST {AUTH_BASE}/paystack/subscription/enable` with `{ subscriptionCode, emailToken? }`
178
+ - `POST {AUTH_BASE}/paystack/subscription/disable` with `{ subscriptionCode, emailToken? }`
179
+
180
+ Paystack documents these as `code` + `token`. If the server cannot fetch `emailToken`, you can still provide it explicitly (e.g., from the Subscription API or your Paystack dashboard).
181
+
182
+ ## Schema
183
+
184
+ The plugin adds:
185
+
186
+ - `user.paystackCustomerCode?: string`
187
+ - `subscription` table with fields like: `plan`, `referenceId`, `paystackCustomerCode`, `paystackSubscriptionCode`, `paystackTransactionReference`, `status`, and optional period/trial fields.
188
+
189
+ ## Options
190
+
191
+ Main options:
192
+
193
+ - `paystackClient` (recommended: `createPaystack({ secretKey })`)
194
+ - `paystackWebhookSecret`
195
+ - `createCustomerOnSignUp?`
196
+ - `onCustomerCreate?`, `getCustomerCreateParams?`
197
+ - `onEvent?`
198
+ - `schema?` (override/mapping)
199
+
200
+ Subscription options (when `subscription.enabled: true`):
201
+
202
+ - `plans` (array or async function)
203
+ - `requireEmailVerification?`
204
+ - `authorizeReference?`
205
+ - `onSubscriptionComplete?`, `onSubscriptionUpdate?`, `onSubscriptionDelete?`
206
+
207
+ ## Troubleshooting
208
+
209
+ - Webhook signature mismatch: ensure your server receives the raw body, and `PAYSTACK_WEBHOOK_SECRET` matches the secret key used by Paystack to sign events.
210
+ - Subscription list returns empty: verify you’re passing the correct `referenceId`, and that `authorizeReference` allows it.
211
+ - Transaction initializes but verify doesn’t update: ensure you call the verify endpoint after redirect, and confirm Paystack returns `status: "success"` for the reference.
212
+
213
+ ## Links
214
+
215
+ - Paystack Webhooks: https://paystack.com/docs/payments/webhooks/
216
+ - Paystack Transaction API: https://paystack.com/docs/api/transaction/
217
+ - Paystack Subscription API: https://paystack.com/docs/api/subscription/
218
+ - Paystack Plan API: https://paystack.com/docs/api/plan/
@@ -0,0 +1,30 @@
1
+ import { n as paystack, r as PaystackNodeClient } from "./index-CZ3Le7Er.mjs";
2
+
3
+ //#region src/client.d.ts
4
+ declare const paystackClient: <O extends {
5
+ subscription: boolean;
6
+ }>(_options?: O | undefined) => {
7
+ id: "paystack-client";
8
+ $InferServerPlugin: ReturnType<typeof paystack<PaystackNodeClient, O["subscription"] extends true ? {
9
+ paystackClient: PaystackNodeClient;
10
+ paystackWebhookSecret: string;
11
+ subscription: {
12
+ enabled: true;
13
+ plans: [];
14
+ };
15
+ } : {
16
+ paystackClient: PaystackNodeClient;
17
+ paystackWebhookSecret: string;
18
+ }>>;
19
+ pathMethods: {
20
+ "/paystack/webhook": "POST";
21
+ "/paystack/transaction/initialize": "POST";
22
+ "/paystack/transaction/verify": "GET";
23
+ "/paystack/subscription/list-local": "GET";
24
+ "/paystack/subscription/disable": "POST";
25
+ "/paystack/subscription/enable": "POST";
26
+ };
27
+ };
28
+ //#endregion
29
+ export { paystackClient };
30
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;cAIa;EAAA,YAAA,EAAA,OAoCZ;CA/Bc,CAAA,CAAA,QAAA,CAAA,EAAA,CAAA,GAAA,SAAA,EAAA,GAAA;EAMC,EAAA,EAAA,iBAAA;EACA,kBAAA,EAHkB,UAGlB,CAAA,OAFG,QAEH,CADA,kBACA,EAAA,CAAA,CAAA,cAAA,CAAA,SAAA,IAAA,GAAA;IAEoB,cAAA,EAAA,kBAAA;IAQA,qBAAA,EAAA,MAAA;IAZjB,YAAA,EAAA;MADe,OAAA,EAAA,IAAA;MAAU,KAAA,EAAA,EAAA;;;oBAaR"}
@@ -0,0 +1,19 @@
1
+ //#region src/client.ts
2
+ const paystackClient = (_options) => {
3
+ return {
4
+ id: "paystack-client",
5
+ $InferServerPlugin: {},
6
+ pathMethods: {
7
+ "/paystack/webhook": "POST",
8
+ "/paystack/transaction/initialize": "POST",
9
+ "/paystack/transaction/verify": "GET",
10
+ "/paystack/subscription/list-local": "GET",
11
+ "/paystack/subscription/disable": "POST",
12
+ "/paystack/subscription/enable": "POST"
13
+ }
14
+ };
15
+ };
16
+
17
+ //#endregion
18
+ export { paystackClient };
19
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { BetterAuthClientPlugin } from \"better-auth\";\nimport type { paystack } from \"./index\";\nimport type { PaystackNodeClient } from \"./types\";\n\nexport const paystackClient = <\n O extends {\n subscription: boolean;\n },\n>(\n _options?: O | undefined,\n) => {\n return {\n id: \"paystack-client\",\n $InferServerPlugin: {} as ReturnType<\n typeof paystack<\n PaystackNodeClient,\n O[\"subscription\"] extends true\n ? {\n paystackClient: PaystackNodeClient;\n paystackWebhookSecret: string;\n subscription: {\n enabled: true;\n plans: [];\n };\n }\n : {\n paystackClient: PaystackNodeClient;\n paystackWebhookSecret: string;\n }\n >\n >,\n pathMethods: {\n \"/paystack/webhook\": \"POST\",\n \"/paystack/transaction/initialize\": \"POST\",\n \"/paystack/transaction/verify\": \"GET\",\n \"/paystack/subscription/list-local\": \"GET\",\n \"/paystack/subscription/disable\": \"POST\",\n \"/paystack/subscription/enable\": \"POST\",\n },\n } satisfies BetterAuthClientPlugin;\n};\n"],"mappings":";AAIA,MAAa,kBAKT,aACC;AACD,QAAO;EACH,IAAI;EACJ,oBAAoB,EAAE;EAkBtB,aAAa;GACT,qBAAqB;GACrB,oCAAoC;GACpC,gCAAgC;GAChC,qCAAqC;GACrC,kCAAkC;GAClC,iCAAiC;GACpC;EACJ"}
@@ -0,0 +1,274 @@
1
+ import * as better_auth0 from "better-auth";
2
+ import { GenericEndpointContext, InferOptionSchema, Session, User } from "better-auth";
3
+ import { createPaystack } from "@alexasomba/paystack-node";
4
+
5
+ //#region src/schema.d.ts
6
+ declare const subscriptions: {
7
+ subscription: {
8
+ fields: {
9
+ plan: {
10
+ type: "string";
11
+ required: true;
12
+ };
13
+ referenceId: {
14
+ type: "string";
15
+ required: true;
16
+ };
17
+ paystackCustomerCode: {
18
+ type: "string";
19
+ required: false;
20
+ };
21
+ paystackSubscriptionCode: {
22
+ type: "string";
23
+ required: false;
24
+ };
25
+ paystackTransactionReference: {
26
+ type: "string";
27
+ required: false;
28
+ };
29
+ status: {
30
+ type: "string";
31
+ defaultValue: string;
32
+ };
33
+ periodStart: {
34
+ type: "date";
35
+ required: false;
36
+ };
37
+ periodEnd: {
38
+ type: "date";
39
+ required: false;
40
+ };
41
+ trialStart: {
42
+ type: "date";
43
+ required: false;
44
+ };
45
+ trialEnd: {
46
+ type: "date";
47
+ required: false;
48
+ };
49
+ cancelAtPeriodEnd: {
50
+ type: "boolean";
51
+ required: false;
52
+ defaultValue: false;
53
+ };
54
+ groupId: {
55
+ type: "string";
56
+ required: false;
57
+ };
58
+ seats: {
59
+ type: "number";
60
+ required: false;
61
+ };
62
+ };
63
+ };
64
+ };
65
+ declare const user: {
66
+ user: {
67
+ fields: {
68
+ paystackCustomerCode: {
69
+ type: "string";
70
+ required: false;
71
+ };
72
+ };
73
+ };
74
+ };
75
+ //#endregion
76
+ //#region src/types.d.ts
77
+ type PaystackNodeClient = ReturnType<typeof createPaystack>;
78
+ type PaystackOpenApiFetchResponse<T = unknown> = {
79
+ data?: T;
80
+ error?: unknown;
81
+ response?: Response;
82
+ };
83
+ type PaystackApiResult<T = unknown> = Promise<T | PaystackOpenApiFetchResponse<T>>;
84
+ type PaystackClientLike = {
85
+ customer_create?: (init?: {
86
+ body?: any;
87
+ } | undefined) => PaystackApiResult<any>;
88
+ transaction_initialize?: (init?: {
89
+ body?: any;
90
+ } | undefined) => PaystackApiResult<any>;
91
+ transaction_verify?: (init: {
92
+ params: {
93
+ path: {
94
+ reference: string;
95
+ };
96
+ };
97
+ }) => PaystackApiResult<any>;
98
+ subscription_fetch?: (init: any) => PaystackApiResult<any>;
99
+ subscription_disable?: (init?: {
100
+ body?: {
101
+ code: string;
102
+ token: string;
103
+ };
104
+ } | undefined) => PaystackApiResult<any>;
105
+ subscription_enable?: (init?: {
106
+ body?: {
107
+ code: string;
108
+ token: string;
109
+ };
110
+ } | undefined) => PaystackApiResult<any>;
111
+ subscription_manage_link?: (init: {
112
+ params: {
113
+ path: {
114
+ code: string;
115
+ };
116
+ };
117
+ }) => PaystackApiResult<any>;
118
+ customer?: {
119
+ create?: (params: any) => Promise<any>;
120
+ };
121
+ transaction?: {
122
+ initialize?: (params: any) => Promise<any>;
123
+ verify?: (reference: string) => Promise<any>;
124
+ };
125
+ subscription?: {
126
+ fetch?: (idOrCode: string) => Promise<any>;
127
+ disable?: (params: any) => Promise<any>;
128
+ enable?: (params: any) => Promise<any>;
129
+ manage?: {
130
+ link?: (code: string) => Promise<any>;
131
+ };
132
+ };
133
+ };
134
+ type NoInfer<T> = [T][T extends any ? 0 : never];
135
+ type AuthSession = {
136
+ user: User;
137
+ session: Session;
138
+ } & Record<string, any>;
139
+ type PaystackPlan = {
140
+ /** Human name stored in DB (lowercased). */
141
+ name: string;
142
+ /** Paystack plan code (if you use Paystack plans). */
143
+ planCode?: string | undefined;
144
+ /** Amount in the smallest currency unit (e.g. kobo). */
145
+ amount?: number | undefined;
146
+ /** Currency ISO code (e.g. NGN). */
147
+ currency?: string | undefined;
148
+ /** Paystack interval keyword (when using Paystack plans). */
149
+ interval?: "daily" | "weekly" | "monthly" | "quarterly" | "biannually" | "annually" | undefined;
150
+ /** Optional invoice limit; Paystack uses `invoice_limit` during init. */
151
+ invoiceLimit?: number | undefined;
152
+ /** Arbitrary limits (stored/consumed by your app). */
153
+ limits?: Record<string, unknown> | undefined;
154
+ /** Optional free trial config, if your app supports it. */
155
+ freeTrial?: {
156
+ days: number;
157
+ } | undefined;
158
+ };
159
+ interface Subscription {
160
+ id: string;
161
+ plan: string;
162
+ referenceId: string;
163
+ paystackCustomerCode?: string | undefined;
164
+ paystackSubscriptionCode?: string | undefined;
165
+ paystackTransactionReference?: string | undefined;
166
+ status: "active" | "canceled" | "incomplete" | "incomplete_expired" | "paused" | "trialing" | "unpaid";
167
+ periodStart?: Date | undefined;
168
+ periodEnd?: Date | undefined;
169
+ trialStart?: Date | undefined;
170
+ trialEnd?: Date | undefined;
171
+ cancelAtPeriodEnd?: boolean | undefined;
172
+ groupId?: string | undefined;
173
+ seats?: number | undefined;
174
+ }
175
+ type SubscriptionOptions = {
176
+ plans: PaystackPlan[] | (() => PaystackPlan[] | Promise<PaystackPlan[]>);
177
+ requireEmailVerification?: boolean | undefined;
178
+ authorizeReference?: ((data: {
179
+ user: User;
180
+ session: AuthSession;
181
+ referenceId: string;
182
+ action: "initialize-transaction" | "verify-transaction" | "list-subscriptions" | "disable-subscription" | "enable-subscription";
183
+ }, ctx: GenericEndpointContext) => Promise<boolean>) | undefined;
184
+ onSubscriptionComplete?: ((data: {
185
+ event: any;
186
+ subscription: Subscription;
187
+ plan: PaystackPlan;
188
+ }, ctx: GenericEndpointContext) => Promise<void>) | undefined;
189
+ onSubscriptionUpdate?: ((data: {
190
+ event: any;
191
+ subscription: Subscription;
192
+ }, ctx: GenericEndpointContext) => Promise<void>) | undefined;
193
+ onSubscriptionDelete?: ((data: {
194
+ event: any;
195
+ subscription: Subscription;
196
+ }, ctx: GenericEndpointContext) => Promise<void>) | undefined;
197
+ };
198
+ interface PaystackOptions<TPaystackClient extends PaystackClientLike = PaystackNodeClient> {
199
+ /** Paystack SDK instance (recommended: `@alexasomba/paystack-node` via `createPaystack({ secretKey })`). */
200
+ paystackClient: NoInfer<TPaystackClient>;
201
+ /** Paystack webhook secret used to verify `x-paystack-signature`. */
202
+ paystackWebhookSecret: string;
203
+ /** Enable customer creation on Better Auth sign up. */
204
+ createCustomerOnSignUp?: boolean | undefined;
205
+ onCustomerCreate?: ((data: {
206
+ paystackCustomer: any;
207
+ user: User & {
208
+ paystackCustomerCode: string;
209
+ };
210
+ }, ctx: GenericEndpointContext) => Promise<void>) | undefined;
211
+ getCustomerCreateParams?: ((user: User, ctx: GenericEndpointContext) => Promise<Record<string, any>>) | undefined;
212
+ subscription?: ({
213
+ enabled: false;
214
+ } | ({
215
+ enabled: true;
216
+ } & SubscriptionOptions)) | undefined;
217
+ onEvent?: ((event: any) => Promise<void>) | undefined;
218
+ schema?: InferOptionSchema<typeof subscriptions & typeof user> | undefined;
219
+ }
220
+ //#endregion
221
+ //#region src/index.d.ts
222
+ declare const paystack: <TPaystackClient extends PaystackClientLike = PaystackNodeClient, O extends PaystackOptions<TPaystackClient> = PaystackOptions<TPaystackClient>>(options: O) => {
223
+ id: "paystack";
224
+ endpoints: {
225
+ paystackWebhook: better_auth0.StrictEndpoint<"/paystack/webhook", {
226
+ method: "POST";
227
+ metadata: {
228
+ openapi: {
229
+ operationId: string;
230
+ };
231
+ scope: "server";
232
+ };
233
+ cloneRequest: true;
234
+ disableBody: true;
235
+ }, {
236
+ received: boolean;
237
+ }>;
238
+ };
239
+ init(ctx: better_auth0.AuthContext<better_auth0.BetterAuthOptions>): {
240
+ options: {
241
+ databaseHooks: {
242
+ user: {
243
+ create: {
244
+ after(user: {
245
+ id: string;
246
+ createdAt: Date;
247
+ updatedAt: Date;
248
+ email: string;
249
+ emailVerified: boolean;
250
+ name: string;
251
+ image?: string | null | undefined;
252
+ } & Record<string, unknown>, hookCtx: better_auth0.GenericEndpointContext<better_auth0.BetterAuthOptions> | null): Promise<void>;
253
+ };
254
+ };
255
+ };
256
+ };
257
+ };
258
+ schema: better_auth0.BetterAuthPluginDBSchema;
259
+ $ERROR_CODES: {
260
+ readonly SUBSCRIPTION_NOT_FOUND: "Subscription not found";
261
+ readonly SUBSCRIPTION_PLAN_NOT_FOUND: "Subscription plan not found";
262
+ readonly UNABLE_TO_CREATE_CUSTOMER: "Unable to create customer";
263
+ readonly FAILED_TO_INITIALIZE_TRANSACTION: "Failed to initialize transaction";
264
+ readonly FAILED_TO_VERIFY_TRANSACTION: "Failed to verify transaction";
265
+ readonly FAILED_TO_DISABLE_SUBSCRIPTION: "Failed to disable subscription";
266
+ readonly FAILED_TO_ENABLE_SUBSCRIPTION: "Failed to enable subscription";
267
+ readonly EMAIL_VERIFICATION_REQUIRED: "Email verification is required before you can subscribe to a plan";
268
+ };
269
+ };
270
+ type PaystackClientFromOptions<O extends PaystackOptions<any>> = O extends PaystackOptions<infer TClient> ? TClient : PaystackNodeClient;
271
+ type PaystackPlugin<O extends PaystackOptions<any> = PaystackOptions> = ReturnType<typeof paystack<PaystackClientFromOptions<O>, O>>;
272
+ //#endregion
273
+ export { PaystackPlan as a, PaystackOptions as i, paystack as n, Subscription as o, PaystackNodeClient as r, SubscriptionOptions as s, PaystackPlugin as t };
274
+ //# sourceMappingURL=index-CZ3Le7Er.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CZ3Le7Er.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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"}
@@ -0,0 +1,2 @@
1
+ import { a as PaystackPlan, i as PaystackOptions, n as paystack, o as Subscription, s as SubscriptionOptions, t as PaystackPlugin } from "./index-CZ3Le7Er.mjs";
2
+ export { PaystackOptions, PaystackPlan, PaystackPlugin, Subscription, SubscriptionOptions, paystack };