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

# Initialize the component

> Create an Alignet One Flex instance and display the responsive payment form.

with `payload` built and `nonce` and established an instance of `FlexPaymentForms` and put the form on your DOM.

<Note>
  You need a `nonce` Current [API Nonce](/en/virtual-payments/checkout-web/flex/api-nonce) and `payload` of [Construction of payload](/en/virtual-payments/checkout-web/flex/payload-construction) before we continue.
</Note>

## Building parameters

Expand every block to check the fields you can send to the builder.

<AccordionGroup>
  <Accordion title="Mandatory information" icon="key" defaultOpen>
    | Field     | Type                | Description                                                                                                                       |
    | :-------- | :------------------ | :-------------------------------------------------------------------------------------------------------------------------------- |
    | `nonce`   | Alphanumeric        | Code encryption generated by backend [API Nonce](/en/virtual-payments/checkout-web/flex/api-nonce).                               |
    | `payload` | Subject matter JSON | Details of purchase and buyer prepared at [Construction of payload](/en/virtual-payments/checkout-web/flex/payload-construction). |
  </Accordion>

  <Accordion title="Settings" icon="gear">
    Control the general visual performance of the component.

    | Field                            | Type    | Description                                                   |
    | :------------------------------- | :------ | :------------------------------------------------------------ |
    | `settings.display_result_screen` | Boolean | Display the result screen at the end of the process.          |
    | `settings.show_close_button`     | Boolean | Display the button to close the component.                    |
    | `settings.show_border`           | Boolean | It activates or deactivates the visual edge of the component. |
    | `settings.show_operation_number` | Boolean | It shows the operation number inside the flow.                |
  </Accordion>

  <Accordion title="Object display_sittings" icon="list-check">
    Define the means of payment that Flex will show the buyer.

    | Field                      | Type            | Description                                                                                             |
    | :------------------------- | :-------------- | :------------------------------------------------------------------------------------------------------ |
    | `display_settings.methods` | Array de String | List necessary for viewing. Accept `CARD`, `YAPE`, `QR`, `BANK_TRANSFER`, `CUOTEALO` or `PAGOEFECTIVO`. |

    You have to send `display_settings.methods` with the payment methods you need to visualise at Flex.
  </Accordion>

  <Accordion title="Subject matter" icon="language">
    Configure available languages within form.

    | Field                   | Type            | Description                                                      |
    | :---------------------- | :-------------- | :--------------------------------------------------------------- |
    | `i18n.mode`             | String          | Language mode. For this flow it's used `multi`.                  |
    | `i18n.default_language` | String          | Undetermined language: `es` or `en`.                             |
    | `i18n.languages`        | Array de String | List of authorized languages. currently supported `es` and `en`. |
  </Accordion>
</AccordionGroup>

## Initiate and mount Flex

<Steps>
  <Step title="It creates an instance">
    Send the `nonce`, `payload` and the configuration that your integration needs.

    ```javascript theme={"system"} theme={"system"}
    const paymentForm = new FlexPaymentForms({
      nonce,
      payload,
      settings: {
        display_result_screen: true,
        show_close_button: true,
        show_border: false,
        show_operation_number: true
      },
      display_settings: {
        methods: ["QR", "BANK_TRANSFER", "CARD"]
      },
      i18n: {
        mode: "multi",
        default_language: "es",
        languages: ["es", "en"]
      }
    });
    ```
  </Step>

  <Step title="Create the container">
    Add to HTML the element where Flex will generate their DOM.

    ```html theme={"system"} theme={"system"}
    <div id="flex-container"></div>
    ```
  </Step>

  <Step title="Surrender form">
    Fits the instance and delivers the functions that will process the response, monitoring and errors.

    ```javascript theme={"system"} theme={"system"}
    paymentForm.init(
      document.querySelector("#flex-container"),
      responseCallback,
      trackingCallback,
      onErrorCallback
    );
    ```
  </Step>
</Steps>

<Note>
  If you define `i18n.default_language`and uses one of the languages listed in `i18n.languages`.
</Note>

