# TSHIRTORDER-1614 — Feedback payment link

> Đây là **feedback vòng 2** cho tính năng "Share payment link" (TSHIRTORDER-1546 / TSHIRTORDER-1607).
> Doc gốc: [`../TSHIRTORDER-1546-share-payment-link/share-payment-link.md`](../TSHIRTORDER-1546-share-payment-link/share-payment-link.md).
> Toàn bộ feedback ở đây nằm trên **trang checkout payment-link** (`templates/payment_link/checkout.html.twig`, route `GET /payment-link/{token}`) — không đụng flow gửi mail / webhook / API.

## Yêu cầu gốc

> 1 số feedback về cái payment link, mockup nằm trong `temp_files/1614`. Review hết các mockup trước, tạo file trong `/docs/issues`.
> Task feedback này là **TSHIRTORDER-1614 Feedback payment link**.

Kèm 5 ảnh mockup (đã copy vào `files/`):

| Ảnh | Nội dung feedback |
|-----|-------------------|
| `files/fb1-heading-forskottsbetalning.jpg` | Đổi tiêu đề trang "KASSA" → "Förskottsbetalning" |
| `files/fb2-kunduppgifter-rename-reorder.jpg` | Block "Kunduppgifter": đổi label "Namn" → "Kund" + đổi thứ tự field (2 cột) |
| `files/fb3-move-kund-block-up.jpg` | Di chuyển block "Kund" (Kunduppgifter) lên trên cùng, ngay dưới header |
| `files/fb4-svea-asks-delivery-address.jpg` | **BUG**: Svea checkout bắt khách nhập lại địa chỉ giao hàng — phải lấy sẵn từ order |
| `files/fb5-show-order-referens-info-leverans.jpg` | Thêm hiển thị "Order referens", "Information till kund", "Leverans" (đọc từ order) |

---

## Tổng quan

5 feedback, **toàn bộ ở phía backend/webshop repo này** (không có phần React):

- **FB1, FB2, FB3, FB5** — ✅ **ĐÃ CODE XONG (2026-08-26)**, chỉ sửa 1 file twig `templates/payment_link/checkout.html.twig` (text, thứ tự block, thêm vài field đọc từ `order`). Nhẹ, không rủi ro, không migration, không đụng entity/service. Lint OK. Chưa live test.
- **FB4** — ⏳ **CHƯA LÀM, chờ quyết định**. **Không phải bug code của mình**, mà là **giới hạn thật của Svea Checkout API**: API này **không cho prefill** Namn/Efternamn/Gatuadress vào iframe (chỉ prefill được email / SĐT / mã bưu điện / national id). Việc này **đã được ghi rõ trong doc gốc 1546 mục "Self-review round 1"**. Cần trao đổi lại với sếp/Liem để chọn hướng xử lý — **không tự ý hứa fix**.

> ⚠️ **Phát hiện quan trọng — phần lớn feedback là chỉnh UI trên 1 file twig có sẵn**
>
> | Việc | Trạng thái codebase hiện tại |
> |------|------------------------------|
> | Trang checkout payment-link | ✅ Đã có: `templates/payment_link/checkout.html.twig` |
> | Block "Kunduppgifter" đọc từ order | ✅ Đã có (dòng 97–124) — chỉ cần đổi label + thứ tự |
> | Tiêu đề "Kassa" | ✅ Đã có (dòng 3 `{% block title %}`, dòng 23 `<h1>`) |
> | Field `erReference`, `intoText`, `deliveryName/Address/PostNr/City/Country/Phone` | ✅ Đã có sẵn getter trên `src/Entity/Order.php` — chỉ chưa render ra twig |
> | `presetValues` gửi Svea | ✅ Đã có (`SveaService::createOrderFromOrder()` dòng 151–167) — **Svea không hỗ trợ thêm field địa chỉ**, xem FB4 |

---

## Chi tiết theo từng feedback

### FB1 — Đổi tiêu đề trang "KASSA" → "Förskottsbetalning"

