# `paymob-widget-alpha`
Paymob Installments Widget that can be embedded in any web page to display installment plans and (optionally) let the user select a plan.

## Installing

### CDN

Using jsDelivr:

```html
<script src="https://cdn.jsdelivr.net/npm/paymob-widget-alpha@latest/main.js" type="module"></script>
```

## Usage

Create a container element in your page:

```html
<div id="paymob-widget"></div>
```

Then instantiate the widget:

```js
new PaymobWidget({
  publicKey: 'egy_pk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  elementId: 'paymob-widget',
  amount: 100000, // required — order total in cents (1000 EGP)
  currency: 'EGP',
  integrationId: 123 || [123456, 2233], // optional — single number or array
});
```

If `amount` is missing, invalid, or not a positive finite number, the widget **will not initialize** and an error is logged to the console.

### When the widget is shown or hidden

The widget is **only rendered** when all of the following are true:

- `amount` is valid (positive finite number in **cents**)
- The installment-plans request returns a **2xx** status
- At least one installment plan is available after processing the response

The widget is **not shown** when:

- `amount` is missing, `≤ 0`, or not a finite number → constructor stops and logs `console.error`
- The API request **fails** (any non-2xx status, e.g. `400`) → widget hidden; `console.error` includes the status code
- The API **succeeds** but returns **no plans** (e.g. invalid integration, amount below minimum, no bank installment configured) → widget hidden; `console.error` is logged

**End users do not see error messages** on the page or in the modal. Errors are for developers in the **browser console** only (`[PaymobWidget] ...`).

### Selectable mode example

To let the user select an installment plan and handle the selection in your app, enable `customerCanSelect` and pass an `onSubmit` callback.

```js
new PaymobWidget({
  publicKey: 'egy_pk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  elementId: 'paymob-widget',
  amount: 100000, // required — order total in cents (1000 EGP)
  currency: 'EGP',
  integrationId: 123 || [123456, 2233], // optional — single number or array
  theme: 'primary',
  customerCanSelect: true,
  onSubmit: (plan) => {
    // Called when the user clicks **Buy now**.
    // With customerCanSelect: true, plan is provided after the user selects a plan.
    // plan = { id: 123, tenure: 12, amount: 25000 } // amount = monthly installment in cents
    // With customerCanSelect: false, onSubmit is called with no payload.
  },
});
```

## Properties

| Property | Type | Required | Definition |
| --- | --- | --- | --- |
| publicKey | String | Yes | Your public key (used to resolve API base URL and authenticate requests). |
| elementId | String | Yes | ID of the HTML element where the widget will be rendered. |
| theme | `"primary" \| "light" \| "dark"` | No | Widget theme. Default: `"primary"`. |
| amount | Number | Yes | Order total in **cents** (positive finite number). **Required** — no default. The widget will not initialize without it. |
| currency | String | No | Currency code. Default: `"EGP"`. |
| integrationId | Number \| Number[] | No | Paymob integration ID(s). If provided, sent when fetching installment plans. |
| customerCanSelect | Boolean | No | If `true`, the user can select a plan and **Buy now** is enabled. Default: `false`. |
| onSubmit | Function | No | Called when the user clicks **Buy now**. With `customerCanSelect: true`, receives `{ id, tenure, amount }`. With `false`, called with no payload. |

### `customerCanSelect` and Learn more

| Value | Behavior |
| --- | --- |
| `true` | User can **select** a plan. Learn more includes the **Select Installment Plan** step. |
| `false` | Plans are **read-only**. Learn more omits the selection step and uses different copy on the final payment step. |

### `onSubmit` payload

When `customerCanSelect` is `true`:

```js
{
  id: string | number,   // installment plan id
  tenure: number,        // number of months
  amount: number         // monthly installment amount in cents
}
```

## Full HTML example

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Paymob Widget Example</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      #paymob-widget {
        width: 100%;
        margin: 10% auto 0;
      }
      body {
        margin: 0;
      }
    </style>
  </head>

  <body>
    <div id="paymob-widget"></div>

    <script src="https://cdn.jsdelivr.net/npm/paymob-widget-alpha@latest/main.js" type="module"></script>

    <script>
      window.onload = () => {
        new PaymobWidget({
          publicKey: 'egy_pk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          elementId: 'paymob-widget',
          amount: 100000, // required — order total in cents (1000 EGP)
          currency: 'EGP',
          integrationId: 123,
          theme: 'primary',
          customerCanSelect: true,
          onSubmit: (plan) => {
            console.log('Selected plan', plan);
          },
        });
      };
    </script>
  </body>
</html>
```

## Notes

- **Rendering**: The widget renders into your `elementId` container only when eligible plans are available (see [When the widget is shown or hidden](#when-the-widget-is-shown-or-hidden)).
- **Isolation**: UI is rendered inside a Shadow DOM wrapper to reduce CSS conflicts with the host page.
