npm package: @kashybee/node-sdk
Description: Official Kashybee Node.js SDK for voucher-based payments
Author: Kashybee
Latest version: 1.0.0

<p align="center">
  <img src="https://www.kashybee.com/nav-loog.svg" alt="Kashybee Logo" width="200" />
</p>

<h1 align="center">@kashybee/node-sdk</h1>

<p align="center">
  <strong>🔐 Official Node.js SDK for the Kashybee API</strong>
</p>

<p align="center">
  Securely integrate voucher-based payments into your Node.js applications
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/@kashybee/node-sdk">
    <img src="https://img.shields.io/npm/v/@kashybee/node-sdk.svg?style=flat-square&color=00D9FF" alt="npm version" />
  </a>
  <a href="https://www.npmjs.com/package/@kashybee/node-sdk">
    <img src="https://img.shields.io/npm/dm/@kashybee/node-sdk.svg?style=flat-square&color=00D9FF" alt="npm downloads" />
  </a>
  <a href="https://opensource.org/licenses/MIT">
    <img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square" alt="License: MIT" />
  </a>
  <a href="#">
    <img src="https://img.shields.io/badge/TypeScript-Ready-blue.svg?style=flat-square" alt="TypeScript" />
  </a>
</p>

<p align="center">
  <a href="#-installation">Installation</a> •
  <a href="#-quick-start">Quick Start</a> •
  <a href="#-api-reference">API Reference</a> •
  <a href="#-error-handling">Error Handling</a> •
  <a href="#-security">Security</a>
</p>

---

## ✨ Features

| Feature                     | Description                                            |
| --------------------------- | ------------------------------------------------------ |
| 🔒 **HMAC Signed Requests** | Every request is cryptographically signed for security |
| 📦 **TypeScript First**     | Full type definitions included out of the box          |
| 🚀 **Promise-Based**        | Modern async/await API design                          |
| 🧪 **Sandbox Support**      | Test in sandbox before going live                      |
| ⚡ **Lightweight**          | Minimal dependencies (axios, uuid)                     |
| 🛡️ **Secure by Design**     | Credentials never exposed to client-side               |

---

## 📦 Installation

```bash
# npm
npm install @kashybee/node-sdk

# yarn
yarn add @kashybee/node-sdk

# pnpm
pnpm add @kashybee/node-sdk
```

---

## 🚀 Quick Start

```javascript
const { KashybeeClient } = require("@kashybee/node-sdk");

// Initialize the client
const kashybee = new KashybeeClient({
  apiKey: process.env.KASHYBEE_API_KEY,
  hmacSecret: process.env.KASHYBEE_HMAC_SECRET,
  isSandbox: true, // Set to false for production
});

// Add funds using a voucher
async function addFunds() {
  const result = await kashybee.addFunds({
    voucherCode: "VOUCHER-CODE-123",
    amount: 100,
    walletCurrency: "USD",
    userId: "user-123",
  });

  if (result.success) {
    console.log("✅ Funds added:", result.data);
  } else {
    console.error("❌ Error:", result.message);
  }
}

addFunds();
```

---

## ⚙️ Configuration

### Client Options

| Option       | Type      | Required | Default | Description                          |
| ------------ | --------- | :------: | ------- | ------------------------------------ |
| `apiKey`     | `string`  |    ✅    | —       | Your Kashybee API key                |
| `hmacSecret` | `string`  |    ✅    | —       | Your HMAC secret for request signing |
| `isSandbox`  | `boolean` |    ❌    | `false` | Use sandbox environment for testing  |

### Environments

| Environment    | Base URL                          | Purpose               |
| -------------- | --------------------------------- | --------------------- |
| **Sandbox**    | `https://sandbox-api.kashybee.io` | Testing & development |
| **Production** | `https://api.kashybee.io`         | Live transactions     |

```javascript
// Development
const devClient = new KashybeeClient({
  apiKey: "your-sandbox-api-key",
  hmacSecret: "your-sandbox-hmac-secret",
  isSandbox: true,
});

// Production
const prodClient = new KashybeeClient({
  apiKey: process.env.KASHYBEE_API_KEY,
  hmacSecret: process.env.KASHYBEE_HMAC_SECRET,
  isSandbox: false,
});
```

---

## 📚 API Reference

### `addFunds(params)`

Add funds to a user's wallet using a voucher code.

#### Parameters