<Info>
  `#flex-container` That's just an example. Can use another selector as long as the item exists before running `paymentForm.init(...)`.
</Info>

## Responsive conduct

Flex retains its internal structure while the outer container calculates an appropriate scale for viewing.

<CardGroup cols={3}>
  <Card title="Web" icon="desktop">
    Keep the original scale as soon as the form fits into the window.
  </Card>

  <Card title="Cell" icon="mobile-screen">
    Reduces the form proportionally to avoid horizontal cuts.
  </Card>

  <Card title="Dynamic constore" icon="arrows-up-down">
    Refigure height when Flex change of passage or payment method.
  </Card>
</CardGroup>

### Example of implementation

<Info>
  That visual example uses a popular presentation. The initialization, callbacks and dismantling described above also apply to drunk and expanded presentations.
</Info>

<Tabs>
  <Tab title="Structure HTML">
    ```html theme={"system"} theme={"system"}
    <div id="payment-modal" class="flex-modal" role="dialog" aria-hidden="true">
      <div class="flex-modal__content">
        <div id="flex-container"></div>
      </div>
    </div>
    ```
  </Tab>

  <Tab title="Base Styles">
    ```css theme={"system"} theme={"system"}
    :root {
      --flex-responsive-scale: 1;
      --flex-natural-width: 415px;
      --flex-natural-height: 656px;
    }

    .flex-modal {
      position: fixed;
      inset: 0;
      z-index: 1000;
      display: none;
      padding: 15px 20px;
      overflow: hidden;
      background: rgb(0 18 37 / 48%);
    }

    .flex-modal.is-open {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .flex-modal__content {
      width: var(--flex-natural-width);
      height: var(--flex-natural-height);
      max-width: calc(100vw - 40px);
      max-height: calc(100vh - 30px);
      max-height: calc(100dvh - 30px);
      transform: scale(var(--flex-responsive-scale));
      transform-origin: center;
    }

    #flex-container {
      width: 100%;
      height: 100%;
    }
    ```
  </Tab>

  <Tab title="Responsible logic">
    ```javascript theme={"system"} theme={"system"}
    const FLEX_RESPONSIVE_LAYOUT = {
      naturalWidth: 415,
      naturalHeight: 656,
      viewportPaddingHorizontal: 40, // 20 px a cada lado
      viewportPaddingVertical: 30,   // 15 px arriba y abajo
      minimumScale: 0.25
    };

    function calculateResponsiveScale() {
      const viewportWidth = window.visualViewport?.width ?? window.innerWidth;
      const viewportHeight = window.visualViewport?.height ?? window.innerHeight;
      const availableWidth =
        viewportWidth - FLEX_RESPONSIVE_LAYOUT.viewportPaddingHorizontal;
      const availableHeight =
        viewportHeight - FLEX_RESPONSIVE_LAYOUT.viewportPaddingVertical;

      return Math.max(
        FLEX_RESPONSIVE_LAYOUT.minimumScale,
        Math.min(
          1,
          availableWidth / FLEX_RESPONSIVE_LAYOUT.naturalWidth,
          availableHeight / FLEX_RESPONSIVE_LAYOUT.naturalHeight
        )
      );
    }

    function updateResponsiveScale() {
      const responsiveScale = calculateResponsiveScale();
      document.documentElement.style.setProperty(
        "--flex-responsive-scale",
        String(responsiveScale)
      );
    }

    // Aplica la escala inicial y la recalcula cuando cambia el viewport.
    updateResponsiveScale();
    window.addEventListener("resize", updateResponsiveScale);
    window.visualViewport?.addEventListener("resize", updateResponsiveScale);

    // Muestra el modal.
    const paymentModal = document.querySelector("#payment-modal");
    paymentModal.classList.add("is-open");
    paymentModal.setAttribute("aria-hidden", "false");

    // Inicializa Flex.
    paymentForm.init(
      document.querySelector("#flex-container"),
      responseCallback,
      trackingCallback,
      onErrorCallback
    );
    ```
  </Tab>

  <Tab title="Unmount Flex">
    ```javascript theme={"system"} theme={"system"}
    function unmountFlex() {
      window.removeEventListener("resize", updateResponsiveScale);
      window.visualViewport?.removeEventListener("resize", updateResponsiveScale);

      paymentForm.terminate?.();

      const flexContainer = document.querySelector("#flex-container");
      flexContainer.innerHTML = "";
    }
    ```
  </Tab>
