paymob-widget-alpha 1.0.13 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # `paymob-widget-alpha`
2
- Paymob Installments Widget that can be embedded in any web page to display **0% interest plans** and (optionally) let the user select a plan.
2
+ Paymob Installments Widget that can be embedded in any web page to display installment plans and (optionally) let the user select a plan.
3
3
 
4
4
  ## Installing
5
5
 
6
-
7
6
  ### CDN
8
7
 
9
8
  Using jsDelivr:
@@ -26,12 +25,30 @@ Then instantiate the widget:
26
25
  new PaymobWidget({
27
26
  publicKey: 'egy_pk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
28
27
  elementId: 'paymob-widget',
29
- amount: 1000, // amount in cents
28
+ amount: 100000, // required — order total in cents (1000 EGP)
30
29
  currency: 'EGP',
31
- integrationId: 123, // optional
30
+ integrationId: 123 || [123456, 2233], // optional — single number or array
32
31
  });
33
32
  ```
34
33
 
34
+ If `amount` is missing, invalid, or not a positive finite number, the widget **will not initialize** and an error is logged to the console.
35
+
36
+ ### When the widget is shown or hidden
37
+
38
+ The widget is **only rendered** when all of the following are true:
39
+
40
+ - `amount` is valid (positive finite number in **cents**)
41
+ - The installment-plans request returns a **2xx** status
42
+ - At least one installment plan is available after processing the response
43
+
44
+ The widget is **not shown** when:
45
+
46
+ - `amount` is missing, `≤ 0`, or not a finite number → constructor stops and logs `console.error`
47
+ - The API request **fails** (any non-2xx status, e.g. `400`) → widget hidden; `console.error` includes the status code
48
+ - The API **succeeds** but returns **no plans** (e.g. invalid integration, amount below minimum, no bank installment configured) → widget hidden; `console.error` is logged
49
+
50
+ **End users do not see error messages** on the page or in the modal. Errors are for developers in the **browser console** only (`[PaymobWidget] ...`).
51
+
35
52
  ### Selectable mode example
36
53
 
37
54
  To let the user select an installment plan and handle the selection in your app, enable `customerCanSelect` and pass an `onSubmit` callback.
@@ -40,46 +57,53 @@ To let the user select an installment plan and handle the selection in your app,
40
57
  new PaymobWidget({
41
58
  publicKey: 'egy_pk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
42
59
  elementId: 'paymob-widget',
43
- amount: 1000, // amount in cents
60
+ amount: 100000, // required — order total in cents (1000 EGP)
44
61
  currency: 'EGP',
45
- integrationId: 123, // optional
62
+ integrationId: 123 || [123456, 2233], // optional — single number or array
46
63
  theme: 'primary',
47
- customerCanSelect: true, // Enable the customer to select a plan.
64
+ customerCanSelect: true,
48
65
  onSubmit: (plan) => {
49
- // `onSubmit` is called when the user clicks **Buy now**.
50
- // In selectable mode (`customerCanSelect: true`), `plan` will be provided after the user selects a plan.
51
- // plan = { id: 123, tenure: 12, amount: 250 }
52
- // In non-selectable mode (`customerCanSelect: false`), `onSubmit` is called with no payload.
66
+ // Called when the user clicks **Buy now**.
67
+ // With customerCanSelect: true, plan is provided after the user selects a plan.
68
+ // plan = { id: 123, tenure: 12, amount: 25000 } // amount = monthly installment in cents
69
+ // With customerCanSelect: false, onSubmit is called with no payload.
53
70
  },
54
71
  });
55
72
  ```
56
73
 
57
74
  ## Properties
58
75
 
59
- The full list of properties is as follows:
60
-
61
76
  | Property | Type | Required | Definition |
62
77
  | --- | --- | --- | --- |
63
78
  | publicKey | String | Yes | Your public key (used to resolve API base URL and authenticate requests). |
64
79
  | elementId | String | Yes | ID of the HTML element where the widget will be rendered. |
65
80
  | theme | `"primary" \| "light" \| "dark"` | No | Widget theme. Default: `"primary"`. |
