CR #201 » SCS-023_卡片商品組合與測試卡片檔產生規格.md
SCS-023 卡片商品組合與測試卡片檔產生規格
| 項 | 內容 |
|---|---|
| 編號 | SCS-023 |
| 版本 | 1.4 |
| 日期 | 2026-09-20 |
| 作者 | WorkBuddy AI |
| 核定 | 待 BEAM PMO 核定 |
| 對應需求 | BEAM PMO 2026-09-20 指示(進件缺口 + 測試基石);BRD 商品設定;NFR 可測試性 |
| 前置文件 |
SDD-001 §3.3(product/parameter)、SCS-003(卡片服務)、CSP-001 §8(組態與產生器紀律) |
1. 目的與範圍
本案過去之測試卡片是手刻幾筆、且維度固定(個人/公司、主附卡、額度模型…),
有兩個結構性問題:
-
用的是列舉(enumeration),不是組合(composition)——維度與取值寫死在程式或文件裡,
新增一種商品就要改程式。這違背「商品可以組合」之需求:
例如客戶之 eLOAN 無擔保信貸,即是以發卡系統之虛擬卡承作,
它既不是「信用卡」也不是「簽帳卡」,而是「既有能力之重新組合」。 - 規模不足——無法支撐「各類交易場景」之批次測試。
本規格定義:
- §3~§4:商品組合模型(能力維度 + 參數化落地),維度可擴充、非固定列舉;
- §5:商品範本(Profile)——只是「常用組合之預設值」,不是枚舉;
- §6:測試卡片檔產生器——依組合產生具規模、Luhn 合法之卡片檔;
- §7:Stripe 對接方式與無金鑰時之降級做法。
本文件不處理:進件流程本身(受理/徵信/製卡)之狀態機——
該部分另立規格,本文件僅定義「商品組合」與「卡片檔產生」此一測試基石。
2. 名詞
| 名詞 | 說明 |
|---|---|
| 商品(Product) | 可發行之卡片產品。product-service 之 products 表一列。 |
| 能力維度(Capability dimension) | 描述商品「能做什麼/怎麼做」之一個參數,如 issuance.form。可增減。
|
| 商品組合(Composition) | 一組「維度鍵 → 值」之集合,即一個商品之完整定義。 |
| 商品範本(Profile) | 常用組合之預設值集合,供快速套用;可被覆寫,故不是枚舉。 |
| 卡片檔(Card file) | 依商品組合產生之測試卡片清單(JSON/CSV),供批次發卡與場景測試使用。 |
| 測試 BIN | 不使用客戶真實 BIN。本期採 Stripe 共用測試 BIN 424242(見 §6.2)。 |
3. 設計原則:組合優於列舉(BEAM PMO 2026-09-20 明確指示)
BEAM PMO 原話:「卡片情境矩陣是符合現有客戶的架構,但不適用他行。
從未來參數設定的角度,不應該局限維度與取值,因為違背了『商品可以組合』的需求。」
3.1 為何不能用 enum
若把「個人/公司」「主附卡」「單一/共用額度」等寫成 enum 欄位:
- 新增一種商品(如 eLOAN 虛擬卡)→ 必須改 DDL、改程式、改文件;
- 他行/新客戶的商品維度不同 → 舊 enum 不適用,又得再改;
- 「同一張卡在某情境可分期、某情境不可」這類條件式能力無法表達。
3.2 改為「參數集合」
商品 = 一組參數。新增商品 = 新增一組參數值,不必改結構。
落地位置:既有基礎設施——product-service 之 parameters 表
(namespace/param_key/param_value JSON/value_type/effective_from/effective_to)。
⚠️ 不新增 enum 欄位。
products表既有之org/card_grade/ticket_type為
「對外呈現用之摘要」,非能力定義;能力一律進parameters,避免兩處打架。
(後續可評估將該三欄降為「由參數推導」,屬重構,本期不做。)
3.3 命名與型別規範
- 維度鍵採 點分式小寫,如
issuance.form、limit.model; -
value_type沿用parameters既有列舉:STRING/NUMBER/BOOLEAN/JSON/AMOUNT/RATE; -
namespace填product_code,使參數可隨商品版本生效(effective_from/effective_to); - 維度鍵之增減不視為結構變更——此即「可組合」之核心。
4. 能力維度(CAPABILITY_KEYS)
⚠️ 本表是「目前收錄」,不是「全部允許」。 新增維度只需加一列參數,
不需改結構、不需改本文件之結構章節——這是刻意設計。
| 維度鍵 | 型別 | 說明 | 預設 |
|---|---|---|---|
issuance.form |
STRING | 發卡形式:PHYSICAL/VIRTUAL/BOTH
|
PHYSICAL |
issuance.virtual_delivery |
STRING | 虛擬卡交付方式:API/WALLET/NONE
|
NONE |
limit.model |
STRING | 額度模型:SINGLE/SHARED/SUB_LIMIT/NONE
|
SINGLE |
limit.shared_scope |
STRING | 共用額度歸屬:ACCOUNT/FAMILY/CORP/NONE
|
NONE |
limit.grant_required |
BOOLEAN | 是否須徵信給額(預付卡/eLOAN 虛擬卡可為 false) | true |
revolving.enabled |
BOOLEAN | 循環信用(可否只繳最低) | true |
revolving.rate_annual |
RATE | 循環年利率 | — |
payment.grace_days |
NUMBER | 寬限期天數 | 20 |
payment.auto_debit |
BOOLEAN | 是否自動扣抵(帳戶連結) | false |
installment.enabled |
BOOLEAN | 可分期 | false |
cash_advance.enabled |
BOOLEAN | 可預借現金 | false |
mcc.allowed |
JSON | 允許之 MCC 清單(null=不限) | null |
mcc.blocked |
JSON | 禁止之 MCC 清單 | null |
ticket.enabled |
BOOLEAN | 電子票證聯名 | false |
ticket.type |
STRING |
EASYCARD/IPASS/ICASH/null(對應 cards.ticket_type) |
null |
supplementary.allowed |
BOOLEAN | 可發附卡 | false |
supplementary.max |
NUMBER | 附卡上限 | 0 |
supplementary.share_limit |
BOOLEAN | 附卡是否共享主卡額度 | false |
cross_border.enabled |
BOOLEAN | 可跨境交易 | true |
dcc.enabled |
BOOLEAN | 動態貨幣轉換 | false |
tokenization.platforms |
JSON | 可綁定之平台(APPLE_PAY…) | [] |
billing.cycle_day |
NUMBER | 結帳日 | 1 |
billing.currency |
STRING | 幣別 | TWD |
kyc.level |
STRING | 徵信等級需求 | STANDARD |
network_allowed |
JSON | 可用國際組織 | ["VISA"] |
條件式能力:值可為 JSON,用以表達「某情境才可」,
例如 installment.enabled 給 {"merchant_scope":"ALL","min_amount":1000}——
不改結構即可表達條件,這是選 JSON 而非純 BOOLEAN 之理由。
5. 商品範本(Profile)
範本只是「常用組合的預設值」,允許逐鍵覆寫。因此「新增商品」=「新增範本或覆寫參數」,
不是新增 enum。
| 範本 | 組合重點 | 代表情境 |
|---|---|---|
REVOLVING_CREDIT |
revolving.enabled=true、limit.model=SINGLE、installment.enabled=true
|
一般信用卡 |
CHARGE_CARD |
revolving.enabled=false、payment.grace_days=0
|
簽帳卡(須一次付清) |
VIRTUAL_LOAN_CARD |
issuance.form=VIRTUAL、limit.grant_required=false、revolving.enabled=true、issuance.virtual_delivery=API
|
eLOAN 無擔保信貸之虛擬卡 |
PURCHASE_CARD |
mcc.allowed=[…]、cash_advance.enabled=false、limit.model=SHARED、limit.shared_scope=CORP
|
採購卡(P-Card) |
COBRAND_TICKET |
ticket.enabled=true、ticket.type=EASYCARD
|
悠遊聯名卡 |
PREPAID |
limit.model=NONE、limit.grant_required=false、kyc.level=BASIC
|
預付卡 |
CORP_TRAVEL |
limit.model=SHARED、limit.shared_scope=CORP、cross_border.enabled=true、dcc.enabled=true
|
商務旅遊卡 |
6. 測試卡片檔產生
6.1 為何需要產生器(而非手刻)
- 場景測試需要規模;手刻無法覆蓋組合;
- 卡號必須通過 Luhn,否則下游(授權、發卡行檢核)會視為無效卡號;
- 產生器須可重現(同一 seed → 同一批卡號),否則測試不可重跑。
6.2 BIN 之選用(⚠️ 重要前提)
不得使用客戶真實 BIN。 本期採 Stripe 共用測試 BIN 424242。
查證結果(2026-09-20,官方文件):
- Stripe 官方 API 範例(
livemode:false)之 Issuing card 為brand=Visa、last4=4242
→ 測試卡使用共用測試 BIN(4242 42…);- 「dedicated BIN」在官方文件中僅出現於正式環境(Autopilot/STIP);
- 官方明載:Issuing 測試卡僅能用於自己帳號內測試,不得用於外部消費。
⚠️ 因此「由 Stripe 分配專屬虛擬測試 BIN 範圍」之假設不成立——
產生器以共用測試 BIN 產生卡號,僅供本系統內部批次與場景測試,
不可視為對外可交易之卡號。
6.3 卡號結構(與既有程式一致)
對齊 CardNumberIssuer:
- PAN 長度 16,主體 15 碼,末 1 碼為 Luhn 檢查碼;
- 主體 = BIN(前 6 碼
424242) + 序號 9 碼; -
bin欄位(cards.bin CHAR(8))取CardNumberIssuer.bin(pan)之前 6 碼。
6.4 產生器
tools/gen_test_cards.py——比照既有產生器之紀律:
| 參數 | 說明 |
|---|---|
--profile |
商品範本(§5);可重複給,或給 --profile ALL
|
--count |
每一組合之卡片數 |
--seed |
亂數種子(可重現) |
--out |
輸出檔(JSON/CSV 依副檔名) |
--check |
只驗證既有卡片檔,不寫入 |
--force |
覆寫已存在之輸出檔 |
覆蓋策略:對每一(商品範本 × 情境)產生卡片,情境含
持卡人型別(個人/公司)、卡片角色(主卡/附卡)、狀態(未開卡/正常/鎖卡/掛失)。
7. Stripe 對接
7.1 發卡側:我們是「授權決策引擎」
Stripe 產生測試授權後,送 issuing_authorization.request webhook 予我方,
須於 2 秒內回應核准/拒絕;逾時依 Stripe 設定自動核准或拒絕。
POST /v1/test_helpers/issuing/authorizations # 產生測試授權(Stripe 端)
→ issuing_authorization.request # 送至我方 webhook
→ 我方以 limit.model/block_code/mcc 等參數決策
→ 回應 approve / decline
此接法才是真正測到本系統:決策邏輯位於真實訊息流之中間,而非自我呼叫。
7.2 收單側:以官方測試卡號模擬他行卡
使用 Stripe 官方測試卡號表(已於 2026-09-20 查證):
| 情境 | 卡號 |
|---|---|
| 成功(Visa/MC/Amex/UnionPay) |
4242424242424242/5555555555554444/378282246310005/6200000000000005
|
| 拒付(generic/餘額不足/遺失/被盜) |
4000000000000002/…9995/…9987/…9979
|
| 過期/CVC 錯誤/卡號錯誤 |
4000000000000069/…0127/4242424242424241
|
| 3DS 必做/支援/不支援 |
4000000000003220/4000000000003055/378282246310005
|
| 爭議(詐欺/未收到/ inquiry) |
4000000000000259/…2685/…1976
|
7.2.1 依卡組織分類之測試卡號(BEAM PMO 2026-09-20 提供,Stripe 回覆)
⚠️ 用途釐清(重要):本表為 Stripe 收單(payment)測試卡號,
用途是「模擬持卡人持他行卡前來刷卡付款」,供我們驗證
授權/拒付/3DS/爭議等收單側路徑。
本表不得作為 embossing file(製卡檔)之卡號來源——
製卡檔是我們發卡時交付製卡廠之檔案,卡號應來自我們自己的 BIN,
即 §6 之tools/gen_test_cards.py(92 張、Luhn 全過、可重現)。
(Stripe 回覆中「可用於 generating embossing file」之說明,
研判係將我方需求理解為「測試付款」,與我們發卡之用途不同。)
| 卡組織 | 測試卡號 | CVC | 有效期 | 位數 |
|---|---|---|---|---|
| Visa | 4242424242424242 |
任意 3 碼 | 任意未來日期 | 16 |
| Visa(簽帳卡) | 4000056655665556 |
任意 3 碼 | 任意未來日期 | 16 |
| Mastercard | 5555555555554444 |
任意 3 碼 | 任意未來日期 | 16 |
| Mastercard(2 系列) | 2223003122003222 |
任意 3 碼 | 任意未來日期 | 16 |
| Mastercard(簽帳卡) | 5200828282828210 |
任意 3 碼 | 任意未來日期 | 16 |
| Mastercard(預付卡) | 5105105105105100 |
任意 3 碼 | 任意未來日期 | 16 |
| American Express | 378282246310005 |
任意 4 碼 | 任意未來日期 | 15 |
| American Express | 371449635398431 |
任意 4 碼 | 任意未來日期 | 15 |
| Discover | 6011111111111117 |
任意 3 碼 | 任意未來日期 | 16 |
| Discover | 6011000990139424 |
任意 3 碼 | 任意未來日期 | 16 |
| Discover(簽帳卡) | 6011981111111113 |
任意 3 碼 | 任意未來日期 | 16 |
| Diners Club | 3056930009020004 |
任意 3 碼 | 任意未來日期 | 16 |
| Diners Club(14 位) | 36227206271667 |
任意 3 碼 | 任意未來日期 | 14 |
| JCB | 3566002020360505 |
任意 3 碼 | 任意未來日期 | 16 |
| UnionPay(銀聯) | 6200000000000005 |
任意 3 碼 | 任意未來日期 | 16 |
| UnionPay(簽帳卡) | 6200000000000047 |
任意 3 碼 | 任意未來日期 | 16 |
| UnionPay(19 位) | 6205500000000000004 |
任意 3 碼 | 任意未來日期 | 19 |
測試重點(卡組織識別/BIN 判定):
-
Mastercard 2 系列(
2223003122003222)必測:Mastercard 於 2016 年起啟用
2221–2720號段(原與51–55併存)。由 Mainframe 轉型之系統常見
「只認51–55、把 2 系列誤判為他組織」之缺陷——這是本次測試最應優先覆蓋者。 -
長度非常態者必測:Amex 15 位、Diners 14 位、UnionPay 19 位。
卡號長度若被假設為固定 16,這三種會被截斷或驗證失敗。 - CVC 長度:Amex 為 4 碼,其餘為 3 碼——不可一律以 3 碼檢核。
- 有效期限「任意未來日期」即可(如
12/34);其餘表單欄位可用任意值。
與 §7.2 之關係:§7.2 依情境分類(成功/拒付/過期/3DS/爭議),
本節依卡組織分類——兩者正交且互補:
- 驗證「拒絕碼路徑是否正確」→ 用 §7.2
- 驗證「卡組織識別與號段判定是否正確」→ 用本節
- 完整覆蓋宜交叉組合(如:以 JCB 卡號觸發餘額不足之拒付)。
7.3 憑證之存放(2026-09-20 BEAM PMO 提供測試金鑰)
| 項目 | 做法 |
|---|---|
| 存放位置 |
~/.config/cardcore/stripe-test.env——repo 之外,權限 600
|
| 載入方式 |
ops/local/env.sh 若存在才載入,匯出 STRIPE_SECRET_KEY/STRIPE_PUBLISHABLE_KEY
|
| repo 內 |
ops/local/.env.example 只放佔位符(sk_test_REPLACE_ME);新增 .gitignore 排除 .env/*.env/secrets/
|
| 禁止事項 | 不得提交至版控、不得寫進任何文件/簡報、不得用於 SIT/UAT/PROD |
為何放 repo 之外:憑證一旦進過版控,即使事後刪除仍留存於歷史。
與「停用只能顯式宣告」同一思路——讓疏忽難以發生,而非依賴人記得。
7.4 ⚠️ 實測發現:本帳號 FinancialAccount 狀態 pending 卡住發卡
2026-09-20 BEAM PMO 啟用 Issuing sandbox 後重測,進展:
| 項目 | 結果 |
|---|---|
| 帳號 |
acct_1UHczARxdfYl5r2o(US、測試模式、charges_enabled=false) |
| Issuing 卡 | ✅ 已啟用(/v1/issuing/cardholders?limit=1 可呼叫) |
| 持卡人 | ✅ 可建(POST /v1/issuing/cardholders 成功)→ ich_1UHdO4Rx…
|
| 持卡人 individual requirements | ✅ 可補(first_name/last_name/dob/card_issuing.user_terms_acceptance)— past_due=[]、disabled_reason=under_review(不再擋發卡) |
| FinancialAccount | ⚠️ auto-create 後狀態 pending,非 open(fa_test_65VR1GsTfNeWTlEj1e716VR0wWTzSQi39y3bVMxqUICDNY) |
| 開卡 | ❌ 被擋:You cannot create a new card for FinancialAccount fa_test_… because its status is pending. Please try again with an open FinancialAccount.
|
已嘗試且失敗之啟用手段(避免 BEAM PMO 重複測):
-
POST /v2/money_management/financial_accounts/{id}/open→ 404 -
POST /v2/money_management/financial_accounts/{id}/activate→ 404 -
POST /v2/money_management/financial_accounts/{id}(Update,僅改display_name/metadata)→ 200 但 status 仍pending -
status_details→null(無提示) - API 版本掃描:
2025-08-27.basil支援 POST、2025-12-15.preview支援 GET——不同 verb 對不同版本,無單一版本同時支援 GET+POST+Update(Stripe v2 文件混亂所致)
判斷:從 pending → open 之轉變不是 API 動作,是 Stripe Dashboard 之「首次 Issuing 設定」流程——
需於後台對 fa_test_… 加入 funding source(測試模式通常為銀行帳戶/top-up)後自動轉 open。
具體步驟見 Dashboard 之 Issuing → 該 financial account → "Add funding source"/"Activate"。
因此「測試卡號之 BIN」仍未取得本帳號之實證——先前「共用測試 BIN(4242 42…)」
之說法仍僅來自官方文件與 API 範例。
待 BEAM PMO 於 Dashboard 完成 FA 設定後重跑tools/stripe_smoke.py,即可拿到真實卡號。
7.5 收單側實測:Stripe decline code → ISO 8583 → cardcore(建議草案)
以 tools/stripe_smoke.py(真實呼叫)實測之結果:
| 情境(token) | Stripe decline_code
|
ISO 8583 | cardcore | 判定 |
|---|---|---|---|---|
tok_visa |
—(成功) | — | — | ✅ |
tok_chargeDeclined |
generic_decline |
05 |
CC-AUTH-1001 |
✅ |
tok_chargeDeclinedInsufficientFunds |
insufficient_funds |
51 |
CC-AUTH-1003 |
✅ |
tok_chargeDeclinedLostCard |
lost_card |
41 |
CC-AUTH-1002 |
✅ |
tok_chargeDeclinedStolenCard |
stolen_card |
43 |
CC-AUTH-1002 |
✅ |
tok_chargeDeclinedExpiredCard |
expired_card |
54 |
CC-AUTH-1002 |
✅ |
tok_chargeDeclinedIncorrectCvc |
incorrect_cvc |
N7 |
CC-AUTH-1006 |
✅ |
⚠️ ISO 8583/cardcore 欄為本文件提出之建議對照,與
CheckCode既有之
ISO 碼(LIMIT=51、CARD_EXPIRY=54、CVV=N7)方向一致,
但尚未登錄為權威——若採行,須依CSP-003 §2程序補登SDD-006 §3.4
後重跑gen_error_codes.py --write,不得於程式內自創。
7.6 對接腳本 tools/stripe_smoke.py
| 性質 | 說明 |
|---|---|
| 可重複 | 換環境重跑即可,結果不依賴「誰記得上次測了什麼」 |
| 金鑰安全 | 只從環境變數讀;只印前綴與長度,輸出不含金鑰(已實測 grep 命中 0) |
| 降級明確 | 未設金鑰時結束碼 2 並說明原因,不做假成功 |
| 能力探測 | 先探 Issuing/原始卡號 API,不可用就明講,不靜默略過 |
8. 實測證據
以 --profile ALL --seed 42(--count 取預設=狀態數)產生,輸出 ops/local/testdata/cards.json:
| # | 項目 | 實測結果 |
|---|---|---|
| 1 | 產生之卡號全部通過 Luhn | ✅ 92/92 通過;PAN 重複 0 |
| 2 | 同一 seed 重跑產生結果一致(可重現) | ✅ 兩次產生之 SHA-256 完全相同(f7cceed350419b71…) |
| 3 | 換 seed 產生不同卡號 | ✅ seed=42 與 seed=7 之 PAN 交集 0
|
| 4 | 情境覆蓋(商品範本 × 持卡人 × 角色 × 狀態) | ✅ 7 種範本、23 組組合、狀態 4/4 全覆蓋(INACTIVE/ACTIVE/LOCKED/LOST);合計 92 張 |
| 5 |
--check 自檢通過 |
✅ Luhn/BIN/唯一性/組合可行性皆正確
|
| 6 |
組合彈性:不改程式,以 --set 疊出原本沒有的維度 |
✅ --set loyalty.enabled=true --set loyalty.program=ELOAN_POINT --set installment.max_terms=72 --set mcc.blocked=7995,6051 皆生效——證明維度可任意擴充,不需更動產生器結構 |
Stripe 對接實測(2026-09-20,真實 sk_test_;tools/stripe_smoke.py)
| # | 項目 | 實測結果 |
|---|---|---|
| 7 | 金鑰可用(帳號識別) | ✅ acct_1UHczARxdfYl5r2o;測試模式 |
| 8 | Issuing 是否啟用 | ❌ 未啟用(not set up to use Issuing)→ 發卡側無法實測
|
| 9 | 原始卡號 API | ❌ 未開放 → 一律改用 tok_*,行為等價 |
| 10 | 收單側 7 情境 | ✅ 全數與預期相符,取得真實 decline_code(見 §7.5) |
| 11 | 腳本不洩漏金鑰 | ✅ 輸出中完整金鑰 grep 命中 0
|
| 12 | 無金鑰時降級 | ✅ 結束碼 2 並明示原因,非假成功 |
⚠️ 實測中發現並已修之一處缺陷:
--count預設為 3,小於狀態數 4,
使LOST永遠不會出現,而摘要仍印「情境狀態 4 種」——
屬「號稱有、實際沒有」的靜默缺陷。已改為:①--count預設改為狀態數
②摘要改印實際出現之狀態數(4/4)③不足時主動警告並提示如何提高--count。
9. 已知限制(誠實揭露)
-
無 Stripe 金鑰→ 已於 v1.2 解除;
⚠️ 目前卡在 v2 FinancialAccount 狀態pending(§7.4)——需於 Dashboard 完成首次資金帳戶設定後重跑。
「測試卡號之 BIN」因此仍無本帳號實證。
已將對應之 smoke 流程加進tools/stripe_smoke.py(--scenario issuing):完成後自動揭露真實 PAN/CVC/BIN/Luhn。 - 共用測試 BIN:產生之卡號僅供本系統內部測試,不具對外可用性(§6.2)。
- 進件流程未納入:受理/徵信/製卡之狀態機另立規格,本期未做。
-
參數尚未落地
parameters表:本期先落於產生器之設定檔;
與product-service之整合(以namespace=product_code寫入)待後續。
10. 修訂記錄
| 版本 | 日期 | 修訂者 | 說明 |
|---|---|---|---|
| 1.0 | 2026-09-20 | WorkBuddy AI | 初版。依 BEAM PMO 2026-09-20 指示「朝商品組合角度設計」建立:§3 組合優於列舉、§4 能力維度(可擴充)、§5 商品範本、§6 測試卡片檔產生(Stripe 共用測試 BIN + Luhn)、§7 Stripe 對接與無金鑰降級。已更正「Stripe 分配專屬測試 BIN」之假設(查官方文件) |
| 1.1 | 2026-09-20 | WorkBuddy AI | 產生器實測完成(§8 #1–#6):92 張卡 Luhn 全過、可重現、換 seed 不重疊、狀態 4/4 覆蓋、--check 通過、--set 任意維度疊加生效。修一處靜默缺陷:--count 預設 3 < 狀態數 4 使 LOST 永不出現而摘要仍號稱 4 種——改為預設=狀態數、摘要印實際值、不足時警告。§9 #1 補明「無金鑰」之查證過程與責任歸屬 |
| 1.2 | 2026-09-20 | WorkBuddy AI |
BEAM PMO 提供 sk_test_ 測試金鑰:存放於 repo 外之 ~/.config/cardcore/stripe-test.env(權限 600),env.sh 若存在才載入;.env.example 只放佔位符;新增 .gitignore 排除 .env/*.env/secrets/。新增 tools/stripe_smoke.py(金鑰只從環境讀、只印前綴、無金鑰時結束碼 2 不做假成功、先探能力再測)。⚠️ 實測兩項新發現:①本帳號 Issuing 未啟用 → 發卡側無法實測,「測試 BIN」仍無本帳號實證;②原始卡號 API 未開放 → 一律改用 tok_*。收單側 7 情境全數取得真實 decline_code,並提出 decline_code → ISO 8583 → cardcore 建議對照(§7.5,須補登 SDD-006 §3.4 方為權威)。§9 #1 改列「發卡側仍被擋」 |
| 1.3 | 2026-09-20 | WorkBuddy AI |
BEAM PMO 啟用 Issuing sandbox 後重測(§7.4):持卡人可建可補、past_due=[],但 v2 FinancialAccount 自動建出後狀態卡在 pending(非 open),開卡仍被擋。已嘗試五種 API 啟用手段皆未成功(列於 §7.4),判斷為 Stripe Dashboard 之「首次 Issuing 設定」流程(需加 funding source),非 API 動作可解。tools/stripe_smoke.py 新增--scenario issuing 流程(持卡人→補 individual→取 FA→開卡→retrieve 揭露 PAN/CVC/BIN/Luhn);§9 #1 改列「卡在 FA pending」。版本探測之副發現:Stripe v2 不同 endpoint 對 API 版本敏感(basil 支援 POST、preview 支援 GET),文件示例與實測不一致。 |
| 1.4 | 2026-09-20 | WorkBuddy AI | 新增 §7.2.1 依卡組織分類之測試卡號(BEAM PMO 提供、Stripe 回覆,17 張)。⚠️ 並釐清用途:本表為 Stripe 收單(payment)測試卡號,供模擬「持卡人持他行卡前來刷卡」,不得作為 embossing file(製卡檔)之卡號來源——製卡檔應用 §6 gen_test_cards.py 產生之自有 BIN 卡號(研判 Stripe 係將我方需求理解為「測試付款」)。本節補足 §7.2 情境表欠缺之 Discover/Diners Club/JCB/MC 2 系列/各類 debit·prepaid,並標明四項測試重點:MC 2 系列(2221–2720)最優先(Mainframe 轉型系統常見誤判)、長度非常態者(Amex 15/Diners 14/UnionPay 19)、Amex CVC 4 碼、以及與 §7.2 情境表之正交互補關係(宜交叉組合測試) |