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

@qazuor/qzpay-dev

v1.1.0

Published

Development and testing utilities for QZPay billing library

Readme

@qazuor/qzpay-dev

Development utilities and mock adapters for testing and development with QZPay.

Installation

pnpm add -D @qazuor/qzpay-dev

Features

  • Mock Payment Adapter: Simulates payment provider without external dependencies
  • Memory Storage Adapter: In-memory storage for fast testing
  • Test Cards: Predefined test card numbers for various scenarios
  • Data Seeds: Pre-configured data templates for common use cases

Usage

Mock Payment Adapter

Use the mock payment adapter for testing without hitting real payment providers:

import { createMockPaymentAdapter } from '@qazuor/qzpay-dev';
import { QZPayBilling } from '@qazuor/qzpay-core';

const mockAdapter = createMockPaymentAdapter({
  // Configure mock behavior
  defaultDelay: 100, // Simulate network delay
  defaultSuccess: true // Default to successful operations
});

const billing = new QZPayBilling({
  storage: storageAdapter,
  paymentAdapter: mockAdapter
});

// Use billing normally - all operations are mocked
const customer = await billing.customers.create({
  email: '[email protected]',
  name: 'Test User'
});

Memory Storage Adapter

Fast in-memory storage for development and testing:

import { createMemoryStorageAdapter } from '@qazuor/qzpay-dev';
import { QZPayBilling } from '@qazuor/qzpay-core';

const memoryStorage = createMemoryStorageAdapter();

const billing = new QZPayBilling({
  storage: memoryStorage,
  paymentAdapter: paymentAdapter
});

// Data persists in memory for the session
// Perfect for unit tests and development

Test Cards

Predefined test card numbers for various scenarios:

import { TEST_CARDS } from '@qazuor/qzpay-dev';

// Successful payment
const successCard = TEST_CARDS.VISA_SUCCESS;
// { number: '4242424242424242', exp_month: 12, exp_year: 2030, cvc: '123' }

// Declined card
const declinedCard = TEST_CARDS.VISA_DECLINED;
// { number: '4000000000000002', exp_month: 12, exp_year: 2030, cvc: '123' }

// Insufficient funds
const insufficientCard = TEST_CARDS.VISA_INSUFFICIENT_FUNDS;
// { number: '4000000000009995', exp_month: 12, exp_year: 2030, cvc: '123' }

// 3D Secure required
const threeDSCard = TEST_CARDS.VISA_3DS_REQUIRED;
// { number: '4000002500003155', exp_month: 12, exp_year: 2030, cvc: '123' }

// Use in tests
await billing.payments.process({
  customerId: 'cus_123',
  amount: 2999,
  currency: 'USD',
  paymentMethodId: successCard.number
});

Data Seeds

Pre-configured data templates for common scenarios:

import { seeds } from '@qazuor/qzpay-dev';

// SaaS template with tiered plans
const saasData = seeds.saas();
// Returns: { plans, prices, customers, subscriptions }

// E-commerce template
const ecomData = seeds.ecommerce();
// Returns: { products, prices, customers, orders }

// API/Usage-based template
const apiData = seeds.api();
// Returns: { plans, customers, usage, limits }

// Seed your database
await Promise.all([
  ...saasData.plans.map(plan => billing.plans.create(plan)),
  ...saasData.prices.map(price => billing.prices.create(price))
]);

Mock Adapter Configuration

Custom Behavior

const mockAdapter = createMockPaymentAdapter({
  // Simulate network latency
  defaultDelay: 500,

  // Default operation result
  defaultSuccess: true,

  // Custom responses
  responses: {
    createCustomer: {
      success: true,
      delay: 200,
      data: { id: 'cus_mock_123' }
    },
    createPayment: {
      success: false,
      error: 'card_declined',
      delay: 100
    }
  }
});

Scenario Testing

import { createMockPaymentAdapter, MockScenario } from '@qazuor/qzpay-dev';

// Test successful flow
const successAdapter = createMockPaymentAdapter({
  scenario: MockScenario.SUCCESS
});

// Test failure flow
const failureAdapter = createMockPaymentAdapter({
  scenario: MockScenario.CARD_DECLINED
});

// Test 3DS flow
const threeDSAdapter = createMockPaymentAdapter({
  scenario: MockScenario.REQUIRES_3DS
});

