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

# Overview

> Headless Web SDK for payment experiences on the web.

In order to make use of the Web SDK you need to create a client-sharable, short-lived secret. This secret is called a `session` as it represents a session between your web application and the Hellgate®.

<Steps>
  <Step title="Create Session">
    Create a session for tokenization using the session API.

    ```bash title="Example: Create session" theme={null}
    curl --request POST \
      --url https://api.hellgate.io/tokens/session \
      --header 'content-type: application/json'
    ```

    The response includes the `session_id` of the created session.

    ```json title="Example: Session response" theme={null}
    {
      "session_id": "7f2c9460-7e2e-403f-a08a-bc58cdcaea83"
    }
    ```

    <Tip>
      Want to confirm the session works before writing any browser code? Paste the `session_id` into the [WebSDK testing page](/platform/resources/testing/web-sdk) to run the full card flow against it.
    </Tip>
  </Step>

  <Step title="Use the SDK">
    Send the `session_id` to your web application in the customer's browser. The `session_id` is safe to share with the client.

    <Warning>
      You must not distribute your server-side API keys to the clients. Use the provided `session_id`, which is short-lived (with a default of 15 minutes) and has a very limited scope. This protects you from malicious acts.
    </Warning>

    After the `session_id` is handed over to the client, initialise the headless SDK.

    ### Load the SDK

    The SDK is distributed via our CDN or from NPM.

    <Tabs>
      <Tab title="NPM">
        ```bash title="Example: Install via NPM" theme={null}
        npm install --save @starfish-codes/hellgate
        ```
      </Tab>

      <Tab title="CDN">
        ```html title="Example: Load via CDN" theme={null}
        <script src="https://sdk.hellgate.io/web/v3.10.0/hellgate-sdk.min.js"></script>
        ```
      </Tab>
    </Tabs>

    ### Initialise the SDK

    With the `session_id` and the loaded SDK, initialise a headless client for your browser session.

    ```javascript title="Example: Initialise client" theme={null}
    import { Hellgate } from '@starfish-codes/hellgate';

    // Create the Hellgate client. Make sure you await the result of the
    // asynchronous initialisation, as subsequent actions will rely on it.
    const client = await Hellgate.init('7f2c9460-7e2e-403f-a08a-bc58cdcaea83', {
      base_url: 'https://sandbox.hellgate.io',
    });
    ```

    The headless client keeps a secure connection to the Hellgate® backend. Connect it with your application to proceed.
  </Step>

  <Step title="Tokenize Card Data">
    <Info>
      Hellgate's Headless SDK enables secure card payment data entry, yet is fully embedded in your web application. The secure communication channel between the SDK and the Hellgate® allows the sensitive card data to be exchanged for so-called tokens. These are made available to you as a payment method.
    </Info>

    Use the `CARD` handler to tokenize cardholder data.

    ```javascript title="Example: Get card handler" theme={null}
    const cardHandler = await client.use('CARD');
    ```

    Based on the handler, two form types can be rendered in your front-end.

    ### One-Line Card Form

    A compact way to collect card details: separate entry fields rendered as one unit.

    ```javascript title="Example: One-line card form integration" theme={null}
    const { Hellgate } = window;
    const client = await Hellgate.init('d5529f03-e84a-4a43-867c-b3412a097e63', {
      base_url: 'https://sandbox.hellgate.io',
    });

    const cardHandler = await client.use('CARD');
    const cardForm = cardHandler.createForm({
      style: {
        fonts: ['https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600;700;800&display=swap'],
        base: {
          fontFamily: 'Nunito, sans-serif',
          color: '#111',
          fontSize: '16px',
          '::placeholder': { color: '#6b7280' },
        },
      },
    });
    const cardholderField = cardHandler.createTextField();

    cardForm.mount('#my-form-element');
    cardholderField.mount('#cardholder-element');

    const submitButton = document.getElementById('my-submit-button');
    submitButton.addEventListener('click', async () => {
      try {
        const result = await cardHandler.process({
          cardholder_name: cardholderField,
        });
        const resultElement = document.getElementById('result');
        const errorElement = document.getElementById('error');
        if (result.status === 'success' || result.status === 'pending') {
          resultElement.textContent = 'Processing has been successfully completed';
          errorElement.textContent = '';
        } else {
          resultElement.textContent = '';
          errorElement.textContent = result.data.reason;
        }
      } catch (err) {
        // handle error (e.g. network issue or backend error)
      }
    });
    ```

    ### Separated Card-Data Fields

    For more flexibility in layout, create individual elements and mount them separately.

    ```javascript title="Example: Separated card fields" theme={null}
    const { Hellgate } = window;
    const client = await Hellgate.init('d5529f03-e84a-4a43-867c-b3412a097e63', {
      base_url: 'https://sandbox.hellgate.io',
    });

    const cardHandler = await client.use('CARD');
    const { cardNumber, expiryDate, securityCode } = cardHandler.createFormFields({
      style: {
        base: {
          color: '#111',
          fontSize: '14px',
        },
      },
    });

    await Promise.all([
      cardNumber.mount('#my-card-number-element'),
      expiryDate.mount('#my-expiry-date-element'),
      securityCode.mount('#my-security-code-element'),
    ]);

    const submitButton = document.getElementById('my-submit-button');
    submitButton.addEventListener('click', async () => {
      try {
        const result = await cardHandler.process({
          cardholder_name: 'Cardholder Name',
        });
        const resultElement = document.getElementById('result');
        const errorElement = document.getElementById('error');
        if (result.status === 'success' || result.status === 'pending') {
          resultElement.textContent = 'Processing has been successfully completed';
          errorElement.textContent = '';
        } else {
          resultElement.textContent = '';
          errorElement.textContent = result.data.reason;
        }
      } catch (err) {
        // handle error
      }
    });
    ```

    ### Separated expiration month and year

    Use `expiryDateElement: 'separate'` to get distinct month and year fields.

    ```javascript title="Example: Separate month and year fields" theme={null}
    const { cardNumber, expiryMonth, expiryYear, securityCode } = cardHandler.createFormFields({
      style: {
        base: {
          color: '#111',
          fontSize: '14px',
        },
      },
      expiryDateElement: 'separate',
    });

    await Promise.all([
      cardNumber.mount('#my-card-number-element'),
      expiryMonth.mount('#my-expiry-month-element'),
      expiryYear.mount('#my-expiry-year-element'),
      securityCode.mount('#my-security-code-element'),
    ]);
    ```
  </Step>
</Steps>
