@kashybee/node-sdk
v1.0.0
Published
Official Kashybee Node.js SDK for voucher-based payments
Maintainers
Readme
✨ 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
# npm
npm install @kashybee/node-sdk
# yarn
yarn add @kashybee/node-sdk
# pnpm
pnpm add @kashybee/node-sdk🚀 Quick Start
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 |
// 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
// 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
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
// 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
const result = await kashybee.withdrawFunds({
email: "[email protected]",
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:
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:
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:
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:
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 existError 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:
- ✅ Generates a unique nonce for each request (prevents replay attacks)
- ✅ Creates a timestamp (prevents stale requests)
- ✅ Signs the request payload with your HMAC secret
- ✅ Includes the signature in the
x-signatureheader
⚠️ Important Security Notes
// ❌ 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
# .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 | Frontend UI widget for React, Vue, and Vanilla JS |
📄 License
MIT © Kashybee
