@cloudbank/checkout
v0.2.1
Published
Browser-based embedded checkout for CloudBank with API integration
Maintainers
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/checkoutCDN (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 pageDeclarative 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-KeyContact 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 modaladdEventListener(type, listener): Adds event listenerremoveEventListener(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].
