Skip to main content
The Paysight Widget uses a message-based system to communicate events and state changes between your application and the widget. This guide explains how to implement effective event handling.

Event System Overview

Events are handled through the onMessage callback provided during widget initialization:
const widget = PaysightSDK.createWidget({
  targetId: 'widget-container',
  config: { /* ... */ },
  onMessage: (message) => {
    console.log('Event received:', message.type, message.payload);
  }
});
  • Event Structure
  • Event Flow
Each event message has a consistent structure:
interface WidgetMessage<T = unknown> {
  // Event type identifier
  type: string;
  
  // Event data (varies by event type)
  payload: T;
}
Always check the event type before accessing payload properties, as the payload structure varies by event type.

Event Types

Lifecycle Events

Events related to the widget’s lifecycle:
// Widget Ready - Fired when the widget is fully loaded and ready
{
  type: 'READY',
  payload: void
}

// Widget Destroyed - Fired when the widget is destroyed
{
  type: 'DESTROY',
  payload: void
}
The READY event indicates that the widget is fully initialized and ready to accept user input. This is a good time to hide any loading indicators.
Events related to the payment process:
// Payment Started - Fired when payment processing begins
{
  type: 'PAYMENT_START',
  payload: void
}

// Payment Successful - Fired when payment is completed successfully
{
  type: 'PAYMENT_SUCCESS',
  payload: {
    transactionId: string;
    amount: number;
    currency: string;
  }
}

// Payment Error - Fired when payment processing fails
{
  type: 'PAYMENT_ERROR',
  payload: {
    code: string;
    message: string;
    details?: unknown;
  }
}
Always implement handlers for PAYMENT_SUCCESS and PAYMENT_ERROR events to provide appropriate feedback to users.
Events related to 3DS verification:
// 3DS Started - Fired when 3DS verification begins
{
  type: 'PAYMENT_3DS_START',
  payload: void
}

// 3DS Successful - Fired when 3DS verification is successful
{
  type: 'PAYMENT_3DS_SUCCESS',
  payload: void
}

// 3DS Error - Fired when 3DS verification encounters an error
{
  type: 'PAYMENT_3DS_ERROR',
  payload: {
    code: string;
    message: string;
    details?: unknown;
  }
}

// 3DS Failed - Fired when 3DS verification fails
{
  type: 'PAYMENT_3DS_FAILURE',
  payload: {
    code: string;
    message: string;
    details?: unknown;
  }
}
3DS events are only triggered when 3D Secure authentication is enabled in your widget configuration.
Events related to form interactions:
// Field Change - Fired when a form field value changes
{
  type: 'FIELD_CHANGE',
  payload: {
    field: string;
    value: unknown;
  }
}

// Field Blur - Fired when a form field loses focus
{
  type: 'FIELD_BLUR',
  payload: {
    field: string;
    value: unknown;
  }
}

// Form Submit - Fired when the form is submitted
{
  type: 'FORM_SUBMIT',
  payload: Record<string, unknown>
}
Form events can be useful for tracking user progress and implementing custom validation logic.

Implementing Event Handlers

const widget = PaysightSDK.createWidget({
  targetId: 'widget-container',
  config: { /* ... */ },
  onMessage: (message) => {
    switch (message.type) {
      case 'PAYMENT_SUCCESS':
        handlePaymentSuccess(message.payload);
        break;
      case 'PAYMENT_ERROR':
        handlePaymentError(message.payload);
        break;
      case 'PAYMENT_3DS_START':
        show3DSLoadingUI();
        break;
      case 'FORM_SUBMIT':
        handleFormSubmit(message.payload);
        break;
    }
  }
});

Best Practices

1

Handle Critical Events

Always implement handlers for these critical events:
const criticalEvents = [
  'PAYMENT_SUCCESS',
  'PAYMENT_ERROR',
  'PAYMENT_3DS_ERROR',
  'ERROR'
];

const widget = PaysightSDK.createWidget({
  onMessage: (message) => {
    if (criticalEvents.includes(message.type)) {
      handleCriticalEvent(message);
    }
  }
});
2

Implement Error Recovery

const handleError = (error) => {
  // Log error for debugging
  console.error('Widget error:', error);

  // Show user-friendly error message
  showErrorUI(error.message);

  // Attempt recovery based on error type
  if (error.code === 'COMMUNICATION_ERROR') {
    retryConnection();
  }
};
3

Maintain UI State

const updateUIState = (message) => {
  switch (message.type) {
    case 'PAYMENT_START':
      showLoadingState();
      break;
    case 'PAYMENT_SUCCESS':
      showSuccessState();
      break;
    case 'PAYMENT_ERROR':
      showErrorState();
      break;
  }
};
4

Provide User Feedback

Always update your UI based on event messages to keep users informed about the payment process status.
Clear user feedback improves conversion rates and reduces support inquiries.

Redirect After Payment

onMessage: (message) => {
  if (message.type === 'PAYMENT_SUCCESS') {
    // Show success message
    showSuccessMessage();
    
    // Redirect to order confirmation page
    setTimeout(() => {
      window.location.href = `/confirmation?orderId=${orderId}&transactionId=${message.payload.transactionId}`;
    }, 1000);
  }
}

Updating Order Status

onMessage: async (message) => {
  if (message.type === 'PAYMENT_SUCCESS') {
    // Update order status in your system
    try {
      await updateOrderStatus(orderId, 'paid', message.payload.transactionId);
      showSuccessMessage('Payment successful! Your order has been confirmed.');
    } catch (error) {
      // Handle order update error
      console.error('Failed to update order status:', error);
      showWarningMessage('Payment successful, but order status update failed. Please contact support.');
    }
  }
}

Next Steps

I