@payzcore/node 1.0.2 → 1.0.3
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 +25 -0
- package/dist/index.d.mts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +40 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,15 @@ Official Node.js SDK for the [PayzCore](https://payzcore.com) blockchain monitor
|
|
|
4
4
|
|
|
5
5
|
Monitor incoming stablecoin transfers (USDT, USDC) across multiple chains (TRC20, BEP20, ERC20, Polygon, Arbitrum) with typed methods and automatic webhook verification.
|
|
6
6
|
|
|
7
|
+
## Important
|
|
8
|
+
|
|
9
|
+
**PayzCore is a blockchain monitoring service, not a payment processor.** All payments are sent directly to your own wallet addresses. PayzCore never holds, transfers, or has access to your funds.
|
|
10
|
+
|
|
11
|
+
- **Your wallets, your funds** — You provide your own wallet (HD xPub or static addresses). Customers pay directly to your addresses.
|
|
12
|
+
- **Read-only monitoring** — PayzCore watches the blockchain for incoming transactions and sends webhook notifications. That's it.
|
|
13
|
+
- **Protection Key security** — Sensitive operations like wallet management, address changes, and API key regeneration require a Protection Key that only you set. PayzCore cannot perform these actions without your authorization.
|
|
14
|
+
- **Your responsibility** — You are responsible for securing your own wallets and private keys. PayzCore provides monitoring and notification only.
|
|
15
|
+
|
|
7
16
|
## Installation
|
|
8
17
|
|
|
9
18
|
```bash
|
|
@@ -67,11 +76,15 @@ const { payment } = await payz.payments.create({
|
|
|
67
76
|
externalOrderId: 'order-456', // optional
|
|
68
77
|
expiresIn: 3600, // optional, seconds (300–86400)
|
|
69
78
|
metadata: { type: 'topup' }, // optional
|
|
79
|
+
address: 'Txxxx...', // optional, static wallet dedicated mode only
|
|
70
80
|
})
|
|
71
81
|
|
|
72
82
|
// payment.id, payment.address, payment.amount, payment.token, payment.expiresAt, payment.qrCode
|
|
83
|
+
// Static wallet projects may also return: payment.notice, payment.originalAmount, payment.requiresTxid
|
|
73
84
|
```
|
|
74
85
|
|
|
86
|
+
> **Note:** The `address` parameter is only used with static wallet projects in dedicated mode. For HD wallet projects, this parameter is ignored.
|
|
87
|
+
|
|
75
88
|
#### USDC on Polygon Example
|
|
76
89
|
|
|
77
90
|
```typescript
|
|
@@ -151,6 +164,18 @@ export async function POST(req: Request) {
|
|
|
151
164
|
| `payment.partial` | Partial payment received |
|
|
152
165
|
| `payment.expired` | Payment window expired |
|
|
153
166
|
|
|
167
|
+
## Static Wallet Mode
|
|
168
|
+
|
|
169
|
+
When the PayzCore project is configured with a static wallet, the API works the same way but may return additional fields in the response:
|
|
170
|
+
|
|
171
|
+
| Field | Type | Description |
|
|
172
|
+
|-------|------|-------------|
|
|
173
|
+
| `notice` | `string` | Instructions for the payer (e.g. "Send exact amount") |
|
|
174
|
+
| `original_amount` | `string` | The original requested amount before any adjustments |
|
|
175
|
+
| `requires_txid` | `boolean` | Whether the payer must submit their transaction ID |
|
|
176
|
+
|
|
177
|
+
In dedicated address mode, you can specify which static address to assign to a customer using the `address` parameter on payment creation. In shared address mode, the project's single static address is used automatically.
|
|
178
|
+
|
|
154
179
|
## Error Handling
|
|
155
180
|
|
|
156
181
|
All errors extend `PayzCoreError` with `status`, `code`, and optional `details`:
|
package/dist/index.d.mts
CHANGED
|
@@ -19,6 +19,8 @@ interface CreatePaymentParams {
|
|
|
19
19
|
token?: Token;
|
|
20
20
|
externalRef: string;
|
|
21
21
|
externalOrderId?: string;
|
|
22
|
+
/** Pre-assign a specific static address for this customer (dedicated mode only) */
|
|
23
|
+
address?: string;
|
|
22
24
|
/** Expiry in seconds (300–86400). Default: 3600 */
|
|
23
25
|
expiresIn?: number;
|
|
24
26
|
metadata?: Record<string, unknown>;
|
|
@@ -33,6 +35,14 @@ interface Payment {
|
|
|
33
35
|
expiresAt: string;
|
|
34
36
|
externalOrderId?: string;
|
|
35
37
|
qrCode?: string;
|
|
38
|
+
/** Instructions for the payer (static wallet pool mode) */
|
|
39
|
+
notice?: string;
|
|
40
|
+
/** Original requested amount before micro-amount adjustment */
|
|
41
|
+
originalAmount?: string;
|
|
42
|
+
/** Whether the payer must submit their transaction hash (txid pool mode) */
|
|
43
|
+
requiresTxid?: boolean;
|
|
44
|
+
/** Endpoint path to submit transaction hash (txid pool mode) */
|
|
45
|
+
confirmEndpoint?: string;
|
|
36
46
|
}
|
|
37
47
|
interface CreatePaymentResponse {
|
|
38
48
|
success: true;
|
|
@@ -171,15 +181,33 @@ declare class Projects {
|
|
|
171
181
|
list(): Promise<ListProjectsResponse>;
|
|
172
182
|
}
|
|
173
183
|
|
|
184
|
+
/** Supported blockchain networks. */
|
|
185
|
+
declare const SUPPORTED_CHAINS: readonly ["TRC20", "BEP20", "ERC20", "POLYGON", "ARBITRUM"];
|
|
186
|
+
/** Supported stablecoin tokens. */
|
|
187
|
+
declare const SUPPORTED_TOKENS: readonly ["USDT", "USDC"];
|
|
174
188
|
/**
|
|
175
189
|
* Verify a webhook signature from PayzCore.
|
|
176
190
|
*
|
|
177
191
|
* @param body - Raw request body string
|
|
178
192
|
* @param signature - Value of X-PayzCore-Signature header
|
|
179
193
|
* @param secret - Webhook secret from project creation (whsec_xxx)
|
|
194
|
+
* @param options - Optional timestamp validation
|
|
195
|
+
* @param options.timestamp - Value of X-PayzCore-Timestamp header
|
|
196
|
+
* @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)
|
|
180
197
|
* @returns true if signature is valid
|
|
181
198
|
*/
|
|
182
|
-
declare function verifyWebhookSignature(body: string, signature: string, secret: string
|
|
199
|
+
declare function verifyWebhookSignature(body: string, signature: string, secret: string, options?: {
|
|
200
|
+
timestamp?: string;
|
|
201
|
+
toleranceMs?: number;
|
|
202
|
+
}): boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Parse a raw webhook body into a typed WebhookPayload.
|
|
205
|
+
* Logs warnings for unknown chain/token values (forward-compatible).
|
|
206
|
+
*
|
|
207
|
+
* @param body - Raw request body string (JSON)
|
|
208
|
+
* @returns Parsed webhook payload
|
|
209
|
+
*/
|
|
210
|
+
declare function parseWebhook(body: string): WebhookPayload;
|
|
183
211
|
/**
|
|
184
212
|
* Verify signature and parse the webhook payload.
|
|
185
213
|
* Throws WebhookSignatureError if signature is invalid.
|
|
@@ -187,9 +215,15 @@ declare function verifyWebhookSignature(body: string, signature: string, secret:
|
|
|
187
215
|
* @param body - Raw request body string
|
|
188
216
|
* @param signature - Value of X-PayzCore-Signature header
|
|
189
217
|
* @param secret - Webhook secret from project creation (whsec_xxx)
|
|
218
|
+
* @param options - Optional timestamp validation
|
|
219
|
+
* @param options.timestamp - Value of X-PayzCore-Timestamp header
|
|
220
|
+
* @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)
|
|
190
221
|
* @returns Parsed and typed webhook payload
|
|
191
222
|
*/
|
|
192
|
-
declare function constructEvent(body: string, signature: string, secret: string
|
|
223
|
+
declare function constructEvent(body: string, signature: string, secret: string, options?: {
|
|
224
|
+
timestamp?: string;
|
|
225
|
+
toleranceMs?: number;
|
|
226
|
+
}): WebhookPayload;
|
|
193
227
|
|
|
194
228
|
declare class PayzCoreError extends Error {
|
|
195
229
|
readonly status: number;
|
|
@@ -228,4 +262,4 @@ declare class PayzCore {
|
|
|
228
262
|
constructor(apiKey: string, options?: PayzCoreOptions);
|
|
229
263
|
}
|
|
230
264
|
|
|
231
|
-
export { AuthenticationError, type Chain, type CreatePaymentParams, type CreatePaymentResponse, type CreateProjectParams, type CreateProjectResponse, ForbiddenError, type GetPaymentResponse, type ListPaymentsParams, type ListPaymentsResponse, type ListProjectsResponse, NotFoundError, type Payment, type PaymentDetail, type PaymentListItem, type PaymentStatus, PayzCore, PayzCoreError, type PayzCoreOptions, type Project, type ProjectListItem, RateLimitError, type Token, type Transaction, ValidationError, type WebhookEventType, type WebhookPayload, WebhookSignatureError, constructEvent, PayzCore as default, verifyWebhookSignature };
|
|
265
|
+
export { AuthenticationError, type Chain, type CreatePaymentParams, type CreatePaymentResponse, type CreateProjectParams, type CreateProjectResponse, ForbiddenError, type GetPaymentResponse, type ListPaymentsParams, type ListPaymentsResponse, type ListProjectsResponse, NotFoundError, type Payment, type PaymentDetail, type PaymentListItem, type PaymentStatus, PayzCore, PayzCoreError, type PayzCoreOptions, type Project, type ProjectListItem, RateLimitError, SUPPORTED_CHAINS, SUPPORTED_TOKENS, type Token, type Transaction, ValidationError, type WebhookEventType, type WebhookPayload, WebhookSignatureError, constructEvent, PayzCore as default, parseWebhook, verifyWebhookSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ interface CreatePaymentParams {
|
|
|
19
19
|
token?: Token;
|
|
20
20
|
externalRef: string;
|
|
21
21
|
externalOrderId?: string;
|
|
22
|
+
/** Pre-assign a specific static address for this customer (dedicated mode only) */
|
|
23
|
+
address?: string;
|
|
22
24
|
/** Expiry in seconds (300–86400). Default: 3600 */
|
|
23
25
|
expiresIn?: number;
|
|
24
26
|
metadata?: Record<string, unknown>;
|
|
@@ -33,6 +35,14 @@ interface Payment {
|
|
|
33
35
|
expiresAt: string;
|
|
34
36
|
externalOrderId?: string;
|
|
35
37
|
qrCode?: string;
|
|
38
|
+
/** Instructions for the payer (static wallet pool mode) */
|
|
39
|
+
notice?: string;
|
|
40
|
+
/** Original requested amount before micro-amount adjustment */
|
|
41
|
+
originalAmount?: string;
|
|
42
|
+
/** Whether the payer must submit their transaction hash (txid pool mode) */
|
|
43
|
+
requiresTxid?: boolean;
|
|
44
|
+
/** Endpoint path to submit transaction hash (txid pool mode) */
|
|
45
|
+
confirmEndpoint?: string;
|
|
36
46
|
}
|
|
37
47
|
interface CreatePaymentResponse {
|
|
38
48
|
success: true;
|
|
@@ -171,15 +181,33 @@ declare class Projects {
|
|
|
171
181
|
list(): Promise<ListProjectsResponse>;
|
|
172
182
|
}
|
|
173
183
|
|
|
184
|
+
/** Supported blockchain networks. */
|
|
185
|
+
declare const SUPPORTED_CHAINS: readonly ["TRC20", "BEP20", "ERC20", "POLYGON", "ARBITRUM"];
|
|
186
|
+
/** Supported stablecoin tokens. */
|
|
187
|
+
declare const SUPPORTED_TOKENS: readonly ["USDT", "USDC"];
|
|
174
188
|
/**
|
|
175
189
|
* Verify a webhook signature from PayzCore.
|
|
176
190
|
*
|
|
177
191
|
* @param body - Raw request body string
|
|
178
192
|
* @param signature - Value of X-PayzCore-Signature header
|
|
179
193
|
* @param secret - Webhook secret from project creation (whsec_xxx)
|
|
194
|
+
* @param options - Optional timestamp validation
|
|
195
|
+
* @param options.timestamp - Value of X-PayzCore-Timestamp header
|
|
196
|
+
* @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)
|
|
180
197
|
* @returns true if signature is valid
|
|
181
198
|
*/
|
|
182
|
-
declare function verifyWebhookSignature(body: string, signature: string, secret: string
|
|
199
|
+
declare function verifyWebhookSignature(body: string, signature: string, secret: string, options?: {
|
|
200
|
+
timestamp?: string;
|
|
201
|
+
toleranceMs?: number;
|
|
202
|
+
}): boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Parse a raw webhook body into a typed WebhookPayload.
|
|
205
|
+
* Logs warnings for unknown chain/token values (forward-compatible).
|
|
206
|
+
*
|
|
207
|
+
* @param body - Raw request body string (JSON)
|
|
208
|
+
* @returns Parsed webhook payload
|
|
209
|
+
*/
|
|
210
|
+
declare function parseWebhook(body: string): WebhookPayload;
|
|
183
211
|
/**
|
|
184
212
|
* Verify signature and parse the webhook payload.
|
|
185
213
|
* Throws WebhookSignatureError if signature is invalid.
|
|
@@ -187,9 +215,15 @@ declare function verifyWebhookSignature(body: string, signature: string, secret:
|
|
|
187
215
|
* @param body - Raw request body string
|
|
188
216
|
* @param signature - Value of X-PayzCore-Signature header
|
|
189
217
|
* @param secret - Webhook secret from project creation (whsec_xxx)
|
|
218
|
+
* @param options - Optional timestamp validation
|
|
219
|
+
* @param options.timestamp - Value of X-PayzCore-Timestamp header
|
|
220
|
+
* @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)
|
|
190
221
|
* @returns Parsed and typed webhook payload
|
|
191
222
|
*/
|
|
192
|
-
declare function constructEvent(body: string, signature: string, secret: string
|
|
223
|
+
declare function constructEvent(body: string, signature: string, secret: string, options?: {
|
|
224
|
+
timestamp?: string;
|
|
225
|
+
toleranceMs?: number;
|
|
226
|
+
}): WebhookPayload;
|
|
193
227
|
|
|
194
228
|
declare class PayzCoreError extends Error {
|
|
195
229
|
readonly status: number;
|
|
@@ -228,4 +262,4 @@ declare class PayzCore {
|
|
|
228
262
|
constructor(apiKey: string, options?: PayzCoreOptions);
|
|
229
263
|
}
|
|
230
264
|
|
|
231
|
-
export { AuthenticationError, type Chain, type CreatePaymentParams, type CreatePaymentResponse, type CreateProjectParams, type CreateProjectResponse, ForbiddenError, type GetPaymentResponse, type ListPaymentsParams, type ListPaymentsResponse, type ListProjectsResponse, NotFoundError, type Payment, type PaymentDetail, type PaymentListItem, type PaymentStatus, PayzCore, PayzCoreError, type PayzCoreOptions, type Project, type ProjectListItem, RateLimitError, type Token, type Transaction, ValidationError, type WebhookEventType, type WebhookPayload, WebhookSignatureError, constructEvent, PayzCore as default, verifyWebhookSignature };
|
|
265
|
+
export { AuthenticationError, type Chain, type CreatePaymentParams, type CreatePaymentResponse, type CreateProjectParams, type CreateProjectResponse, ForbiddenError, type GetPaymentResponse, type ListPaymentsParams, type ListPaymentsResponse, type ListProjectsResponse, NotFoundError, type Payment, type PaymentDetail, type PaymentListItem, type PaymentStatus, PayzCore, PayzCoreError, type PayzCoreOptions, type Project, type ProjectListItem, RateLimitError, SUPPORTED_CHAINS, SUPPORTED_TOKENS, type Token, type Transaction, ValidationError, type WebhookEventType, type WebhookPayload, WebhookSignatureError, constructEvent, PayzCore as default, parseWebhook, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -26,10 +26,13 @@ __export(index_exports, {
|
|
|
26
26
|
PayzCore: () => PayzCore,
|
|
27
27
|
PayzCoreError: () => PayzCoreError,
|
|
28
28
|
RateLimitError: () => RateLimitError,
|
|
29
|
+
SUPPORTED_CHAINS: () => SUPPORTED_CHAINS,
|
|
30
|
+
SUPPORTED_TOKENS: () => SUPPORTED_TOKENS,
|
|
29
31
|
ValidationError: () => ValidationError,
|
|
30
32
|
WebhookSignatureError: () => WebhookSignatureError,
|
|
31
33
|
constructEvent: () => constructEvent,
|
|
32
34
|
default: () => index_default,
|
|
35
|
+
parseWebhook: () => parseWebhook,
|
|
33
36
|
verifyWebhookSignature: () => verifyWebhookSignature
|
|
34
37
|
});
|
|
35
38
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -108,6 +111,7 @@ var HttpClient = class {
|
|
|
108
111
|
}
|
|
109
112
|
async request(method, path, body) {
|
|
110
113
|
const url = `${this.baseUrl}${path}`;
|
|
114
|
+
const bodyStr = body != null ? JSON.stringify(body) : "";
|
|
111
115
|
const headers = {
|
|
112
116
|
"Content-Type": "application/json",
|
|
113
117
|
"User-Agent": "@payzcore/node/1.0.0"
|
|
@@ -126,7 +130,7 @@ var HttpClient = class {
|
|
|
126
130
|
const response = await fetch(url, {
|
|
127
131
|
method,
|
|
128
132
|
headers,
|
|
129
|
-
body:
|
|
133
|
+
body: bodyStr || void 0,
|
|
130
134
|
signal: AbortSignal.timeout(this.timeout)
|
|
131
135
|
});
|
|
132
136
|
if (response.ok) {
|
|
@@ -201,7 +205,11 @@ function mapPayment(raw) {
|
|
|
201
205
|
status: raw.status,
|
|
202
206
|
expiresAt: raw.expires_at,
|
|
203
207
|
externalOrderId: raw.external_order_id,
|
|
204
|
-
qrCode: raw.qr_code
|
|
208
|
+
qrCode: raw.qr_code,
|
|
209
|
+
notice: raw.notice,
|
|
210
|
+
originalAmount: raw.original_amount,
|
|
211
|
+
requiresTxid: raw.requires_txid,
|
|
212
|
+
confirmEndpoint: raw.confirm_endpoint
|
|
205
213
|
};
|
|
206
214
|
}
|
|
207
215
|
function mapPaymentListItem(raw) {
|
|
@@ -252,6 +260,7 @@ var Payments = class {
|
|
|
252
260
|
token: params.token,
|
|
253
261
|
external_ref: params.externalRef,
|
|
254
262
|
external_order_id: params.externalOrderId,
|
|
263
|
+
address: params.address,
|
|
255
264
|
expires_in: params.expiresIn,
|
|
256
265
|
metadata: params.metadata
|
|
257
266
|
};
|
|
@@ -337,20 +346,27 @@ var Projects = class {
|
|
|
337
346
|
|
|
338
347
|
// src/webhook.ts
|
|
339
348
|
var import_crypto = require("crypto");
|
|
340
|
-
|
|
349
|
+
var SUPPORTED_CHAINS = ["TRC20", "BEP20", "ERC20", "POLYGON", "ARBITRUM"];
|
|
350
|
+
var SUPPORTED_TOKENS = ["USDT", "USDC"];
|
|
351
|
+
function verifyWebhookSignature(body, signature, secret, options) {
|
|
352
|
+
if (options?.timestamp) {
|
|
353
|
+
const ts = new Date(options.timestamp).getTime();
|
|
354
|
+
const tolerance = options.toleranceMs ?? 5 * 60 * 1e3;
|
|
355
|
+
if (isNaN(ts) || Math.abs(Date.now() - ts) > tolerance) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
341
359
|
const expected = (0, import_crypto.createHmac)("sha256", secret).update(body).digest("hex");
|
|
342
360
|
if (signature.length !== expected.length) return false;
|
|
343
361
|
return (0, import_crypto.timingSafeEqual)(Buffer.from(signature), Buffer.from(expected));
|
|
344
362
|
}
|
|
345
|
-
function
|
|
346
|
-
|
|
347
|
-
|
|
363
|
+
function parseWebhook(body) {
|
|
364
|
+
const raw = JSON.parse(body);
|
|
365
|
+
if (raw.chain && !SUPPORTED_CHAINS.includes(raw.chain)) {
|
|
366
|
+
console.warn(`[PayzCore] Unknown chain in webhook: ${raw.chain}`);
|
|
348
367
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
raw = JSON.parse(body);
|
|
352
|
-
} catch {
|
|
353
|
-
throw new WebhookSignatureError("Invalid webhook payload");
|
|
368
|
+
if (raw.token && !SUPPORTED_TOKENS.includes(raw.token)) {
|
|
369
|
+
console.warn(`[PayzCore] Unknown token in webhook: ${raw.token}`);
|
|
354
370
|
}
|
|
355
371
|
return {
|
|
356
372
|
event: raw.event,
|
|
@@ -369,6 +385,16 @@ function constructEvent(body, signature, secret) {
|
|
|
369
385
|
timestamp: raw.timestamp
|
|
370
386
|
};
|
|
371
387
|
}
|
|
388
|
+
function constructEvent(body, signature, secret, options) {
|
|
389
|
+
if (!verifyWebhookSignature(body, signature, secret, options)) {
|
|
390
|
+
throw new WebhookSignatureError();
|
|
391
|
+
}
|
|
392
|
+
try {
|
|
393
|
+
return parseWebhook(body);
|
|
394
|
+
} catch {
|
|
395
|
+
throw new WebhookSignatureError("Invalid webhook payload");
|
|
396
|
+
}
|
|
397
|
+
}
|
|
372
398
|
|
|
373
399
|
// src/index.ts
|
|
374
400
|
var PayzCore = class {
|
|
@@ -392,9 +418,12 @@ var index_default = PayzCore;
|
|
|
392
418
|
PayzCore,
|
|
393
419
|
PayzCoreError,
|
|
394
420
|
RateLimitError,
|
|
421
|
+
SUPPORTED_CHAINS,
|
|
422
|
+
SUPPORTED_TOKENS,
|
|
395
423
|
ValidationError,
|
|
396
424
|
WebhookSignatureError,
|
|
397
425
|
constructEvent,
|
|
426
|
+
parseWebhook,
|
|
398
427
|
verifyWebhookSignature
|
|
399
428
|
});
|
|
400
429
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/resources/payments.ts","../src/resources/projects.ts","../src/webhook.ts"],"sourcesContent":["import { HttpClient } from './client'\nimport { Payments } from './resources/payments'\nimport { Projects } from './resources/projects'\nimport type { PayzCoreOptions } from './types'\n\nexport class PayzCore {\n readonly payments: Payments\n readonly projects: Projects\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n if (!apiKey) {\n throw new Error('PayzCore API key is required. Pass your pk_live_xxx or mk_xxx key.')\n }\n\n const client = new HttpClient(apiKey, options)\n this.payments = new Payments(client)\n this.projects = new Projects(client)\n }\n}\n\nexport default PayzCore\n\n// Webhook utilities\nexport { verifyWebhookSignature, constructEvent } from './webhook'\n\n// Error classes\nexport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n WebhookSignatureError,\n} from './errors'\n\n// Types\nexport type {\n Chain,\n Token,\n PaymentStatus,\n WebhookEventType,\n PayzCoreOptions,\n CreatePaymentParams,\n Payment,\n CreatePaymentResponse,\n PaymentListItem,\n ListPaymentsParams,\n ListPaymentsResponse,\n Transaction,\n PaymentDetail,\n GetPaymentResponse,\n CreateProjectParams,\n Project,\n CreateProjectResponse,\n ProjectListItem,\n ListProjectsResponse,\n WebhookPayload,\n} from './types'\n","import type { ApiErrorBody } from './types'\n\nexport class PayzCoreError extends Error {\n readonly status: number\n readonly code: string\n readonly details?: Array<{ code: string; path?: string[]; message: string }>\n\n constructor(message: string, status: number, code: string, details?: ApiErrorBody['details']) {\n super(message)\n this.name = 'PayzCoreError'\n this.status = status\n this.code = code\n this.details = details\n }\n}\n\nexport class AuthenticationError extends PayzCoreError {\n constructor(message = 'Invalid or missing API key') {\n super(message, 401, 'authentication_error')\n this.name = 'AuthenticationError'\n }\n}\n\nexport class ForbiddenError extends PayzCoreError {\n constructor(message = 'Access denied') {\n super(message, 403, 'forbidden')\n this.name = 'ForbiddenError'\n }\n}\n\nexport class NotFoundError extends PayzCoreError {\n constructor(message = 'Resource not found') {\n super(message, 404, 'not_found')\n this.name = 'NotFoundError'\n }\n}\n\nexport class ValidationError extends PayzCoreError {\n constructor(\n message: string,\n details?: ApiErrorBody['details'],\n ) {\n super(message, 400, 'validation_error', details)\n this.name = 'ValidationError'\n }\n}\n\nexport class RateLimitError extends PayzCoreError {\n readonly retryAfter: number | null\n readonly isDaily: boolean\n\n constructor(message: string, retryAfter: number | null = null, isDaily = false) {\n super(message, 429, 'rate_limit_error')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n this.isDaily = isDaily\n }\n}\n\nexport class WebhookSignatureError extends Error {\n constructor(message = 'Webhook signature verification failed') {\n super(message)\n this.name = 'WebhookSignatureError'\n }\n}\n","import type { ApiErrorBody, PayzCoreOptions } from './types'\nimport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n} from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.payzcore.com'\nconst DEFAULT_TIMEOUT = 30_000\nconst DEFAULT_MAX_RETRIES = 2\nconst RETRY_BASE_MS = 200\n\nexport class HttpClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeout: number\n private readonly maxRetries: number\n private readonly useMasterKey: boolean\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n this.apiKey = apiKey\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n this.useMasterKey = options.masterKey ?? false\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': '@payzcore/node/1.0.0',\n }\n\n if (this.useMasterKey) {\n headers['x-master-key'] = this.apiKey\n } else {\n headers['x-api-key'] = this.apiKey\n }\n\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n await sleep(RETRY_BASE_MS * 2 ** (attempt - 1))\n }\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: body != null ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(this.timeout),\n })\n\n if (response.ok) {\n return (await response.json()) as T\n }\n\n // Non-retryable errors — throw immediately\n if (response.status < 500 && response.status !== 429) {\n await throwApiError(response)\n }\n\n // 429 — don't retry\n if (response.status === 429) {\n await throwApiError(response)\n }\n\n // 5xx — retry if attempts remain\n lastError = await buildApiError(response)\n } catch (err) {\n if (\n err instanceof PayzCoreError ||\n err instanceof AuthenticationError ||\n err instanceof ForbiddenError ||\n err instanceof NotFoundError ||\n err instanceof ValidationError ||\n err instanceof RateLimitError\n ) {\n throw err\n }\n\n // Network / timeout errors — retry\n lastError = err instanceof Error ? err : new Error(String(err))\n }\n }\n\n throw lastError ?? new PayzCoreError('Request failed after retries', 0, 'network_error')\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nasync function throwApiError(response: Response): Promise<never> {\n throw await buildApiError(response)\n}\n\nasync function buildApiError(response: Response): Promise<PayzCoreError> {\n let body: ApiErrorBody\n try {\n body = (await response.json()) as ApiErrorBody\n } catch {\n body = { error: response.statusText || 'Unknown error' }\n }\n\n const message = body.error ?? 'Unknown error'\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, body.details)\n case 401:\n return new AuthenticationError(message)\n case 403:\n return new ForbiddenError(message)\n case 404:\n return new NotFoundError(message)\n case 429: {\n const resetHeader = response.headers.get('X-RateLimit-Reset')\n const dailyHeader = response.headers.get('X-RateLimit-Daily')\n const retryAfter = resetHeader ? parseInt(resetHeader, 10) : null\n const isDaily = dailyHeader === 'true'\n return new RateLimitError(message, retryAfter, isDaily)\n }\n default:\n return new PayzCoreError(message, response.status, 'api_error')\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreatePaymentParams,\n CreatePaymentResponse,\n ListPaymentsParams,\n ListPaymentsResponse,\n GetPaymentResponse,\n} from '../types'\n\n// Map snake_case API response to camelCase SDK types\nfunction mapPayment(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n address: raw.address,\n amount: raw.amount,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n status: raw.status,\n expiresAt: raw.expires_at,\n externalOrderId: raw.external_order_id,\n qrCode: raw.qr_code,\n }\n}\n\nfunction mapPaymentListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n externalRef: raw.external_ref,\n externalOrderId: raw.external_order_id,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n address: raw.address,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n status: raw.status,\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n paidAt: raw.paid_at,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapPaymentDetail(raw: Record<string, unknown>) {\n const txs = raw.transactions as Array<Record<string, unknown>> | undefined\n return {\n id: raw.id,\n status: raw.status,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n address: raw.address,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n transactions: (txs ?? []).map((t) => ({\n txHash: t.tx_hash,\n amount: t.amount,\n from: t.from,\n confirmed: t.confirmed,\n })),\n }\n}\n\nexport class Payments {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreatePaymentParams): Promise<CreatePaymentResponse> {\n const body = {\n amount: params.amount,\n chain: params.chain,\n token: params.token,\n external_ref: params.externalRef,\n external_order_id: params.externalOrderId,\n expires_in: params.expiresIn,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/payments', body)\n return {\n success: true,\n existing: raw.existing as boolean,\n payment: mapPayment(raw.payment as Record<string, unknown>),\n } as CreatePaymentResponse\n }\n\n async list(params: ListPaymentsParams = {}): Promise<ListPaymentsResponse> {\n const searchParams = new URLSearchParams()\n if (params.status) searchParams.set('status', params.status)\n if (params.limit != null) searchParams.set('limit', String(params.limit))\n if (params.offset != null) searchParams.set('offset', String(params.offset))\n\n const qs = searchParams.toString()\n const path = `/api/v1/payments${qs ? `?${qs}` : ''}`\n const raw = await this.client.get<Record<string, unknown>>(path)\n const payments = raw.payments as Array<Record<string, unknown>>\n\n return {\n success: true,\n payments: payments.map(mapPaymentListItem),\n } as ListPaymentsResponse\n }\n\n async get(id: string): Promise<GetPaymentResponse> {\n const raw = await this.client.get<Record<string, unknown>>(`/api/v1/payments/${encodeURIComponent(id)}`)\n return {\n success: true,\n payment: mapPaymentDetail(raw.payment as Record<string, unknown>),\n } as GetPaymentResponse\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreateProjectParams,\n CreateProjectResponse,\n ListProjectsResponse,\n} from '../types'\n\nfunction mapProject(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookSecret: raw.webhook_secret,\n webhookUrl: raw.webhook_url,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapProjectListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookUrl: raw.webhook_url,\n isActive: raw.is_active,\n createdAt: raw.created_at,\n }\n}\n\nexport class Projects {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreateProjectParams): Promise<CreateProjectResponse> {\n const body = {\n name: params.name,\n slug: params.slug,\n webhook_url: params.webhookUrl,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/projects', body)\n return {\n success: true,\n project: mapProject(raw.project as Record<string, unknown>),\n } as CreateProjectResponse\n }\n\n async list(): Promise<ListProjectsResponse> {\n const raw = await this.client.get<Record<string, unknown>>('/api/v1/projects')\n const projects = raw.projects as Array<Record<string, unknown>>\n\n return {\n success: true,\n projects: projects.map(mapProjectListItem),\n } as ListProjectsResponse\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto'\nimport { WebhookSignatureError } from './errors'\nimport type { WebhookPayload, Chain, PaymentStatus, WebhookEventType } from './types'\n\n/**\n * Verify a webhook signature from PayzCore.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @returns true if signature is valid\n */\nexport function verifyWebhookSignature(\n body: string,\n signature: string,\n secret: string,\n): boolean {\n const expected = createHmac('sha256', secret).update(body).digest('hex')\n if (signature.length !== expected.length) return false\n return timingSafeEqual(Buffer.from(signature), Buffer.from(expected))\n}\n\n/**\n * Verify signature and parse the webhook payload.\n * Throws WebhookSignatureError if signature is invalid.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @returns Parsed and typed webhook payload\n */\nexport function constructEvent(\n body: string,\n signature: string,\n secret: string,\n): WebhookPayload {\n if (!verifyWebhookSignature(body, signature, secret)) {\n throw new WebhookSignatureError()\n }\n\n let raw: Record<string, unknown>\n try {\n raw = JSON.parse(body) as Record<string, unknown>\n } catch {\n throw new WebhookSignatureError('Invalid webhook payload')\n }\n\n return {\n event: raw.event as WebhookEventType,\n paymentId: raw.payment_id as string,\n externalRef: raw.external_ref as string,\n externalOrderId: raw.external_order_id as string | undefined,\n chain: raw.chain as Chain,\n token: (raw.token as string) ?? 'USDT',\n address: raw.address as string,\n expectedAmount: raw.expected_amount as string,\n paidAmount: raw.paid_amount as string,\n txHash: raw.tx_hash as string | null,\n status: raw.status as PaymentStatus,\n paidAt: raw.paid_at as string | null,\n metadata: (raw.metadata as Record<string, unknown>) ?? {},\n timestamp: raw.timestamp as string,\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/resources/payments.ts","../src/resources/projects.ts","../src/webhook.ts"],"sourcesContent":["import { HttpClient } from './client'\nimport { Payments } from './resources/payments'\nimport { Projects } from './resources/projects'\nimport type { PayzCoreOptions } from './types'\n\nexport class PayzCore {\n readonly payments: Payments\n readonly projects: Projects\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n if (!apiKey) {\n throw new Error('PayzCore API key is required. Pass your pk_live_xxx or mk_xxx key.')\n }\n\n const client = new HttpClient(apiKey, options)\n this.payments = new Payments(client)\n this.projects = new Projects(client)\n }\n}\n\nexport default PayzCore\n\n// Webhook utilities\nexport { verifyWebhookSignature, constructEvent, parseWebhook, SUPPORTED_CHAINS, SUPPORTED_TOKENS } from './webhook'\n\n// Error classes\nexport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n WebhookSignatureError,\n} from './errors'\n\n// Types\nexport type {\n Chain,\n Token,\n PaymentStatus,\n WebhookEventType,\n PayzCoreOptions,\n CreatePaymentParams,\n Payment,\n CreatePaymentResponse,\n PaymentListItem,\n ListPaymentsParams,\n ListPaymentsResponse,\n Transaction,\n PaymentDetail,\n GetPaymentResponse,\n CreateProjectParams,\n Project,\n CreateProjectResponse,\n ProjectListItem,\n ListProjectsResponse,\n WebhookPayload,\n} from './types'\n","import type { ApiErrorBody } from './types'\n\nexport class PayzCoreError extends Error {\n readonly status: number\n readonly code: string\n readonly details?: Array<{ code: string; path?: string[]; message: string }>\n\n constructor(message: string, status: number, code: string, details?: ApiErrorBody['details']) {\n super(message)\n this.name = 'PayzCoreError'\n this.status = status\n this.code = code\n this.details = details\n }\n}\n\nexport class AuthenticationError extends PayzCoreError {\n constructor(message = 'Invalid or missing API key') {\n super(message, 401, 'authentication_error')\n this.name = 'AuthenticationError'\n }\n}\n\nexport class ForbiddenError extends PayzCoreError {\n constructor(message = 'Access denied') {\n super(message, 403, 'forbidden')\n this.name = 'ForbiddenError'\n }\n}\n\nexport class NotFoundError extends PayzCoreError {\n constructor(message = 'Resource not found') {\n super(message, 404, 'not_found')\n this.name = 'NotFoundError'\n }\n}\n\nexport class ValidationError extends PayzCoreError {\n constructor(\n message: string,\n details?: ApiErrorBody['details'],\n ) {\n super(message, 400, 'validation_error', details)\n this.name = 'ValidationError'\n }\n}\n\nexport class RateLimitError extends PayzCoreError {\n readonly retryAfter: number | null\n readonly isDaily: boolean\n\n constructor(message: string, retryAfter: number | null = null, isDaily = false) {\n super(message, 429, 'rate_limit_error')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n this.isDaily = isDaily\n }\n}\n\nexport class WebhookSignatureError extends Error {\n constructor(message = 'Webhook signature verification failed') {\n super(message)\n this.name = 'WebhookSignatureError'\n }\n}\n","import type { ApiErrorBody, PayzCoreOptions } from './types'\nimport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n} from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.payzcore.com'\nconst DEFAULT_TIMEOUT = 30_000\nconst DEFAULT_MAX_RETRIES = 2\nconst RETRY_BASE_MS = 200\n\nexport class HttpClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeout: number\n private readonly maxRetries: number\n private readonly useMasterKey: boolean\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n this.apiKey = apiKey\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n this.useMasterKey = options.masterKey ?? false\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const bodyStr = body != null ? JSON.stringify(body) : ''\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': '@payzcore/node/1.0.0',\n }\n\n if (this.useMasterKey) {\n headers['x-master-key'] = this.apiKey\n } else {\n headers['x-api-key'] = this.apiKey\n }\n\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n await sleep(RETRY_BASE_MS * 2 ** (attempt - 1))\n }\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: bodyStr || undefined,\n signal: AbortSignal.timeout(this.timeout),\n })\n\n if (response.ok) {\n return (await response.json()) as T\n }\n\n // Non-retryable errors — throw immediately\n if (response.status < 500 && response.status !== 429) {\n await throwApiError(response)\n }\n\n // 429 — don't retry\n if (response.status === 429) {\n await throwApiError(response)\n }\n\n // 5xx — retry if attempts remain\n lastError = await buildApiError(response)\n } catch (err) {\n if (\n err instanceof PayzCoreError ||\n err instanceof AuthenticationError ||\n err instanceof ForbiddenError ||\n err instanceof NotFoundError ||\n err instanceof ValidationError ||\n err instanceof RateLimitError\n ) {\n throw err\n }\n\n // Network / timeout errors — retry\n lastError = err instanceof Error ? err : new Error(String(err))\n }\n }\n\n throw lastError ?? new PayzCoreError('Request failed after retries', 0, 'network_error')\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nasync function throwApiError(response: Response): Promise<never> {\n throw await buildApiError(response)\n}\n\nasync function buildApiError(response: Response): Promise<PayzCoreError> {\n let body: ApiErrorBody\n try {\n body = (await response.json()) as ApiErrorBody\n } catch {\n body = { error: response.statusText || 'Unknown error' }\n }\n\n const message = body.error ?? 'Unknown error'\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, body.details)\n case 401:\n return new AuthenticationError(message)\n case 403:\n return new ForbiddenError(message)\n case 404:\n return new NotFoundError(message)\n case 429: {\n const resetHeader = response.headers.get('X-RateLimit-Reset')\n const dailyHeader = response.headers.get('X-RateLimit-Daily')\n const retryAfter = resetHeader ? parseInt(resetHeader, 10) : null\n const isDaily = dailyHeader === 'true'\n return new RateLimitError(message, retryAfter, isDaily)\n }\n default:\n return new PayzCoreError(message, response.status, 'api_error')\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreatePaymentParams,\n CreatePaymentResponse,\n ListPaymentsParams,\n ListPaymentsResponse,\n GetPaymentResponse,\n} from '../types'\n\n// Map snake_case API response to camelCase SDK types\nfunction mapPayment(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n address: raw.address,\n amount: raw.amount,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n status: raw.status,\n expiresAt: raw.expires_at,\n externalOrderId: raw.external_order_id,\n qrCode: raw.qr_code,\n notice: raw.notice,\n originalAmount: raw.original_amount,\n requiresTxid: raw.requires_txid,\n confirmEndpoint: raw.confirm_endpoint,\n }\n}\n\nfunction mapPaymentListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n externalRef: raw.external_ref,\n externalOrderId: raw.external_order_id,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n address: raw.address,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n status: raw.status,\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n paidAt: raw.paid_at,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapPaymentDetail(raw: Record<string, unknown>) {\n const txs = raw.transactions as Array<Record<string, unknown>> | undefined\n return {\n id: raw.id,\n status: raw.status,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n address: raw.address,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n transactions: (txs ?? []).map((t) => ({\n txHash: t.tx_hash,\n amount: t.amount,\n from: t.from,\n confirmed: t.confirmed,\n })),\n }\n}\n\nexport class Payments {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreatePaymentParams): Promise<CreatePaymentResponse> {\n const body = {\n amount: params.amount,\n chain: params.chain,\n token: params.token,\n external_ref: params.externalRef,\n external_order_id: params.externalOrderId,\n address: params.address,\n expires_in: params.expiresIn,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/payments', body)\n return {\n success: true,\n existing: raw.existing as boolean,\n payment: mapPayment(raw.payment as Record<string, unknown>),\n } as CreatePaymentResponse\n }\n\n async list(params: ListPaymentsParams = {}): Promise<ListPaymentsResponse> {\n const searchParams = new URLSearchParams()\n if (params.status) searchParams.set('status', params.status)\n if (params.limit != null) searchParams.set('limit', String(params.limit))\n if (params.offset != null) searchParams.set('offset', String(params.offset))\n\n const qs = searchParams.toString()\n const path = `/api/v1/payments${qs ? `?${qs}` : ''}`\n const raw = await this.client.get<Record<string, unknown>>(path)\n const payments = raw.payments as Array<Record<string, unknown>>\n\n return {\n success: true,\n payments: payments.map(mapPaymentListItem),\n } as ListPaymentsResponse\n }\n\n async get(id: string): Promise<GetPaymentResponse> {\n const raw = await this.client.get<Record<string, unknown>>(`/api/v1/payments/${encodeURIComponent(id)}`)\n return {\n success: true,\n payment: mapPaymentDetail(raw.payment as Record<string, unknown>),\n } as GetPaymentResponse\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreateProjectParams,\n CreateProjectResponse,\n ListProjectsResponse,\n} from '../types'\n\nfunction mapProject(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookSecret: raw.webhook_secret,\n webhookUrl: raw.webhook_url,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapProjectListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookUrl: raw.webhook_url,\n isActive: raw.is_active,\n createdAt: raw.created_at,\n }\n}\n\nexport class Projects {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreateProjectParams): Promise<CreateProjectResponse> {\n const body = {\n name: params.name,\n slug: params.slug,\n webhook_url: params.webhookUrl,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/projects', body)\n return {\n success: true,\n project: mapProject(raw.project as Record<string, unknown>),\n } as CreateProjectResponse\n }\n\n async list(): Promise<ListProjectsResponse> {\n const raw = await this.client.get<Record<string, unknown>>('/api/v1/projects')\n const projects = raw.projects as Array<Record<string, unknown>>\n\n return {\n success: true,\n projects: projects.map(mapProjectListItem),\n } as ListProjectsResponse\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto'\nimport { WebhookSignatureError } from './errors'\nimport type { WebhookPayload, Chain, PaymentStatus, WebhookEventType } from './types'\n\n/** Supported blockchain networks. */\nexport const SUPPORTED_CHAINS = ['TRC20', 'BEP20', 'ERC20', 'POLYGON', 'ARBITRUM'] as const\n\n/** Supported stablecoin tokens. */\nexport const SUPPORTED_TOKENS = ['USDT', 'USDC'] as const\n\n/**\n * Verify a webhook signature from PayzCore.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @param options - Optional timestamp validation\n * @param options.timestamp - Value of X-PayzCore-Timestamp header\n * @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)\n * @returns true if signature is valid\n */\nexport function verifyWebhookSignature(\n body: string,\n signature: string,\n secret: string,\n options?: { timestamp?: string; toleranceMs?: number },\n): boolean {\n // Timestamp replay protection (optional but recommended)\n if (options?.timestamp) {\n const ts = new Date(options.timestamp).getTime()\n const tolerance = options.toleranceMs ?? 5 * 60 * 1000 // ±5 minutes default\n if (isNaN(ts) || Math.abs(Date.now() - ts) > tolerance) {\n return false\n }\n }\n\n const expected = createHmac('sha256', secret).update(body).digest('hex')\n if (signature.length !== expected.length) return false\n return timingSafeEqual(Buffer.from(signature), Buffer.from(expected))\n}\n\n/**\n * Parse a raw webhook body into a typed WebhookPayload.\n * Logs warnings for unknown chain/token values (forward-compatible).\n *\n * @param body - Raw request body string (JSON)\n * @returns Parsed webhook payload\n */\nexport function parseWebhook(body: string): WebhookPayload {\n const raw = JSON.parse(body) as Record<string, unknown>\n\n if (raw.chain && !(SUPPORTED_CHAINS as readonly string[]).includes(raw.chain as string)) {\n console.warn(`[PayzCore] Unknown chain in webhook: ${raw.chain}`)\n }\n if (raw.token && !(SUPPORTED_TOKENS as readonly string[]).includes(raw.token as string)) {\n console.warn(`[PayzCore] Unknown token in webhook: ${raw.token}`)\n }\n\n return {\n event: raw.event as WebhookEventType,\n paymentId: raw.payment_id as string,\n externalRef: raw.external_ref as string,\n externalOrderId: raw.external_order_id as string | undefined,\n chain: raw.chain as Chain,\n token: (raw.token as string) ?? 'USDT',\n address: raw.address as string,\n expectedAmount: raw.expected_amount as string,\n paidAmount: raw.paid_amount as string,\n txHash: raw.tx_hash as string | null,\n status: raw.status as PaymentStatus,\n paidAt: raw.paid_at as string | null,\n metadata: (raw.metadata as Record<string, unknown>) ?? {},\n timestamp: raw.timestamp as string,\n }\n}\n\n/**\n * Verify signature and parse the webhook payload.\n * Throws WebhookSignatureError if signature is invalid.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @param options - Optional timestamp validation\n * @param options.timestamp - Value of X-PayzCore-Timestamp header\n * @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)\n * @returns Parsed and typed webhook payload\n */\nexport function constructEvent(\n body: string,\n signature: string,\n secret: string,\n options?: { timestamp?: string; toleranceMs?: number },\n): WebhookPayload {\n if (!verifyWebhookSignature(body, signature, secret, options)) {\n throw new WebhookSignatureError()\n }\n\n try {\n return parseWebhook(body)\n } catch {\n throw new WebhookSignatureError('Invalid webhook payload')\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -72,6 +72,7 @@ var HttpClient = class {
|
|
|
72
72
|
}
|
|
73
73
|
async request(method, path, body) {
|
|
74
74
|
const url = `${this.baseUrl}${path}`;
|
|
75
|
+
const bodyStr = body != null ? JSON.stringify(body) : "";
|
|
75
76
|
const headers = {
|
|
76
77
|
"Content-Type": "application/json",
|
|
77
78
|
"User-Agent": "@payzcore/node/1.0.0"
|
|
@@ -90,7 +91,7 @@ var HttpClient = class {
|
|
|
90
91
|
const response = await fetch(url, {
|
|
91
92
|
method,
|
|
92
93
|
headers,
|
|
93
|
-
body:
|
|
94
|
+
body: bodyStr || void 0,
|
|
94
95
|
signal: AbortSignal.timeout(this.timeout)
|
|
95
96
|
});
|
|
96
97
|
if (response.ok) {
|
|
@@ -165,7 +166,11 @@ function mapPayment(raw) {
|
|
|
165
166
|
status: raw.status,
|
|
166
167
|
expiresAt: raw.expires_at,
|
|
167
168
|
externalOrderId: raw.external_order_id,
|
|
168
|
-
qrCode: raw.qr_code
|
|
169
|
+
qrCode: raw.qr_code,
|
|
170
|
+
notice: raw.notice,
|
|
171
|
+
originalAmount: raw.original_amount,
|
|
172
|
+
requiresTxid: raw.requires_txid,
|
|
173
|
+
confirmEndpoint: raw.confirm_endpoint
|
|
169
174
|
};
|
|
170
175
|
}
|
|
171
176
|
function mapPaymentListItem(raw) {
|
|
@@ -216,6 +221,7 @@ var Payments = class {
|
|
|
216
221
|
token: params.token,
|
|
217
222
|
external_ref: params.externalRef,
|
|
218
223
|
external_order_id: params.externalOrderId,
|
|
224
|
+
address: params.address,
|
|
219
225
|
expires_in: params.expiresIn,
|
|
220
226
|
metadata: params.metadata
|
|
221
227
|
};
|
|
@@ -301,20 +307,27 @@ var Projects = class {
|
|
|
301
307
|
|
|
302
308
|
// src/webhook.ts
|
|
303
309
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
304
|
-
|
|
310
|
+
var SUPPORTED_CHAINS = ["TRC20", "BEP20", "ERC20", "POLYGON", "ARBITRUM"];
|
|
311
|
+
var SUPPORTED_TOKENS = ["USDT", "USDC"];
|
|
312
|
+
function verifyWebhookSignature(body, signature, secret, options) {
|
|
313
|
+
if (options?.timestamp) {
|
|
314
|
+
const ts = new Date(options.timestamp).getTime();
|
|
315
|
+
const tolerance = options.toleranceMs ?? 5 * 60 * 1e3;
|
|
316
|
+
if (isNaN(ts) || Math.abs(Date.now() - ts) > tolerance) {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
305
320
|
const expected = createHmac("sha256", secret).update(body).digest("hex");
|
|
306
321
|
if (signature.length !== expected.length) return false;
|
|
307
322
|
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
|
|
308
323
|
}
|
|
309
|
-
function
|
|
310
|
-
|
|
311
|
-
|
|
324
|
+
function parseWebhook(body) {
|
|
325
|
+
const raw = JSON.parse(body);
|
|
326
|
+
if (raw.chain && !SUPPORTED_CHAINS.includes(raw.chain)) {
|
|
327
|
+
console.warn(`[PayzCore] Unknown chain in webhook: ${raw.chain}`);
|
|
312
328
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
raw = JSON.parse(body);
|
|
316
|
-
} catch {
|
|
317
|
-
throw new WebhookSignatureError("Invalid webhook payload");
|
|
329
|
+
if (raw.token && !SUPPORTED_TOKENS.includes(raw.token)) {
|
|
330
|
+
console.warn(`[PayzCore] Unknown token in webhook: ${raw.token}`);
|
|
318
331
|
}
|
|
319
332
|
return {
|
|
320
333
|
event: raw.event,
|
|
@@ -333,6 +346,16 @@ function constructEvent(body, signature, secret) {
|
|
|
333
346
|
timestamp: raw.timestamp
|
|
334
347
|
};
|
|
335
348
|
}
|
|
349
|
+
function constructEvent(body, signature, secret, options) {
|
|
350
|
+
if (!verifyWebhookSignature(body, signature, secret, options)) {
|
|
351
|
+
throw new WebhookSignatureError();
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
return parseWebhook(body);
|
|
355
|
+
} catch {
|
|
356
|
+
throw new WebhookSignatureError("Invalid webhook payload");
|
|
357
|
+
}
|
|
358
|
+
}
|
|
336
359
|
|
|
337
360
|
// src/index.ts
|
|
338
361
|
var PayzCore = class {
|
|
@@ -355,10 +378,13 @@ export {
|
|
|
355
378
|
PayzCore,
|
|
356
379
|
PayzCoreError,
|
|
357
380
|
RateLimitError,
|
|
381
|
+
SUPPORTED_CHAINS,
|
|
382
|
+
SUPPORTED_TOKENS,
|
|
358
383
|
ValidationError,
|
|
359
384
|
WebhookSignatureError,
|
|
360
385
|
constructEvent,
|
|
361
386
|
index_default as default,
|
|
387
|
+
parseWebhook,
|
|
362
388
|
verifyWebhookSignature
|
|
363
389
|
};
|
|
364
390
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/resources/payments.ts","../src/resources/projects.ts","../src/webhook.ts","../src/index.ts"],"sourcesContent":["import type { ApiErrorBody } from './types'\n\nexport class PayzCoreError extends Error {\n readonly status: number\n readonly code: string\n readonly details?: Array<{ code: string; path?: string[]; message: string }>\n\n constructor(message: string, status: number, code: string, details?: ApiErrorBody['details']) {\n super(message)\n this.name = 'PayzCoreError'\n this.status = status\n this.code = code\n this.details = details\n }\n}\n\nexport class AuthenticationError extends PayzCoreError {\n constructor(message = 'Invalid or missing API key') {\n super(message, 401, 'authentication_error')\n this.name = 'AuthenticationError'\n }\n}\n\nexport class ForbiddenError extends PayzCoreError {\n constructor(message = 'Access denied') {\n super(message, 403, 'forbidden')\n this.name = 'ForbiddenError'\n }\n}\n\nexport class NotFoundError extends PayzCoreError {\n constructor(message = 'Resource not found') {\n super(message, 404, 'not_found')\n this.name = 'NotFoundError'\n }\n}\n\nexport class ValidationError extends PayzCoreError {\n constructor(\n message: string,\n details?: ApiErrorBody['details'],\n ) {\n super(message, 400, 'validation_error', details)\n this.name = 'ValidationError'\n }\n}\n\nexport class RateLimitError extends PayzCoreError {\n readonly retryAfter: number | null\n readonly isDaily: boolean\n\n constructor(message: string, retryAfter: number | null = null, isDaily = false) {\n super(message, 429, 'rate_limit_error')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n this.isDaily = isDaily\n }\n}\n\nexport class WebhookSignatureError extends Error {\n constructor(message = 'Webhook signature verification failed') {\n super(message)\n this.name = 'WebhookSignatureError'\n }\n}\n","import type { ApiErrorBody, PayzCoreOptions } from './types'\nimport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n} from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.payzcore.com'\nconst DEFAULT_TIMEOUT = 30_000\nconst DEFAULT_MAX_RETRIES = 2\nconst RETRY_BASE_MS = 200\n\nexport class HttpClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeout: number\n private readonly maxRetries: number\n private readonly useMasterKey: boolean\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n this.apiKey = apiKey\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n this.useMasterKey = options.masterKey ?? false\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': '@payzcore/node/1.0.0',\n }\n\n if (this.useMasterKey) {\n headers['x-master-key'] = this.apiKey\n } else {\n headers['x-api-key'] = this.apiKey\n }\n\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n await sleep(RETRY_BASE_MS * 2 ** (attempt - 1))\n }\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: body != null ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(this.timeout),\n })\n\n if (response.ok) {\n return (await response.json()) as T\n }\n\n // Non-retryable errors — throw immediately\n if (response.status < 500 && response.status !== 429) {\n await throwApiError(response)\n }\n\n // 429 — don't retry\n if (response.status === 429) {\n await throwApiError(response)\n }\n\n // 5xx — retry if attempts remain\n lastError = await buildApiError(response)\n } catch (err) {\n if (\n err instanceof PayzCoreError ||\n err instanceof AuthenticationError ||\n err instanceof ForbiddenError ||\n err instanceof NotFoundError ||\n err instanceof ValidationError ||\n err instanceof RateLimitError\n ) {\n throw err\n }\n\n // Network / timeout errors — retry\n lastError = err instanceof Error ? err : new Error(String(err))\n }\n }\n\n throw lastError ?? new PayzCoreError('Request failed after retries', 0, 'network_error')\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nasync function throwApiError(response: Response): Promise<never> {\n throw await buildApiError(response)\n}\n\nasync function buildApiError(response: Response): Promise<PayzCoreError> {\n let body: ApiErrorBody\n try {\n body = (await response.json()) as ApiErrorBody\n } catch {\n body = { error: response.statusText || 'Unknown error' }\n }\n\n const message = body.error ?? 'Unknown error'\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, body.details)\n case 401:\n return new AuthenticationError(message)\n case 403:\n return new ForbiddenError(message)\n case 404:\n return new NotFoundError(message)\n case 429: {\n const resetHeader = response.headers.get('X-RateLimit-Reset')\n const dailyHeader = response.headers.get('X-RateLimit-Daily')\n const retryAfter = resetHeader ? parseInt(resetHeader, 10) : null\n const isDaily = dailyHeader === 'true'\n return new RateLimitError(message, retryAfter, isDaily)\n }\n default:\n return new PayzCoreError(message, response.status, 'api_error')\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreatePaymentParams,\n CreatePaymentResponse,\n ListPaymentsParams,\n ListPaymentsResponse,\n GetPaymentResponse,\n} from '../types'\n\n// Map snake_case API response to camelCase SDK types\nfunction mapPayment(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n address: raw.address,\n amount: raw.amount,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n status: raw.status,\n expiresAt: raw.expires_at,\n externalOrderId: raw.external_order_id,\n qrCode: raw.qr_code,\n }\n}\n\nfunction mapPaymentListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n externalRef: raw.external_ref,\n externalOrderId: raw.external_order_id,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n address: raw.address,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n status: raw.status,\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n paidAt: raw.paid_at,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapPaymentDetail(raw: Record<string, unknown>) {\n const txs = raw.transactions as Array<Record<string, unknown>> | undefined\n return {\n id: raw.id,\n status: raw.status,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n address: raw.address,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n transactions: (txs ?? []).map((t) => ({\n txHash: t.tx_hash,\n amount: t.amount,\n from: t.from,\n confirmed: t.confirmed,\n })),\n }\n}\n\nexport class Payments {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreatePaymentParams): Promise<CreatePaymentResponse> {\n const body = {\n amount: params.amount,\n chain: params.chain,\n token: params.token,\n external_ref: params.externalRef,\n external_order_id: params.externalOrderId,\n expires_in: params.expiresIn,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/payments', body)\n return {\n success: true,\n existing: raw.existing as boolean,\n payment: mapPayment(raw.payment as Record<string, unknown>),\n } as CreatePaymentResponse\n }\n\n async list(params: ListPaymentsParams = {}): Promise<ListPaymentsResponse> {\n const searchParams = new URLSearchParams()\n if (params.status) searchParams.set('status', params.status)\n if (params.limit != null) searchParams.set('limit', String(params.limit))\n if (params.offset != null) searchParams.set('offset', String(params.offset))\n\n const qs = searchParams.toString()\n const path = `/api/v1/payments${qs ? `?${qs}` : ''}`\n const raw = await this.client.get<Record<string, unknown>>(path)\n const payments = raw.payments as Array<Record<string, unknown>>\n\n return {\n success: true,\n payments: payments.map(mapPaymentListItem),\n } as ListPaymentsResponse\n }\n\n async get(id: string): Promise<GetPaymentResponse> {\n const raw = await this.client.get<Record<string, unknown>>(`/api/v1/payments/${encodeURIComponent(id)}`)\n return {\n success: true,\n payment: mapPaymentDetail(raw.payment as Record<string, unknown>),\n } as GetPaymentResponse\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreateProjectParams,\n CreateProjectResponse,\n ListProjectsResponse,\n} from '../types'\n\nfunction mapProject(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookSecret: raw.webhook_secret,\n webhookUrl: raw.webhook_url,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapProjectListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookUrl: raw.webhook_url,\n isActive: raw.is_active,\n createdAt: raw.created_at,\n }\n}\n\nexport class Projects {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreateProjectParams): Promise<CreateProjectResponse> {\n const body = {\n name: params.name,\n slug: params.slug,\n webhook_url: params.webhookUrl,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/projects', body)\n return {\n success: true,\n project: mapProject(raw.project as Record<string, unknown>),\n } as CreateProjectResponse\n }\n\n async list(): Promise<ListProjectsResponse> {\n const raw = await this.client.get<Record<string, unknown>>('/api/v1/projects')\n const projects = raw.projects as Array<Record<string, unknown>>\n\n return {\n success: true,\n projects: projects.map(mapProjectListItem),\n } as ListProjectsResponse\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto'\nimport { WebhookSignatureError } from './errors'\nimport type { WebhookPayload, Chain, PaymentStatus, WebhookEventType } from './types'\n\n/**\n * Verify a webhook signature from PayzCore.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @returns true if signature is valid\n */\nexport function verifyWebhookSignature(\n body: string,\n signature: string,\n secret: string,\n): boolean {\n const expected = createHmac('sha256', secret).update(body).digest('hex')\n if (signature.length !== expected.length) return false\n return timingSafeEqual(Buffer.from(signature), Buffer.from(expected))\n}\n\n/**\n * Verify signature and parse the webhook payload.\n * Throws WebhookSignatureError if signature is invalid.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @returns Parsed and typed webhook payload\n */\nexport function constructEvent(\n body: string,\n signature: string,\n secret: string,\n): WebhookPayload {\n if (!verifyWebhookSignature(body, signature, secret)) {\n throw new WebhookSignatureError()\n }\n\n let raw: Record<string, unknown>\n try {\n raw = JSON.parse(body) as Record<string, unknown>\n } catch {\n throw new WebhookSignatureError('Invalid webhook payload')\n }\n\n return {\n event: raw.event as WebhookEventType,\n paymentId: raw.payment_id as string,\n externalRef: raw.external_ref as string,\n externalOrderId: raw.external_order_id as string | undefined,\n chain: raw.chain as Chain,\n token: (raw.token as string) ?? 'USDT',\n address: raw.address as string,\n expectedAmount: raw.expected_amount as string,\n paidAmount: raw.paid_amount as string,\n txHash: raw.tx_hash as string | null,\n status: raw.status as PaymentStatus,\n paidAt: raw.paid_at as string | null,\n metadata: (raw.metadata as Record<string, unknown>) ?? {},\n timestamp: raw.timestamp as string,\n }\n}\n","import { HttpClient } from './client'\nimport { Payments } from './resources/payments'\nimport { Projects } from './resources/projects'\nimport type { PayzCoreOptions } from './types'\n\nexport class PayzCore {\n readonly payments: Payments\n readonly projects: Projects\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n if (!apiKey) {\n throw new Error('PayzCore API key is required. Pass your pk_live_xxx or mk_xxx key.')\n }\n\n const client = new HttpClient(apiKey, options)\n this.payments = new Payments(client)\n this.projects = new Projects(client)\n }\n}\n\nexport default PayzCore\n\n// Webhook utilities\nexport { verifyWebhookSignature, constructEvent } from './webhook'\n\n// Error classes\nexport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n WebhookSignatureError,\n} from './errors'\n\n// Types\nexport type {\n Chain,\n Token,\n PaymentStatus,\n WebhookEventType,\n PayzCoreOptions,\n CreatePaymentParams,\n Payment,\n CreatePaymentResponse,\n PaymentListItem,\n ListPaymentsParams,\n ListPaymentsResponse,\n Transaction,\n PaymentDetail,\n GetPaymentResponse,\n CreateProjectParams,\n Project,\n CreateProjectResponse,\n ProjectListItem,\n ListProjectsResponse,\n WebhookPayload,\n} from './types'\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/resources/payments.ts","../src/resources/projects.ts","../src/webhook.ts","../src/index.ts"],"sourcesContent":["import type { ApiErrorBody } from './types'\n\nexport class PayzCoreError extends Error {\n readonly status: number\n readonly code: string\n readonly details?: Array<{ code: string; path?: string[]; message: string }>\n\n constructor(message: string, status: number, code: string, details?: ApiErrorBody['details']) {\n super(message)\n this.name = 'PayzCoreError'\n this.status = status\n this.code = code\n this.details = details\n }\n}\n\nexport class AuthenticationError extends PayzCoreError {\n constructor(message = 'Invalid or missing API key') {\n super(message, 401, 'authentication_error')\n this.name = 'AuthenticationError'\n }\n}\n\nexport class ForbiddenError extends PayzCoreError {\n constructor(message = 'Access denied') {\n super(message, 403, 'forbidden')\n this.name = 'ForbiddenError'\n }\n}\n\nexport class NotFoundError extends PayzCoreError {\n constructor(message = 'Resource not found') {\n super(message, 404, 'not_found')\n this.name = 'NotFoundError'\n }\n}\n\nexport class ValidationError extends PayzCoreError {\n constructor(\n message: string,\n details?: ApiErrorBody['details'],\n ) {\n super(message, 400, 'validation_error', details)\n this.name = 'ValidationError'\n }\n}\n\nexport class RateLimitError extends PayzCoreError {\n readonly retryAfter: number | null\n readonly isDaily: boolean\n\n constructor(message: string, retryAfter: number | null = null, isDaily = false) {\n super(message, 429, 'rate_limit_error')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n this.isDaily = isDaily\n }\n}\n\nexport class WebhookSignatureError extends Error {\n constructor(message = 'Webhook signature verification failed') {\n super(message)\n this.name = 'WebhookSignatureError'\n }\n}\n","import type { ApiErrorBody, PayzCoreOptions } from './types'\nimport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n} from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.payzcore.com'\nconst DEFAULT_TIMEOUT = 30_000\nconst DEFAULT_MAX_RETRIES = 2\nconst RETRY_BASE_MS = 200\n\nexport class HttpClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly timeout: number\n private readonly maxRetries: number\n private readonly useMasterKey: boolean\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n this.apiKey = apiKey\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES\n this.useMasterKey = options.masterKey ?? false\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`\n const bodyStr = body != null ? JSON.stringify(body) : ''\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': '@payzcore/node/1.0.0',\n }\n\n if (this.useMasterKey) {\n headers['x-master-key'] = this.apiKey\n } else {\n headers['x-api-key'] = this.apiKey\n }\n\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n await sleep(RETRY_BASE_MS * 2 ** (attempt - 1))\n }\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: bodyStr || undefined,\n signal: AbortSignal.timeout(this.timeout),\n })\n\n if (response.ok) {\n return (await response.json()) as T\n }\n\n // Non-retryable errors — throw immediately\n if (response.status < 500 && response.status !== 429) {\n await throwApiError(response)\n }\n\n // 429 — don't retry\n if (response.status === 429) {\n await throwApiError(response)\n }\n\n // 5xx — retry if attempts remain\n lastError = await buildApiError(response)\n } catch (err) {\n if (\n err instanceof PayzCoreError ||\n err instanceof AuthenticationError ||\n err instanceof ForbiddenError ||\n err instanceof NotFoundError ||\n err instanceof ValidationError ||\n err instanceof RateLimitError\n ) {\n throw err\n }\n\n // Network / timeout errors — retry\n lastError = err instanceof Error ? err : new Error(String(err))\n }\n }\n\n throw lastError ?? new PayzCoreError('Request failed after retries', 0, 'network_error')\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>('GET', path)\n }\n\n post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>('POST', path, body)\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nasync function throwApiError(response: Response): Promise<never> {\n throw await buildApiError(response)\n}\n\nasync function buildApiError(response: Response): Promise<PayzCoreError> {\n let body: ApiErrorBody\n try {\n body = (await response.json()) as ApiErrorBody\n } catch {\n body = { error: response.statusText || 'Unknown error' }\n }\n\n const message = body.error ?? 'Unknown error'\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, body.details)\n case 401:\n return new AuthenticationError(message)\n case 403:\n return new ForbiddenError(message)\n case 404:\n return new NotFoundError(message)\n case 429: {\n const resetHeader = response.headers.get('X-RateLimit-Reset')\n const dailyHeader = response.headers.get('X-RateLimit-Daily')\n const retryAfter = resetHeader ? parseInt(resetHeader, 10) : null\n const isDaily = dailyHeader === 'true'\n return new RateLimitError(message, retryAfter, isDaily)\n }\n default:\n return new PayzCoreError(message, response.status, 'api_error')\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreatePaymentParams,\n CreatePaymentResponse,\n ListPaymentsParams,\n ListPaymentsResponse,\n GetPaymentResponse,\n} from '../types'\n\n// Map snake_case API response to camelCase SDK types\nfunction mapPayment(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n address: raw.address,\n amount: raw.amount,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n status: raw.status,\n expiresAt: raw.expires_at,\n externalOrderId: raw.external_order_id,\n qrCode: raw.qr_code,\n notice: raw.notice,\n originalAmount: raw.original_amount,\n requiresTxid: raw.requires_txid,\n confirmEndpoint: raw.confirm_endpoint,\n }\n}\n\nfunction mapPaymentListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n externalRef: raw.external_ref,\n externalOrderId: raw.external_order_id,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n address: raw.address,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n status: raw.status,\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n paidAt: raw.paid_at,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapPaymentDetail(raw: Record<string, unknown>) {\n const txs = raw.transactions as Array<Record<string, unknown>> | undefined\n return {\n id: raw.id,\n status: raw.status,\n expectedAmount: raw.expected_amount,\n paidAmount: raw.paid_amount,\n address: raw.address,\n chain: raw.chain,\n token: raw.token ?? 'USDT',\n txHash: raw.tx_hash,\n expiresAt: raw.expires_at,\n transactions: (txs ?? []).map((t) => ({\n txHash: t.tx_hash,\n amount: t.amount,\n from: t.from,\n confirmed: t.confirmed,\n })),\n }\n}\n\nexport class Payments {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreatePaymentParams): Promise<CreatePaymentResponse> {\n const body = {\n amount: params.amount,\n chain: params.chain,\n token: params.token,\n external_ref: params.externalRef,\n external_order_id: params.externalOrderId,\n address: params.address,\n expires_in: params.expiresIn,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/payments', body)\n return {\n success: true,\n existing: raw.existing as boolean,\n payment: mapPayment(raw.payment as Record<string, unknown>),\n } as CreatePaymentResponse\n }\n\n async list(params: ListPaymentsParams = {}): Promise<ListPaymentsResponse> {\n const searchParams = new URLSearchParams()\n if (params.status) searchParams.set('status', params.status)\n if (params.limit != null) searchParams.set('limit', String(params.limit))\n if (params.offset != null) searchParams.set('offset', String(params.offset))\n\n const qs = searchParams.toString()\n const path = `/api/v1/payments${qs ? `?${qs}` : ''}`\n const raw = await this.client.get<Record<string, unknown>>(path)\n const payments = raw.payments as Array<Record<string, unknown>>\n\n return {\n success: true,\n payments: payments.map(mapPaymentListItem),\n } as ListPaymentsResponse\n }\n\n async get(id: string): Promise<GetPaymentResponse> {\n const raw = await this.client.get<Record<string, unknown>>(`/api/v1/payments/${encodeURIComponent(id)}`)\n return {\n success: true,\n payment: mapPaymentDetail(raw.payment as Record<string, unknown>),\n } as GetPaymentResponse\n }\n}\n","import type { HttpClient } from '../client'\nimport type {\n CreateProjectParams,\n CreateProjectResponse,\n ListProjectsResponse,\n} from '../types'\n\nfunction mapProject(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookSecret: raw.webhook_secret,\n webhookUrl: raw.webhook_url,\n createdAt: raw.created_at,\n }\n}\n\nfunction mapProjectListItem(raw: Record<string, unknown>) {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n apiKey: raw.api_key,\n webhookUrl: raw.webhook_url,\n isActive: raw.is_active,\n createdAt: raw.created_at,\n }\n}\n\nexport class Projects {\n constructor(private readonly client: HttpClient) {}\n\n async create(params: CreateProjectParams): Promise<CreateProjectResponse> {\n const body = {\n name: params.name,\n slug: params.slug,\n webhook_url: params.webhookUrl,\n metadata: params.metadata,\n }\n\n const raw = await this.client.post<Record<string, unknown>>('/api/v1/projects', body)\n return {\n success: true,\n project: mapProject(raw.project as Record<string, unknown>),\n } as CreateProjectResponse\n }\n\n async list(): Promise<ListProjectsResponse> {\n const raw = await this.client.get<Record<string, unknown>>('/api/v1/projects')\n const projects = raw.projects as Array<Record<string, unknown>>\n\n return {\n success: true,\n projects: projects.map(mapProjectListItem),\n } as ListProjectsResponse\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto'\nimport { WebhookSignatureError } from './errors'\nimport type { WebhookPayload, Chain, PaymentStatus, WebhookEventType } from './types'\n\n/** Supported blockchain networks. */\nexport const SUPPORTED_CHAINS = ['TRC20', 'BEP20', 'ERC20', 'POLYGON', 'ARBITRUM'] as const\n\n/** Supported stablecoin tokens. */\nexport const SUPPORTED_TOKENS = ['USDT', 'USDC'] as const\n\n/**\n * Verify a webhook signature from PayzCore.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @param options - Optional timestamp validation\n * @param options.timestamp - Value of X-PayzCore-Timestamp header\n * @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)\n * @returns true if signature is valid\n */\nexport function verifyWebhookSignature(\n body: string,\n signature: string,\n secret: string,\n options?: { timestamp?: string; toleranceMs?: number },\n): boolean {\n // Timestamp replay protection (optional but recommended)\n if (options?.timestamp) {\n const ts = new Date(options.timestamp).getTime()\n const tolerance = options.toleranceMs ?? 5 * 60 * 1000 // ±5 minutes default\n if (isNaN(ts) || Math.abs(Date.now() - ts) > tolerance) {\n return false\n }\n }\n\n const expected = createHmac('sha256', secret).update(body).digest('hex')\n if (signature.length !== expected.length) return false\n return timingSafeEqual(Buffer.from(signature), Buffer.from(expected))\n}\n\n/**\n * Parse a raw webhook body into a typed WebhookPayload.\n * Logs warnings for unknown chain/token values (forward-compatible).\n *\n * @param body - Raw request body string (JSON)\n * @returns Parsed webhook payload\n */\nexport function parseWebhook(body: string): WebhookPayload {\n const raw = JSON.parse(body) as Record<string, unknown>\n\n if (raw.chain && !(SUPPORTED_CHAINS as readonly string[]).includes(raw.chain as string)) {\n console.warn(`[PayzCore] Unknown chain in webhook: ${raw.chain}`)\n }\n if (raw.token && !(SUPPORTED_TOKENS as readonly string[]).includes(raw.token as string)) {\n console.warn(`[PayzCore] Unknown token in webhook: ${raw.token}`)\n }\n\n return {\n event: raw.event as WebhookEventType,\n paymentId: raw.payment_id as string,\n externalRef: raw.external_ref as string,\n externalOrderId: raw.external_order_id as string | undefined,\n chain: raw.chain as Chain,\n token: (raw.token as string) ?? 'USDT',\n address: raw.address as string,\n expectedAmount: raw.expected_amount as string,\n paidAmount: raw.paid_amount as string,\n txHash: raw.tx_hash as string | null,\n status: raw.status as PaymentStatus,\n paidAt: raw.paid_at as string | null,\n metadata: (raw.metadata as Record<string, unknown>) ?? {},\n timestamp: raw.timestamp as string,\n }\n}\n\n/**\n * Verify signature and parse the webhook payload.\n * Throws WebhookSignatureError if signature is invalid.\n *\n * @param body - Raw request body string\n * @param signature - Value of X-PayzCore-Signature header\n * @param secret - Webhook secret from project creation (whsec_xxx)\n * @param options - Optional timestamp validation\n * @param options.timestamp - Value of X-PayzCore-Timestamp header\n * @param options.toleranceMs - Max age in ms (default: 300000 = 5 minutes)\n * @returns Parsed and typed webhook payload\n */\nexport function constructEvent(\n body: string,\n signature: string,\n secret: string,\n options?: { timestamp?: string; toleranceMs?: number },\n): WebhookPayload {\n if (!verifyWebhookSignature(body, signature, secret, options)) {\n throw new WebhookSignatureError()\n }\n\n try {\n return parseWebhook(body)\n } catch {\n throw new WebhookSignatureError('Invalid webhook payload')\n }\n}\n","import { HttpClient } from './client'\nimport { Payments } from './resources/payments'\nimport { Projects } from './resources/projects'\nimport type { PayzCoreOptions } from './types'\n\nexport class PayzCore {\n readonly payments: Payments\n readonly projects: Projects\n\n constructor(apiKey: string, options: PayzCoreOptions = {}) {\n if (!apiKey) {\n throw new Error('PayzCore API key is required. Pass your pk_live_xxx or mk_xxx key.')\n }\n\n const client = new HttpClient(apiKey, options)\n this.payments = new Payments(client)\n this.projects = new Projects(client)\n }\n}\n\nexport default PayzCore\n\n// Webhook utilities\nexport { verifyWebhookSignature, constructEvent, parseWebhook, SUPPORTED_CHAINS, SUPPORTED_TOKENS } from './webhook'\n\n// Error classes\nexport {\n PayzCoreError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n WebhookSignatureError,\n} from './errors'\n\n// Types\nexport type {\n Chain,\n Token,\n PaymentStatus,\n WebhookEventType,\n PayzCoreOptions,\n CreatePaymentParams,\n Payment,\n CreatePaymentResponse,\n PaymentListItem,\n ListPaymentsParams,\n ListPaymentsResponse,\n Transaction,\n PaymentDetail,\n GetPaymentResponse,\n CreateProjectParams,\n Project,\n CreateProjectResponse,\n ProjectListItem,\n ListProjectsResponse,\n WebhookPayload,\n} from './types'\n"],"mappings":"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","names":[]}
|