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

qbitflow

v1.2.0

Published

Official JavaScript/TypeScript SDK for QBitFlow - Next Generation Crypto Payment Processing

Readme

QBitFlow JavaScript/TypeScript SDK

npm version License: MPL-2.0

Official JavaScript/TypeScript SDK for QBitFlow - a comprehensive cryptocurrency payment processing platform that enables seamless integration of crypto payments and recurring subscriptions into your applications.

Features

  • 🔐 Type-Safe: Full TypeScript support with comprehensive type definitions
  • 🚀 Easy to Use: Simple, intuitive API design
  • 🔄 Automatic Retries: Built-in retry logic for failed requests
  • Real-time Updates: WebSocket support for transaction status monitoring
  • 📦 Dual Package: Works with both CommonJS and ES modules
  • 🧪 Well Tested: Comprehensive test coverage
  • 📚 Great Documentation: Detailed docs with examples
  • 🔌 Webhook Support: Handle payment notifications easily
  • 💳 One-Time Payments: Accept cryptocurrency payments with ease
  • 🔄 Recurring Subscriptions: Automated recurring billing in cryptocurrency
  • 👥 Customer Management: Create and manage customer profiles
  • 🛍️ Product Management: Organise your products and pricing
  • 📈 Transaction Tracking: Real-time transaction status updates
  • 💰 Refunds: Query and track refund entries
  • 📊 Accounting Export: Export payment data as JSON or CSV
  • 🔑 Account Claims: Manage user fund claim requests

Table of Contents

Installation

npm install qbitflow

Or using yarn:

yarn add qbitflow

Quick Start

1. Get Your API Key

Sign up at QBitFlow and obtain your API key from the dashboard.

2. Initialize the Client

import { QBitFlow } from 'qbitflow';

const client = new QBitFlow('your-api-key');

3. Create a One-Time Payment

const payment = await client.oneTimePayments.createSession({
	productId: 1,
	customerUUID: 'customer-uuid',
	webhookUrl: 'https://yourapp.com/webhook',
	successUrl: 'https://yourapp.com/success',
	cancelUrl: 'https://yourapp.com/cancel',
});

console.log('Payment link:', payment.link); // Send this link to your customer

4. Create a Recurring Subscription

const subscription = await client.subscriptions.createSession({
	productId: 1,
	frequency: { unit: 'months', value: 1 }, // Bill monthly
	trialPeriod: { unit: 'days', value: 7 }, // 7-day free trial (optional)
	webhookUrl: 'https://yourapp.com/webhook',
	customerUUID: 'customer-uuid',
});

console.log('Subscription link:', subscription.link);

5. Check Transaction Status

import { TransactionType, TransactionStatusValue } from 'qbitflow';

const status = await client.transactionStatus.get(
	'transaction-uuid',
	TransactionType.ONE_TIME_PAYMENT
);

if (status.status === TransactionStatusValue.COMPLETED) {
	console.log('Payment completed! Transaction hash:', status.txHash);
} else if (status.status === TransactionStatusValue.FAILED) {
	console.log('Payment failed:', status.message);
}

Configuration

| Option | Type | Default | Description | | ------------ | ------ | -------------------------- | -------------------------------------------- | | apiKey | string | (required) | Your QBitFlow API key | | baseUrl | string | https://api.qbitflow.app | API base URL | | timeout | number | 30000 | Request timeout in milliseconds | | maxRetries | number | 3 | Number of retry attempts for failed requests |

One-Time Payments

Create a Payment Session

Provide either a productId or inline product details (productName + description + price):

// Using an existing product
const payment = await client.oneTimePayments.createSession({
	productId: 1,
	customerUUID: 'customer-uuid',
	webhookUrl: 'https://yourapp.com/webhook',
	successUrl: 'https://yourapp.com/success',
	cancelUrl: 'https://yourapp.com/cancel',
});

// Or with inline product details
const payment = await client.oneTimePayments.createSession({
	productName: 'Custom Product',
	description: 'Product description',
	price: 99.99, // USD
	customerUUID: 'customer-uuid',
	webhookUrl: 'https://yourapp.com/webhook',
});

