Skip to main content

Widget Events

The NowRamp Widget emits events throughout its lifecycle. Subscribe to these events to integrate the widget behavior with your application.

Event Flow Overview

The following diagram shows the typical event flow during a widget session:

Event Subscription

// Subscribe
widget.on('eventName', (data) => {
  console.log('Event data:', data);
});

// Unsubscribe
widget.off('eventName', handler);

// Subscribe once
widget.once('eventName', (data) => {
  console.log('This only fires once');
});

Lifecycle Events

ready

Fired when the widget is fully loaded and ready.
widget.on('ready', () => {
  console.log('Widget is ready');
  hideLoadingSpinner();
});

close

Fired when the user closes the widget or clicks outside.
widget.on('close', () => {
  console.log('Widget closed');
  hideModal();
});

error

Fired when an error occurs.
widget.on('error', (error) => {
  console.error('Widget error:', error);
  // error: { code: string, message: string, details?: any }
});
Error CodeDescription
INIT_FAILEDWidget failed to initialize
NETWORK_ERRORNetwork request failed
SESSION_EXPIREDUser session expired
INVALID_CONFIGInvalid configuration
PROVIDER_ERRORExternal provider error

stepChanged

Fired when the user navigates to a different step. This event includes provider data when available.
widget.on('stepChanged', (payload) => {
  const { from, to, providerData } = payload;
  console.log(`Navigated from ${from} to ${to}`);
  analytics.track('Widget Step', { step: to });

  // Provider data is included when transitioning to/from payment steps
  if (providerData) {
    console.log('Provider data:', providerData);
  }
});
Payload Structure:
interface StepChangePayload {
  from: string;           // Previous step name
  to: string;             // Current step name
  providerData?: {        // Optional provider-specific data
    status?: string;      // Provider status (e.g., 'loading', 'ready', 'processing')
    progress?: number;    // Progress percentage (0-100)
    metadata?: Record<string, unknown>;  // Additional provider metadata
  };
}
Steps: amountconfirmkycwalletpaymentcomplete

back

Fired when the user goes back to a previous step.
widget.on('back', ({ from, to }) => {
  console.log(`Went back from ${from} to ${to}`);
});

Quote Events

quoteRequested

Fired when a quote is being generated.
widget.on('quoteRequested', ({ amount, sourceCurrency, targetCurrency }) => {
  console.log(`Requesting quote: ${amount} ${sourceCurrency}${targetCurrency}`);
});

quoteGenerated

Fired when a quote is successfully generated.
widget.on('quoteGenerated', (quote) => {
  console.log('Quote generated:', quote);
  // quote: {
  //   id: string,
  //   sourceAmount: string,
  //   sourceCurrency: string,
  //   targetAmount: string,
  //   targetCurrency: string,
  //   exchangeRate: string,
  //   fees: { platform: string, network: string, total: string },
  //   expiresAt: string
  // }
});

quoteExpired

Fired when the current quote expires.
widget.on('quoteExpired', (quote) => {
  console.log('Quote expired:', quote.id);
  // Widget will auto-refresh the quote
});

KYC Events

kycRequired

Fired when KYC verification is needed.
widget.on('kycRequired', () => {
  console.log('KYC verification required');
  analytics.track('KYC Required');
});

kycStarted

Fired when the user begins KYC verification.
widget.on('kycStarted', ({ kycCaseId, verificationUrl }) => {
  console.log('KYC started:', kycCaseId);
});

kycCompleted

Fired when KYC verification completes.
widget.on('kycCompleted', ({ status, kycCaseId }) => {
  console.log('KYC completed:', status);
  // status: 'approved' | 'rejected' | 'pending'
});

Wallet Events

walletSelected

Fired when a wallet is selected.
widget.on('walletSelected', (wallet) => {
  console.log('Wallet selected:', wallet);
  // wallet: { id: string, address: string, currency: string }
});

walletAdded

Fired when a new wallet is added.
widget.on('walletAdded', (wallet) => {
  console.log('New wallet added:', wallet.address);
});

walletScreened

Fired when wallet screening completes.
widget.on('walletScreened', ({ wallet, status }) => {
  console.log(`Wallet ${wallet.address} screening: ${status}`);
  // status: 'clear' | 'flagged' | 'blocked'
});

Order Events

orderCreated

Fired when an order is created.
widget.on('orderCreated', (order) => {
  console.log('Order created:', order.id);
  analytics.track('Order Created', {
    orderId: order.id,
    amount: order.sourceAmount,
  });
});

orderProcessing

Fired when order processing begins.
widget.on('orderProcessing', (order) => {
  console.log('Processing order:', order.id);
});

orderComplete

