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

@cloudbank/checkout

v0.2.1

Published

Browser-based embedded checkout for CloudBank with API integration

Readme

@cloudbank/checkout

Browser-based embedded checkout for CloudBank with client-side API integration.

Features

  • Dual Flow Support: Use pre-created checkout URLs or create sessions directly from the client
  • Multiple Display Modes: Embedded iframe modal or full-page redirect
  • Publishable Key Authentication: Safe client-side API calls with automatic environment detection
  • Event System: Track checkout lifecycle (loaded, confirmed, close, error)
  • Theme Customization: Light and dark themes
  • TypeScript Support: Full type safety and IDE autocomplete
  • Universal Module Support: ESM, CJS, and UMD/IIFE builds

Installation

Package Manager

npm install @cloudbank/checkout
# or
yarn add @cloudbank/checkout
# or
bun add @cloudbank/checkout

CDN (Browser)

Use directly in the browser via CDN:

<!-- unpkg -->
<script src="https://unpkg.com/@cloudbank/checkout@latest/dist/index.global.js"></script>

<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@cloudbank/checkout@latest/dist/index.global.js"></script>

<!-- Specific version (recommended for production) -->
<script src="https://unpkg.com/@cloudbank/[email protected]/dist/index.global.js"></script>

The global CloudBankCheckout namespace will be available:

<script>
  // Access via global namespace
  const { CloudBankEmbedCheckout, CloudBankAPICheckout } = CloudBankCheckout;

  // Use as normal
  const checkout = await CloudBankEmbedCheckout.create(checkoutUrl);
</script>

Quick Start

Flow A: Pre-created Checkout URL (Server-side Session)

import { CloudBankEmbedCheckout } from '@cloudbank/checkout';

// Server creates session and returns URL
const checkoutUrl = 'https://checkout.cloudbank.fnstack.dev/session/...';

// Client opens embedded checkout
const checkout = await CloudBankEmbedCheckout.create(checkoutUrl);

// Listen for events
checkout.addEventListener('confirmed', (event) => {
  console.log('Payment confirmed:', event.detail);
});

checkout.addEventListener('close', () => {
  console.log('Checkout closed');
});

Flow B: Client-side Session Creation (API Integration)

import { CloudBankEmbedCheckout } from '@cloudbank/checkout';

const checkout = await CloudBankEmbedCheckout.create({
  publishableKey: 'pk_test_...',
  amount: {
    value: 5000,
    currency: 'XAF'
  },
  externalId: `order_${Date.now()}`,
  successUrl: window.location.href + '/success',
  cancelUrl: window.location.href + '/cancel',
  customer: {
    email: '[email protected]',
    name: 'John Doe'
  },
  description: 'Premium subscription',
  mode: 'embed', // or 'redirect'
  theme: 'light'  // or 'dark'
});

Display Modes

Embed Mode (Default)

Opens checkout in an iframe modal overlay:

const checkout = await CloudBankEmbedCheckout.create({
  publishableKey: 'pk_test_...',
  amount: { value: 1000, currency: 'XAF' },
  externalId: 'order_123',
  successUrl: '/success',
  mode: 'embed' // Default
});

Redirect Mode

Navigates to checkout in full-page:

await CloudBankEmbedCheckout.create({
  publishableKey: 'pk_test_...',
  amount: { value: 1000, currency: 'XAF' },
  externalId: 'order_123',
  successUrl: '/success',
  mode: 'redirect'
});
// Browser will redirect to checkout page

Declarative API

Use HTML data attributes for simple integrations:

<button
  data-cloudbank-checkout="https://checkout.cloudbank.fnstack.dev/session/..."
  data-cloudbank-theme="dark"
  data-cloudbank-mode="embed">
  Pay Now
</button>

<script type="module">
  import { CloudBankEmbedCheckout } from '@cloudbank/checkout';
  CloudBankEmbedCheckout.init();
</script>

Events

Listen to checkout lifecycle events:

const checkout = await CloudBankEmbedCheckout.create(checkoutUrl);

// Checkout iframe loaded
checkout.addEventListener('loaded', (event) => {
  console.log('Checkout loaded', event.detail.sessionId);
});

// Payment confirmed
checkout.addEventListener('confirmed', (event) => {
  console.log('Payment confirmed:', event.detail);
  // event.detail: { sessionId, externalId, amount }
});

// User closed checkout
checkout.addEventListener('close', (event) => {
  console.log('Checkout closed');
});

// Error occurred
checkout.addEventListener('error', (event) => {
  console.error('Checkout error:', event.detail.message);
});

Programmatic Control

const checkout = await CloudBankEmbedCheckout.create(checkoutUrl);

// Check if checkout is open
if (checkout.isOpen) {
  console.log('Checkout is currently open');
}

