npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

inventpay

v1.0.0

Published

Official JavaScript/TypeScript SDK for InventPay Payment API

Downloads

8

Readme

InventPay JavaScript/TypeScript SDK

InventPay Version License

The official JavaScript/TypeScript SDK for InventPay - Accept crypto payments, manage withdrawals, and handle real-time notifications with ease.

✨ Features

  • 💳 Accept Crypto Payments - Bitcoin, Ethereum, Litecoin, USDT (ERC20 & BEP20)
  • 🔄 Withdrawal Management - Withdraw funds to any wallet address
  • 💰 Balance Tracking - Real-time balance and limit monitoring
  • 🔔 Webhook Support - Secure payment notifications and event handling
  • 🎯 Dual Payment Modes - Fixed currency or multi-currency invoices
  • 🛡️ TypeScript Ready - Full type definitions and auto-completion
  • Lightweight - Zero dependencies, fast and reliable

🚀 Quick Start

Installation

npm install inventpay

Initialize SDK

// CommonJS
const { PaymentSDK } = require("inventpay");

// ES Modules
import { PaymentSDK } from "inventpay";

// TypeScript
import { PaymentSDK, PaymentRequest } from "inventpay";

// Initialize with your API key
const sdk = new PaymentSDK({
  apiKey: "your-api-key-here", // Get from https://inventpay.io/dashboard
  baseUrl: "https://api.inventpay.io", // Optional
  timeout: 30000, // Optional, defaults to 30 seconds
});

Test Connection

// Verify your API key and connection
const connection = await sdk.testConnection();
console.log(connection.message); // "API connection successful"

💳 Accepting Payments

Option 1: Fixed Currency Payment

Get an immediate payment address for a specific cryptocurrency.

const payment = await sdk.createPayment({
  amount: 29.99, // Amount in USD
  amountCurrency: "USD", // Base currency for amount
  currency: "USDT_BEP20", // Payment currency: BTC, ETH, LTC, USDT_ERC20, USDT_BEP20
  orderId: "order-12345",
  description: "Premium Plan Subscription",
  callbackUrl: "https://yourapp.com/webhooks/payments", // Optional
  expirationMinutes: 30, // Optional, 5-1440 minutes
});

console.log(payment.data);
// {
//   paymentId: 'cmh123...',
//   amount: 29.99,
//   currency: 'USDT_BEP20',
//   address: '0x742d35Cc...',
//   invoiceUrl: 'https://inventpay.io/invoice/cmh123...',
//   qrCode: 'usdt_bep20:0x742d35Cc...?amount=29.99',
//   expiresAt: '2024-01-01T12:00:00.000Z'
// }

Option 2: Multi-Currency Invoice

Let customers choose their preferred cryptocurrency.

const invoice = await sdk.createInvoice({
  amount: 49.99,
  amountCurrency: "USD",
  orderId: "order-67890",
  description: "E-commerce Purchase",
  expirationMinutes: 60,
});

console.log(invoice.data);
// {
//   paymentId: 'cmh456...',
//   baseAmount: 49.99,
//   baseCurrency: 'USDT',
//   conversionRates: {
//     BTC: { cryptoAmount: 0.0012, price: 41500 },
//     ETH: { cryptoAmount: 0.032, price: 3200 },
//     USDT_BEP20: { cryptoAmount: 49.99, price: 1 }
//   },
//   invoiceUrl: 'https://inventpay.io/invoice/cmh456...',
//   allowCurrencySelection: true
// }

Check Payment Status

// Public endpoint - no API key required
const status = await sdk.getPaymentStatus("cmh123...");
console.log(status);
// {
//   status: 'PENDING', // PENDING, COMPLETED, EXPIRED, FAILED
//   currentBalance: '0.5',
//   confirmations: 3
// }

💰 Managing Balances

Get All Balances

const balances = await sdk.getBalances();
console.log(balances.data);
// {
//   merchantId: 'cmf123...',
//   businessName: 'Your Business',
//   balances: {
//     BTC: { availableBalance: 0.5, totalEarned: 1.2, ... },
//     ETH: { availableBalance: 2.1, totalEarned: 5.6, ... },
//     USDT_BEP20: { availableBalance: 1500.75, totalEarned: 5000, ... }
//   }
// }

