@pague-dev/sdk-node 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/README.md +38 -0
- package/dist/index.cjs +265 -0
- package/dist/index.d.cts +437 -0
- package/dist/index.d.mts +437 -0
- package/dist/index.mjs +263 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# @pague-dev/sdk-node
|
|
2
|
+
|
|
3
|
+
SDK oficial do [pague.dev](https://pague.dev) para Node.js e browsers.
|
|
4
|
+
|
|
5
|
+
## Instalacao
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @pague-dev/sdk-node
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Uso
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Pdev } from '@pague-dev/sdk-node';
|
|
15
|
+
|
|
16
|
+
// Opção 1: Passar a API key diretamente
|
|
17
|
+
const pdev = new Pdev('pd_live_sua_api_key');
|
|
18
|
+
|
|
19
|
+
// Opção 2: Usar variável de ambiente PDEV_API_KEY
|
|
20
|
+
const pdev = new Pdev();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Recursos
|
|
24
|
+
|
|
25
|
+
- **PIX** - Cobranças instantâneas
|
|
26
|
+
- **Charges** - Links de pagamento
|
|
27
|
+
- **Customers** - Gestão de clientes
|
|
28
|
+
- **Projects** - Organização por projetos
|
|
29
|
+
- **Transactions** - Consulta de transações
|
|
30
|
+
- **Webhooks** - Notificações em tempo real
|
|
31
|
+
|
|
32
|
+
## Documentacao
|
|
33
|
+
|
|
34
|
+
Exemplos e guias de integração: **[docs.pague.dev](https://docs.pague.dev)**
|
|
35
|
+
|
|
36
|
+
## Licenca
|
|
37
|
+
|
|
38
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/common/utils/build-pagination-query.ts
|
|
3
|
+
function buildPaginationQuery(options) {
|
|
4
|
+
const searchParams = new URLSearchParams();
|
|
5
|
+
for (const [key, value] of Object.entries(options)) if (value !== void 0 && value !== null) searchParams.set(key, String(value));
|
|
6
|
+
return searchParams.toString();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/common/base-resource.ts
|
|
11
|
+
/**
|
|
12
|
+
* Base class for API resources that follow CRUD patterns.
|
|
13
|
+
* Provides common create, list, and get operations.
|
|
14
|
+
*/
|
|
15
|
+
var BaseResource = class {
|
|
16
|
+
constructor(pdev) {
|
|
17
|
+
this.pdev = pdev;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a new entity
|
|
21
|
+
*/
|
|
22
|
+
async create(options) {
|
|
23
|
+
return this.pdev.post(this.endpoint, options);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* List entities with pagination
|
|
27
|
+
*/
|
|
28
|
+
async list(options = {}) {
|
|
29
|
+
const queryString = buildPaginationQuery(options);
|
|
30
|
+
const path = queryString ? `${this.endpoint}?${queryString}` : this.endpoint;
|
|
31
|
+
return this.pdev.get(path);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get a single entity by ID
|
|
35
|
+
*/
|
|
36
|
+
async get(id) {
|
|
37
|
+
return this.pdev.get(`${this.endpoint}/${id}`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Base class for resources that only support create operations
|
|
42
|
+
*/
|
|
43
|
+
var CreateOnlyResource = class {
|
|
44
|
+
constructor(pdev) {
|
|
45
|
+
this.pdev = pdev;
|
|
46
|
+
}
|
|
47
|
+
async create(options) {
|
|
48
|
+
return this.pdev.post(this.endpoint, options);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Base class for resources that only support get operations
|
|
53
|
+
*/
|
|
54
|
+
var GetOnlyResource = class {
|
|
55
|
+
constructor(pdev) {
|
|
56
|
+
this.pdev = pdev;
|
|
57
|
+
}
|
|
58
|
+
async get(id) {
|
|
59
|
+
return this.pdev.get(`${this.endpoint}/${id}`);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/charges/charges.ts
|
|
65
|
+
var Charges = class extends BaseResource {
|
|
66
|
+
endpoint = "/charges";
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/config.ts
|
|
71
|
+
const config = { baseUrl: "https://api.pague.dev/v1" };
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/customers/customers.ts
|
|
75
|
+
var Customers = class extends BaseResource {
|
|
76
|
+
endpoint = "/customers";
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/pix/pix.ts
|
|
81
|
+
var Pix = class extends CreateOnlyResource {
|
|
82
|
+
endpoint = "/pix";
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/projects/projects.ts
|
|
87
|
+
var Projects = class extends BaseResource {
|
|
88
|
+
endpoint = "/projects";
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/transactions/transactions.ts
|
|
93
|
+
var Transactions = class extends GetOnlyResource {
|
|
94
|
+
endpoint = "/transactions";
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/pdev.ts
|
|
99
|
+
var Pdev = class {
|
|
100
|
+
key;
|
|
101
|
+
baseUrl;
|
|
102
|
+
headers;
|
|
103
|
+
pix;
|
|
104
|
+
customers;
|
|
105
|
+
projects;
|
|
106
|
+
charges;
|
|
107
|
+
transactions;
|
|
108
|
+
constructor(key) {
|
|
109
|
+
if (!key) {
|
|
110
|
+
if (typeof process !== "undefined" && process.env) this.key = process.env.PDEV_API_KEY || "";
|
|
111
|
+
else this.key = "";
|
|
112
|
+
if (!this.key) throw new Error("Missing API key. Pass it to the constructor `new Pdev(\"pd_live_xxx\")` or set the PDEV_API_KEY environment variable.");
|
|
113
|
+
} else this.key = key;
|
|
114
|
+
this.baseUrl = config.baseUrl;
|
|
115
|
+
this.headers = new Headers({
|
|
116
|
+
"X-API-Key": this.key,
|
|
117
|
+
"Content-Type": "application/json"
|
|
118
|
+
});
|
|
119
|
+
this.pix = new Pix(this);
|
|
120
|
+
this.customers = new Customers(this);
|
|
121
|
+
this.projects = new Projects(this);
|
|
122
|
+
this.charges = new Charges(this);
|
|
123
|
+
this.transactions = new Transactions(this);
|
|
124
|
+
}
|
|
125
|
+
async post(path, body, options = {}) {
|
|
126
|
+
const url = this.buildUrl(path, options.query);
|
|
127
|
+
return this.fetchRequest(url, {
|
|
128
|
+
method: "POST",
|
|
129
|
+
headers: this.headers,
|
|
130
|
+
body: body ? JSON.stringify(body) : void 0
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async get(path, options = {}) {
|
|
134
|
+
const url = this.buildUrl(path, options.query);
|
|
135
|
+
return this.fetchRequest(url, {
|
|
136
|
+
method: "GET",
|
|
137
|
+
headers: this.headers
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
buildUrl(path, query) {
|
|
141
|
+
let url = `${this.baseUrl}${path}`;
|
|
142
|
+
if (query) {
|
|
143
|
+
const searchParams = new URLSearchParams();
|
|
144
|
+
for (const [key, value] of Object.entries(query)) if (value !== void 0 && value !== null) searchParams.set(key, String(value));
|
|
145
|
+
const queryString = searchParams.toString();
|
|
146
|
+
if (queryString) url += `?${queryString}`;
|
|
147
|
+
}
|
|
148
|
+
return url;
|
|
149
|
+
}
|
|
150
|
+
async fetchRequest(url, options) {
|
|
151
|
+
try {
|
|
152
|
+
const response = await fetch(url, options);
|
|
153
|
+
if (!response.ok) try {
|
|
154
|
+
const rawError = await response.text();
|
|
155
|
+
return {
|
|
156
|
+
data: null,
|
|
157
|
+
error: JSON.parse(rawError)
|
|
158
|
+
};
|
|
159
|
+
} catch {
|
|
160
|
+
return {
|
|
161
|
+
data: null,
|
|
162
|
+
error: {
|
|
163
|
+
statusCode: response.status,
|
|
164
|
+
error: "UnknownError",
|
|
165
|
+
message: "An unexpected error occurred"
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
data: await response.json(),
|
|
171
|
+
error: null
|
|
172
|
+
};
|
|
173
|
+
} catch {
|
|
174
|
+
return {
|
|
175
|
+
data: null,
|
|
176
|
+
error: {
|
|
177
|
+
statusCode: null,
|
|
178
|
+
error: "NetworkError",
|
|
179
|
+
message: "Unable to fetch data. The request could not be resolved."
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/webhooks/verify.ts
|
|
188
|
+
/**
|
|
189
|
+
* Type guard to check if an event is a valid WebhookEvent
|
|
190
|
+
*/
|
|
191
|
+
function isValidWebhookEvent(event) {
|
|
192
|
+
if (typeof event !== "object" || event === null) return false;
|
|
193
|
+
const obj = event;
|
|
194
|
+
if (typeof obj.event !== "string") return false;
|
|
195
|
+
if (typeof obj.eventId !== "string") return false;
|
|
196
|
+
if (typeof obj.timestamp !== "string") return false;
|
|
197
|
+
if (typeof obj.data !== "object" || obj.data === null) return false;
|
|
198
|
+
return [
|
|
199
|
+
"payment_completed",
|
|
200
|
+
"payment_failed",
|
|
201
|
+
"refund_completed"
|
|
202
|
+
].includes(obj.event);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Parses a webhook payload and returns a type-safe WebhookEvent.
|
|
206
|
+
* Returns null if the payload is invalid.
|
|
207
|
+
*
|
|
208
|
+
* @param payload - The raw request body as a string
|
|
209
|
+
* @returns Parsed WebhookEvent or null if invalid
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* import { parseWebhook } from 'pague-dev';
|
|
214
|
+
*
|
|
215
|
+
* app.post('/webhook', (req, res) => {
|
|
216
|
+
* // 1. Verify signature first (implement using your framework)
|
|
217
|
+
* // const isValid = verifySignature(req.body, req.headers['x-webhook-signature'], secret);
|
|
218
|
+
*
|
|
219
|
+
* // 2. Parse the webhook payload
|
|
220
|
+
* const event = parseWebhook(req.body);
|
|
221
|
+
*
|
|
222
|
+
* if (!event) {
|
|
223
|
+
* return res.status(400).send('Invalid webhook payload');
|
|
224
|
+
* }
|
|
225
|
+
*
|
|
226
|
+
* // 3. Handle the event with full type safety
|
|
227
|
+
* switch (event.event) {
|
|
228
|
+
* case 'payment_completed':
|
|
229
|
+
* // event.data is PaymentCompletedData
|
|
230
|
+
* console.log('Payment completed:', event.data.transactionId);
|
|
231
|
+
* console.log('Amount:', event.data.amount);
|
|
232
|
+
* console.log('Net amount:', event.data.netAmount);
|
|
233
|
+
* break;
|
|
234
|
+
*
|
|
235
|
+
* case 'payment_failed':
|
|
236
|
+
* // event.data is PaymentFailedData
|
|
237
|
+
* console.log('Payment failed:', event.data.transactionId);
|
|
238
|
+
* console.log('Reason:', event.data.failureReason);
|
|
239
|
+
* break;
|
|
240
|
+
*
|
|
241
|
+
* case 'refund_completed':
|
|
242
|
+
* // event.data is RefundCompletedData
|
|
243
|
+
* console.log('Refund completed:', event.data.refundTransactionId);
|
|
244
|
+
* console.log('Original transaction:', event.data.originalTransactionId);
|
|
245
|
+
* break;
|
|
246
|
+
* }
|
|
247
|
+
*
|
|
248
|
+
* res.status(200).send('OK');
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
function parseWebhook(payload) {
|
|
253
|
+
let parsed;
|
|
254
|
+
try {
|
|
255
|
+
parsed = JSON.parse(payload);
|
|
256
|
+
} catch {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
if (!isValidWebhookEvent(parsed)) return null;
|
|
260
|
+
return parsed;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
//#endregion
|
|
264
|
+
exports.Pdev = Pdev;
|
|
265
|
+
exports.parseWebhook = parseWebhook;
|