66
- | amount | Number | Yes | Order total in **cents** (positive finite number). Required — the widget will not initialize without it. |
81
+ | amount | Number | Yes | Order total in **cents** (positive finite number). **Required**no default. The widget will not initialize without it. |
67
82
  | currency | String | No | Currency code. Default: `"EGP"`. |
68
- | integrationId | Number | No | Paymob integration ID. If provided, it will be sent when fetching installment plans. |
69
- | customerCanSelect | Boolean | No | If `true`, the widget allows selecting a plan and will show **Buy now** actions. Default: `false`. |
70
- | onSubmit | Function | No | Called when the user clicks **Buy now**. In selectable mode (`customerCanSelect: true`), it receives `{ id, tenure, amount }`. In non-selectable mode (`customerCanSelect: false`), it is called with no payload. |
83
+ | integrationId | Number \| Number[] | No | Paymob integration ID(s). If provided, sent when fetching installment plans. |
84
+ | customerCanSelect | Boolean | No | If `true`, the user can select a plan and **Buy now** is enabled. Default: `false`. |
85
+ | onSubmit | Function | No | Called when the user clicks **Buy now**. With `customerCanSelect: true`, receives `{ id, tenure, amount }`. With `false`, called with no payload. |
86
+
87
+ ### `customerCanSelect` and Learn more
88
+
89
+ | Value | Behavior |
90
+ | --- | --- |
91
+ | `true` | User can **select** a plan. Learn more includes the **Select Installment Plan** step. |
92
+ | `false` | Plans are **read-only**. Learn more omits the selection step and uses different copy on the final payment step. |
71
93
 
72
94
  ### `onSubmit` payload
73
95
 
96
+ When `customerCanSelect` is `true`:
97
+
74
98
  ```js
75
99
  {
76
100
  id: string | number, // installment plan id
77
101
  tenure: number, // number of months
78
- amount: number // monthly amount
102
+ amount: number // monthly installment amount in cents
79
103
  }
80
104
  ```
81
105
 
82
- ### Full HTML example
106
+ ## Full HTML example
83
107
 
84
108
  ```html
85
109
  <!DOCTYPE html>
@@ -91,12 +115,12 @@ The full list of properties is as follows:
91
115
  <meta name="viewport" content="width=device-width, initial-scale=1" />
92
116
  <style>
93
117
  #paymob-widget {
94
- width: 100%;
95
- margin: 10% auto 0;
96
- }
118
+ width: 100%;
119
+ margin: 10% auto 0;
120
+ }
97
121
  body {
98
- margin: 0;
99
- }
122
+ margin: 0;
123
+ }
100
124
  </style>
101
125
  </head>
102
126
 
@@ -110,16 +134,13 @@ The full list of properties is as follows:
110
134
  new PaymobWidget({
111
135
  publicKey: 'egy_pk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
112
136
  elementId: 'paymob-widget',
113
- amount: 1000,
137
+ amount: 100000, // required — order total in cents (1000 EGP)
114
138
  currency: 'EGP',
115
- integrationId: 123, // optional
116
- theme: 'primary', // "primary" | "light" | "dark"
117
- customerCanSelect: true, // Enable the customer to select a plan.
139
+ integrationId: 123,
140
+ theme: 'primary',
141
+ customerCanSelect: true,
118
142
  onSubmit: (plan) => {
119
- // `onSubmit` is called when the user clicks **Buy now**.
120
- // In selectable mode (`customerCanSelect: true`), `plan` will be provided after the user selects a plan.
121
- // plan = { id: 123, tenure: 12, amount: 250 }
122
- // In non-selectable mode (`customerCanSelect: false`), `onSubmit` is called with no payload.
143
+ console.log('Selected plan', plan);
123
144
  },
124
145
  });
125
146
  };
@@ -130,8 +151,5 @@ The full list of properties is as follows:
130
151
 
131
152
  ## Notes
132
153
 
133
- - **Rendering**: The widget renders a Installment Widget into your `elementId` container.
154
+ - **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)).
134
155
  - **Isolation**: UI is rendered inside a Shadow DOM wrapper to reduce CSS conflicts with the host page.
135
-
136
-
137
-
Binary file