Get Specific Currency Balance

const balance = await sdk.getBalance("USDT_BEP20");
console.log(balance.data);
// {
//   currency: 'USDT_BEP20',
//   balance: {
//     availableBalance: 1500.75,
//     totalEarned: 5000,
//     totalWithdrawn: 3499.25,
//     limits: { daily: { limit: 10000, used: 1500 } }
//   }
// }

🔄 Withdraw Funds

Create Withdrawal

const withdrawal = await sdk.createWithdrawal({
  amount: 10,
  currency: "USDT_BEP20",
  destinationAddress: "0x1E3D6848dE165e64052f0F2A3dA8823A27CAc22D",
  description: "Monthly payout",
});

console.log(withdrawal.data);
// {
//   withdrawalId: 'cmh789...',
//   amount: '10',
//   currency: 'USDT_BEP20',
//   destinationAddress: '0x1E3D6848dE165e64052f0F2A3dA8823A27CAc22D',
//   status: 'PENDING',
//   feeAmount: '0.051',
//   metadata: {
//     netAmount: 9.949,
//     networkFee: 0.001,
//     serviceFee: 0.05
//   }
// }

Check Withdrawal Status

const withdrawalStatus = await sdk.getWithdrawal("cmh789...");
console.log(withdrawalStatus.data.status); // PENDING, PROCESSING, COMPLETED, FAILED

🔔 Webhook Handling

Configure Webhooks

// Set your webhook URL
await sdk.configureWebhook({
  webhookUrl: "https://yourapp.com/api/webhooks/inventpay",
});

// Test webhook delivery
const testResult = await sdk.testWebhook();
console.log(testResult.message); // "Webhook test successful"

Webhook Server Example

Here's a complete, production-ready webhook listener for handling InventPay notifications:

// merchant-webhook-listener.js
const express = require("express");
const crypto = require("crypto");
const bodyParser = require("body-parser");

const app = express();
const PORT = process.env.WEBHOOK_PORT || 3008;

// IMPORTANT: Replace with your actual webhook secret from InventPay dashboard
const WEBHOOK_SECRET =
  process.env.INVENTPAY_WEBHOOK_SECRET || "your-webhook-secret";

// Middleware to parse JSON and preserve raw body for signature verification
app.use(
  bodyParser.json({
    verify: (req, res, buf) => {
      req.rawBody = buf.toString("utf8");
    },
  })
);

// Logging middleware
app.use((req, res, next) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
  next();
});

/**
 * Verify webhook signature to ensure request is from InventPay
 */
function verifyWebhookSignature(payload, signature, secret) {
  try {
    const expectedSignature = crypto
      .createHmac("sha256", secret)
      .update(payload)
      .digest("hex");

    return crypto.timingSafeEqual(
      Buffer.from(signature),
      Buffer.from(expectedSignature)
    );
  } catch (error) {
    console.error("Signature verification error:", error.message);
    return false;
  }
}

/**
 * Process payment.created event
 */
function handlePaymentCreated(payload) {
  console.log("=== PAYMENT CREATED ===");
  console.log(`Payment ID: ${payload.paymentId}`);
  console.log(`Order ID: ${payload.orderId || "N/A"}`);
  console.log(`Amount: ${payload.baseAmount} ${payload.baseCurrency}`);
  console.log(`Currency: ${payload.currency}`);
  console.log(`Invoice URL: ${payload.invoiceUrl}`);
  console.log(`Expires At: ${payload.expiresAt}`);

  // TODO: Add your business logic here
  // - Store payment reference in your database
  // - Send invoice link to customer
  // - Reserve inventory
  // - Update order status to "awaiting_payment"

  return { success: true, message: "Payment created notification received" };
}

/**
 * Process payment.pending event
 */
function handlePaymentPending(payload) {
  console.log("=== PAYMENT PENDING ===");
  console.log(`Payment ID: ${payload.paymentId}`);
  console.log(`Amount: ${payload.amount} ${payload.currency}`);
  console.log(
    `Current Balance: ${payload.currentBalance || 0} ${payload.currency}`
  );
  console.log(`Status: ${payload.status}`);

  if (payload.currencySelected) {
    console.log(`Currency Selected: ${payload.currencySelected}`);
    console.log(`Address: ${payload.address}`);
    console.log(`Crypto Amount: ${payload.cryptoAmount}`);
  }

  // TODO: Add your business logic
  // - Update order status to "payment_pending"
  // - Show "payment received, awaiting confirmation" to user

  return { success: true, message: "Payment pending notification received" };
}