| Parameter        | Type     | Required | Description                        |
| ---------------- | -------- | :------: | ---------------------------------- |
| `voucherCode`    | `string` |    ✅    | The voucher code to redeem         |
| `amount`         | `number` |    ✅    | Amount to add                      |
| `walletCurrency` | `string` |    ✅    | Currency code (e.g., `"USD"`)      |
| `userId`         | `string` |    ✅    | Your system's user identifier      |
| `country`        | `string` |    ❌    | User's country code (e.g., `"US"`) |

#### Response

```typescript
// Success Response
{
  success: true,
  message: "Funds added successfully",
  data: {
    depositedAmount: 100,
    currency: "USD",
    transactionId: "txn_abc123xyz",
    voucherCode: "VOUCHER-123",
    createdAt: "2026-01-22T06:00:00.000Z"
  }
}

// Error Response
{
  success: false,
  message: "Invalid voucher code",
  error: {
    message: "The voucher code has already been used",
    code: "VOUCHER_ALREADY_USED",
    statusCode: 400
  }
}
```

#### Example

```javascript
const result = await kashybee.addFunds({
  voucherCode: "ABC123XYZ",
  amount: 50,
  walletCurrency: "USD",
  userId: "user-456",
});

if (result.success) {
  console.log(
    `✅ Deposited ${result.data.depositedAmount} ${result.data.currency}`,
  );
  console.log(`📋 Transaction ID: ${result.data.transactionId}`);
} else {
  console.error(`❌ Failed: ${result.message}`);
}
```

---

### `withdrawFunds(params)`

Withdraw funds from a user's wallet to a voucher.

#### Parameters

| Parameter        | Type     | Required | Description                               |
| ---------------- | -------- | :------: | ----------------------------------------- |
| `email`          | `string` |    ✅    | User's email address for voucher delivery |
| `userId`         | `string` |    ✅    | Your system's user identifier             |
| `amount`         | `number` |    ✅    | Amount to withdraw                        |
| `walletCurrency` | `string` |    ✅    | Currency code (e.g., `"USD"`)             |
| `country`        | `string` |    ❌    | User's country code (e.g., `"US"`)        |

#### Response

```typescript
// Success Response
{
  success: true,
  message: "Withdrawal successful",
  data: {
    amountWithdrawn: 25,
    currency: "USD",
    transactionId: "txn_xyz789abc",
    voucherCode: "WITHDRAW-789",
    createdAt: "2026-01-22T06:00:00.000Z"
  }
}

// Error Response
{
  success: false,
  message: "Insufficient balance",
  error: {
    message: "User does not have enough funds",
    code: "INSUFFICIENT_BALANCE",
    statusCode: 400
  }
}
```

#### Example

```javascript
const result = await kashybee.withdrawFunds({
  email: "user@example.com",
  userId: "user-456",
  amount: 25,
  walletCurrency: "USD",
});

if (result.success) {
  console.log(
    `✅ Withdrew ${result.data.amountWithdrawn} ${result.data.currency}`,
  );
  console.log(`🎟️ Voucher Code: ${result.data.voucherCode}`);
} else {
  console.error(`❌ Failed: ${result.message}`);
}
```

---

## 🌐 Express.js Integration

Complete example of integrating the SDK with an Express.js server:

```javascript
const express = require("express");
const cors = require("cors");
const { KashybeeClient } = require("@kashybee/node-sdk");

const app = express();
app.use(cors());
app.use(express.json());

// Initialize Kashybee client
const kashybee = new KashybeeClient({
  apiKey: process.env.KASHYBEE_API_KEY,
  hmacSecret: process.env.KASHYBEE_HMAC_SECRET,
  isSandbox: process.env.NODE_ENV !== "production",
});

// Add funds endpoint
app.post("/api/kashybee/add-funds", async (req, res) => {
  const { voucherCode, amount, walletCurrency, userId, country } = req.body;

  const result = await kashybee.addFunds({
    voucherCode,
    amount,
    walletCurrency,
    userId,
    country,
  });

  if (!result.success) {
    return res.status(400).json(result);
  }

  res.json(result);
});

// Withdraw funds endpoint
app.post("/api/kashybee/withdraw-funds", async (req, res) => {
  const { email, userId, amount, walletCurrency, country } = req.body;

  const result = await kashybee.withdrawFunds({
    email,
    userId,
    amount,
    walletCurrency,
    country,
  });

  if (!result.success) {
    return res.status(400).json(result);
  }

  res.json(result);
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`🚀 Server running on port ${PORT}`);
});
```