console.log(payment.uuid); // Session UUID
console.log(payment.link); // Payment link for customer

Get Payment Session

const session = await client.oneTimePayments.getSession('session-uuid');
console.log(session.productName, session.price);

Get Completed Payment

const payment = await client.oneTimePayments.get('payment-uuid');
console.log(payment.transactionHash, payment.amount);

List All Payments

const result = await client.oneTimePayments.getAll({ limit: 10 });

console.log(result.items); // Array of payments
console.log(result.hasMore()); // Whether there are more pages

if (result.hasMore()) {
	const nextPage = await client.oneTimePayments.getAll({
		limit: 10,
		cursor: result.nextCursor,
	});
}

List Combined Payments

Get all payments (one-time and subscription billings) in a single feed:

const result = await client.oneTimePayments.getAllCombined({ limit: 20 });
result.items.forEach((payment) => {
	console.log(payment.source); // "payment" or "subscription_history"
	console.log(payment.amount, payment.amountMinUnits);
});

Get Customer for a Transaction

const customer = await client.oneTimePayments.getCustomerForTransaction('transaction-uuid');
console.log(customer.email);

Subscriptions

Create a Subscription

const subscription = await client.subscriptions.createSession({
	productId: 1,
	frequency: { unit: 'months', value: 1 }, // Bill monthly
	trialPeriod: { unit: 'days', value: 7 }, // 7-day trial (optional)
	minPeriods: 3, // Minimum commitment periods (optional)
	webhookUrl: 'https://yourapp.com/webhook',
	customerUUID: 'customer-uuid',
});

console.log(subscription.link);

Frequency Units

Available units for frequency and trialPeriod:

seconds · minutes · hours · days · weeks · months

Get Subscription Session

const session = await client.subscriptions.getSession('session-uuid');
// Returns SubscriptionSession — frequency and trialPeriod are in raw seconds
console.log(session.frequency, session.trialPeriod);

Get Subscription

const sub = await client.subscriptions.get('subscription-uuid');
console.log(sub.subscriptionStatus, sub.nextBillingDate);

Get Subscription Payment History

const history = await client.subscriptions.getPaymentHistory('subscription-uuid');
history.forEach((record) => {
	console.log(record.uuid, record.amount, record.createdAt);
});

Force-Cancel a Subscription

Bypasses the normal subscriber-signed cancellation flow (admin use only):

const result = await client.subscriptions.forceCancel('subscription-uuid');
console.log(result.message);

Execute Test Billing Cycle

Test mode only — manually trigger a billing cycle to validate your webhook handling:

const result = await client.subscriptions.executeTestBilling('subscription-uuid');
console.log('Status link:', result.statusLink);

Transaction Status

Check Status

import { TransactionType } from 'qbitflow';

const status = await client.transactionStatus.get(
	'transaction-uuid',
	TransactionType.ONE_TIME_PAYMENT
);

console.log(status.status); // "created", "pending", "completed", etc.
console.log(status.txHash); // On-chain transaction hash

Transaction Types

enum TransactionType {
	ONE_TIME_PAYMENT = 'payment',
	CREATE_SUBSCRIPTION = 'createSubscription',
	CANCEL_SUBSCRIPTION = 'cancelSubscription',
	EXECUTE_SUBSCRIPTION_PAYMENT = 'executeSubscription',
	INCREASE_ALLOWANCE = 'increaseAllowance',
}

Status Values

enum TransactionStatusValue {
	CREATED = 'created',
	WAITING_CONFIRMATION = 'waitingConfirmation',
	PENDING = 'pending',
	COMPLETED = 'completed',
	FAILED = 'failed',
	CANCELLED = 'cancelled',
	EXPIRED = 'expired',
}

Refunds

Get Refund by Transaction UUID

Public endpoint — no authentication required:

const refund = await client.refunds.getByTransaction('transaction-uuid');
console.log(refund.status, refund.reason);

List Active Refunds

