The @zbdpay/ramp-react package is a React wrapper for the ZBD Ramp widget that enables Buying Bitcoin with USD directly to the Lightning Network.

Features

  • React Optimized: Built specifically for React with hooks and components
  • TypeScript Support: Full type safety with comprehensive TypeScript definitions
  • Ref API: Access to underlying ramp instance methods via React refs
  • Hook Support: useZBDRamp hook for programmatic usage
  • Session Token Based: Uses secure session tokens for authentication

Installation

npm install @zbdpay/ramp-react

Quick Start

1. Create Session Token

First, create a session token using the ZBD API:
import { initRampSession, QuoteCurrencyEnum, BaseCurrencyEnum } from '@zbdpay/ramp-react';

const response = await initRampSession({
  apikey: 'your-zbd-api-key',
  email: 'user@example.com',
  destination: 'lightning-address@zbd.gg',
  quote_currency: QuoteCurrencyEnum.USD,
  base_currency: BaseCurrencyEnum.BTC,
  webhook_url: 'https://your-webhook-url.com',
});

const sessionToken = response.data.session_token;

2. Use ZBDRamp Component

import { ZBDRamp } from '@zbdpay/ramp-react';

function App() {
  const handleSuccess = (data) => {
    console.log('Payment successful:', data);
  };

  const handleError = (error) => {
    console.error('Payment error:', error);
  };

  return (
    <ZBDRamp
      sessionToken="your-session-token"
      onSuccess={handleSuccess}
      onError={handleError}
      style={{ width: '100%', height: '600px' }}
    />
  );
}

API Reference

initRampSession

Creates a new session token for the ZBD Ramp widget.
config
InitRampSessionConfig
required
Configuration object for creating a session

Configuration Parameters

apikey
string
required
Your ZBD API key
email
string
required
User’s email address
destination
string
required
Lightning address or Bitcoin address
quote_currency
QuoteCurrencyEnum
required
Quote currency (e.g., USD)
base_currency
BaseCurrencyEnum
required
Base currency (e.g., BTC)
webhook_url
string
Webhook URL for notifications
reference_id
string
Your internal reference ID
metadata
Record<string, any>
Additional metadata to attach to the session

ZBDRamp Component

React component that renders the ZBD Ramp widget.

Props

sessionToken
string
required
Session token from ZBD API
width
string | number
default:"100%"
Widget width
height
string | number
default:"600px"
Widget height (minimum 600px recommended)
className
string
CSS class for container
style
React.CSSProperties
Inline styles for container

Callback Props

onSuccess
(data: any) => void
Called when payment is successful
onError
(error: RampError) => void
Called when an error occurs
onStepChange
(step: string) => void
Called when user navigates to a different step
onLog
(log: RampLog) => void
Debug/info logging callback
onReady
() => void
Called when widget is fully loaded
onClose
() => void
Called when user closes the widget

Ref API

interface ZBDRampRef {
  mount: (container?: HTMLElement | string) => void;
  unmount: () => void;
  destroy: () => void;
}

useZBDRamp Hook

Hook for creating and managing ZBD Ramp instances programmatically.
const { createInstance, destroyInstance, instance } = useZBDRamp(options);

Usage Examples

Basic Component

import React from 'react';
import { ZBDRamp } from '@zbdpay/ramp-react';

function PaymentWidget({ sessionToken }) {
  const handleSuccess = (data: any) => {
    console.log('Payment successful:', data);
    // Handle successful payment
  };

  const handleError = (error: any) => {
    console.error('Payment error:', error);
    // Handle error
  };

  return (
    <div className="payment-container">
      <h1>Make a Payment</h1>
      <ZBDRamp
        sessionToken={sessionToken}
        onSuccess={handleSuccess}
        onError={handleError}
        style={{
          width: '100%',
          height: '600px',
          border: '1px solid #ddd',
          borderRadius: '8px'
        }}
      />
    </div>
  );
}

With Ref for Control

import React, { useRef } from 'react';
import { ZBDRamp } from '@zbdpay/ramp-react';
import type { ZBDRampRef } from '@zbdpay/ramp-react';

function ControlledPayment({ sessionToken }) {
  const rampRef = useRef<ZBDRampRef>(null);

  const closeWidget = () => {
    rampRef.current?.unmount();
  };

  const destroyWidget = () => {
    rampRef.current?.destroy();
  };

  return (
    <div>
      <button onClick={closeWidget}>Close Widget</button>
      <button onClick={destroyWidget}>Destroy Widget</button>

      <ZBDRamp
        ref={rampRef}
        sessionToken={sessionToken}
        onSuccess={(data) => console.log('Success:', data)}
        onError={(error) => console.error('Error:', error)}
      />
    </div>
  );
}

Using the Hook

import React, { useState } from 'react';
import { useZBDRamp } from '@zbdpay/ramp-react';

