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 🙏

© 2025 – Pkg Stats / Ryan Hefner

voltage-payments-component

v0.2.0

Published

Lightweight, framework-agnostic Bitcoin payment components for web applications using Voltage Payments

Readme

Voltage Payment Component

A lightweight, framework-agnostic Bitcoin payment component library for web applications.

🚀 Features

  • Drop-in Integration: Simple script tag or npm package installation
  • Framework Agnostic: Works with any web framework (React, Vue, Angular, vanilla JS)
  • Real-time Updates: Live payment status with configurable polling
  • Voltage API Integration: Powered by the official Voltage API SDK
  • Multiple Payment Types: Lightning (Bolt11), On-chain, BIP21 (unified), and Taproot Assets
  • Customizable UI: CSS custom properties for complete theming control
  • TypeScript Support: Full type definitions included
  • Responsive Design: Mobile-first responsive layout

📦 Installation

NPM Package

npm install voltage-payments-component

Script Tag (CDN)

<script src="https://unpkg.com/voltage-payments-component/dist/voltage-payments.umd.js"></script>

🔑 Voltage API Setup

Before using the component, you'll need:

  1. Voltage Account: Sign up at voltage.cloud
  2. API Key: Generate an API key from your Voltage dashboard
  3. Organization ID: Your organization ID from the dashboard
  4. Environment ID: Your environment ID (e.g., production, staging)
  5. Wallet ID: The ID of the wallet you want to receive payments to

🎯 Quick Start

ES Modules (Recommended)

import { VoltagePayments } from "voltage-payments-component";

const payment = VoltagePayments.create({
  // Required: Voltage API credentials
  apiKey: "your-voltage-api-key",
  organizationId: "your-org-id",
  environmentId: "your-env-id",
  walletId: "your-wallet-id",

  // Payment configuration
  amount: 100000, // 100k millisats = 100 sats (BTC)
  paymentKind: "bip21", // 'bolt11', 'onchain', 'bip21', or 'taprootasset'
  description: "Coffee purchase",

  // Optional: Custom API endpoint
  baseUrl: "https://api.voltage.com/v1", // Defaults to https://voltageapi.com/v1

  // Event handlers
  onReady: (payment) => console.log("Payment ready:", payment),
  onSuccess: (payment) => console.log("Payment completed!", payment),
  onError: (error) => console.error("Payment failed:", error),
});

// Mount to DOM element
await payment.mount("#payment-container");

Modal Payment

// Create a modal payment that opens when a button is clicked
const modalPayment = VoltagePayments.create({
  apiKey: "your-voltage-api-key",
  organizationId: "your-org-id",
  environmentId: "your-env-id",
  walletId: "your-wallet-id",
  amount: 50000,
  variant: "modal", // Creates a modal dialog
  paymentKind: "bolt11",
  description: "Lightning Payment",
  autoClose: true, // Auto-close modal on successful payment

  // Modal-specific callbacks
  onModalOpen: () => console.log("Modal opened"),
  onModalClose: () => console.log("Modal closed"),
  onSuccess: (payment) => {
    console.log("Payment completed!");
    // Modal will auto-close in 2 seconds
  },
});

// This creates a "Pay with Bitcoin" button that opens the modal
await modalPayment.mount("#modal-button-container");

Button Payment

// Create a button that reveals payment interface when clicked
const buttonPayment = VoltagePayments.create({
  apiKey: "your-voltage-api-key",
  organizationId: "your-org-id",
  environmentId: "your-env-id",
  walletId: "your-wallet-id",
  amount: 25000,
  variant: "button", // Creates a click-to-reveal button
  paymentKind: "bolt11",
  description: "Quick Payment",

  // Button-specific callbacks
  onButtonActivated: () => console.log("Payment interface revealed"),
  onSuccess: (payment) => {
    console.log("Payment completed!");
    // Interface auto-collapses after 3 seconds
  },
});

// This creates a button that reveals the payment interface when clicked
await buttonPayment.mount("#button-container");

UMD (Script Tag)

<div id="payment-container"></div>

<script>
  const payment = VoltagePayments.create({
    apiKey: "your-voltage-api-key",
    organizationId: "your-org-id",
    environmentId: "your-env-id",
    walletId: "your-wallet-id",
    amount: 50000,
    paymentKind: "bolt11",
    description: "Lightning payment",
  });

  payment.mount("#payment-container");
</script>

🎨 Customization

Appearance Options

VoltagePayments.create({
  // ... API config
  appearance: {
    primaryColor: "#f7931a", // Bitcoin orange
    backgroundColor: "#ffffff", // Component background
    borderColor: "#e5e7eb", // Border color
    borderRadius: "12px", // Border radius
    fontFamily: "Inter, sans-serif", // Font family
    textColor: "#1f2937", // Primary text color
    secondaryTextColor: "#6b7280", // Secondary text color
  },
});

Payment Types

Lightning (Bolt11)

VoltagePayments.create({
  paymentKind: "bolt11",
  amount: 100000, // Required for fixed amount
  // ... other config
});

// Amountless Lightning invoice (payer specifies amount)
VoltagePayments.create({
  paymentKind: "bolt11",
  amount: null, // Omit amount entirely for amountless invoices
  // ... other config
});

On-chain

VoltagePayments.create({
  paymentKind: "onchain",
  amount: 54600000, // Must be >= 1 msat (546 sats = dust limit recommended)
  // ... other config
});

BIP21 (Unified)

VoltagePayments.create({
  paymentKind: "bip21", // Provides both Lightning and on-chain options
  amount: 250000, // Must be >= 1 msat for on-chain compatibility
  // ... other config
});

#### Taproot Asset

```javascript
// Receive a Taproot Asset payment by specifying assetCurrency and assetAmount
VoltagePayments.create({
  paymentKind: "taprootasset",
  // VCASH group key (mutinynet); replace with your asset
  assetCurrency:
    "asset:034d8de991e76a6994753ddb4505d354873f96a1aa400a82eac1ee4fd443cfd62e",
  assetAmount: 1_000_000, // base units (1 VCASH with decimals=6)
  assetDecimals: 6, // optional, for display formatting
  assetLabel: "VCASH", // optional UI label
  // ... API and other config
});

Payment Variants

Inline Payment (Default)

VoltagePayments.create({
  variant: "inline", // Default - embeds directly in your page
  // ... other config
});

Modal Payment

VoltagePayments.create({
  variant: "modal", // Creates a modal dialog triggered by a button
  autoClose: true, // Auto-close modal on success (default: true)
  description: "Custom button text", // Used as button text
  appearance: {
    primaryColor: "#8b5cf6", // Customizes button and modal styling
  },
  onModalOpen: () => console.log("Modal opened"),
  onModalClose: () => console.log("Modal closed"),
  // ... other config
});

Button Payment

VoltagePayments.create({
  variant: "button", // Creates a button that reveals payment interface inline
  description: "Quick Payment", // Used as button text
  appearance: {
    primaryColor: "#10b981", // Customizes button styling
    borderRadius: "10px",
  },
  onButtonActivated: () => console.log("Payment interface visible"),
  onButtonDeactivated: () => console.log("Payment interface hidden"),
  onSuccess: (payment) => {
    console.log("Payment completed!");
    // Interface auto-collapses after 3 seconds
  },
  // ... other config
});

⚠️ Amount Requirements:

  • Lightning (bolt11): Use amount: null for amountless invoices (payer specifies amount), or specify amount > 0 for fixed amounts
  • On-chain: Must use amount >= 1 (recommend 546 sats = 54,600,000 msats as dust limit)
  • BIP21: Must use amount >= 1 for on-chain compatibility
  • Taproot Asset: Provide assetCurrency and assetAmount (base units). Optional assetDecimals controls display formatting (e.g., 6).

📡 Event Handling

VoltagePayments.create({
  // ... config
  onReady: (payment) => {
    // Payment request generated and ready for payment
    console.log("Payment ID:", payment.id);
    console.log("Payment Request:", payment.paymentRequest);
  },

  onQRGenerated: (qrData, paymentRequest, address) => {
    // QR code data is ready
    console.log("Scan this:", qrData);
  },

  onStatusChange: (status, payment) => {
    // Payment status updated
    console.log("New status:", status);
  },

  onSuccess: (payment) => {
    // Payment completed successfully
    showSuccessMessage("Payment received!");
    redirectToThankYouPage();
  },

  onError: (error) => {
    // Payment failed or error occurred
    console.error("Error:", error.message);
    showErrorMessage(error.message);
  },

  onExpired: (payment) => {
    // Payment request expired
    console.log("Payment expired, creating new one...");
  },
});

⚙️ Configuration Options

Polling Configuration

VoltagePayments.create({
  // ... other config
  pollingConfig: {
    maxAttempts: 100, // Maximum polling attempts
    intervalMs: 5000, // Poll every 5 seconds
    timeoutMs: 300000, // 5 minute timeout
  },
});

UI Options

VoltagePayments.create({
  // ... other config
  showQRCode: true, // Show/hide QR code (default: true)
  showCopyButton: true, // Show/hide copy button (default: true)
  theme: "auto", // 'light', 'dark', or 'auto'
});

🛠️ Development

Local Development

git clone https://github.com/voltage/voltage-payment-component
cd voltage-payment-component
npm install
npm run dev

Visit http://localhost:5175 to see the interactive demo.

Using Real API Credentials in Development

To test with real Voltage API credentials instead of mock data:

  1. Copy the environment template:

    cp .env.example .env
  2. Fill in your real Voltage API credentials in .env:

    # Your actual Voltage API credentials
    VITE_VOLTAGE_API_KEY=vltg_your_actual_api_key_here
    VITE_VOLTAGE_ORGANIZATION_ID=your_actual_org_id
    VITE_VOLTAGE_ENVIRONMENT_ID=your_actual_env_id
    VITE_VOLTAGE_WALLET_ID=your_actual_wallet_id
  3. Start the development server:

    npm run dev

The demo will automatically detect and use your real API credentials, allowing you to:

  • ✅ Create real payment requests
  • ✅ Generate actual Lightning invoices and Bitcoin addresses
  • ✅ Test real payment status polling
  • ✅ Receive actual Bitcoin payments (be careful!)

⚠️ Security Note: The .env file is ignored by git and should never be committed. Only use testnet/regtest credentials for development.

Building

npm run build        # Build library
npm run type-check   # Type checking
npm run test         # Run tests

📖 API Reference

VoltagePayments.create(options)

Creates a new payment component instance.

Options

| Option | Type | Required | Description | | --------------------- | -------------------------------- | -------- | ----------------------------------------------- | | apiKey | string | ✅ | Your Voltage API key | | organizationId | string | ✅ | Your Voltage organization ID | | environmentId | string | ✅ | Your Voltage environment ID | | walletId | string | ✅ | Target wallet ID for payments | | amount | number | ❌ | BTC amount in millisats (use 0 or null for any-amount bolt11) | | paymentKind | 'bolt11' | 'onchain' | 'bip21' | 'taprootasset' | ❌ | Payment type (default: 'bip21') | | variant | 'inline' | 'modal' | 'button' | ❌ | Payment variant (default: 'inline') | | description | string | ❌ | Payment description | | autoClose | boolean | ❌ | Auto-close modal on success (modal only) | | baseUrl | string | ❌ | Custom Voltage API base URL | | appearance | AppearanceConfig | ❌ | Visual customization options | | pollingConfig | PollingConfig | ❌ | Payment status polling configuration | | onReady | function | ❌ | Called when payment is ready | | onSuccess | function | ❌ | Called when payment succeeds | | onError | function | ❌ | Called when payment fails | | onExpired | function | ❌ | Called when payment expires | | onStatusChange | function | ❌ | Called when payment status changes | | onQRGenerated | function | ❌ | Called when QR code is generated | | onModalOpen | function | ❌ | Called when modal opens (modal only) | | onModalClose | function | ❌ | Called when modal closes (modal only) | | onButtonActivated | function | ❌ | Called when button is activated (button only) | | onButtonDeactivated | function | ❌ | Called when button is deactivated (button only) | | assetCurrency | string | ❌ | Taproot Asset group key asset:<66-hex> (required for taprootasset) | | assetAmount | number | ❌ | Taproot Asset amount in base units (required for taprootasset) | | assetDecimals | number | ❌ | Optional decimals for display formatting (e.g., VCASH = 6) | | assetLabel | string | ❌ | Optional asset label for UI (e.g., 'VCASH') |

Payment Component Methods

const payment = VoltagePayments.create({...});

await payment.mount('#container');     // Mount to DOM element
payment.unmount();                     // Unmount from DOM
payment.destroy();                     // Clean up and destroy
payment.updateOptions({...});          // Update configuration
payment.getStatus();                   // Get current status
payment.getPaymentData();              // Get payment data

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

MIT License - see LICENSE file for details.

🆘 Support


Current Status: ✅ Phase 3 Complete - All Payment Variants Implemented

Completed Features:

  • ✅ Inline Payment Component (embeds directly in page)
  • ✅ Modal Payment Component (opens in modal dialog)
  • ✅ Button Payment Component (click-to-reveal interface)
  • ✅ Real Voltage API Integration
  • ✅ QR Code Generation & Display
  • ✅ Multiple Payment Types (Lightning, On-chain, BIP21)
  • ✅ Custom Styling & Theming
  • ✅ TypeScript Support
  • ✅ Mobile Responsive Design
  • ✅ Accessibility Features

Next Steps:

  • [ ] Enhanced Error Handling & Recovery
  • [ ] Framework Wrappers (React, Vue, Angular)
  • [ ] NPM Package Publishing
  • [ ] Advanced Customization Options