**Mockup**: `files/fb1-heading-forskottsbetalning.jpg`

- Annotation: *"Change text to"* → *"Förskottsbetalning"*, mũi tên trỏ vào ô tiêu đề **"KASSA"** (góc trên phải trang, cạnh `Order: 121306 / Datum / Att betala`).
- "Förskottsbetalning" = "thanh toán trước / trả trước" — đúng bản chất tính năng payment link.

**Thay đổi** (`templates/payment_link/checkout.html.twig`):

| Dòng | Hiện tại | Đổi thành |
|------|----------|-----------|
| 23 | `<h1 ... >Kassa</h1>` | `<h1 ... >Förskottsbetalning</h1>` |
| 3 | `{% block title %}Kassa - {{ order.orderNr }}{% endblock %}` | `{% block title %}Förskottsbetalning - {{ order.orderNr }}{% endblock %}` |

- **Không đổi** heading "Svea Kassa" ở block iframe (dòng 128) — đó là tên khu vực thanh toán của Svea, không phải tiêu đề trang. *(Nếu sếp muốn đổi luôn thì nói rõ — mặc định giữ nguyên.)*

---

### FB2 — Block "Kunduppgifter": đổi label "Namn" → "Kund" + đổi thứ tự field

**Mockup**: `files/fb2-kunduppgifter-rename-reorder.jpg`

Annotation trên mockup:
- *"Change text to Kund"* — mũi tên lớn trỏ thẳng vào label **"Namn:"** → đổi label `Namn` → `Kund` (lý do hợp lý: với khách B2B thì đây thường là **tên công ty**, không phải tên người).
- *"Change sort order"* — sắp lại thứ tự field trong block thành **2 cột**:

| | Cột trái (Left side) | Cột phải (Right side) |
|---|----------------------|------------------------|
| Thứ tự mới | **Kund** → **Adress** → **Postkod** → **Stad** | **Mobil** → **Email** |

**Layout hiện tại** (`checkout.html.twig` dòng 108–122) — để so sánh:

| | Cột trái | Cột phải |
|---|----------|----------|
| Hiện tại | Namn → Adress → Stad → Mobil | Email → Postkod → Land |

**Việc cần làm** — ✅ đã code:
1. Đổi heading section `<h2>Kunduppgifter</h2>` → `<h2>Kund</h2>` (chốt với user 2026-08-26).
2. Đổi label `Namn:` → `Kund:` (giá trị vẫn là `order.customerName`).
3. `Postkod` (`order.customerPostCode`) chuyển từ cột phải → cột trái, đặt sau `Adress`.
4. `Mobil` (`order.customerMobile`) chuyển từ cột trái → cột phải, đặt trước `Email`.
5. `Stad` (`order.customerCity`) giữ ở cột trái, xuống cuối.
6. `Land` (`order.customerCountry`) — **bỏ hẳn khỏi trang** (chốt lại với user 2026-08-26, đảo quyết định "giữ" trước đó). Bỏ ở cả card "Kund" lẫn card "Leverans".

**Markup đã áp dụng**:

```twig
<div class="row">
    <div class="col-md-6"><strong>Kund:</strong> {{ order.customerName }}</div>
    <div class="col-md-6"><strong>Mobil:</strong> {{ order.customerMobile }}</div>
</div>
<div class="row">
    <div class="col-md-6"><strong>Adress:</strong> {{ order.customerAddress }}</div>
    <div class="col-md-6"><strong>Email:</strong> {{ order.customerEmail }}</div>
</div>
<div class="row">
    <div class="col-md-6"><strong>Postkod:</strong> {{ order.customerPostCode }}</div>
</div>
<div class="row">
    <div class="col-md-6"><strong>Stad:</strong> {{ order.customerCity }}</div>
</div>
```

- **Heading section**: đã đổi `<h2>Kunduppgifter</h2>` → `<h2>Kund</h2>` theo chốt của user (2026-08-26).

---

### FB3 — Di chuyển block "Kund" (Kunduppgifter) lên trên cùng

**Mockup**: `files/fb3-move-kund-block-up.jpg`

- Annotation: *"Move up"* + 1 mũi tên lớn kéo từ block **KUNDUPPGIFTER** (đang nằm dưới cùng, trước "Svea Kassa") **lên vị trí ngay dưới logo/header**, **phía trên "Dina Produkter"**.

**Thứ tự block hiện tại** (`checkout.html.twig`):

```
Header (logo + Order/Datum/Att betala)
 └─ Dina Produkter          (card, dòng 32–76)
 └─ Betalning               (card, dòng 78–95)
 └─ Kunduppgifter           (card, dòng 97–124)
 └─ Svea Kassa (iframe)     (card, dòng 126–131)
```

**Thứ tự mong muốn sau FB3**:

```
Header
 └─ Kund (Kunduppgifter)    ← chuyển lên đây
 └─ Dina Produkter
 └─ Betalning
 └─ Svea Kassa (iframe)
```

**Việc cần làm**: di chuyển nguyên `<div class="card">...</div>` của block Kunduppgifter (dòng 97–124) lên **ngay sau** `</div>` đóng header (sau dòng 30), trước block "Dina Produkter". Không đổi nội dung bên trong (nội dung do FB2 xử lý).

---

### FB4 — BUG: Svea checkout bắt khách nhập lại địa chỉ giao hàng

**Mockup**: `files/fb4-svea-asks-delivery-address.jpg`

- Annotation: *"BUG sea ask for delivery adress, should be fetch from order"*.
- Ảnh cho thấy iframe Svea ở bước **"Lägg till leveransadress"** đang bắt khách nhập **Förnamn / Efternamn / Gatuadress** (các field bôi đỏ *"Fyll i detta fält för att fortsätta"*), trong khi order đã có sẵn đầy đủ địa chỉ (panel "Leverans" trên order detail).

#### ⚠️ Đây KHÔNG phải bug code của mình — là giới hạn của Svea Checkout API

Đã xác nhận lại bằng README chính thức của SDK (`vendor/sveaekonomi/checkout/README.md` §11.4 "PresetValue"). Svea Checkout **chỉ cho prefill đúng 5 loại field**:

| typeName hỗ trợ | Ghi chú |
|---|---|
| `NationalId` | Personnummer / orgnr — nếu gửi cái này, Svea **tự tra cứu và điền sẵn tên + địa chỉ**, khách không phải gõ |
| `EmailAddress` | ✅ đang gửi |
| `PhoneNumber` | ✅ đang gửi |
| `PostalCode` | ✅ đang gửi |
| `IsCompany` | Bắt buộc đi kèm nếu có `NationalId` |

→ **Không có** `FirstName` / `LastName` / `StreetAddress` / `City` trong danh sách. Svea Checkout API **không có cơ chế nào** để đẩy sẵn tên + địa chỉ đường vào iframe. Điều này **đã ghi trong doc gốc TSHIRTORDER-1546 → "Self-review round 1", mục 2 và "Chi tiết theo mockup → Mockup 2"**.

#### Các hướng xử lý (cần sếp/Liem quyết)

| # | Hướng | Đánh giá |
|---|-------|----------|
| **A** | **Gửi `NationalId` + `IsCompany` vào `presetValues`** → Svea tự điền tên + địa chỉ, khách không phải gõ | ✅ Đúng ý mockup nhất, nhưng ❌ **`Order` entity hiện KHÔNG lưu personnummer/orgnr** (đã grep toàn bộ `Order.php` — không có field national id / org nr). Cần: (1) thêm field mới vào Order + migration, (2) đảm bảo dữ liệu này có sẵn lúc tạo order (từ đâu?). Ngoài scope 1 sprint nhỏ. |
| **B** | **Chấp nhận giới hạn** — trang mình đã hiển thị "Kunduppgifter" (và sau FB5 là cả "Leverans") read-only để khách đối chiếu; khách xác nhận địa chỉ 1 lần trong iframe Svea. Có thể thêm `IdentityFlags: HideChangeAddress` (README §11.12) để iframe gọn hơn sau khi khách đã nhập. | ✅ Ít việc nhất, ⚠️ khách vẫn phải gõ địa chỉ 1 lần trong Svea. |
| **C** | Tự làm form nhập địa chỉ riêng trước iframe rồi map sang Svea | ❌ Không có API để map địa chỉ sang Svea Checkout → vô nghĩa. |