---

## 🔷 TypeScript Support

This SDK is written in TypeScript and includes full type definitions:

```typescript
import {
  KashybeeClient,
  KashybeeClientConfig,
  AddFundsParams,
  AddFundsResponse,
  WithdrawFundsParams,
  WithdrawFundsResponse,
  SDKResult,
  SDKError,
} from "@kashybee/node-sdk";

// Typed configuration
const config: KashybeeClientConfig = {
  apiKey: "your-api-key",
  hmacSecret: "your-hmac-secret",
  isSandbox: true,
};

const kashybee = new KashybeeClient(config);

// Typed parameters
const params: AddFundsParams = {
  voucherCode: "ABC123",
  amount: 100,
  walletCurrency: "USD",
  userId: "user-123",
};

// Result is SDKResult<AddFundsResponse> = AddFundsResponse | SDKError
const result = await kashybee.addFunds(params);

// Type narrowing with success check
if (result.success) {
  // TypeScript knows result.data exists here
  console.log(result.data.transactionId);
} else {
  // TypeScript knows this is an error
  console.error(result.error?.message);
}
```

---

## ⚠️ Error Handling

The SDK returns a **union type** (`SDKResult<T>`) that can be either a success response or an error:

```typescript
type SDKResult<T> = T | SDKError;

interface SDKError {
  success: false;
  message: string;
  error?: {
    message: string;
    code?: string;
    statusCode?: number;
  };
}
```

### Best Practice: Type Narrowing

Always check the `success` property before accessing the `data`:

```javascript
const result = await kashybee.addFunds(params);

// ✅ Correct: Check success first
if (result.success) {
  console.log("Transaction ID:", result.data.transactionId);
} else {
  console.error("Error Code:", result.error?.code);
  console.error("Error Message:", result.message);
}

// ❌ Wrong: Destructuring without checking
const { data } = result; // TypeScript error: 'data' may not exist
```

### Error Codes

| Code                   | Description                           |
| ---------------------- | ------------------------------------- |
| `VOUCHER_NOT_FOUND`    | The voucher code doesn't exist        |
| `VOUCHER_ALREADY_USED` | The voucher has already been redeemed |
| `VOUCHER_EXPIRED`      | The voucher has expired               |
| `INSUFFICIENT_BALANCE` | User doesn't have enough funds        |
| `INVALID_AMOUNT`       | The amount is invalid                 |
| `UNAUTHORIZED`         | Invalid API key or signature          |

---

## 🔒 Security

All requests are signed using **HMAC-SHA256**. The SDK automatically handles:

1. ✅ Generates a unique **nonce** for each request (prevents replay attacks)
2. ✅ Creates a **timestamp** (prevents stale requests)
3. ✅ Signs the request payload with your **HMAC secret**
4. ✅ Includes the signature in the `x-signature` header

### ⚠️ Important Security Notes

```javascript
// ❌ NEVER do this - exposes credentials to client
const kashybee = new KashybeeClient({
  apiKey: "pk_live_xxx", // Exposed in client bundle!
  hmacSecret: "sk_live_xxx", // CRITICAL: Never expose!
});

// ✅ Always use environment variables on the server
const kashybee = new KashybeeClient({
  apiKey: process.env.KASHYBEE_API_KEY,
  hmacSecret: process.env.KASHYBEE_HMAC_SECRET,
});
```

### Environment Variables Setup

```bash
# .env file (never commit this!)
KASHYBEE_API_KEY=your_api_key_here
KASHYBEE_HMAC_SECRET=your_hmac_secret_here
```

---

## 📋 Requirements

- **Node.js** >= 18.0.0
- **npm** >= 8.0.0

---

## 🔗 Related Packages

| Package                                                                    | Description                                       |
| -------------------------------------------------------------------------- | ------------------------------------------------- |
| [`@kashybee/ui-widget`](https://www.npmjs.com/package/@kashybee/ui-widget) | Frontend UI widget for React, Vue, and Vanilla JS |

---

## 📄 License

MIT © [Kashybee](https://kashybee.com)

---

<p align="center">
  <strong>Built with ❤️ by the Kashybee Team</strong>
</p>

<p align="center">
  <a href="https://kashybee.com">Website</a> •
  <a href="https://kashybee.com/api-docs">Documentation</a> •
  <a href="https://github.com/kashybee">GitHub</a>
</p>