function HookExample({ sessionToken }) {
  const [isOpen, setIsOpen] = useState(false);

  const { createInstance, destroyInstance } = useZBDRamp({
    sessionToken,
    container: '#ramp-container',
    onSuccess: (data) => {
      console.log('Payment successful:', data);
      setIsOpen(false);
    },
    onClose: () => {
      setIsOpen(false);
    },
  });

  const openRamp = () => {
    setIsOpen(true);
    createInstance();
  };

  const closeRamp = () => {
    setIsOpen(false);
    destroyInstance();
  };

  return (
    <div>
      <button onClick={openRamp}>Open Payment</button>
      {isOpen && (
        <div>
          <button onClick={closeRamp}>Close</button>
          <div id="ramp-container" style={{ width: '100%', height: '600px' }} />
        </div>
      )}
    </div>
  );
}

Error Handling

import React, { useState } from 'react';
import { ZBDRamp } from '@zbdpay/ramp-react';
import type { RampError } from '@zbdpay/ramp-react';

function PaymentWithErrorHandling({ sessionToken }) {
  const [error, setError] = useState<string | null>(null);

  const handleError = (error: RampError) => {
    switch (error.code) {
      case 'INVALID_CONFIG':
        setError('Configuration error. Please check your settings.');
        break;
      case 'NETWORK_ERROR':
        setError('Network error. Please check your connection.');
        break;
      case 'PAYMENT_FAILED':
        setError('Payment failed. Please try again.');
        break;
      default:
        setError('An unexpected error occurred.');
    }
  };

  const clearError = () => setError(null);

  return (
    <div>
      {error && (
        <div style={{ color: 'red', marginBottom: '10px' }}>
          Error: {error}
          <button onClick={clearError}>×</button>
        </div>
      )}

      <ZBDRamp
        sessionToken={sessionToken}
        onSuccess={() => setError(null)}
        onError={handleError}
      />
    </div>
  );
}

Session Token Creation

import React, { useState } from 'react';
import { ZBDRamp, initRampSession, QuoteCurrencyEnum, BaseCurrencyEnum } from '@zbdpay/ramp-react';

function SessionTokenExample() {
  const [sessionToken, setSessionToken] = useState('');
  const [isLoading, setIsLoading] = useState(false);

  const createSession = async () => {
    setIsLoading(true);
    try {
      const response = await initRampSession({
        apikey: 'your-zbd-api-key',
        email: 'user@example.com',
        destination: 'lightning-address@zbd.gg',
        quote_currency: QuoteCurrencyEnum.USD,
        base_currency: BaseCurrencyEnum.BTC,
        webhook_url: 'https://your-webhook.com',
      });

      if (response.success) {
        setSessionToken(response.data.session_token);
      } else {
        console.error('Failed to create session:', response.error);
      }
    } catch (error) {
      console.error('Error creating session:', error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div>
      {!sessionToken ? (
        <button onClick={createSession} disabled={isLoading}>
          {isLoading ? 'Creating Session...' : 'Create Session'}
        </button>
      ) : (
        <ZBDRamp
          sessionToken={sessionToken}
          onSuccess={(data) => console.log('Success:', data)}
        />
      )}
    </div>
  );
}
import React, { useState } from 'react';
import { ZBDRamp } from '@zbdpay/ramp-react';

function ModalExample({ sessionToken }) {
  const [isModalOpen, setIsModalOpen] = useState(false);

  return (
    <>
      <button onClick={() => setIsModalOpen(true)}>
        Open Payment Modal
      </button>

      {isModalOpen && (
        <div className="modal-overlay" onClick={() => setIsModalOpen(false)}>
          <div className="modal-content" onClick={(e) => e.stopPropagation()}>
            <button
              className="modal-close"
              onClick={() => setIsModalOpen(false)}
            >
              ×
            </button>

            <ZBDRamp
              sessionToken={sessionToken}
              onSuccess={(data) => {
                console.log('Payment successful:', data);
                setIsModalOpen(false);
              }}
              onClose={() => setIsModalOpen(false)}
              style={{ width: '100%', height: '600px' }}
            />
          </div>
        </div>
      )}
    </>
  );
}

TypeScript Support

The package includes comprehensive TypeScript definitions:
import type {
  ZBDRampProps,
  ZBDRampRef,
  RampConfig,
  RampCallbacks,
  RampOptions,
  RampError,
  RampLog,
  RampInstance,
  PostMessageData,
  InitRampSessionConfig,
  InitRampSessionData,
  InitRampSessionResponse,
  QuoteCurrencyEnum,
  BaseCurrencyEnum,
} from '@zbdpay/ramp-react';

Type Examples

// Define typed configuration
const config: InitRampSessionConfig = {
  apikey: process.env.REACT_APP_ZBD_API_KEY!,
  email: 'user@example.com',
  destination: 'lightning-address@zbd.gg',
  quote_currency: QuoteCurrencyEnum.USD,
  base_currency: BaseCurrencyEnum.BTC,
};

// Handle typed responses
const handleSuccess = (data: any): void => {
  console.log('Payment completed:', data);
};

const handleError = (error: RampError): void => {
  console.error(`Error ${error.code}: ${error.message}`);
};

// Create typed ref
const rampRef = useRef<ZBDRampRef>(null);

Complete Example App

The repository includes a complete example application:
# Clone and run example
git clone https://github.com/zbdpay/ramp-react.git
cd ramp-react/example
npm install
npm run dev
The example includes:
  • Session token creation form
  • Complete ZBD Ramp integration
  • Error handling and callbacks
  • TypeScript implementation

Resources

Support

For support and questions: