@htmlbricks/hb-checkout 0.71.35 → 0.71.37
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 +321 -30
- package/main.iife.js +1 -1
- package/main.iife.js.map +1 -1
- package/manifest.json +93 -30
- package/package.json +1 -1
- package/types/webcomponent.type.d.json +0 -3
- package/types/webcomponent.type.d.ts +0 -2
- package/types/webcomponent_events.type.d.json +1 -9
package/README.md
CHANGED
|
@@ -1,54 +1,345 @@
|
|
|
1
1
|
## `hb-checkout` — checkout
|
|
2
2
|
|
|
3
|
-
**Category:** commerce
|
|
3
|
+
**Category:** commerce · **Tags:** commerce, checkout · **Package:** `@htmlbricks/hb-checkout`
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Summary
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
`hb-checkout` is a **multi-step commerce checkout surface** hosted as a single custom element. It combines:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- A **delivery / identity** block (read-only profile, a fixed “display-only” profile mode, or an embedded **`hb-form`** for address capture).
|
|
10
|
+
- An optional **shipment method** block (built from your `shipments` array into another **`hb-form`** radio group, plus read-only summaries with **edit** affordances).
|
|
11
|
+
- A **payment** block that can render **PayPal** (`hb-payment-paypal`) and/or **Google Pay** (`<google-pay-button>` from `@google-pay/button-element`), driven by a **`gateways`** list and a shared **`payment`** descriptor.
|
|
12
|
+
- A **terms / notice** region (default copy + slot), and a **post-payment** confirmation region when checkout is marked complete.
|
|
10
13
|
|
|
11
|
-
`
|
|
14
|
+
Structured inputs (`shipments`, `user`, `gateways`, `payment`) are **JSON-serialized strings** when used from HTML attributes; the component **parses** them in an effect and normalizes defaults (for example **`payment.type`** defaults to **`buy`** if omitted, and **Google Pay** gateways without `cardNetworks` get **`["VISA","MASTERCARD"]`**).
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
---
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
### Behavior
|
|
19
|
+
|
|
20
|
+
#### Data ingestion and normalization
|
|
21
|
+
|
|
22
|
+
- **`payment`**, **`shipments`**, **`gateways`**, and **`user`** may arrive as **strings** (JSON). The component parses them inside `$effect` and replaces the bound values with parsed objects where applicable.
|
|
23
|
+
- If **`payment.type`** is missing after parse, it is set to **`buy`**.
|
|
24
|
+
- For each **Google** gateway after parsing **`gateways`**, if **`cardNetworks`** is missing or empty, it is set to **`["VISA","MASTERCARD"]`**.
|
|
25
|
+
- **`user`** (when a string) is merged into the internal **`formUserSchema`** field **`value`** entries so the embedded profile form reflects prefilled data (including nested **`row`** / **`columns`** ids when present in the schema).
|
|
26
|
+
|
|
27
|
+
#### Shipment radio schema
|
|
28
|
+
|
|
29
|
+
- The shipment **`hb-form`** uses a single required **radio** field with id **`shipmentsolution`**. Its options are rebuilt from **`shipments`**: each option’s **`label`** is **`${label} ${price}${currency}`** and **`value`** is the shipment **`id`**.
|
|
30
|
+
- If any shipment has **`selected: true`** or **`standard: true`**, that shipment’s **`id`** becomes the radio **`value`** in the schema (so the UI starts on a preselected / standard line when you pass those flags).
|
|
31
|
+
|
|
32
|
+
#### Local UI state (not separate custom events)
|
|
33
|
+
|
|
34
|
+
- **`editUser`** and **`editShipping`** toggle between **summary rows** (with ghost **edit** buttons) and the **`hb-form`** editors.
|
|
35
|
+
- Submitting the profile or shipment form sets internal **`formUserSchemaSubmitted`** / **`formShipmentSchemaSubmitted`** to **`yes`** briefly (with a short timeout back to **`no`**) so **`hb-form`** can run its submit path while **`hide_submit="yes"`** hides the form’s own submit control; the visible **Continue** button triggers that pulse.
|
|
36
|
+
- **`completed`** is a **host prop** (`"yes"` | `"no"`). When a wallet flow finishes successfully, the code sets **`completed = "yes"`** locally and fires **`paymentCompleted`**. It does **not** currently dispatch a separate **`completed`** custom event (see [Events](#events-customevent)).
|
|
37
|
+
|
|
38
|
+
#### Wallet rendering rules
|
|
39
|
+
|
|
40
|
+
- **PayPal**: rendered for every gateway with **`id === "paypal"`**, passing **`paypalid`**, **`total`** as a string from **`payment.total`**, and listening for **`hb-payment-paypal`** **`paymentCompleted`** to call the shared **`paymentCompleted("paypal")`** handler.
|
|
41
|
+
- **Google Pay**: rendered only when **`id === "google"`** **and** **`payment.countryCode`** is truthy. The `<google-pay-button>` is configured with **`environment="TEST"`** (hardcoded in the template), **`button-type`** from **`payment.type`** lowercased, **`button-size-mode="fill"`**, and a **`paymentRequest`** built from **`payment`** plus gateway fields (`gatewayId`, `gatewayMerchantId`, optional `merchantId` on the gateway, `merchantName` on `payment`, `allowedCardNetworks` from the gateway). **`loadpaymentdata`** calls **`paymentCompleted("google")`**.
|
|
42
|
+
- **`visibleWalletCount`** counts gateways that will actually render (**PayPal** always; **Google** only with **`countryCode`**). The wallet row adds a **single-column** layout class when that count is **`1`**, and **empty** PayPal/Google containers are hidden in the single-column case so a non-rendered Google row does not leave a blank grid cell.
|
|
43
|
+
|
|
44
|
+
#### Card form
|
|
45
|
+
|
|
46
|
+
- A **credit-card** path exists in **`libs/formSchemes.ts`** (`formCreditCardSchema`) and helper **`cardChange`**, but the **card UI block is commented out** in `component.wc.svelte`. **Consumers should not expect manual card entry** in the current build—only PayPal and Google Pay surfaces are active.
|
|
47
|
+
|
|
48
|
+
#### Dependencies loaded at runtime
|
|
49
|
+
|
|
50
|
+
- **`addComponent`** registers **`@htmlbricks/hb-form`** and **`@htmlbricks/hb-payment-paypal`** at the same version as the builder **`package.json`** so nested custom elements resolve consistently.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### UI layout (top to bottom)
|
|
55
|
+
|
|
56
|
+
1. **`title` slot** — Default content is a centered **`<h1 class="title">`** with text **Checkout** and **`part="title"`** (bottom border uses **`--hb-checkout-border`**).
|
|
57
|
+
2. **`#border_top`** — Main “Delivery” column:
|
|
58
|
+
- **Subtitle** “Delivery” with send icon; the heading exposes `part="subtitle"`.
|
|
59
|
+
- **Profile branch** (exact branch is described under [Checkout logic](#checkout-logic--visibility)):
|
|
60
|
+
- Fixed user mode, read-only filled user, or **`hb-form`** + **Continue**.
|
|
61
|
+
- **`#shipment_separator`** (only if **`shipments.length > 0`**): shipment summary or **`hb-form`** + **Continue**, depending on user completeness, edit flags, and whether a **selected/standard** shipment exists.
|
|
62
|
+
3. **`.payment_title`** — Separated from the block above by **`--hb-checkout-border`** on the top:
|
|
63
|
+
- If **`completed !== "yes"`**: “Payment Method” subtitle (wallet icon), optional **wallet grid**, then **`.footer_note`** with **`part="payment_terms_note"`** wrapping the **`payment_terms`** slot.
|
|
64
|
+
- If **`completed === "yes"`**: **`payment_completed`** slot (default centered “payment completed”, total line, text **invoice** button—**no click handler** is wired in the default fragment).
|
|
65
|
+
|
|
66
|
+
Icons use **Bootstrap Icons** classes; **`webcomponent.scss`** imports the icon font into the **shadow tree** (a `<svelte:head>` stylesheet link **does not** apply inside shadow DOM, so the Sass **`@import`** is the reliable source).
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### Checkout logic & visibility
|
|
71
|
+
|
|
72
|
+
#### Profile (delivery identity)
|
|
73
|
+
|
|
74
|
+
| Condition | What you see |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| **`user?.fixed`** and **not** **`editUser`** | Minimal **read-only** area: default **`userinfo`** slot content only renders **`fullName`** when set (you can replace the slot for richer fixed-profile layouts). |
|
|
77
|
+
| **`user.fullName`** and **`user.addressWithNumber`** and **not** **`editUser`** | Read-only **Name** and **Address** rows (address concatenates street, city, zip, nationality) plus an **edit** button → **`editUser`** mode. |
|
|
78
|
+
| Otherwise | **“Address”** subtitle and **`hb-form`** (user schema) + primary **Continue**. On successful submit → **`saveUser`** event, internal **`user`** update, **`editUser`** cleared. |
|
|
79
|
+
|
|
80
|
+
#### Shipment block
|
|
81
|
+
|
|
82
|
+
Rendered only when **`shipments`** is a non-empty array.
|
|
83
|
+
|
|
84
|
+
- If **((full profile)** **`fullName` + `addressWithNumber`)** **or** **`user.fixed`**) **and** **not** **`editUser`**:
|
|
85
|
+
- With **not** **`editShipping`** and a **selected** or **standard** shipment → **read-only** fee + arrival rows (arrival formatted with **dayjs** in this branch) and **edit** → **`editShipping`**.
|
|
86
|
+
- Else → shipment **`hb-form`** + **Continue** → **`saveShipment`** selects that id, clears **`editShipping`**.
|
|
87
|
+
- Else if **not** **`editShipping`** and a **selected** or **standard** shipment exists → **read-only** shipment summary **without** requiring the full address branch first (second row shows **“Shipping Time”** and the raw **`arriveDate`** value—**not** passed through **dayjs** in this branch; consider keeping ISO strings for consistent display).
|
|
88
|
+
|
|
89
|
+
#### Payment block
|
|
90
|
+
|
|
91
|
+
Wallet buttons render only when **all** of the following hold:
|
|
92
|
+
|
|
93
|
+
- **`completed !== "yes"`**
|
|
94
|
+
- **Not** in **`editUser`** and **not** in **`editShipping`**
|
|
95
|
+
- Either **no shipments** **or** there is a **selected** or **standard** shipment (or the list is treated as satisfied via **`find`** on **`shipments`**)
|
|
96
|
+
|
|
97
|
+
Otherwise the payment wallet area is **suppressed** until the flow is in a “stable” profile + shipment state.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### Custom element tag
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<hb-checkout></hb-checkout>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### Attributes (snake_case; HTML values are strings)
|
|
110
|
+
|
|
111
|
+
From HTML or **`setAttribute`**, pass **objects and arrays as JSON strings**, **numbers as their decimal string**, and **booleans as `yes` / `no`** where applicable (see project conventions).
|
|
112
|
+
|
|
113
|
+
| Attribute | Required | Description |
|
|
114
|
+
| --- | --- | --- |
|
|
115
|
+
| **`shipments`** | Yes | JSON array of **`IShipment`** (see [Typings](#typings)). Each item needs at least **`price`**, **`arriveDate`** (ISO string recommended), **`available`**, **`id`**, **`label`**, **`currency`**. Optional **`selected`**, **`standard`** preselect a line. |
|
|
116
|
+
| **`gateways`** | Yes | JSON array of **`IGateway`** (see [Typings](#typings)). Supports **`id`**: **`paypal`** \| **`google`**. PayPal rows need a **`paypalid`**. Google rows need gateway configuration fields used in the **`paymentRequest`** (`gatewayId`, `gatewayMerchantId`, optional `merchantId`, etc.—see types). |
|
|
117
|
+
| **`payment`** | Yes | JSON **`IPayment`**: **`merchantName`**, **`total`**, **`currencyCode`**, **`countryCode`**, optional **`type`** (**`IPaymentType`**; defaults to **`buy`** if omitted), optional **`shipmentFee`**. **`countryCode`** controls whether **Google Pay** can render. |
|
|
118
|
+
| **`user`** | No | JSON **`IUser`** for prefilled / read-only display. Optional **`fixed`**: when **`true`** (boolean inside the JSON object), the component uses the **minimal fixed** profile branch. |
|
|
119
|
+
| **`completed`** | No | **`yes`** \| **`no`** (strings). **`no`** default. When **`yes`**, the component shows the **`payment_completed`** slot instead of wallet UI (you can set this from the host after your own backend confirmation, or it flips to **`yes`** after **`paymentCompleted`** handling in code). |
|
|
120
|
+
| **`id`** | No | Host element id string. |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### Events (`CustomEvent`)
|
|
125
|
+
|
|
126
|
+
Listeners use the **exact event type string** (camelCase), e.g. **`addEventListener("paymentCompleted", …)`** or in Svelte **`onpaymentCompleted={…}`**.
|
|
127
|
+
|
|
128
|
+
| Event | `detail` shape | When it fires |
|
|
129
|
+
| --- | --- | --- |
|
|
130
|
+
| **`saveUser`** | **`IUser`** | After the address **`hb-form`** submits valid data: **`fullName`**, **`addressWithNumber`**, **`city`**, **`zip`**, **`nationality`**. Internal schema values and **`user`** are updated; **`editUser`** becomes false. |
|
|
131
|
+
| **`saveShipment`** | **`IShipment`** | After the shipment radio form submits a valid **`shipmentsolution`** id that exists in **`shipments`**: that shipment is marked **`selected: true`**, others **`selected: false`**, and **`editShipping`** becomes false. |
|
|
132
|
+
| **`paymentCompleted`** | **`{ total: number; method: string; completed: true }`** | After **PayPal** or **Google Pay** signals success via their respective handlers. **`method`** is **`"paypal"`** or **`"google"`**. The host **`completed`** prop is set to **`yes`** (not a separate DOM event). |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Styling
|
|
137
|
+
|
|
138
|
+
#### Bulma and host baseline
|
|
139
|
+
|
|
140
|
+
`styles/bulma.scss` forwards Bulma **1.x** utilities and **`button`**, **`title`**, plus helpers (**spacing**, **flexbox**, **gap**, **typography**), then applies **`light`** theme + **`setup`** on **`:host`**. Prefer **Bulma CSS variables** documented by Bulma and the variables below.
|
|
141
|
+
|
|
142
|
+
`styles/webcomponent.scss` pulls in **`host-baseline`** shared styles, sets **`:host`** display and typography tokens (**`--bulma-title-size`**, **`--bulma-subtitle-size`**, base **`font-size`** from **`--bulma-size-medium`**), and defines layout for titles, edit buttons, data rows, the wallet grid, and the terms panel.
|
|
143
|
+
|
|
144
|
+
#### CSS custom properties (documented for consumers)
|
|
145
|
+
|
|
146
|
+
| Variable | Role |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| **`--bulma-primary`** | Primary **Continue** buttons. |
|
|
149
|
+
| **`--bulma-link`** | Ghost **terms** link color; feeds **`--edit-color`** when unset. |
|
|
150
|
+
| **`--bulma-text`** | Default foreground for body and headings inside the flow. |
|
|
151
|
+
| **`--bulma-border`** | Dividers and default border color. |
|
|
152
|
+
| **`--bulma-border-weak`** | Softer border on the terms notice panel. |
|
|
153
|
+
| **`--bulma-background`** | Mixed into the terms notice **background** (`color-mix` with border). |
|
|
154
|
+
| **`--bulma-text-weak`** | Muted default terms copy. |
|
|
155
|
+
| **`--bulma-title-size`**, **`--bulma-subtitle-size`**, **`--bulma-subtitle-weight`** | Title / subtitle scale and weight on **` :host`**. |
|
|
156
|
+
| **`--bulma-size-medium`**, **`--bulma-size-small`** | Base host font size and smaller terms text. |
|
|
157
|
+
| **`--bulma-block-spacing`** | Line height spacing for definition-style rows. |
|
|
158
|
+
| **`--bulma-weight-bold`**, **`--bulma-weight-semibold`** | Edit controls and terms link weight. |
|
|
159
|
+
| **`--bulma-radius`** | Radius for the terms panel and compact links. |
|
|
160
|
+
| **`--edit-color`** | Ghost **edit** buttons (defaults to **`--bulma-link`**). |
|
|
161
|
+
| **`--hb-checkout-border`** | Border under the main title and above the payment section (default **`1px solid`** using **`--bulma-border`**). |
|
|
162
|
+
| **`--paypal-button-color`** | Reserved for PayPal chrome overrides (optional). |
|
|
163
|
+
|
|
164
|
+
#### Layout classes
|
|
165
|
+
|
|
166
|
+
- **`#payment_btn_container.hb-payment-wallet-row`** — two-column **CSS grid** for wallet buttons with gap; collapses to one column with **`.hb-payment-wallet-row--single`** when only one wallet is visible.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### CSS parts (`::part`)
|
|
171
|
+
|
|
172
|
+
Style from outside the shadow tree with **`hb-checkout::part(...)`**.
|
|
173
|
+
|
|
174
|
+
| Part | Exposed on | Purpose |
|
|
16
175
|
| --- | --- | --- |
|
|
17
|
-
|
|
|
18
|
-
| `
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
176
|
+
| **`title`** | Default heading in **`title` slot** | Centered main title; bottom rule uses **`--hb-checkout-border`**. |
|
|
177
|
+
| **`subtitle`** | Multiple **`h3` / `h4` subtitles** | Section labels (Delivery, Address, Shipment Service, Payment Method, etc.). |
|
|
178
|
+
| **`payment_terms_note`** | Wrapper **`.footer_note`** around **`payment_terms`** | Panel chrome (border, radius, background mix) for legal / policy copy. |
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### Slots
|
|
183
|
+
|
|
184
|
+
| Slot | Default | Purpose |
|
|
185
|
+
| --- | --- | --- |
|
|
186
|
+
| **`title`** | `<h1 part="title">Checkout</h1>` | Replace or wrap the main title region. |
|
|
187
|
+
| **`userinfo`** | Conditional name row in **fixed** user mode | Extra markup in the billing / shipping profile area around **`hb-form`** / read-only rows when you need custom layout (especially with **`user.fixed`**). |
|
|
188
|
+
| **`payment_terms`** | Short default sentence + ghost **terms and conditions** button (no navigation wired) | Replace with binding legal text, links, or checkboxes. Still wrapped by **`payment_terms_note`** styling unless you override via **`::part`**. |
|
|
189
|
+
| **`payment_completed`** | Centered confirmation title, total, **invoice** text button | Replace the post-payment panel when **`completed="yes"`**. |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### Typings
|
|
194
|
+
|
|
195
|
+
Authoring types live in **`types/webcomponent.type.d.ts`**. Shapes below mirror that file.
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
export type IShipment = {
|
|
199
|
+
price: number;
|
|
200
|
+
selected?: boolean;
|
|
201
|
+
standard?: boolean;
|
|
202
|
+
arriveDate: Date;
|
|
203
|
+
available: boolean;
|
|
204
|
+
id: string;
|
|
205
|
+
label: string;
|
|
206
|
+
currency: string;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export type IUser = {
|
|
210
|
+
fullName: string;
|
|
211
|
+
addressWithNumber?: string;
|
|
212
|
+
city?: string;
|
|
213
|
+
zip?: string;
|
|
214
|
+
nationality?: string;
|
|
215
|
+
fixed?: boolean;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export type IGateway = {
|
|
219
|
+
id: "google" | "paypal";
|
|
220
|
+
label: string;
|
|
221
|
+
fixedPrice?: number;
|
|
222
|
+
currency?: "€" | "$";
|
|
223
|
+
percentagePrice?: number;
|
|
224
|
+
paypalid?: string;
|
|
225
|
+
cardNetworks?: string[];
|
|
226
|
+
gatewayId?: string;
|
|
227
|
+
gatewayMerchantId?: string;
|
|
228
|
+
merchantId?: string;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export type IPaymentType =
|
|
232
|
+
| "book"
|
|
233
|
+
| "buy"
|
|
234
|
+
| "checkout"
|
|
235
|
+
| "donate"
|
|
236
|
+
| "order"
|
|
237
|
+
| "pay"
|
|
238
|
+
| "plain"
|
|
239
|
+
| "subscribe";
|
|
240
|
+
|
|
241
|
+
export type IPayment = {
|
|
242
|
+
merchantName: string;
|
|
243
|
+
total: number;
|
|
244
|
+
currencyCode: string;
|
|
245
|
+
countryCode: string;
|
|
246
|
+
type?: IPaymentType;
|
|
247
|
+
shipmentFee?: number;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
export type Component = {
|
|
251
|
+
id?: string;
|
|
252
|
+
shipments: IShipment[];
|
|
253
|
+
user?: IUser;
|
|
254
|
+
gateways: IGateway[];
|
|
255
|
+
payment: IPayment;
|
|
256
|
+
completed?: "yes" | "no";
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export type Events = {
|
|
260
|
+
paymentCompleted: { total: number; method: string; completed: true };
|
|
261
|
+
saveUser: IUser;
|
|
262
|
+
saveShipment: IShipment;
|
|
263
|
+
};
|
|
264
|
+
```
|
|
24
265
|
|
|
25
|
-
**
|
|
266
|
+
**Runtime vs authoring:** At runtime, JSON parsing yields **plain objects**; date fields may be **strings** until you convert them—**dayjs** is used only in one shipment summary branch.
|
|
26
267
|
|
|
27
|
-
|
|
268
|
+
---
|
|
28
269
|
|
|
29
|
-
|
|
30
|
-
- **`saveUser`** — `IUser` payload
|
|
31
|
-
- **`saveShipment`** — `IShipment` payload
|
|
32
|
-
- **`completed`** — `"yes"` \| `"no"` (listed in `Events` interface)
|
|
270
|
+
### Examples
|
|
33
271
|
|
|
34
|
-
|
|
272
|
+
#### PayPal only (minimal host page)
|
|
35
273
|
|
|
36
|
-
|
|
274
|
+
```html
|
|
275
|
+
<hb-checkout
|
|
276
|
+
completed="no"
|
|
277
|
+
payment='{"merchantName":"Acme","total":"49.99","currencyCode":"EUR","countryCode":"IT","type":"buy"}'
|
|
278
|
+
shipments='[{"id":"std","label":"Standard","price":5,"arriveDate":"2026-04-01T00:00:00.000Z","available":true,"currency":"€","standard":true}]'
|
|
279
|
+
gateways='[{"id":"paypal","label":"PayPal","paypalid":"YOUR_CLIENT_OR_SANDBOX_ID"}]'
|
|
280
|
+
></hb-checkout>
|
|
281
|
+
```
|
|
37
282
|
|
|
38
|
-
|
|
283
|
+
#### PayPal + Google Pay (Google requires `countryCode` and gateway fields)
|
|
39
284
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
285
|
+
```html
|
|
286
|
+
<hb-checkout
|
|
287
|
+
completed="no"
|
|
288
|
+
payment='{"merchantName":"Acme","total":"99.00","currencyCode":"EUR","countryCode":"IT","type":"buy"}'
|
|
289
|
+
shipments='[{"id":"express","label":"Express","price":"9","arriveDate":"2026-04-18T12:00:00.000Z","available":true,"currency":"€"}]'
|
|
290
|
+
gateways='[
|
|
291
|
+
{"id":"paypal","label":"PayPal","paypalid":"YOUR_PAYPAL_ID"},
|
|
292
|
+
{
|
|
293
|
+
"id":"google",
|
|
294
|
+
"label":"Google Pay",
|
|
295
|
+
"gatewayId":"example",
|
|
296
|
+
"gatewayMerchantId":"exampleGatewayMerchantId",
|
|
297
|
+
"merchantId":"01234567890123456789",
|
|
298
|
+
"cardNetworks":["VISA","MASTERCARD"]
|
|
299
|
+
}
|
|
300
|
+
]'
|
|
301
|
+
></hb-checkout>
|
|
302
|
+
```
|
|
44
303
|
|
|
45
|
-
|
|
304
|
+
#### Prefilled profile (read-only until **edit**)
|
|
46
305
|
|
|
47
306
|
```html
|
|
48
307
|
<hb-checkout
|
|
49
308
|
completed="no"
|
|
50
|
-
payment='{"merchantName":"Acme","total":
|
|
51
|
-
shipments='[{"id":"
|
|
309
|
+
payment='{"merchantName":"Acme","total":"45","currencyCode":"EUR","countryCode":"IT"}'
|
|
310
|
+
shipments='[{"id":"s1","label":"Ground","price":10,"arriveDate":"2026-05-01T08:00:00.000Z","available":true,"currency":"€","selected":true}]'
|
|
52
311
|
gateways='[{"id":"paypal","label":"PayPal","paypalid":"sandbox"}]'
|
|
312
|
+
user='{"fullName":"Jane Example","addressWithNumber":"Via Roma 1","city":"Milan","zip":"20100","nationality":"IT"}'
|
|
53
313
|
></hb-checkout>
|
|
54
314
|
```
|
|
315
|
+
|
|
316
|
+
#### Completed state (confirmation slot default)
|
|
317
|
+
|
|
318
|
+
```html
|
|
319
|
+
<hb-checkout
|
|
320
|
+
completed="yes"
|
|
321
|
+
payment='{"merchantName":"Acme","total":"45","currencyCode":"EUR","countryCode":"IT"}'
|
|
322
|
+
shipments='[]'
|
|
323
|
+
gateways='[]'
|
|
324
|
+
></hb-checkout>
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### Listening from JavaScript
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
const el = document.querySelector("hb-checkout");
|
|
331
|
+
el.addEventListener("saveUser", (e) => console.log("user", e.detail));
|
|
332
|
+
el.addEventListener("saveShipment", (e) => console.log("shipment", e.detail));
|
|
333
|
+
el.addEventListener("paymentCompleted", (e) =>
|
|
334
|
+
console.log(e.detail.method, e.detail.total, e.detail.completed),
|
|
335
|
+
);
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
### Operational notes
|
|
341
|
+
|
|
342
|
+
- **Google Pay** is wired with **`environment="TEST"`** in the template; change the source before production if you need **PRODUCTION**.
|
|
343
|
+
- Nested **`hb-form`** and **`hb-payment-paypal`** carry **their own** styles and events—consult their READMEs for schema knobs and PayPal props.
|
|
344
|
+
- This component declares **no i18n language list** in **`extra/docs.ts`**; UI strings are **English** in the template.
|
|
345
|
+
- Bundle size: pulling **`hb-checkout`** also implies **`hb-form`** (large input surface) and **`hb-payment-paypal`** per **`componentSetup.dependencies`** in **`extra/docs.ts`**.
|