/**
 * Process payment.confirmed/completed event
 */
function handlePaymentConfirmed(payload) {
  console.log("=== PAYMENT CONFIRMED ===");
  console.log(`Payment ID: ${payload.paymentId}`);
  console.log(`Order ID: ${payload.orderId || "N/A"}`);
  console.log(`Amount: ${payload.amount} ${payload.currency}`);
  console.log(`Settlement Amount: ${payload.settlementAmount}`);
  console.log(
    `Fee: ${payload.feeAmount} (Rate: ${(payload.feeRate * 100).toFixed(2)}%)`
  );
  console.log(`Status: ${payload.status}`);
  console.log(`Timestamp: ${payload.timestamp}`);

  // TODO: Add your business logic here
  // - Update order status in your database to 'PAID'
  // - Send confirmation email to customer
  // - Trigger fulfillment process
  // - Update inventory

  return {
    success: true,
    message: "Payment confirmed and processed successfully",
  };
}

/**
 * Process payment.underpaid event
 */
function handlePaymentUnderpaid(payload) {
  console.log("=== PAYMENT UNDERPAID ===");
  console.log(`Payment ID: ${payload.paymentId}`);
  console.log(`Expected: ${payload.requiredAmount} ${payload.currency}`);
  console.log(`Received: ${payload.currentBalance} ${payload.currency}`);
  console.log(`Remaining: ${payload.remainingAmount} ${payload.currency}`);
  console.log(`Paid: ${payload.paidPercentage}%`);
  console.log(`Remaining: ${payload.remainingPercentage}%`);

  // TODO: Add your business logic
  // - Notify customer of underpayment
  // - Send reminder with remaining amount
  // - Update order status to "partially_paid"

  return { success: true, message: "Underpayment notification received" };
}

/**
 * Process payment.expired event
 */
function handlePaymentExpired(payload) {
  console.log("=== PAYMENT EXPIRED ===");
  console.log(`Payment ID: ${payload.paymentId}`);
  console.log(`Order ID: ${payload.orderId || "N/A"}`);
  console.log(`Was Underpaid: ${payload.wasUnderpaid ? "YES" : "NO"}`);
  console.log(`Final Balance: ${payload.currentBalance} ${payload.currency}`);
  console.log(`Expired At: ${payload.expiresAt}`);

  // TODO: Add your business logic
  // - Cancel order
  // - Release reserved inventory
  // - Notify customer of expiration

  return { success: true, message: "Payment expiration handled" };
}

/**
 * Process payment.failed event
 */
function handlePaymentFailed(payload) {
  console.log("=== PAYMENT FAILED ===");
  console.log(`Payment ID: ${payload.paymentId}`);
  console.log(`Order ID: ${payload.orderId || "N/A"}`);
  console.log(`Error: ${payload.error || "Unknown"}`);
  console.log(`Failure Reason: ${payload.failureReason || "Unknown"}`);
  console.log(`Status: ${payload.status}`);

  // TODO: Add your business logic
  // - Update order status to "payment_failed"
  // - Send notification to customer
  // - Release reserved inventory

  return { success: true, message: "Payment failure handled" };
}

/**
 * Process test event
 */
function handleTestEvent(payload) {
  console.log("=== TEST WEBHOOK ===");
  console.log("Test webhook received successfully!");
  console.log("Payload:", JSON.stringify(payload, null, 2));

  return { success: true, message: "Test webhook received and verified" };
}

