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 +21 -0
- package/README.md +79 -0
- package/dist/events/charge.d.ts +125 -0
- package/dist/events/charge.js +2 -0
- package/dist/events/charge.js.map +1 -0
- package/dist/events/subscription.d.ts +296 -0
- package/dist/events/subscription.js +2 -0
- package/dist/events/subscription.js.map +1 -0
- package/dist/events/transfer.d.ts +248 -0
- package/dist/events/transfer.js +2 -0
- package/dist/events/transfer.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/common.d.ts +29 -0
- package/dist/shared/common.js +2 -0
- package/dist/shared/common.js.map +1 -0
- package/dist/shared/metadata.d.ts +1 -0
- package/dist/shared/metadata.js +2 -0
- package/dist/shared/metadata.js.map +1 -0
- package/dist/shared/util.d.ts +12 -0
- package/dist/shared/util.js +2 -0
- package/dist/shared/util.js.map +1 -0
- package/dist/webhook.d.ts +5 -0
- package/dist/webhook.js +2 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +50 -0
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../src/events/transfer.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/shared/common.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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 @@
|
|
|
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;
|
package/dist/webhook.js
ADDED
|
@@ -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
|
+
}
|