const refunds = await client.refunds.getAll();
refunds.forEach((r) => console.log(r.uuid, r.status, r.amountMinUnits));

List Inactive (Resolved) Refunds

const result = await client.refunds.getAllInactive({ limit: 20 });
result.items.forEach((r) => console.log(r.uuid, r.respondedAt));

if (result.hasMore()) {
	const next = await client.refunds.getAllInactive({ cursor: result.nextCursor });
}

Refund Statuses

enum RefundStatus {
	PENDING = 'pending',
	APPROVED = 'approved',
	REFUSED = 'refused',
	FAILED = 'failed',
}

Accounting Export

Export transaction data for reconciliation and bookkeeping.

// JSON export — returns AccountingEvent[]
const events = await client.accounting.export('2024-01-01', '2024-12-31', 'json') as AccountingEvent[];
events.forEach((e) => {
	console.log(e.paymentId, e.type, e.netAmountUsd);
});

// CSV export — returns a raw CSV string
import fs from 'fs';
const csv = await client.accounting.export('2024-01-01', '2024-12-31', 'csv') as string;
fs.writeFileSync('transactions.csv', csv);

Each AccountingEvent includes: transaction identifiers, product info, on-chain details (chain, block, tx hash, addresses), token info, gross/net amounts, platform and organization fees, and network fees for refunds.

Claims

Claims enable organizations to transfer accumulated earnings to users who have claimed their account.

Get Pending Claim Obligations

const funds = await client.claims.getFunds();
funds.forEach((f) => {
	console.log(`User ${f.userId} is owed $${f.totalAmountOwed}`);
});

Create a Claim Request for a User

Generate a one-time link that lets the user set up their password and wallet (admin only):

const { link } = await client.claims.createRequest(userId);
// Send `link` to the user via email
console.log('Claim link:', link);

Get an Existing Claim Request for a User

Check whether a claim request already exists for a given user and retrieve the link:

const { link } = await client.claims.getRequestByUser(userId);
console.log('Existing claim link:', link);

Trigger Test Claim Fund Computation

Test mode only — manually compute ledger totals for a user without waiting for the hourly job:

await client.claims.triggerTestClaimFunds(userId);

Customer Management

Create a Customer

const customer = await client.customers.create({
	name: 'John',
	lastName: 'Doe',
	email: '[email protected]',
	phoneNumber: '+1234567890',
	reference: 'CRM-12345',
});
console.log('Customer created:', customer.uuid);

Get Customer

const customer = await client.customers.get('customer-uuid');
const byEmail = await client.customers.getByEmail('[email protected]');

List Customers

const result = await client.customers.getAll({ limit: 10 });
if (result.hasMore()) {
	const next = await client.customers.getAll({ limit: 10, cursor: result.nextCursor });
}

Update Customer

const updated = await client.customers.update('customer-uuid', {
	name: 'John',
	lastName: 'Doe',
	email: '[email protected]',
	phoneNumber: '+9876543210',
});

Delete Customer

const response = await client.customers.delete('customer-uuid');
console.log(response.message);

Product Management

Create a Product

const product = await client.products.create({
	name: 'Premium Subscription',
	description: 'Access to all premium features',
	price: 29.99,
	reference: 'PROD-PREMIUM',
});

Get, List, Update, Delete

const product = await client.products.get(1);
const byRef = await client.products.getByReference('PROD-PREMIUM');
const all = await client.products.getAll();

const updated = await client.products.update(1, {
	name: 'Premium Plus',
	description: 'Enhanced features',
	price: 39.99,
});

await client.products.delete(1);

User Management

Create a User

// Create (admin only)
const user = await client.users.create({
	name: 'Alice',
	lastName: 'Smith',
	email: '[email protected]',
	role: 'user',             // 'user' or 'admin'
	organizationFeeBps: 100,  // optional, 1% fee
});

Get, List, Update, Delete

// Get current user (identified by API key)
const me = await client.users.get();

// Get by ID / list all (admin only)
const byId = await client.users.getById(42);
const all = await client.users.getAll();

// Update
const updated = await client.users.update(user.id, {
	name: 'Alicia',
	lastName: 'Smith',
	email: user.email,
});

// Delete (admin only)
await client.users.delete(user.id);

API Key Management

Create an API Key

const resp = await client.apiKeys.create({
	name: 'Production Key',
	userId: userId,
	test: false,
});
console.log('Key (only shown once):', resp.key);

List and Delete

// List API keys for the current user
const keys = await client.apiKeys.getAll();

// List API keys for a specific user (admin only)
const forUser = await client.apiKeys.getForUser(userId);

// Delete
await client.apiKeys.delete(keyId);

Webhook Handling

Express.js Example

import express from 'express';
import {
	QBitFlow,
	SessionWebhookResponse,
	TransactionStatusValue,
	OneTimePaymentSession,
	SubscriptionSession,
} from 'qbitflow';

const app = express();
const qbitflowClient = new QBitFlow('your-api-key');

app.use(express.json());

app.post('/webhook', async (req, res) => {
	const signature = req.headers[qbitflowClient.webhooks.signatureHeader.toLowerCase()] as string;
	const timestamp = req.headers[qbitflowClient.webhooks.timestampHeader.toLowerCase()] as string;

	if (!signature || !timestamp) {
		res.status(400).json({ error: 'Missing required headers' });
		return;
	}

	if (!(await qbitflowClient.webhooks.verify(req.body, signature, timestamp))) {
		res.status(401).json({ error: 'Invalid signature' });
		return;
	}

	const event = req.body as SessionWebhookResponse;
	// event.session is typed as SessionCheckout (OneTimePaymentSession | SubscriptionSession | PaygSubscriptionSession)
	const session = event.session as OneTimePaymentSession | SubscriptionSession;

	if (event.status.status === TransactionStatusValue.COMPLETED) {
		console.log('Payment completed for product:', session.productName);
	} else if (event.status.status === TransactionStatusValue.FAILED) {
		// Handle failed payment
	}

	res.status(200).json({ received: true });
});

Error Handling

import {
	NotFoundException,
	UnauthorizedException,
	ForbiddenException,
	ValidationException,
	RateLimitException,
	NetworkException,
	QBitFlowError,
} from 'qbitflow';

try {
	const payment = await client.oneTimePayments.get('invalid-uuid');
} catch (error) {
	if (error instanceof NotFoundException) {
		console.error('Not found');
	} else if (error instanceof UnauthorizedException) {
		console.error('Invalid API key');
	} else if (error instanceof ForbiddenException) {
		console.error('Insufficient permissions');
	} else if (error instanceof ValidationException) {
		console.error('Validation error:', error.message);
	} else if (error instanceof RateLimitException) {
		console.error('Rate limit exceeded');
	} else if (error instanceof NetworkException) {
		console.error('Network error:', error.message);
	} else if (error instanceof QBitFlowError) {
		console.error('QBitFlow error:', error.message);
	}
}

API Reference

QBitFlow

Main client class.

Constructor

new QBitFlow(apiKey: string)
new QBitFlow(config: QBitFlowConfig)

Properties

| Property | Type | Description | | ------------------- | ---------------------------- | ---------------------------------------- | | customers | CustomerRequests | Customer CRUD operations | | products | ProductRequests | Product CRUD operations | | users | UserRequests | User management | | apiKeys | ApiKeyRequests | API key management | | webhooks | WebhookRequests | Webhook signature verification | | oneTimePayments | PaymentRequests | One-time payment sessions and history | | subscriptions | SubscriptionRequests | Subscription sessions and management | | transactionStatus | TransactionStatusRequests | Transaction status polling and WebSocket | | refunds | RefundRequests | Refund query operations | | accounting | AccountingRequests | Accounting data export (JSON / CSV) | | claims | ClaimRequests | Fund claim request management |

License

This project is licensed under the MPL-2.0 License - see the LICENSE file for details.

Support

Changelog

See CHANGELOG.md for version history.

Security

For security issues, please email [email protected] instead of using the issue tracker.