> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clearline.me/llms.txt
> Use this file to discover all available pages before exploring further.

# POS Integration: CFS Web API Events

> Communicate between CFS and POS systems using iframe postMessage events

## Overview

Communication between ClearLine's **Customer-Facing Screen (CFS)** and third-party POS systems (e.g., **Clover**, **PAX**) is implemented via **JavaScript iframe events** using the `window.postMessage()` API. This enables seamless interaction between the CFS application running in an iframe and the parent POS system.

***

## Event Model

All events follow a standardized TypeScript interface:

```typescript Event Types theme={null}
export enum IframeMessageTypes {
  buttonClick = "buttonClick",
  inputFocus = "inputFocus",
  inputBlur = "inputBlur",
  formSubmitted = "formSubmitted",
  userActivity = "userActivity",
  setWindowClass = "setWindowClass",
  scanCompleted = "scanCompleted",
  scanCancelled = "scanCancelled",
  init = "init",
}

interface IframeMessageData<T> {
  type: IframeMessageTypes;
  data: T;
}
```

### Sending Events

Events are sent using the standard postMessage API:

```typescript Usage theme={null}
window.postMessage(params, "*");
```

<Note>
  The target origin is set to `"*"` for compatibility across different POS system domains. Implement additional validation in production environments as needed.
</Note>

***

## Output Events (CFS → POS System)

These events are sent **from** the CFS application **to** the external POS system.

### `init`

Triggered when the CFS application completes initialization. This event signals that the CFS is ready to receive messages.

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "init",
      data: {
        projectName: "cfs",
      },
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

| Field       | Type   | Description                                         |
| ----------- | ------ | --------------------------------------------------- |
| projectName | string | Static string "cfs" – identifies the source project |

***

### `buttonClick`

Emitted when a button is clicked in the CFS application. Commonly used to request external hardware scanner usage (e.g., for customer check-in).

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "buttonClick",
      data: {
        targetId: "scan",
        buttonId: "scan",
      },
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

| Field    | Type   | Description                                                 |
| -------- | ------ | ----------------------------------------------------------- |
| targetId | string | HTML element ID of the clicked button (e.g., "scan")        |
| buttonId | string | **Deprecated.** Legacy support only (use targetId instead). |

<Tip>
  Use `targetId` for all new implementations. The `buttonId` field is maintained for backward compatibility only.
</Tip>

***

### `inputFocus`

Emitted when an input field in the CFS gains focus. Use this event to notify the external POS to prepare for login or check-in actions.

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "inputFocus",
      data: {
        targetId: "search",
        inputId: "search",
      },
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

| Field    | Type   | Description                                                 |
| -------- | ------ | ----------------------------------------------------------- |
| targetId | string | HTML element ID of the input field (e.g., "search")         |
| inputId  | string | **Deprecated.** Legacy support only (use targetId instead). |

***

### `inputBlur`

Emitted when an input field in the CFS loses focus.

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "inputBlur",
      data: {
        targetId: "search",
        inputId: "search",
      },
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

| Field    | Type   | Description                                                 |
| -------- | ------ | ----------------------------------------------------------- |
| targetId | string | HTML element ID of the input field (e.g., "search")         |
| inputId  | string | **Deprecated.** Legacy support only (use targetId instead). |

***

## Input Events (POS System → CFS)

These events are sent **from** the external POS system **to** the CFS application.

### `formSubmitted`

Instructs the CFS to close the current iframe window, typically after a form has been submitted externally (e.g., in a CFS Template iframe).

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "formSubmitted",
      data: null
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

*No additional parameters required.*

***

### `userActivity`

Used to prolong user activity inside the iframe and prevent inactivity prompts (e.g., "Are you still here?" dialogs).

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "userActivity",
      data: null
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

*No additional parameters required.*

***

### `setWindowClass`

Previously used to set CSS class on the iframe window.

<Warning>
  This event is **deprecated** and should not be used in new implementations.
</Warning>

***

### `scanCompleted`

Delivers the result of an external hardware scan (barcode, QR code, username, email). Commonly used for customer login or check-in workflows.

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "scanCompleted",
      data: "user@example.com"
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

| Field | Type   | Description                                                   |
| ----- | ------ | ------------------------------------------------------------- |
| data  | string | String value representing scan result (username, code, email) |

<Note>
  The CFS application will automatically process the scanned value and populate the appropriate input field or trigger the login/check-in flow.