// Close checkout programmatically
checkout.close();

Publishable Keys

Key Formats

  • Test keys: pk_test_... → Routes to staging API
  • Live keys: pk_live_... → Routes to production API

Security

  • Safe for client-side: Publishable keys are designed for browser use
  • Never use secret keys: Secret keys (sk_*) are rejected with an error
  • 🔐 Automatic masking: Keys are masked in error messages and logs
// ✅ Correct - publishable key
const checkout = await CloudBankEmbedCheckout.create({
  publishableKey: 'pk_test_abc123...',
  // ...
});

// ❌ Error - secret key rejected
const checkout = await CloudBankEmbedCheckout.create({
  publishableKey: 'sk_test_secret123...', // Throws AuthenticationError
  // ...
});

Theme Customization

// Light theme (default)
const checkout = await CloudBankEmbedCheckout.create({
  publishableKey: 'pk_test_...',
  // ...
  theme: 'light'
});

// Dark theme
const checkout = await CloudBankEmbedCheckout.create({
  publishableKey: 'pk_test_...',
  // ...
  theme: 'dark'
});

TypeScript

Full TypeScript support with complete type definitions:

import type {
  CheckoutSessionParams,
  CheckoutOptions,
  ConfirmedEventDetail,
  CreateCheckoutParams
} from '@cloudbank/checkout';

const params: CheckoutSessionParams = {
  publishableKey: 'pk_test_...',
  amount: { value: 1000, currency: 'XAF' },
  externalId: 'order_123',
  successUrl: '/success'
};

const checkout = await CloudBankEmbedCheckout.create(params);

checkout.addEventListener('confirmed', (event: CustomEvent<ConfirmedEventDetail>) => {
  // event.detail is properly typed
  console.log(event.detail.sessionId);
});

React Integration

import { useEffect, useState } from 'react';
import { CloudBankEmbedCheckout } from '@cloudbank/checkout';

function CheckoutButton() {
  const [loading, setLoading] = useState(false);

  const handleCheckout = async () => {
    setLoading(true);

    try {
      const checkout = await CloudBankEmbedCheckout.create({
        publishableKey: process.env.NEXT_PUBLIC_CLOUDBANK_KEY!,
        amount: { value: 5000, currency: 'XAF' },
        externalId: `order_${Date.now()}`,
        successUrl: window.location.origin + '/success',
      });

      checkout.addEventListener('confirmed', (event) => {
        console.log('Payment confirmed:', event.detail);
      });

      checkout.addEventListener('close', () => {
        setLoading(false);
      });
    } catch (error) {
      console.error('Checkout failed:', error);
      setLoading(false);
    }
  };

  return (
    <button onClick={handleCheckout} disabled={loading}>
      {loading ? 'Processing...' : 'Pay Now'}
    </button>
  );
}

Error Handling

import {
  APIError,
  AuthenticationError,
  NetworkError,
  ValidationError
} from '@cloudbank/checkout';

try {
  const checkout = await CloudBankEmbedCheckout.create({
    publishableKey: 'pk_test_...',
    amount: { value: -100, currency: 'XAF' }, // Invalid amount
    externalId: 'order_123',
    successUrl: '/success'
  });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid publishable key');
  } else if (error instanceof ValidationError) {
    console.error('Invalid parameters:', error.message);
  } else if (error instanceof APIError) {
    console.error('API error:', error.statusCode, error.message);
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
  }
}

CORS Configuration

For client-side API integration to work, your CloudBank API must be configured with appropriate CORS headers:

Access-Control-Allow-Origin: https://yourdomain.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, Idempotency-Key

Contact CloudBank support to configure CORS for your domain.

Browser Compatibility

  • Chrome/Edge (latest 2 versions)
  • Firefox (latest 2 versions)
  • Safari (latest 2 versions)

Bundle Size

  • ESM: ~6.5 KB (minified)
  • CJS: ~7.0 KB (minified)
  • IIFE: ~7.0 KB (minified)

Gzipped sizes are approximately 30% smaller.

API Reference

CloudBankEmbedCheckout.create(params)

Creates and opens a checkout instance.

Parameters:

  • params: string | CheckoutSessionParams & CheckoutOptions

Returns: Promise<CloudBankEmbedCheckout>

CloudBankEmbedCheckout.init()

Initializes declarative checkout triggers for elements with data-cloudbank-checkout attribute.

Instance Methods

  • close(): Closes the checkout modal
  • addEventListener(type, listener): Adds event listener
  • removeEventListener(type, listener): Removes event listener

Instance Properties

  • isOpen: boolean - Whether checkout is currently open

License

MIT

Support

For questions and support, visit CloudBank Documentation or contact [email protected].