// Main webhook endpoint
app.post("/webhook/inventpay", async (req, res) => {
  try {
    console.log("\n🔔 Webhook received from InventPay");

    // Get signature and event type from headers
    const signature = req.headers["x-webhook-signature"];
    const eventType = req.headers["x-webhook-event"];

    if (!signature) {
      console.error("❌ No signature provided");
      return res.status(401).json({
        success: false,
        error: "Missing signature",
      });
    }

    // Verify signature
    const isValid = verifyWebhookSignature(
      req.rawBody,
      signature,
      WEBHOOK_SECRET
    );

    if (!isValid) {
      console.error("❌ Invalid signature");
      return res.status(401).json({
        success: false,
        error: "Invalid signature",
      });
    }

    console.log("✅ Signature verified");

    // Get the payload (entire body is the payload)
    const payload = req.body;

    console.log(`Event Type: ${payload.event || eventType}`);
    console.log(`Timestamp: ${payload.timestamp}`);
    console.log(`Payment ID: ${payload.paymentId}`);
    console.log(`Test Mode: ${payload.test ? "YES" : "NO"}`);

    // Route to appropriate handler based on event type
    let result;
    const event = payload.event || eventType;

    switch (event) {
      case "payment.created":
        result = handlePaymentCreated(payload);
        break;
      case "payment.pending":
        result = handlePaymentPending(payload);
        break;
      case "payment.confirmed":
      case "payment.completed":
        result = handlePaymentConfirmed(payload);
        break;
      case "payment.underpaid":
        result = handlePaymentUnderpaid(payload);
        break;
      case "payment.expired":
        result = handlePaymentExpired(payload);
        break;
      case "payment.failed":
        result = handlePaymentFailed(payload);
        break;
      case "payment.test":
        result = handleTestEvent(payload);
        break;
      default:
        console.warn(`⚠️ Unknown event type: ${event}`);
        result = { success: true, message: "Event received but not processed" };
    }

    // Return 200 OK to acknowledge receipt
    res.status(200).json({
      success: true,
      message: result.message,
      received: true,
      event: event,
      paymentId: payload.paymentId,
      timestamp: new Date().toISOString(),
    });

    console.log("✅ Webhook processed successfully\n");
  } catch (error) {
    console.error("❌ Webhook processing error:", error);
    res.status(500).json({
      success: false,
      error: "Internal server error",
      message: error.message,
    });
  }
});

// Health check endpoint
app.get("/health", (req, res) => {
  res.json({
    status: "healthy",
    service: "InventPay Webhook Listener",
    timestamp: new Date().toISOString(),
    webhookSecret: WEBHOOK_SECRET ? "configured" : "missing",
  });
});

// Start server
app.listen(PORT, () => {
  console.log("🚀 InventPay Webhook Listener Started");
  console.log(`📡 Listening on port: ${PORT}`);
  console.log(`🔗 Webhook URL: http://localhost:${PORT}/webhook/inventpay`);
  console.log(`🏥 Health Check: http://localhost:${PORT}/health`);
});

Running the Webhook Listener

  1. Install dependencies:
npm install express body-parser
  1. Set environment variables:
export INVENTPAY_WEBHOOK_SECRET="your-webhook-secret-from-dashboard"
export WEBHOOK_PORT=3008
  1. Run the server:
node merchant-webhook-listener.js
  1. Configure your webhook URL in InventPay dashboard: https://yourdomain.com/webhook/inventpay

Monitor Webhook Deliveries

// Get recent webhook deliveries
const deliveries = await sdk.getWebhookDeliveries({
  page: 1,
  limit: 10,
  success: true,
});

// Get webhook statistics
const stats = await sdk.getWebhookStats(7); // Last 7 days
console.log(stats.data.summary.successRate); // "98.50%"

🛡️ Error Handling

try {
  const payment = await sdk.createPayment({
    amount: 25,
    currency: "USDT_BEP20",
  });
} catch (error) {
  if (error.statusCode === 401) {
    console.error("Invalid API key");
  } else if (error.statusCode === 400) {
    console.error("Invalid request:", error.details);
  } else if (error.statusCode === 429) {
    console.error("Rate limit exceeded");
  } else {
    console.error("Unexpected error:", error.message);
  }
}

📚 API Reference

Core Methods

| Method | Description | Endpoint | | ---------------------- | ----------------------------- | ------------------------------------- | | createPayment() | Create fixed currency payment | POST /v1/create_payment | | createInvoice() | Create multi-currency invoice | POST /v1/create_invoice | | getPaymentStatus() | Check payment status | GET /v1/invoice/{id}/status | | getBalances() | Get all currency balances | GET /v1/merchant/balance | | getBalance(currency) | Get specific currency balance | GET /v1/merchant/balance/{currency} | | createWithdrawal() | Create withdrawal | POST /v1/merchant/withdrawal/create | | getWithdrawal() | Get withdrawal status | GET /v1/withdrawal/{id} |