// Test rate limiting
const rateLimitAdapter = createMockPaymentAdapter({
  scenario: MockScenario.RATE_LIMITED
});

Testing Example

import { describe, it, expect, beforeEach } from 'vitest';
import { QZPayBilling } from '@qazuor/qzpay-core';
import {
  createMockPaymentAdapter,
  createMemoryStorageAdapter,
  TEST_CARDS
} from '@qazuor/qzpay-dev';

describe('Payment Flow', () => {
  let billing: QZPayBilling;

  beforeEach(() => {
    billing = new QZPayBilling({
      storage: createMemoryStorageAdapter(),
      paymentAdapter: createMockPaymentAdapter()
    });
  });

  it('should process successful payment', async () => {
    const customer = await billing.customers.create({
      email: '[email protected]',
      name: 'Test User'
    });

    const payment = await billing.payments.process({
      customerId: customer.id,
      amount: 2999,
      currency: 'USD',
      paymentMethodId: TEST_CARDS.VISA_SUCCESS.number
    });

    expect(payment.status).toBe('succeeded');
    expect(payment.amount).toBe(2999);
  });

  it('should handle card decline', async () => {
    const customer = await billing.customers.create({
      email: '[email protected]',
      name: 'Test User'
    });

    await expect(
      billing.payments.process({
        customerId: customer.id,
        amount: 2999,
        currency: 'USD',
        paymentMethodId: TEST_CARDS.VISA_DECLINED.number
      })
    ).rejects.toThrow('card_declined');
  });
});

Available Test Cards

| Card Type | Number | Scenario | |-----------|--------|----------| | Visa Success | 4242424242424242 | Successful payment | | Visa Declined | 4000000000000002 | Card declined | | Visa Insufficient | 4000000000009995 | Insufficient funds | | Visa 3DS | 4000002500003155 | Requires 3D Secure | | Visa Expired | 4000000000000069 | Expired card | | Visa Processing Error | 4000000000000119 | Processing error | | Mastercard Success | 5555555555554444 | Successful payment | | Mastercard Declined | 5100000000000008 | Card declined | | Amex Success | 378282246310005 | Successful payment |

Data Seed Templates

SaaS Template

const saasData = seeds.saas();

// Plans: Free, Basic, Pro, Enterprise
// Prices: Monthly and annual for each plan
// Features: Different entitlements per plan
// Limits: API calls, users, storage per plan

E-commerce Template

const ecomData = seeds.ecommerce();

// Products: Digital and physical products
// Prices: Various price points and currencies
// Customers: Sample customer data
// Orders: Sample order history

API Template

const apiData = seeds.api();

// Plans: Usage-based API plans
// Customers: API consumers
// Usage: Sample API usage data
// Limits: Rate limits per plan

Mock Adapter Features

  • Deterministic: Same inputs produce same outputs
  • Fast: No network calls, instant responses
  • Configurable: Control behavior per test
  • Realistic: Simulates real provider behavior
  • Error Simulation: Test error scenarios easily

Memory Storage Features

  • Fast: In-memory operations
  • Isolated: Each instance is independent
  • Reset: Easy to clear between tests
  • Complete: Implements full storage adapter interface
  • Transactions: Supports transaction semantics

Best Practices

1. Use Memory Storage for Unit Tests

// ✅ Good - Fast and isolated
const storage = createMemoryStorageAdapter();

// ❌ Avoid - Slower and requires cleanup
const storage = createDrizzleAdapter(testDb);

2. Configure Mock Adapter Per Test

// ✅ Good - Test-specific behavior
it('handles declined card', async () => {
  const adapter = createMockPaymentAdapter({
    scenario: MockScenario.CARD_DECLINED
  });
  // ... test
});

// ❌ Avoid - Shared mock state
const adapter = createMockPaymentAdapter();
describe('tests', () => {
  // All tests share same mock
});

3. Use Seed Data for Development

// ✅ Good - Rich development data
async function seedDevelopment() {
  const data = seeds.saas();
  await populateDatabase(data);
}

// ❌ Avoid - Manual data creation
async function seedDevelopment() {
  await createPlan({ name: 'Free', ... });
  await createPlan({ name: 'Pro', ... });
  // Tedious and error-prone
}

License

MIT