</Note>

***

### `scanCancelled`

Indicates cancellation of a scan request. When received, the CFS typically:

* Shows a toast notification to the user
* Resets the scan state
* May resend a cancellation acknowledgment to the external system

<CodeGroup>
  ```typescript Example theme={null}
  window.postMessage(
    {
      type: "scanCancelled",
      data: null
    },
    "*"
  );
  ```
</CodeGroup>

#### Event Data

*No additional parameters required.*

***

## Event Flow Examples

<AccordionGroup>
  <Accordion title="Customer Check-In Flow" icon="user-check">
    **Typical event sequence for customer check-in:**

    1. **CFS → POS:** `buttonClick` (user clicks scan button)
    2. **POS activates scanner**
    3. **POS → CFS:** `scanCompleted` (with scanned email/phone)
    4. **CFS processes check-in**

    Alternatively, if the user cancels:

    1. **CFS → POS:** `buttonClick` (user clicks scan button)
    2. **POS activates scanner**
    3. **User cancels scan**
    4. **POS → CFS:** `scanCancelled`
    5. **CFS shows cancellation message**
  </Accordion>

  <Accordion title="Form Interaction Flow" icon="file-pen">
    **Typical event sequence for form interaction:**

    1. **CFS → POS:** `inputFocus` (user focuses on input field)
    2. **POS prepares for input** (e.g., shows keyboard)
    3. **User enters data and submits**
    4. **POS → CFS:** `formSubmitted`
    5. **CFS closes iframe/modal**
  </Accordion>

  <Accordion title="Keep-Alive Flow" icon="heart-pulse">
    **Preventing inactivity timeouts:**

    * **POS → CFS:** Send `userActivity` events periodically
    * **CFS resets inactivity timer**
    * **Prevents "Are you still here?" prompts**

    <Tip>
      Send `userActivity` events every 30-60 seconds during active customer interactions.
    </Tip>
  </Accordion>
</AccordionGroup>

***

## Implementation Guide

<Steps>
  <Step title="Set Up Event Listener">
    In your POS system, add a message event listener to receive events from the CFS:

    ```typescript theme={null}
    window.addEventListener('message', (event) => {
      const message = event.data as IframeMessageData<any>;
      
      switch (message.type) {
        case 'init':
          console.log('CFS initialized:', message.data);
          break;
        case 'buttonClick':
          handleButtonClick(message.data);
          break;
        case 'inputFocus':
          handleInputFocus(message.data);
          break;
        // Handle other events...
      }
    });
    ```
  </Step>

  <Step title="Send Events to CFS">
    Send events from your POS system to the CFS iframe:

    ```typescript theme={null}
    const cfsIframe = document.getElementById('cfs-iframe') as HTMLIFrameElement;

    cfsIframe.contentWindow?.postMessage(
      {
        type: 'scanCompleted',
        data: 'customer@example.com'
      },
      '*'
    );
    ```
  </Step>

  <Step title="Handle Event Responses">
    Implement handlers for each event type based on your business logic:

    ```typescript theme={null}
    function handleButtonClick(data: { targetId: string }) {
      if (data.targetId === 'scan') {
        // Activate hardware scanner
        activateScanner();
      }
    }
    ```
  </Step>
</Steps>

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Validate Event Origin" icon="shield-check">
    In production, validate the event origin instead of accepting all origins (`"*"`).
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation">
    Implement robust error handling for message parsing and event processing.
  </Card>

  <Card title="Type Safety" icon="code">
    Use TypeScript interfaces to ensure type safety for event data.
  </Card>

  <Card title="Event Logging" icon="list-check">
    Log all events during development to debug integration issues.
  </Card>
</CardGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Automated Flow" icon="robot" href="/integration-options/checkout-integration-app/automated-flow-in-pos-system-checkout">
    Implement automated widget triggering
  </Card>

  <Card title="Manual Flow" icon="hand" href="/integration-options/checkout-integration-app/manual-flow-in-pos-system-checkout-cmc">
    Set up manual widget selection
  </Card>

  <Card title="Checkout Integration" icon="diagram-project" href="/integration-options/checkout-integration-app/checkout-integration-flow-example">
    View complete integration workflow
  </Card>

  <Card title="Widget API" icon="window" href="/api-reference/widgets/introduction">
    Explore widget endpoints
  </Card>
</CardGroup>