**Đề xuất**: hướng **B** cho ngắn hạn (đóng phần lớn giá trị của mockup nhờ FB5 hiển thị đủ Leverans/Kunduppgifter), ghi nhận hướng **A** thành ticket riêng nếu công ty muốn khách không phải gõ gì. **Chờ sếp xác nhận trước khi code.**

---

### FB5 — Thêm hiển thị "Order referens", "Information till kund", "Leverans" (đọc từ order)

**Mockup**: `files/fb5-show-order-referens-info-leverans.jpg`

- Annotation: *"Add this field in ecom"*, mũi tên kéo từ trang payment-link (phần Kunduppgifter / Svea Kassa) sang các field được bôi xanh trên **order detail** (order #63350):
  - **"Order referens"** (kèm link "Lägg till kontakt")
  - **"Information till kund"** (đang "inget innehåll" trong ảnh)
  - **"Leverans"** (panel địa chỉ giao hàng, bên trái order detail)

→ **Đã xác nhận với user (2026-08-26)**: *"ecom"* ở đây là **trang payment-link**, KHÔNG phải trang ecom checkout thật (`templates/webshop/checkout.html.twig`). Việc cần làm: **bổ sung hiển thị các thông tin này của order lên trang checkout payment-link** (read-only, đọc thẳng từ `order`), gom vào **card "Leverans"** (không phải card "Kund").

**Mapping field** (getter đã có sẵn trên `src/Entity/Order.php`):

| Nhãn trên order detail | Field / getter | Ghi chú |
|---|---|---|
| Order referens | `order.erReference` (`getErReference()`) | ✅ Đã chốt dùng `erReference` (user, 2026-08-26), không phải `varReference`. |
| Information till kund | `order.intoText` (`getIntoText()`) | **Field riêng dành cho khách** — KHÁC `order.comment` (comment nội bộ, chứa log `payment_id`/URL...). Doc gốc round 5 đã bỏ qua `comment` vì lộ thông tin nội bộ; `intoText` thì đúng nghĩa "thông tin gửi khách". ⚠️ Với order import từ "deco" (`OrderService.php:2575`), `intoText` được nạp từ mảng `notes` dạng `"Tên (email): nội dung"` — về lý thuyết có thể chứa trao đổi nội bộ. Nhưng đây chính là field mà mockup chỉ vào để hiển thị cho khách → hiển thị theo yêu cầu, nếu sếp thấy nội dung không phù hợp cho khách thì báo lại. |
| Leverans (địa chỉ giao hàng) | `order.deliveryName`, `order.deliveryAddress`, `order.deliveryPostNr`, `order.deliveryCity`, `order.deliveryCountry`, `order.deliveryPhone` (+ `getDeliveryStreet()`, `getDeliveryAddressOther()` nếu có dùng) | Hiện trang chỉ có "Kunduppgifter" (địa chỉ hoá đơn / khách), **chưa hề hiển thị địa chỉ giao hàng**. |

**Việc cần làm** (`templates/payment_link/checkout.html.twig`) — ✅ đã code:
1. Thêm card **"Leverans"** (read-only) — hiển thị địa chỉ giao hàng từ `order.name/contactName/deliveryAddressOther/deliveryAddress/deliveryPostNr/deliveryCity/mobileNr/contactEmail` (cùng mapping với `templates/pdf/order/__address.html.twig`, **trừ `deliveryCountry`/Land — đã bỏ**).
2. **`Order referens` + `Information till kund` đặt TRONG card "Leverans"** (chốt với user 2026-08-26 — không phải trong card "Kund"), phân tách bằng `<hr/>`:
   - `Order referens: {{ order.erReference }}` — chỉ hiện nếu `is not empty`.
   - `Information till kund: {{ order.intoText | raw }}` — chỉ hiện nếu `is not empty`. *(field `intoText` là `text`, có thể chứa HTML `<p>` — dùng `| raw` theo convention có sẵn; nội dung do staff nhập, không phải khách.)*
3. Toàn bộ card "Leverans" chỉ render khi **ít nhất 1** trong 4 field (`deliveryAddress`, `name`, `erReference`, `intoText`) có giá trị — mỗi dòng đều guard riêng, không hiện nhãn trống.
4. **KHÔNG** hiển thị `order.comment` (giữ nguyên quyết định round 5).

**✅ Đã chốt (2026-08-26)**:
- *"ecom"* trong annotation = **trang payment-link** (không đụng ecom checkout thật).
- "Order referens" = **`erReference`**.

---

## Pending Clarification — còn lại, check sau

> FB1/FB2/FB3/FB5 **đã code xong** theo "đề xuất mặc định" bên dưới (2026-08-26). Các câu hỏi này chỉ điều chỉnh chi tiết nhỏ, không chặn — nếu chốt khác thì sửa lại vài dòng twig.

| # | FB | Câu hỏi | Kết quả |
|---|----|---------|---------|
| 1 | FB2 | Field `Land` (`customerCountry` / `deliveryCountry`) — bỏ hay giữ? | ✅ **Chốt: bỏ hẳn** (user, 2026-08-26) — bỏ ở cả card "Kund" lẫn card "Leverans" |
| 2 | FB2 | Có đổi heading section "Kunduppgifter" không? | ✅ **Chốt: đổi** (user, 2026-08-26) — heading `Kunduppgifter` → `Kund`, label `Namn:` → `Kund:` |
| 3 | FB4 | Chọn hướng A / B / C (xem bảng FB4). Hướng A cần thêm field personnummer/orgnr vào Order + nguồn dữ liệu. | ⏳ **User đang check** |
| 4 | FB5 | ~~*"Add this field in ecom"* — trang payment-link hay ecom checkout thật?~~ | ✅ **Chốt: chỉ trang payment-link** (user, 2026-08-26) |
| 5 | FB5 | "Order referens" = `erReference` hay `varReference`? | ✅ **Chốt: `erReference`** (user, 2026-08-26) |
| 6 | FB1 | Đổi luôn heading "Svea Kassa" ở block iframe? | ✅ Giữ nguyên "Svea Kassa" (mặc định, chưa có phản hồi khác) |

---

## TODO List

### Templates — Twig (`templates/payment_link/checkout.html.twig`) — repo này ✅ ĐÃ XONG (2026-08-26)

- [x] **FB1** — `<h1>` → `Förskottsbetalning`; `{% block title %}` → `Förskottsbetalning - {{ order.orderNr }}`.
- [x] **FB2** — Block "Kunduppgifter": heading `Kunduppgifter` → `Kund`, label `Namn:` → `Kund:`; 2 cột — trái `Kund / Adress / Postkod / Stad`, phải `Mobil / Email`. **Bỏ hẳn `Land`** (cả card Kund lẫn Leverans).
- [x] **FB3** — Card "Kunduppgifter" chuyển lên ngay sau header, phía trên "Dina Produkter" (+ card "Leverans" mới cũng đặt cùng khu vực này).
- [x] **FB5** — Thêm card "Leverans" read-only (`order.name/contactName/deliveryAddressOther/deliveryAddress/deliveryPostNr/deliveryCity/mobileNr/contactEmail` — cùng mapping với `templates/pdf/order/__address.html.twig`, không có `deliveryCountry`).
- [x] **FB5** — `Order referens` (`order.erReference`) + `Information till kund` (`order.intoText | raw`) đặt **trong card "Leverans"** (sau `<hr/>`), không phải card "Kund" (chốt user 2026-08-26). Card "Leverans" render khi ít nhất 1 trong `deliveryAddress`/`name`/`erReference`/`intoText` có giá trị.
- [x] Lint: `php bin/console lint:twig templates/payment_link/` → **OK, 4/4 file hợp lệ**.

> Chưa chạy live test trên môi trường thật (theo pattern 1546 — để user tự test).

### Backend — chỉ khi FB4 chọn hướng A (chờ quyết định)

- [ ] **[Order entity]** Thêm field `customerNationalId` (string, nullable) + `customerIsCompany` (bool, nullable) vào `src/Entity/Order.php` + getter/setter.
- [ ] **[Migration]** `doctrine:migrations:diff` → `migrate` (lọc bỏ schema drift không liên quan như các migration trước của 1546).
- [ ] Xác định **nguồn dữ liệu** personnummer/orgnr lúc tạo order (import? nhập tay? từ customer?).
- [ ] **[SveaService]** `createOrderFromOrder()` (dòng 151): thêm phần tử `presetValues` với `typeName = 'nationalId'` + `typeName = 'isCompany'` khi order có dữ liệu.
- [ ] *(optional)* Thêm `IdentityFlags: HideChangeAddress` vào `merchantSettings`.

### Test / kiểm tra

- [ ] Mở `GET /payment-link/{token}` trên môi trường thật — verify: tiêu đề "Förskottsbetalning", block "Kund" nằm trên cùng, label + thứ tự field đúng, có block "Leverans" + "Order referens" + "Information till kund" khi order có dữ liệu.
- [ ] Order **không có** địa chỉ giao hàng / không có `intoText` / không có `erReference` → các block/dòng đó **ẩn hẳn**, không hiện nhãn trống.
- [ ] Order có `intoText` chứa HTML → render đúng, không vỡ layout.
- [ ] (FB4) Nếu chọn hướng A: test 1 order có personnummer thật → iframe Svea tự điền địa chỉ, khách không phải gõ.

---

## Các file liên quan

| File | Mục đích | FB |
|------|----------|-----|
| `templates/payment_link/checkout.html.twig` | Toàn bộ FB1/FB2/FB3/FB5 — text, thứ tự block, thêm field đọc từ `order` | 1,2,3,5 |
| `src/Entity/Order.php` | Getter đã có sẵn: `getErReference()`, `getIntoText()`, `getDelivery*()`. Chỉ thêm field mới nếu FB4 chọn hướng A | 5 (đọc), 4 (nếu A) |
| `src/Service/Payment/SveaService.php` | `createOrderFromOrder()` dòng 151–167 — `presetValues`. Chỉ sửa nếu FB4 chọn hướng A | 4 (nếu A) |
| `vendor/sveaekonomi/checkout/README.md` | §11.4 PresetValue (bằng chứng Svea không hỗ trợ prefill địa chỉ), §11.12 IdentityFlags | 4 |
| `docs/issues/TSHIRTORDER-1546-share-payment-link/share-payment-link.md` | Doc gốc — "Self-review round 1" đã ghi giới hạn Svea prefill | 4 |
| `files/fb1..fb5-*.jpg` | 5 mockup feedback | tất cả |

---

## Estimate

| # | Task | Giờ |
|---|------|-----|
| 1 | FB1 + FB2 + FB3 (text + reorder + move block) | 1h |
| 2 | FB5 (block Leverans + 2 dòng Order referens / Information till kund) | 1.5h |
| 3 | Test tay trên môi trường thật (nhiều loại order) | 1h |
| 4 | FB4 — hướng B (IdentityFlags + đối chiếu) | 0.5h |
| 5 | FB4 — hướng A (field mới + migration + nguồn data + Svea presetValues) *(chỉ nếu chọn A)* | 4h+ |

**Tổng (không tính FB4 hướng A): ~4h**
