# CR-048　支付路徑（payPath）結構化欄位跨服務透傳

| 項目 | 內容 |
|---|---|
| 文件編號 | CR-048 |
| 版本 | **1.1** |
| 狀態 | **實作完成**（真機通過；BEAM PMO 2026-10-17 裁定：授權側**新增結構化欄位**；**不接受**以 `UNKNOWN` 交差） |
| 觸發 | `SCS-026 §7.13` R-4（`#A-266`）——BRD §11「支付路徑限定（實版）：實體／國際三Pay／自家支付／第三方條碼」為**條件式比率**分層維度；原授權側僅自由格式 `emv_data`（`#A-257` 實查） |
| 需求依據 | `BRD-005 §11`（支付路徑限定）、§6B／AC 8（值域） |
| 規格依據 | `SCS-026 §7.13`（條件式比率凍結定案）、`SCS-001 §7.17`（契約欄位補實作慣例）、`SCS-003 §7`（入帳事件） |
| 影響模組 | `authorization-service`（新欄位）、`posting-service`（透傳）、`campaign-service`（條件判定）、契約（`AuthorizeRequest`／`PostingRequest`／`posting.transaction.posted.v1`） |

---

## 1. 問題陳述

活動之**條件式比率**需依「支付路徑」分層（BRD §11）；惟授權側原**無結構化欄位**——僅自由格式
`emv_data`（`{"arqc": ...}`），無法可靠判定 `PHYSICAL`／`INTL_3PAY`／`BANK_OWN`／`THIRDPARTY`。

BEAM PMO 2026-10-17 明確裁定：**新增結構化欄位**；**不接受**以 `UNKNOWN` 交差。

## 2. 設計（值域與語意）

| 項目 | 內容 |
|---|---|
| 欄位 | `pay_path VARCHAR2(24)`（`authorizations`／`transactions`） |
| 值域 | `PHYSICAL`（實體卡）／`INTL_3PAY`（國際三 Pay）／`BANK_OWN`（自家支付）／`THIRDPARTY`（第三方條碼）——依 `BRD-005 §6B／AC 8` |
| `NULL` 語意 | **未提供**＝**未判定**（`SCS-026 §7.13④`）——**不是**猜成 `UNKNOWN`；活動條件含 `payPath` 時該檔**不套用**（記 WARN） |
| 透傳路徑 | `AuthorizeRequest.payPath` → `Authorization`（落庫）→ **呼叫端自授權紀錄帶入** `PostingRequest.payPath`（同 `mcc` 既有模式，`#A-255`）→ `Transaction`（落庫）→ `posting.transaction.posted.v1` payload → `campaign` 條件判定 |
| 契約 | `AuthorizeRequest`／`PostingRequest` 加可選 `payPath`；事件 payload 加可選 `payPath`（**不升版**，`SAD-004 §5.3`） |

## 3. 為何「不是 UNKNOWN」

- **`UNKNOWN` ＝ 把不確定猜成一個類別** → 可能誤用高回饋率（例：把第三方條碼當實體卡給 3%）→ **禁止**；
- 本 CR 的做法：**補強來源使其可得**（結構化欄位）＋**缺值時不判定**（不套用該條件檔）。
  兩者並行——既不放任 UNKNOWN，也不臆造。

## 4. 驗收（真機）

1. 授權帶 `payPath=PHYSICAL` → 落庫（`authorizations.pay_path`）；
2. 入帳帶同值 → `transactions.pay_path` 落庫 → 事件 payload 帶出；
3. campaign：活動條件 `{"payPath":"PHYSICAL"}` → 命中（指令帶該 rate＋`rateReason=PAYPATH:PHYSICAL`）；
4. 缺值（未帶）→ 條件**不套用**（記 WARN），**不得**出現 `UNKNOWN` 值；
5. CHECK 約束擋非法值。

## 5. 修訂記錄

| 版本 | 說明 |
|---|---|
| 1.0 | 2026-10-17：初版。依 BEAM PMO R-4 裁定開立；值域依 BRD §6B／AC 8；`NULL`＝未判定（非 UNKNOWN）；透傳路徑 auth→posting→campaign；驗收五項。 |
| 1.1 | 2026-10-17：★ **實作完成（真機通過）**。① `authorization-service`：`V13__authorization_pay_path.sql`（`pay_path`＋CHECK 值域）＋`AuthorizeRequest.payPath`（Pattern 驗證）＋`Authorization`（欄位／`decide` 簽名／getter）＋`JdbcAuthorizationRepository`（INSERT／SELECT 綁定，★ **欄位序：`emv_data` → `pay_path` → `tx_time`**——首次綁定插錯位導致 18 例連鎖失敗，已修）；② `posting-service`：`V10__pay_path.sql`＋`PostingRequest.payPath`＋`Transaction`（欄位／Builder／`post`／`reconstitute` 多載）＋`JdbcTransactionRepository`＋`PostingEventFactory`（payload 帶出）；③ `campaign-service`：`PostedTransactionListener` 讀 `payPath`＋`RateResolver` 條件匹配；④ 契約同步（`AuthorizeRequest`／`PostingRequest`／`posted.v1` payload／`PointsAccountView.tier`）＋ACL 重生（`SAD-002 §5` 補 campaign 列）。**仍缺**：`campaign → card/product` 之 planCode 來源（R-1b）、`birthMonth` 客戶主檔介面（R-2 外部依賴）、`minLevel` 層級序（R-3b）。 |