Webhook Methods

| Method | Description | | ------------------------ | ---------------------------- | | configureWebhook() | Set webhook URL | | getWebhookConfig() | Get webhook configuration | | testWebhook() | Test webhook endpoint | | getWebhookDeliveries() | Get delivery history | | getWebhookStats() | Get delivery statistics | | deleteWebhook() | Remove webhook configuration |

🔧 Configuration

SDK Options

const sdk = new PaymentSDK({
  apiKey: "string", // Required: Your InventPay API key
  baseUrl: "string", // Optional: API base URL (default: https://api.inventpay.io)
  timeout: 30000, // Optional: Request timeout in ms (default: 30000)
});

Supported Currencies

Payment Currencies:

  • BTC - Bitcoin
  • ETH - Ethereum
  • LTC - Litecoin
  • USDT_ERC20 - USDT on Ethereum
  • USDT_BEP20 - USDT on Binance Smart Chain
  • MULTI - Multi-currency invoice

Amount Currencies:

  • USD - US Dollars
  • USDT - Tether
  • BTC - Bitcoin
  • ETH - Ethereum
  • LTC - Litecoin

🌟 Best Practices

1. Store API Keys Securely

// Use environment variables
const sdk = new PaymentSDK({
  apiKey: process.env.INVENTPAY_API_KEY,
});

2. Handle Webhooks Properly

// Always verify webhook signatures
// Implement retry logic for failed webhooks
// Log all webhook events for debugging

3. Monitor Payment Status

// Poll for payment status if not using webhooks
// Set appropriate expiration times
// Handle partial payments and overpayments

📱 Examples

React Component Example

import React, { useState } from "react";
import { PaymentSDK } from "inventpay";

function PaymentButton({ amount, onSuccess }) {
  const [loading, setLoading] = useState(false);

  const handlePayment = async () => {
    setLoading(true);
    try {
      const sdk = new PaymentSDK({
        apiKey: process.env.REACT_APP_INVENTPAY_API_KEY,
      });

      const payment = await sdk.createPayment({
        amount,
        currency: "USDT_BEP20",
        orderId: `order-${Date.now()}`,
      });

      // Redirect to payment page
      window.location.href = payment.data.invoiceUrl;
    } catch (error) {
      console.error("Payment failed:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <button onClick={handlePayment} disabled={loading}>
      {loading ? "Processing..." : `Pay $${amount}`}
    </button>
  );
}

Node.js Express Server

const express = require("express");
const { PaymentSDK } = require("inventpay");

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

const sdk = new PaymentSDK({
  apiKey: process.env.INVENTPAY_API_KEY,
});

app.post("/api/create-payment", async (req, res) => {
  try {
    const { amount, currency } = req.body;

    const payment = await sdk.createPayment({
      amount,
      currency: currency || "USDT_BEP20",
      orderId: `order-${Date.now()}`,
      callbackUrl: `${process.env.BASE_URL}/webhooks/payments`,
    });

    res.json({ success: true, data: payment.data });
  } catch (error) {
    res.status(400).json({
      success: false,
      error: error.message,
    });
  }
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});

❓ Frequently Asked Questions

How do I get an API key?

Visit InventPay Dashboard to create an account and generate your API keys.

What's the difference between createPayment and createInvoice?

  • createPayment generates an immediate address for a specific cryptocurrency
  • createInvoice creates a multi-currency invoice where customers can choose their preferred crypto

Are webhooks required?

No, but highly recommended for real-time payment notifications. You can also poll payment status using getPaymentStatus().

How are conversion rates handled?

InventPay uses real-time market rates from multiple exchanges. Rates are locked when a payment is created.

What happens if a payment expires?

Expired payments cannot be completed. You should create a new payment and notify the customer.

📞 Support

📄 License

MIT License - see LICENSE for details.


Ready to start? Get your API key and begin accepting crypto payments in minutes! 🚀