blaaiz-nodejs-sdk 1.1.2 → 1.2.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 +10 -3
- package/index.d.ts +3 -2
- package/package.json +1 -1
- package/src/services/WebhookService.js +7 -4
package/README.md
CHANGED
|
@@ -286,12 +286,17 @@ const payout = await blaaiz.payouts.initiate({
|
|
|
286
286
|
to_currency_id: "NGN",
|
|
287
287
|
bank_id: "bank-id", // Required for NGN
|
|
288
288
|
account_number: "0123456789",
|
|
289
|
-
phone_number: "+2348012345678" // Optional
|
|
289
|
+
phone_number: "+2348012345678", // Optional
|
|
290
|
+
note: "Acme Ltd" // Optional — appears in the transaction description; defaults to business name
|
|
290
291
|
});
|
|
291
292
|
|
|
292
293
|
console.log('Payout Status:', payout.data.transaction.status);
|
|
293
294
|
```
|
|
294
295
|
|
|
296
|
+
#### Passing additional fields
|
|
297
|
+
|
|
298
|
+
`payouts.initiate()` forwards the entire payload verbatim to the API, so any field documented in the [Blaaiz API reference](https://docs.business.blaaiz.com) can be included even if it isn't listed in this README. For example, `note` sets the transaction description (defaulting to the business name when omitted). This means the SDK stays compatible with new API fields without requiring an update here.
|
|
299
|
+
|
|
295
300
|
#### Bank Transfer Payout (GBP)
|
|
296
301
|
|
|
297
302
|
```javascript
|
|
@@ -691,6 +696,8 @@ The Blaaiz API has a rate limit of 100 requests per minute. The SDK automaticall
|
|
|
691
696
|
|
|
692
697
|
The SDK provides built-in webhook signature verification to ensure webhook authenticity. The signature is computed using HMAC-SHA256 with the format `timestamp.payload`.
|
|
693
698
|
|
|
699
|
+
> **Important:** `payload` must be the **raw request body string** exactly as received. Do not pass a parsed object — parsing and re-serializing (e.g. `JSON.stringify`) changes the bytes and will break signature verification. Capture the raw body with `express.raw({ type: 'application/json' })` and pass `req.body.toString()` (see the Express example below).
|
|
700
|
+
|
|
694
701
|
```javascript
|
|
695
702
|
const { Blaaiz } = require('blaaiz-nodejs-sdk');
|
|
696
703
|
|
|
@@ -698,7 +705,7 @@ const blaaiz = new Blaaiz('your-api-key');
|
|
|
698
705
|
|
|
699
706
|
// Method 1: Verify signature manually
|
|
700
707
|
const isValid = blaaiz.webhooks.verifySignature(
|
|
701
|
-
payload, // Raw
|
|
708
|
+
payload, // Raw request body string (do not pass a parsed object)
|
|
702
709
|
signature, // Signature from webhook headers (x-blaaiz-signature)
|
|
703
710
|
timestamp, // Timestamp from webhook headers (x-blaaiz-timestamp)
|
|
704
711
|
webhookSecret // Your webhook secret key
|
|
@@ -713,7 +720,7 @@ if (isValid) {
|
|
|
713
720
|
// Method 2: Construct verified event (recommended)
|
|
714
721
|
try {
|
|
715
722
|
const event = blaaiz.webhooks.constructEvent(
|
|
716
|
-
payload, // Raw
|
|
723
|
+
payload, // Raw request body string (do not pass a parsed object)
|
|
717
724
|
signature, // Signature from webhook headers
|
|
718
725
|
timestamp, // Timestamp from webhook headers
|
|
719
726
|
webhookSecret // Your webhook secret key
|
package/index.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export interface PayoutData {
|
|
|
139
139
|
wallet_address?: string;
|
|
140
140
|
wallet_network?: string;
|
|
141
141
|
wallet_token?: string;
|
|
142
|
+
note?: string;
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
export interface PayoutResponse {
|
|
@@ -347,8 +348,8 @@ export declare class WebhookService {
|
|
|
347
348
|
get(): Promise<BlaaizResponse<WebhookData>>;
|
|
348
349
|
update(webhookData: Partial<WebhookData>): Promise<BlaaizResponse<any>>;
|
|
349
350
|
replay(replayData: WebhookReplayData): Promise<BlaaizResponse<any>>;
|
|
350
|
-
verifySignature(payload: string
|
|
351
|
-
constructEvent(payload: string
|
|
351
|
+
verifySignature(payload: string, signature: string, timestamp: string, secret: string): boolean;
|
|
352
|
+
constructEvent(payload: string, signature: string, timestamp: string, secret: string): WebhookEvent;
|
|
352
353
|
}
|
|
353
354
|
|
|
354
355
|
// Main SDK Class
|
package/package.json
CHANGED
|
@@ -54,13 +54,16 @@ class WebhookService {
|
|
|
54
54
|
throw new Error('Webhook secret is required for signature verification')
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
// The payload must be the raw request body string. Parsing and
|
|
58
|
+
// re-serializing an object changes the bytes and breaks verification.
|
|
59
|
+
if (typeof payload !== 'string') {
|
|
60
|
+
throw new Error('Webhook payload must be the raw request body string. Do not pass a parsed object — parsing and re-serializing changes the bytes and breaks signature verification. Use the raw body (e.g. express.raw({ type: "application/json" }) then req.body.toString()).')
|
|
61
|
+
}
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
const payloadString = typeof payload === 'string' ? payload : JSON.stringify(payload)
|
|
63
|
+
const crypto = require('crypto')
|
|
61
64
|
|
|
62
65
|
// Create signed payload with timestamp
|
|
63
|
-
const signedPayload = `${timestamp}.${
|
|
66
|
+
const signedPayload = `${timestamp}.${payload}`
|
|
64
67
|
|
|
65
68
|
// Create HMAC signature
|
|
66
69
|
const expectedSignature = crypto
|