</Tabs>

## Life cycle of the instance

`paymentForm.terminate?.()` complete the internal processes, list and resources that maintain the Flex. That operation is different from eliminating the form from DOM (`flexContainer.innerHTML = ""`) and applying to any type of presentation.

<Info>
  The operator `?.` run `terminate()` only when the method exists. That prevents an error if the loaded version of Flex Do not implement that method.
</Info>

### When to dismount according to presentation

| Presentation  | When to Unmount                                                               | Following visual action                                      |
| :------------ | :---------------------------------------------------------------------------- | :----------------------------------------------------------- |
| Drink         | When you hide the checkout, you change Section or navigate to another screen. | Withdraw or replace the constore where it was Flex.          |
| Popup (modal) | When the buyer closes his pup or his flow ends.                               | Hide the overlay and return the focus to the main interface. |
| Expand        | When you get a check out or leave an expanded vision.                         | Take the panel or restore the earlier Layout.                |

In all 3 cases, first process any outstanding result and then run `unmountFlex()` before updating the visual presentation.

<Warning>
  Do not modify the internal styles of Flex. Execut `unmountFlex()` When you withdraw the form, regardless of whether it's embedded, into a popup or an expanded view.
</Warning>

### own result screen

When you set up `settings.display_result_screen: false`, Flex doesn't have his final screen. Your application should get the `response`, evaluate the status of the transaction and display an own result screen.

<Steps>
  <Step title="Mount form">
    `paymentForm.init(...)` challenges Flex inside the container.
  </Step>

  <Step title="Receives result">
    Flex run `responseCallback(response)`. Read the result from `response.transaction.state` and conduct related business validations.
  </Step>

  <Step title="Show your screen">
    Save the `response` at the status of your application and navigate or render the result screen from the merchant.
  </Step>

  <Step title="Unmount Flex">
    When the result has been processed, run `terminate()`, cleanes the container and updates the presentation drunk, popup or expanded.
  </Step>
</Steps>

```javascript theme={"system"} theme={"system"}
const paymentForm = new FlexPaymentForms({
  nonce,
  payload,
  settings: {
    display_result_screen: false
  }
});

const flexContainer = document.querySelector("#flex-container");

paymentForm.init(
  flexContainer,
  (response) => {
    const transactionState = response.transaction?.state;

    // Procesa y conserva la respuesta antes de desmontar Flex.
    showMerchantResultScreen({ transactionState, response });
    unmountFlex();
  },
  (tracking) => {
    console.log("Evento de seguimiento", tracking);
  },
  (error) => {
    console.error("Error de Flex", error);
  }
);
```

<Warning>
  Don't run `terminate()` before receiving and processing `responseCallback(response)`. If you finish the instance earlier, you can stop the flow and lose the result that Flex He's been put up.
</Warning>

### Reusable cleaning

It encapsulates initiation and dismantling into an independent framework controller. You can use them from pure JavaScript or connect them to React's life cycle, Vue, Angular or other technologies.

```javascript theme={"system"} theme={"system"}
function createFlexController({
  container,
  configuration,
  onResult,
  onTracking,
  onError
}) {
  let instance = null;

  function mount() {
    // Evita conservar una instancia anterior al volver a abrir Flex.
    destroy();

    instance = new FlexPaymentForms(configuration);
    instance.init(container, onResult, onTracking, onError);
  }

  function destroy() {
    instance?.terminate?.();
    instance = null;
    container.replaceChildren();
  }

  return { mount, destroy };
}

const flexController = createFlexController({
  container: document.querySelector("#flex-container"),
  configuration: {
    nonce,
    payload,
    settings: {
      display_result_screen: false
    }
  },
  onResult: responseCallback,
  onTracking: trackingCallback,
  onError: onErrorCallback
});

// Abre o vuelve a crear el formulario.
flexController.mount();

// Finaliza la instancia al cerrar, navegar o retirar la presentación.
// flexController.destroy();
```