Fired when an order is successfully completed.
widget.on('orderComplete', (order) => {
  console.log('Order completed:', order);
  // order: {
  //   id: string,
  //   status: 'completed',
  //   sourceAmount: string,
  //   sourceCurrency: string,
  //   targetAmount: string,
  //   targetCurrency: string,
  //   walletAddress: string,
  //   txHash?: string
  // }

  // Track conversion
  analytics.track('Purchase Complete', {
    orderId: order.id,
    revenue: parseFloat(order.sourceAmount),
    currency: order.sourceCurrency,
  });
});

orderFailed

Fired when an order fails.
widget.on('orderFailed', ({ order, error }) => {
  console.error('Order failed:', error);
  analytics.track('Order Failed', {
    orderId: order.id,
    error: error.code,
  });
});

Payment Events

paymentInitiated

Fired when payment is initiated.
widget.on('paymentInitiated', ({ orderId, paymentMethod }) => {
  console.log('Payment initiated:', paymentMethod);
});

paymentComplete

Fired when payment is confirmed.
widget.on('paymentComplete', ({ orderId }) => {
  console.log('Payment confirmed for order:', orderId);
});

paymentFailed

Fired when payment fails.
widget.on('paymentFailed', ({ orderId, error }) => {
  console.error('Payment failed:', error);
});

Handling Provider Events

The NowRamp Widget forwards events from underlying payment providers. These events are normalized and delivered through the standard event system, allowing you to track provider status without provider-specific code.

Provider Status Updates

Monitor provider status through the stepChanged event:
widget.on('stepChanged', ({ from, to, providerData }) => {
  if (to === 'payment' && providerData) {
    switch (providerData.status) {
      case 'loading':
        console.log('Payment provider is loading...');
        break;
      case 'ready':
        console.log('Payment provider is ready for input');
        break;
      case 'processing':
        console.log(`Processing payment: ${providerData.progress}%`);
        break;
      case 'awaiting_confirmation':
        console.log('Awaiting payment confirmation');
        break;
    }
  }
});

Provider Progress Tracking

Track payment progress for user feedback:
widget.on('stepChanged', ({ providerData }) => {
  if (providerData?.progress !== undefined) {
    updateProgressBar(providerData.progress);

    if (providerData.progress === 100) {
      showMessage('Payment processing complete');
    }
  }
});

Provider Metadata

Access additional provider metadata when available:
widget.on('stepChanged', ({ providerData }) => {
  if (providerData?.metadata) {
    // Log metadata for debugging (avoid exposing to end users)
    console.log('Provider metadata:', providerData.metadata);

    // Example: Check for specific provider capabilities
    if (providerData.metadata.supports3DS) {
      console.log('3D Secure authentication may be required');
    }
  }
});

Error Handling for Provider Events

Handle provider-specific errors gracefully:
widget.on('error', (error) => {
  if (error.code === 'PROVIDER_ERROR') {
    // Provider-specific error handling
    console.error('Provider error:', error.message);

    // Show user-friendly message
    showError('There was an issue with the payment provider. Please try again.');

    // Optionally track for monitoring
    analytics.track('Provider Error', {
      message: error.message,
      details: error.details,
    });
  }
});

Complete Example

import { RampWidget } from '@nowramp/sdk';

const widget = new RampWidget({
  apiKey: 'your_api_key',
  projectId: 'your_project_id',
  externalUserId: 'user_123',
  containerId: 'widget-container',
  environment: 'production', // or 'sandbox'
  // Widget URL: https://widget.nowramp.com
});

// Lifecycle
widget.on('ready', () => hideLoader());
widget.on('close', () => hideModal());
widget.on('error', (e) => showError(e.message));

// Analytics
widget.on('stepChanged', ({ to, providerData }) => {
  analytics.page(to);

  // Track provider status changes
  if (providerData?.status) {
    analytics.track('Provider Status', {
      step: to,
      status: providerData.status,
    });
  }
});
widget.on('quoteGenerated', (q) => analytics.track('Quote', q));
widget.on('kycStarted', () => analytics.track('KYC Started'));
widget.on('orderCreated', (o) => analytics.track('Order Created', o));

// Provider progress
widget.on('stepChanged', ({ providerData }) => {
  if (providerData?.progress !== undefined) {
    updateProgressIndicator(providerData.progress);
  }
});

// Conversions
widget.on('orderComplete', (order) => {
  analytics.track('Purchase', {
    value: order.sourceAmount,
    currency: order.sourceCurrency,
  });
  showSuccess('Your crypto is on the way!');
});

widget.on('orderFailed', ({ error }) => {
  showError('Order failed. Please try again.');
});

widget.mount();