qbitflow
v1.2.0
Published
Official JavaScript/TypeScript SDK for QBitFlow - Next Generation Crypto Payment Processing
Maintainers
Readme
QBitFlow JavaScript/TypeScript SDK
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
- Quick Start
- Configuration
- One-Time Payments
- Subscriptions
- Transaction Status
- Refunds
- Accounting Export
- Claims
- Customer Management
- Product Management
- User Management
- API Key Management
- Webhook Handling
- Error Handling
- API Reference
- License
- Support
- Changelog
Installation
npm install qbitflowOr using yarn:
yarn add qbitflowQuick 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 customer4. 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 customerGet 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 hashTransaction 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.