<CardGroup cols={3}>
  <Card title="JavaScript" icon="code">
    Execut `destroy()` before withdrawing the container from the page.
  </Card>

  <Card title="Implementation SPA" icon="arrows-rotate">
    Connect `destroy()` to change of path or to dismount vision.
  </Card>

  <Card title="Dynamic presentation" icon="window-restore">
    Do so by hiding the embossed block, closing the Popup or getting an expanded view.
  </Card>
</CardGroup>

`container.replaceChildren()` an empty constore equivalent to `container.innerHTML = ""`without dependent on a specific framework.

<Note>
  `terminate()` does not return the payment response. The result always comes with the first call of `paymentForm.init(...)`. Check. [Capture callback functions](/en/virtual-payments/checkout-web/flex/handling-callback-functions) to interpret and confirm the operation.
</Note>

### Management of closure with show\_close\_button

Figure `settings.show_close_button: true` to display the native clasp of Flex. That option works with embumbing, pounding and expanding presentations.

```javascript theme={"system"} theme={"system"}
const paymentForm = new FlexPaymentForms({
  nonce,
  payload,
  settings: {
    show_close_button: true
  }
});
```

When the buyer presses the button, Flex send message `cerro el carrito` with `onErrorCallback`. Although using the error call, this message represents a voluntary action by the buyer and not a technical failure.

<CardGroup cols={3}>
  <Card title="Show the button" icon="circle-xmark">
    Active `show_close_button` inside `settings`.
  </Card>

  <Card title="Play the event" icon="code-branch">
    Identifies the exact message `cerro el carrito` in `onErrorCallback`.
  </Card>

  <Card title="Close presentation" icon="power-off">
    Execut `onClose()` for dismantling Flex and update the interface.
  </Card>
</CardGroup>

It implements an exclusive branch for voluntary closure and preserves other messages as technical errors:

```javascript theme={"system"} theme={"system"}
function getFlexErrorMessage(error) {
  if (typeof error === "string") return error;
  return error?.message ?? "";
}

function onErrorCallback(error) {
  const errorMessage = getFlexErrorMessage(error).trim();

  if (errorMessage === "cerro el carrito") {
    onClose();
    return;
  }

  // Los demás mensajes se procesan como errores técnicos.
  handleFlexError(error);
}

function onClose() {
  unmountFlex();

  // Oculta el popup, retira el bloque embebido o contrae la vista expandida.
  hideFlexPresentation();
}
```

The closing flow is `show_close_button` → `onErrorCallback` → `onClose()` → `unmountFlex()`. `hideFlexPresentation()` represents the visual logic of your application: remove the embedded block, hide the popup or get an expanded view.

<Warning>
  Execut `onClose()` only after complete message `cerro el carrito`. Any other value received at `onErrorCallback` have to continue to manage technical errors.
</Warning>

## Before posting

Check the component in these scenarios:

| Scenario                     | Expected result                                      |
| :--------------------------- | :--------------------------------------------------- |
| Wide viewing web             | The form keeps the scale `1` and it's focused.       |
| Vertical and horizontal cell | No horizontal scroll or cut constore appears.        |
| Retirement                   | The scale recalculates without re-initializing Flex. |
| Change of step or method     | The new height remains inside the Viewport.          |
| Virtual keyboard open        | Active fields are still visible and usable.          |

<Warning>
  The callbacks do not replace payment confirmation from backend. Continue with the callback guide to interpret the result.
</Warning>

## Next step

<CardGroup cols={2}>
  <Card title="Capture callback functions" icon="arrow-right" href="/en/virtual-payments/checkout-web/flex/handling-callback-functions">
    Define `responseCallback`, `trackingCallback` and `onErrorCallback` to react correctly to the flow.
  </Card>

  <Card title="Construction of payload" icon="arrow-left" href="/en/virtual-payments/checkout-web/flex/payload-construction">
    If you haven't put up an operation's item, come back to the guide to `payload`.
  </Card>
</CardGroup>
