paystack-webhook-types 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Erastus Beloved
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # @types/paystack-webhook-types
2
+
3
+ TypeScript type definitions for [Paystack Webhooks](https://paystack.com/docs/payments/webhooks).
4
+ This package provides strongly-typed event objects for Paystack webhooks, making it easier and safer to integrate into your Node.js or TypeScript backend.
5
+
6
+ ---
7
+
8
+ ## Features
9
+ - Full type coverage for Paystack webhook events (e.g., `charge.success`, `transfer.failed`, etc.).
10
+ - Discriminated union support — safely narrow down events by their `event` property.
11
+ - Autocomplete & IntelliSense in your IDE.
12
+ - Easy to extend and contribute.
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @types/paystack-webhook-types
20
+ # or
21
+ yarn add @types/paystack-webhook-types
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Usage
27
+
28
+ ```ts
29
+ import { PaystackWebhookEvent, ExtractEvent, Events } from "@types/paystack-webhook-types";
30
+ import { Request, Response } from "express";
31
+
32
+ app.post("/webhook", (req: Request, res: Response) => {
33
+ const event = req.body as PaystackWebhookEvent;
34
+
35
+ switch (event.event as Events) {
36
+ case "charge.success": {
37
+ const data = (event as ExtractEvent<"charge.success">).data;
38
+ console.log("Charge was successful:", data);
39
+ break;
40
+ }
41
+ case "transfer.failed": {
42
+ const data = (event as ExtractEvent<"transfer.failed">).data;
43
+ console.error("Transfer failed:", data);
44
+ break;
45
+ }
46
+ default:
47
+ console.log("Unhandled event:", event.event);
48
+ }
49
+
50
+ res.sendStatus(200);
51
+ });
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Contributing
57
+
58
+ Contributions are welcome
59
+ If you’d like to add new event types, improve docs, or fix issues:
60
+
61
+ 1. Fork the repo
62
+ 2. Create a feature branch: `git checkout -b feature/my-update`
63
+ 3. Commit changes: `git commit -m "Add XYZ event type"`
64
+ 4. Push and open a Pull Request
65
+
66
+ Please make sure to add/update tests for new event types.
67
+
68
+ ---
69
+
70
+ ## License
71
+
72
+ MIT License © 2025-present
73
+ Open to community contributions.
74
+
75
+ ---
76
+
77
+ ## Acknowledgements
78
+ - [Paystack Documentation](https://paystack.com/docs/)
79
+ - Inspired by DefinitelyTyped and similar community-driven type packages
@@ -0,0 +1,125 @@
1
+ import type { Authorization, Currency, Customer, WebhookStatus } from "../shared/common";
2
+ export type ChargeEvents = "charge.success" | "charge.failed";
3
+ export interface ChargeData {
4
+ id: number;
5
+ domain: string;
6
+ status: WebhookStatus;
7
+ reference: string;
8
+ amount: number;
9
+ message: string | null;
10
+ gateway_response: string;
11
+ paid_at: string;
12
+ created_at: string;
13
+ channel: string;
14
+ currency: Currency;
15
+ ip_address: string;
16
+ metadata: Record<string, any>;
17
+ log: {
18
+ start_time: number | null;
19
+ time_spent: number;
20
+ attempts: number;
21
+ authentication: string;
22
+ errors: number;
23
+ success: boolean;
24
+ mobile: boolean;
25
+ input: any[];
26
+ history: Array<{
27
+ type: string;
28
+ message: string;
29
+ time: number;
30
+ }>;
31
+ } | null;
32
+ fees: number | null;
33
+ fees_split: any;
34
+ authorization: Authorization;
35
+ customer: Customer;
36
+ plan: any;
37
+ split: Record<string, any>;
38
+ order_id: string | null;
39
+ requested_amount: number;
40
+ pos_transaction_data: any;
41
+ source: any;
42
+ fees_breakdown: any;
43
+ }
44
+ /**
45
+ * @description
46
+ * A successful charge was made
47
+ * @example
48
+ * {
49
+ "event": "charge.success",
50
+ "data": {
51
+ "id": 302961,
52
+ "domain": "live",
53
+ "status": "success",
54
+ "reference": "qTPrJoy9Bx",
55
+ "amount": 10000,
56
+ "message": null,
57
+ "gateway_response": "Approved by Financial Institution",
58
+ "paid_at": "2016-09-30T21:10:19.000Z",
59
+ "created_at": "2016-09-30T21:09:56.000Z",
60
+ "channel": "card",
61
+ "currency": "NGN",
62
+ "ip_address": "41.242.49.37",
63
+ "metadata": 0,
64
+ "log": {
65
+ "time_spent": 16,
66
+ "attempts": 1,
67
+ "authentication": "pin",
68
+ "errors": 0,
69
+ "success": false,
70
+ "mobile": false,
71
+ "input": [],
72
+ "channel": null,
73
+ "history": [
74
+ {
75
+ "type": "input",
76
+ "message": "Filled these fields: card number, card expiry, card cvv",
77
+ "time": 15
78
+ },
79
+ {
80
+ "type": "action",
81
+ "message": "Attempted to pay",
82
+ "time": 15
83
+ },
84
+ {
85
+ "type": "auth",
86
+ "message": "Authentication Required: pin",
87
+ "time": 16
88
+ }
89
+ ]
90
+ },
91
+ "fees": null,
92
+ "customer": {
93
+ "id": 68324,
94
+ "first_name": "BoJack",
95
+ "last_name": "Horseman",
96
+ "email": "bojack@horseman.com",
97
+ "customer_code": "CUS_qo38as2hpsgk2r0",
98
+ "phone": null,
99
+ "metadata": null,
100
+ "risk_action": "default"
101
+ },
102
+ "authorization": {
103
+ "authorization_code": "AUTH_f5rnfq9p",
104
+ "bin": "539999",
105
+ "last4": "8877",
106
+ "exp_month": "08",
107
+ "exp_year": "2020",
108
+ "card_type": "mastercard DEBIT",
109
+ "bank": "Guaranty Trust Bank",
110
+ "country_code": "NG",
111
+ "brand": "mastercard",
112
+ "account_name": "BoJack Horseman"
113
+ },
114
+ "plan": {}
115
+ }
116
+ }
117
+ */
118
+ export interface ChargeSuccessEvent {
119
+ event: 'charge.success';
120
+ data: ChargeData;
121
+ }
122
+ export interface ChargeFailedEvent {
123
+ event: 'charge.failed';
124
+ data: ChargeData;
125
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=charge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charge.js","sourceRoot":"","sources":["../../src/events/charge.ts"],"names":[],"mappings":""}
@@ -0,0 +1,296 @@
1
+ import type { Authorization, Currency, Customer, Domain } from "../shared/common";
2
+ export type SubscriptionStatus = 'active' | 'non-renewing' | 'cancelled' | 'attention' | 'complete';
3
+ export type SubscriptionPlanInterval = 'daily' | 'weekly' | 'monthly' | 'annually';
4
+ export type SubscriptionEvents = 'subscription.create' | 'subscription.disable' | 'subscription.not_renew' | 'subscription.expiring_cards';
5
+ export interface SubscriptionData {
6
+ id: number | null;
7
+ domain: Domain;
8
+ status: SubscriptionStatus;
9
+ subscription_code: string;
10
+ email_token: string | null;
11
+ amount: number;
12
+ cron_expression: string;
13
+ next_payment_date: string;
14
+ open_invoice: string | null;
15
+ integration: number | null;
16
+ authorization: Authorization;
17
+ customer: Customer;
18
+ invoices: any[] | null;
19
+ invoices_history: any[] | null;
20
+ invoice_limit: number | null;
21
+ split_code: string | null;
22
+ created_at: string;
23
+ most_recent_invoice: any | null;
24
+ }
25
+ export interface SubscriptionPlan {
26
+ name: string;
27
+ plan_code: string;
28
+ description: string | null;
29
+ amount: number;
30
+ interval: SubscriptionPlanInterval;
31
+ send_invoices: boolean;
32
+ send_sms: boolean;
33
+ currency: Currency;
34
+ }
35
+ /**
36
+ * Subscription plan information when event is "disable".
37
+ *
38
+ * @example
39
+ * {
40
+ * "id": 67572,
41
+ "name": "Monthly retainer",
42
+ "plan_code": "PLN_gx2wn530m0i3w3m",
43
+ "description": null,
44
+ "amount": 50000,
45
+ "interval": "monthly",
46
+ "send_invoices": true,
47
+ "send_sms": true,
48
+ "currency": "NGN"
49
+ * }
50
+ */
51
+ export interface SubscriptionPlanWithId extends SubscriptionPlan {
52
+ id: number;
53
+ }
54
+ export interface SubscriptionPlanWithoutId extends SubscriptionPlan {
55
+ id: null;
56
+ }
57
+ /**
58
+ * @description
59
+ * A subscription has been created
60
+ * @example
61
+ * {
62
+ "event": "subscription.create",
63
+ "data": {
64
+ "domain": "test",
65
+ "status": "active",
66
+ "subscription_code": "SUB_vsyqdmlzble3uii",
67
+ "amount": 50000,
68
+ "cron_expression": "0 0 28 * *",
69
+ "next_payment_date": "2016-05-19T07:00:00.000Z",
70
+ "open_invoice": null,
71
+ "createdAt": "2016-03-20T00:23:24.000Z",
72
+ "plan": {
73
+ "name": "Monthly retainer",
74
+ "plan_code": "PLN_gx2wn530m0i3w3m",
75
+ "description": null,
76
+ "amount": 50000,
77
+ "interval": "monthly",
78
+ "send_invoices": true,
79
+ "send_sms": true,
80
+ "currency": "NGN"
81
+ },
82
+ "authorization": {
83
+ "authorization_code": "AUTH_96xphygz",
84
+ "bin": "539983",
85
+ "last4": "7357",
86
+ "exp_month": "10",
87
+ "exp_year": "2017",
88
+ "card_type": "MASTERCARD DEBIT",
89
+ "bank": "GTBANK",
90
+ "country_code": "NG",
91
+ "brand": "MASTERCARD",
92
+ "account_name": "BoJack Horseman"
93
+ },
94
+ "customer": {
95
+ "first_name": "BoJack",
96
+ "last_name": "Horseman",
97
+ "email": "bojack@horsinaround.com",
98
+ "customer_code": "CUS_xnxdt6s1zg1f4nx",
99
+ "phone": "",
100
+ "metadata": {},
101
+ "risk_action": "default"
102
+ },
103
+ "created_at": "2016-10-01T10:59:59.000Z"
104
+ }
105
+ }
106
+ */
107
+ export interface SubscriptionCreateEvent {
108
+ event: 'subscription.create';
109
+ data: SubscriptionData & {
110
+ plan: SubscriptionPlanWithoutId;
111
+ };
112
+ }
113
+ /**
114
+ * @description
115
+ * A subscription on your account has been disabled
116
+ * @example
117
+ * {
118
+ "event": "subscription.disable",
119
+ "data": {
120
+ "domain": "test",
121
+ "status": "complete",
122
+ "subscription_code": "SUB_vsyqdmlzble3uii",
123
+ "email_token": "ctt824k16n34u69",
124
+ "amount": 300000,
125
+ "cron_expression": "0 * * * *",
126
+ "next_payment_date": "2020-11-26T15:00:00.000Z",
127
+ "open_invoice": null,
128
+ "plan": {
129
+ "id": 67572,
130
+ "name": "Monthly retainer",
131
+ "plan_code": "PLN_gx2wn530m0i3w3m",
132
+ "description": null,
133
+ "amount": 50000,
134
+ "interval": "monthly",
135
+ "send_invoices": true,
136
+ "send_sms": true,
137
+ "currency": "NGN"
138
+ },
139
+ "authorization": {
140
+ "authorization_code": "AUTH_96xphygz",
141
+ "bin": "539983",
142
+ "last4": "7357",
143
+ "exp_month": "10",
144
+ "exp_year": "2017",
145
+ "card_type": "MASTERCARD DEBIT",
146
+ "bank": "GTBANK",
147
+ "country_code": "NG",
148
+ "brand": "MASTERCARD",
149
+ "account_name": "BoJack Horseman"
150
+ },
151
+ "customer": {
152
+ "first_name": "BoJack",
153
+ "last_name": "Horseman",
154
+ "email": "bojack@horsinaround.com",
155
+ "customer_code": "CUS_xnxdt6s1zg1f4nx",
156
+ "phone": "",
157
+ "metadata": {},
158
+ "risk_action": "default"
159
+ },
160
+ "created_at": "2020-11-26T14:45:06.000Z"
161
+ }
162
+ }
163
+ */
164
+ export interface SubscriptionDisableEvent {
165
+ event: 'subscription.disable';
166
+ data: SubscriptionData & {
167
+ plan: SubscriptionPlanWithId;
168
+ };
169
+ }
170
+ /**
171
+ * @description
172
+ * A subscription on your account's status has changed to non-renewing. This means the subscription will not be charged on the next payment date
173
+ * @example
174
+ * {
175
+ "event": "subscription.not_renew",
176
+ "data": {
177
+ "id": 317617,
178
+ "domain": "test",
179
+ "status": "non-renewing",
180
+ "subscription_code": "SUB_d638sdiWAio7jnl",
181
+ "email_token": "086x99rmqc4qhcw",
182
+ "amount": 120000,
183
+ "cron_expression": "0 0 8 10 *",
184
+ "next_payment_date": null,
185
+ "open_invoice": null,
186
+ "integration": 116430,
187
+ "plan": {
188
+ "id": 103028,
189
+ "name": "(1,200) - annually - [1 - Year]",
190
+ "plan_code": "PLN_tlknnnzfi4w2evu",
191
+ "description": "Subscription not_renewed for sub@notrenew.com",
192
+ "amount": 120000,
193
+ "interval": "annually",
194
+ "send_invoices": true,
195
+ "send_sms": true,
196
+ "currency": "NGN"
197
+ },
198
+ "authorization": {
199
+ "authorization_code": "AUTH_5ftfl9xrl0",
200
+ "bin": "424242",
201
+ "last4": "4081",
202
+ "exp_month": "06",
203
+ "exp_year": "2023",
204
+ "channel": "card",
205
+ "card_type": "mastercard debit",
206
+ "bank": "Guaranty Trust Bank",
207
+ "country_code": "NG",
208
+ "brand": "mastercard",
209
+ "reusable": true,
210
+ "signature": "SIG_biPYZE4PgDCQUJMIT4sE",
211
+ "account_name": null
212
+ },
213
+ "customer": {
214
+ "id": 57199167,
215
+ "first_name": null,
216
+ "last_name": null,
217
+ "email": "sub@notrenew.com",
218
+ "customer_code": "CUS_8gbmdpvn12c67ix",
219
+ "phone": null,
220
+ "metadata": null,
221
+ "risk_action": "default",
222
+ "international_format_phone": null
223
+ },
224
+ "invoices": [],
225
+ "invoices_history": [],
226
+ "invoice_limit": 0,
227
+ "split_code": null,
228
+ "most_recent_invoice": null,
229
+ "created_at": "2021-10-08T14:50:39.000Z"
230
+ }
231
+ }
232
+ */
233
+ export interface SubscriptionNotRenewingEvent {
234
+ event: 'subscription.not_renew';
235
+ data: SubscriptionData & {
236
+ plan: SubscriptionPlanWithId;
237
+ };
238
+ }
239
+ /**
240
+ * @description
241
+ * Contains information on all subscriptions with cards that are expiring that month. Sent at the beginning of the month, to merchants using Subscriptions
242
+ * @example
243
+ * {
244
+ "event": "subscription.expiring_cards",
245
+ "data": [
246
+ {
247
+ "expiry_date": "12/2021",
248
+ "description": "visa ending with 4081",
249
+ "brand": "visa",
250
+ "subscription": {
251
+ "id": 94729,
252
+ "subscription_code": "SUB_lejj927x2kxciw1",
253
+ "amount": 44000,
254
+ "next_payment_date": "2021-11-11T00:00:01.000Z",
255
+ "plan": {
256
+ "interval": "monthly",
257
+ "id": 22637,
258
+ "name": "Premium Service (Monthly)",
259
+ "plan_code": "PLN_pfmwz75o021slex"
260
+ }
261
+ },
262
+ "customer": {
263
+ "id": 7808239,
264
+ "first_name": "Bojack",
265
+ "last_name": "Horseman",
266
+ "email": "bojackhoresman@gmail.com",
267
+ "customer_code": "CUS_8v6g420rc16spqw"
268
+ }
269
+ }
270
+ ]
271
+ }
272
+ */
273
+ export interface SubscriptionExpiringCardsEvent {
274
+ event: 'subscription.expiring_cards';
275
+ data: SubscriptionExpiringCardsEvent[];
276
+ }
277
+ export interface SubscriptionDataExpiringCards {
278
+ /**
279
+ * @example "12/2021"
280
+ */
281
+ expiry_date: string;
282
+ description: string;
283
+ brand: string;
284
+ subscription: {
285
+ id: number;
286
+ subscription_code: string;
287
+ amount: number;
288
+ next_payment_date: string;
289
+ plan: {
290
+ interval: SubscriptionPlanInterval;
291
+ id: number;
292
+ name: string;
293
+ plan_code: string;
294
+ };
295
+ };
296
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=subscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/events/subscription.ts"],"names":[],"mappings":""}
@@ -0,0 +1,248 @@
1
+ import type { Currency, Domain } from "../shared/common";
2
+ import type { Without } from "../shared/util";
3
+ export type TransferEvents = 'transfer.success' | 'transfer.failed' | 'transfer.reversed';
4
+ export type TransactionSource = 'balance';
5
+ export type TransferStatus = 'success' | 'failed' | 'pending' | 'reversed' | 'otp' | 'processing';
6
+ export interface TransferData {
7
+ id: number;
8
+ amount: number;
9
+ createdAt: string;
10
+ currency: Currency;
11
+ domain: Domain;
12
+ failures: any | null;
13
+ integration: {
14
+ id: number;
15
+ is_live: boolean;
16
+ business_name: string;
17
+ logo_path: string | null;
18
+ };
19
+ reason: string;
20
+ reference: string;
21
+ source: TransactionSource;
22
+ source_details: string | null;
23
+ status: TransferStatus;
24
+ titan_code: string | null;
25
+ transfer_code: string;
26
+ transferred_at: string | null;
27
+ updatedAt: string | null;
28
+ recipient: TransferRecipient;
29
+ session: {
30
+ provider: string | null;
31
+ id: number | null;
32
+ };
33
+ created_at: string;
34
+ updated_at: string;
35
+ fee_charged: number;
36
+ gateway_response: string;
37
+ }
38
+ export interface TransferRecipient {
39
+ id: number;
40
+ active: boolean;
41
+ currency: Currency;
42
+ description: string | null;
43
+ domain: Domain;
44
+ email: string | null;
45
+ integration: number;
46
+ metadata: Record<string, any> | null;
47
+ name: string;
48
+ recipient_code: string;
49
+ type: 'nuban' | 'mobile_money' | 'basa' | 'authorization';
50
+ createdAt: string | null;
51
+ updatedAt: string | null;
52
+ is_deleted: boolean;
53
+ details: {
54
+ authorization_code: string | null;
55
+ account_number: string | null;
56
+ account_name: string | null;
57
+ bank_code: string | null;
58
+ bank_name: string | null;
59
+ };
60
+ created_at: string | null;
61
+ updated_at: string | null;
62
+ }
63
+ /**
64
+ * @description
65
+ * A successful transfer has been completed
66
+ * @example
67
+ * {
68
+ "event": "transfer.success",
69
+ "data": {
70
+ "amount": 100000,
71
+ "createdAt": "2025-08-04T10:32:40.000Z",
72
+ "currency": "NGN",
73
+ "domain": "test",
74
+ "failures": null,
75
+ "id": 860703114,
76
+ "integration": {
77
+ "id": 463433,
78
+ "is_live": true,
79
+ "business_name": "Paystack Demo",
80
+ "logo_path": "https://public-files-paystack-prod.s3.eu-west-1.amazonaws.com/integration-logos/hpyxo8n1c7du6gxup7h6.png"
81
+ },
82
+ "reason": "Bonus for the week",
83
+ "reference": "acv_9ee55786-2323-4760-98e2-6380c9cb3f68",
84
+ "source": "balance",
85
+ "source_details": null,
86
+ "status": "success",
87
+ "titan_code": null,
88
+ "transfer_code": "TRF_v5tip3zx8nna9o78",
89
+ "transferred_at": null,
90
+ "updatedAt": "2025-08-04T10:32:40.000Z",
91
+ "recipient": {
92
+ "active": true,
93
+ "createdAt": "2023-07-11T15:42:27.000Z",
94
+ "currency": "NGN",
95
+ "description": "",
96
+ "domain": "test",
97
+ "email": null,
98
+ "id": 56824902,
99
+ "integration": 463433,
100
+ "metadata": null,
101
+ "name": "Jekanmo Padie",
102
+ "recipient_code": "RCP_gd9vgag7n5lr5ix",
103
+ "type": "nuban",
104
+ "updatedAt": "2023-07-11T15:42:27.000Z",
105
+ "is_deleted": false,
106
+ "details": {
107
+ "authorization_code": null,
108
+ "account_number": "9876543210",
109
+ "account_name": null,
110
+ "bank_code": "044",
111
+ "bank_name": "Access Bank"
112
+ }
113
+ },
114
+ "session": {
115
+ "provider": null,
116
+ "id": null
117
+ },
118
+ "fee_charged": 0,
119
+ "gateway_response": null
120
+ }
121
+ }
122
+ */
123
+ export interface TransferSuccessEvent {
124
+ event: 'transfer.success';
125
+ data: Without<TransferData, 'created_at' | 'updated_at'>;
126
+ }
127
+ /**
128
+ * @description
129
+ * A transfer you attempted has failed
130
+ * @example
131
+ * {
132
+ "event": "transfer.failed",
133
+ "data": {
134
+ "amount": 200000,
135
+ "currency": "NGN",
136
+ "domain": "test",
137
+ "failures": null,
138
+ "id": 69123462,
139
+ "integration": {
140
+ "id": 100043,
141
+ "is_live": true,
142
+ "business_name": "Paystack"
143
+ },
144
+ "reason": "Enjoy",
145
+ "reference": "1976435206",
146
+ "source": "balance",
147
+ "source_details": null,
148
+ "status": "failed",
149
+ "titan_code": null,
150
+ "transfer_code": "TRF_chs98y5rykjb47w",
151
+ "transferred_at": null,
152
+ "recipient": {
153
+ "active": true,
154
+ "currency": "NGN",
155
+ "description": null,
156
+ "domain": "test",
157
+ "email": "test@email.com",
158
+ "id": 13584206,
159
+ "integration": 100043,
160
+ "metadata": null,
161
+ "name": "Ted Lasso",
162
+ "recipient_code": "RCP_cjcua8itre45gs",
163
+ "type": "nuban",
164
+ "is_deleted": false,
165
+ "details": {
166
+ "authorization_code": null,
167
+ "account_number": "0123456789",
168
+ "account_name": "Ted Lasso",
169
+ "bank_code": "011",
170
+ "bank_name": "First Bank of Nigeria"
171
+ },
172
+ "created_at": "2021-04-12T15:30:14.000Z",
173
+ "updated_at": "2021-04-12T15:30:14.000Z"
174
+ },
175
+ "session": {
176
+ "provider": "nip",
177
+ "id": "74849400998877667"
178
+ },
179
+ "created_at": "2021-04-12T15:30:15.000Z",
180
+ "updated_at": "2021-04-12T15:41:21.000Z"
181
+ }
182
+ }
183
+ */
184
+ export interface TransferFailedEvent {
185
+ event: 'transfer.failed';
186
+ data: Without<TransferData, 'fee_charged' | 'gateway_response' | 'createdAt'>;
187
+ }
188
+ /**
189
+ * @description
190
+ * A transfer you attempted has been reversed
191
+ * @example
192
+ * {
193
+ "event": "transfer.reversed",
194
+ "data": {
195
+ "amount": 10000,
196
+ "currency": "NGN",
197
+ "domain": "live",
198
+ "failures": null,
199
+ "id": 20615868,
200
+ "integration": {
201
+ "id": 100073,
202
+ "is_live": true,
203
+ "business_name": "Night's Watch Inc"
204
+ },
205
+ "reason": "test balance ledger elastic changes",
206
+ "reference": "jvrjckwenm",
207
+ "source": "balance",
208
+ "source_details": null,
209
+ "status": "reversed",
210
+ "titan_code": null,
211
+ "transfer_code": "TRF_js075pj9u07f34l",
212
+ "transferred_at": "2020-03-24T07:14:00.000Z",
213
+ "recipient": {
214
+ "active": true,
215
+ "currency": "NGN",
216
+ "description": null,
217
+ "domain": "live",
218
+ "email": "jon@sn.ow",
219
+ "id": 1476759,
220
+ "integration": 100073,
221
+ "metadata": null,
222
+ "name": "JON SNOW",
223
+ "recipient_code": "RCP_hmcj8ciho490bvi",
224
+ "type": "nuban",
225
+ "is_deleted": false,
226
+ "details": {
227
+ "authorization_code": null,
228
+ "account_number": "0000000000",
229
+ "account_name": null,
230
+ "bank_code": "011",
231
+ "bank_name": "First Bank of Nigeria"
232
+ },
233
+ "created_at": "2019-04-10T08:39:10.000Z",
234
+ "updated_at": "2019-11-27T20:43:57.000Z"
235
+ },
236
+ "session": {
237
+ "provider": "nip",
238
+ "id": "110006200324071331002061586801"
239
+ },
240
+ "created_at": "2020-03-24T07:13:31.000Z",
241
+ "updated_at": "2020-03-24T07:14:55.000Z"
242
+ }
243
+ }
244
+ */
245
+ export interface TransferReversedEvent {
246
+ event: 'transfer.reversed';
247
+ data: Without<TransferData, 'fee_charged' | 'gateway_response' | 'createdAt'>;
248
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../src/events/transfer.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export * from './events/charge';
2
+ export * from './events/subscription';
3
+ export * from './events/transfer';
4
+ export * from './shared/common';
5
+ export * from './webhook';
6
+ export type { PaystackWebhookEvent, Events } from './webhook';
7
+ export type { ExtractEvent } from './shared/util';
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './events/charge';
2
+ export * from './events/subscription';
3
+ export * from './events/transfer';
4
+ export * from './shared/common';
5
+ export * from './webhook';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AAEjC,cAAc,iBAAiB,CAAA;AAE/B,cAAc,WAAW,CAAA"}
@@ -0,0 +1,29 @@
1
+ export interface Customer {
2
+ id: number;
3
+ first_name: string | null;
4
+ last_name: string | null;
5
+ email: string;
6
+ customer_code: string;
7
+ phone: string | null;
8
+ metadata: Record<string, any> | null;
9
+ risk_action: string;
10
+ international_format_phone: string | null;
11
+ }
12
+ export interface Authorization {
13
+ authorization_code: string;
14
+ bin: string;
15
+ last4: string;
16
+ exp_month: string;
17
+ exp_year: string;
18
+ channel: 'card' | 'bank' | 'ussd' | 'qr' | 'mobile_money' | 'bank_transfer';
19
+ card_type: string;
20
+ bank: string;
21
+ country_code: string;
22
+ brand: string;
23
+ reusable: boolean;
24
+ signature: string | null;
25
+ account_name: string | null;
26
+ }
27
+ export type WebhookStatus = 'success' | 'failed' | 'pending' | 'abandoned';
28
+ export type Currency = 'NGN' | 'GHS' | 'ZAR' | 'USD';
29
+ export type Domain = 'test' | 'live';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/shared/common.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/shared/metadata.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { PaystackWebhookEvent } from "../webhook";
2
+ export type Without<T, K extends keyof T> = Omit<T, K> & {
3
+ [P in K]?: never;
4
+ };
5
+ /**
6
+ * Extract event type from event name
7
+ * @example
8
+ * type ChargeSuccess = ExtractEvent<'charge.success'>
9
+ */
10
+ export type ExtractEvent<T extends PaystackWebhookEvent['event']> = Extract<PaystackWebhookEvent, {
11
+ event: T;
12
+ }>;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/shared/util.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type { ChargeEvents, ChargeFailedEvent, ChargeSuccessEvent } from "./events/charge";
2
+ import type { SubscriptionCreateEvent, SubscriptionDisableEvent, SubscriptionEvents, SubscriptionExpiringCardsEvent, SubscriptionNotRenewingEvent } from "./events/subscription";
3
+ import type { TransferEvents, TransferFailedEvent, TransferReversedEvent, TransferSuccessEvent } from "./events/transfer";
4
+ export type PaystackWebhookEvent = ChargeSuccessEvent | ChargeFailedEvent | SubscriptionCreateEvent | SubscriptionDisableEvent | SubscriptionNotRenewingEvent | SubscriptionExpiringCardsEvent | TransferSuccessEvent | TransferFailedEvent | TransferReversedEvent;
5
+ export type Events = ChargeEvents | SubscriptionEvents | TransferEvents;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "paystack-webhook-types",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript definitions for Paystack webhook events",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc -p tsconfig.build.json",
15
+ "test": "jest",
16
+ "test:watch": "jest --watch",
17
+ "lint": "eslint src --ext .ts",
18
+ "format": "prettier --write \"src/**/*.ts\"",
19
+ "prepublishOnly": "npm run build && npm test",
20
+ "docs": "typedoc src/index.ts"
21
+ },
22
+ "keywords": [
23
+ "paystack",
24
+ "webhook",
25
+ "types",
26
+ "typescript",
27
+ "payments",
28
+ "events"
29
+ ],
30
+ "author": "Erastus ND <belovederastus@gmail.com>",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/Ndbeloved/paystack-webhook-types.git"
35
+ },
36
+ "devDependencies": {
37
+ "@types/jest": "^30.0.0",
38
+ "@types/node": "^24.6.2",
39
+ "@typescript-eslint/eslint-plugin": "^8.45.0",
40
+ "@typescript-eslint/parser": "^8.45.0",
41
+ "eslint": "^9.37.0",
42
+ "jest": "^30.2.0",
43
+ "prettier": "^3.6.2",
44
+ "ts-jest": "^29.4.4",
45
+ "ts-node": "^10.9.2",
46
+ "tsx": "^4.20.6",
47
+ "typedoc": "^0.28.13",
48
+ "typescript": "^5.9.3"
49
+ }
50
+ }