← 全部的單
GitHub #258 ↗
帳務・功能
在真的開始收錢之前,先替系統打一層地基:藍新送來的付款通知,系統要能確認是真的、同一筆只算一次、晚到或順序顛倒也不會算錯、處理到一半當機也不會漏;付款和發票各記各的。這張不做任何能真的被扣款的按鈕。
#258 金流(藍新):訂閱扣款與綁卡的骨架——付款與發票狀態分開、webhook 驗簽/去重/亂序/補償
狀態
卡住
誰在做
宜芳分派
做到哪
研究底稿交了,程式還沒開始。PR
#283
(Draft,沒合)把驗簽、重複、亂序、當機恢復、退款、個資保存的風險和一張「假服務商」測試清單整理好,但它自己講明不是 ADR。這張要求的第一步——一份給負責人過目的 ADR(三張表的欄位、驗簽/去重/亂序/補償的介面)——還沒寫。另外
#284
(PR
#285
,已上線)在管理台做了一個假的帳務展示台,點得出類似的規則,但那不是這張的成品(
ADR-0129
第六節)。
卡在
卡在負責人兩件事:一是還沒有 ADR 可以讓他逐項說「同意」(要先有人寫);二是藍新那邊——特店帳號、測試(sandbox)帳號、串接文件、定期定額的實際費率都還沒拿到(10/03 工程把這幾件回派給負責人)。負責人 10/04 已寄信問藍新(題目在
#316
第五節,主要是發票與合約費用),回信還沒到。骨架本身照本單可以不等藍新文件,但要等 ADR 被接受。
下一步
宜芳:決定這張分派給誰寫 ADR——拿
#283
的底稿當材料,把 10/04(
#316
)、10/05(
#326
)已經裁掉的幾題收進去,送給負責人逐項回「同意」並留日期;同時跟負責人確認藍新申請到哪一步(測試帳號、串接文件、定期定額費率、是藍新代排扣款還是我們每期去請款)。
提醒:
一、本文〈還沒裁〉有三題已經被後來的裁決回答、本文沒改:欠費寬限(
#316
:扣款失敗 21 天照常,之後唯讀)、發票自動還是人工開(
#316
:扣款成功那一刻開)、有沒有年繳(
#316
:有);10/03 工程回派負責人的「續訂失敗寬限天數」也已被 21 天回答。寫 ADR 時直接收進去,不要再問一次。二、本文自己有兩句打架:〈要做什麼〉第 3 點要畫面上有「確認中」與逾時提示,〈測試方式〉第 5 點又說本單不產出畫面——建議把畫面留到接真金流那張。三、標題寫「綁卡的骨架」,但綁卡其實在
#257
(假的綁卡已由 PR
#287
上線),這張不處理綁卡。四、管理台「功能展示」的假帳務台(
#284
)看起來很像這張做完了,其實不是:它只在瀏覽器記憶體裡跑,
ADR-0129
明講不接受這張的正式方案。五、本文〈已經裁定的〉列了「不重用案件請款的 firm_receipts」「上線要另案批准」兩條,出處是研究文件的一段,但那段標題就寫「不是新增產品裁決」,所以這裡沒當定案(工程上沒有爭議,寫 ADR 時請負責人一起點頭即可)。六、
#326
定了加席要另扣一筆,代表扣款不只每期訂閱一種,ADR 的「同一期只扣一次」要把這種也算進去。
一步一步 12
已經定的 16
還沒定的 10
怎麼驗收 9
這張不做 10
這張要解決什麼
之後要按月或按年付訂閱費的付款人(例如事務所負責人);這張的直接受益者是之後接真金流的工程,和管帳的負責人
,付款人在藍新的頁面刷完卡被導回 Slate;藍新另外在背景送付款通知給 Slate。通知可能重送好幾次、可能晚到、可能順序顛倒,Slate 自己也可能處理到一半當機——要能 不管通知怎麼來,每一筆錢只算一次、狀態不會被舊消息打回去、原始通知不會遺失;付款和發票是兩本帳。這層在開收費之前先做好、測好,之後拿到藍新文件只要接一個轉接頭(adapter),不用重寫
一步一步
12 步
宜芳(PM)
把這張分派出去,請接手的工程先寫一份 ADR(Proposed):三張表——原始通知、付款事件、發票——各記什麼;驗簽、去重、亂序、補償四件事的介面;還有「同一位付款人同一期只能成功扣一次」要怎麼擋
docs/adr/ 多一份狀態寫 Proposed 的 ADR,用 PR 送上來給負責人看。被接受之前,不寫資料表、不開對外的通知端點
負責人
讀那份 ADR,一項一項回「同意」或改,寫在 ADR 或 issue 上並留日期
ADR 改成 Accepted,檔頭附負責人原話和日期(
ADR-0096
:找不到原話就不算 Accepted)。這一步過了,工程才開始寫骨架
負責人
(跟上面兩步同時進行)向藍新申請特店帳號、測試帳號與串接文件,問清楚定期定額的實際費率、是藍新代排每期扣款還是我們每期主動請款、通知裡有沒有穩定的通知 ID 與事件順序欄位
文件到手之後,另一張單才能接上真的簽名格式和 API;費率到手之後,
#254
的扣點表要用含稅總額重算。這一步不擋骨架
工程(宜芳分派的人)
照 Accepted 的 ADR 做骨架:一個假的服務商(test provider)、付款狀態機、發票狀態機、接收通知的驗簽/去重/亂序/補償,每一條先寫會失敗的測試(紅燈)再實作
一張骨架 PR:全部用假服務商驅動,不接藍新、不接 ezPay、不開任何付款按鈕;新端點附「付款人 A 讀不到付款人 B 的帳單」的隔離測試
付款人(未來;這個畫面在接真金流那張才做)
在藍新頁面刷完卡,被導回 Slate
畫面只顯示「確認中」,不會因為網址上帶著 success 之類的字就當成已付款、解鎖功能。要等後端真的收到並處理過藍新的通知,才變成已付款
付款確認中(示意,這張不做)
付款確認中
正在等藍新的付款通知;收到之前不算付款成功
等太久會顯示逾時提示——逾時之後怎麼處理(人工查單、客服)還沒定
藍新(服務商)
在背景送一封付款通知(webhook)給 Slate
Slate 先驗簽:沒設密鑰、簽名不對、時間戳過期,一律拒絕——不是記個警告照樣處理;被拒絕的通知不改任何帳
Slate 後端
驗簽通過後,先把整封通知原封不動存進「原始通知」表,存好才開始處理
處理到一半當機,通知還在;可以用一支函式或腳本把它重放一次,重放不會把同一筆錢算兩次
Slate 後端
檢查這封通知以前有沒有收過
同一個通知 ID、內容一樣:回藍新「收到了」(免得它一直重送),但不再處理一次。同一個 ID 但內容不一樣(例如金額不同):標成衝突、不改帳、留給人查,不會靜靜把舊的蓋掉
Slate 後端
判斷先後:看通知自己帶的事件時間或版本,不看哪一封先到
較舊的通知晚到時,不會把狀態打回去。例:先收到「付款成功」,後來才到一封其實發生得更早的「付款失敗」——狀態維持付款成功
Slate 後端
把付款狀態往前推:等待中 → 已付款/失敗/已退款
付款狀態只有通知能改。發票是另一條獨立的狀態(未開 → 已開/作廢),照負責人 10/04 的裁決在扣款成功那一刻開(開票本身是
#259
的事)。付款人畫面從「確認中」變成「已付款」
宜芳或負責人(想先看懂這些規則長什麼樣)
用管理員帳號開「管理台 → 功能展示」,打開「啟用帳務展示」,按「載入範例」,對帳單按「送成功」,再到事件紀錄按「重送相同事件」「同 ID +1 分」,最後回帳單按「送失敗」
假帳單只入帳一次;重送的那筆顯示「重複(未重做)」;同 ID 不同金額顯示「衝突(未套用)」;晚到的失敗不會把已付款打回去。這是
#284
做的假展示台,資料只在瀏覽器裡、重新整理就消失,拿來看懂規則用,不是這張的成品
管理台 → 功能展示:帳務生命週期模擬台(#284,已上線)
啟用帳務展示(Feature flag),預設關
帳務生命週期模擬台
模擬模式:不會扣款、不會寄信、不會開真發票;重新整理資料消失。請勿輸入真個資。
載入範例
重置模擬台
帳單:期別 · 金額;狀態、已付、已退
送成功
送失敗
模擬驗證失敗
部分退款
開立假發票
事件紀錄:種類/ID、狀態、訊息、操作(重送相同事件、同 ID +1 分、重試)
收件回條:收到不等於已入帳
宜芳(PM)
照下面的驗收步驟看骨架 PR,過了才請審查者合併
合併之後正式站還是沒有任何能真的扣款或開通訂閱的按鈕;接真藍新、開收費開關,各是之後另開的單
已經定的
16 條
金流用藍新,電子發票用 ezPay
負責人 2026-10-02(
#258
本文〈已經裁定的〉、
#248
已裁定清單)
合併之前不開收費:這張只做地基,不接真的服務商、不產生真的訂閱、不做能讓人被扣款的入口
負責人
#240
回覆(「合併前不開收費」);
ADR-0117
〈修訂〉七;
#248
訂閱、帳單、點數都在付款人名下,帳單只有付款人看得到;發票要能填公司統編
負責人
#240
回覆(
#248
已裁定清單)
金流與電子發票的法律、會計確認由負責人本人負責
負責人
#240
回覆(
#248
已裁定清單)
註冊時綁信用卡,但綁卡不扣款;不存卡號,只存藍新給的代碼。綁卡怎麼做在
#257
,不在這張
負責人 2026-10-02(
#257
、
#248
)
發票在扣款成功那一刻開(所以不扣款的期間不會開);載具與捐贈碼訂閱時填、續訂沿用
負責人 2026-10-04(
#316
第五節、
#259
)
扣款失敗:21 天內照常使用,之後唯讀、不刪、不設期限、能匯出
負責人 2026-10-04(
#316
第二節、
#248
)
有年繳(折扣 16.7%~20%,取哪個數還沒定);點數照樣按月發
負責人 2026-10-04(
#316
第二節)
加席當下另扣一筆、扣款成功另開一張發票;比例金額四捨五入到元,分母用這一期實際天數
負責人 2026-10-05「照PM建議」(
#326
、
#248
)
減席不退錢,用到這一期結束
負責人 2026-10-04(
#316
第二、三節)
儲值、加購點數包、自動加值:先拿到律師與會計師的書面意見才做
ADR-0057
決策九;
ADR-0117
〈2026-10-01 修訂〉五;
#261
接真金流之後的驗收,只能用藍新/ezPay 的測試環境和官方測試卡號,不准用真卡
負責人 2026-10-02(
#258
本文〈測試方式〉第 5 點)
新增對外暴露面(這裡是 webhook 端點和三張新表)之前要先寫 ADR,負責人過目後才實作
CLAUDE.md〈最重要的一條〉;
#258
本文〈要做什麼〉第一步
ADR 要算 Accepted,必須附負責人、日期和原話
ADR-0096
決策一
新端點沒有跨租戶(這裡是跨付款人)隔離測試,不得合併
ADR-0019
決策二
管理台的帳務展示台只是假的 MVP 展示,不等於這張的正式方案;也不能拿它的「驗證通過」開關當真的驗簽
ADR-0129
第二節第 7 點、第六節
還沒定的
10 題
工程做法本身負責人還沒點頭:付款和發票分兩條狀態機、通知先存再處理、同 ID 不同內容算衝突、不靠導回網址判斷成功。本文照這個做法寫,但出處(研究文件第 7 題)自己寫明是「建議契約,批准前不啟用」
照
#283
的整理接受
逐項修改後接受
建議:
寫成 ADR 後請負責人逐項回「同意」並留日期;沒點頭前不寫表、不開端點(
#283
)
誰裁:負責人
同一位付款人、同一期,出現兩封不同的「付款成功」(例如逾時後重新請款,或付款人等不及又按一次)要怎麼擋?通知 ID 去重擋不住這種
自動擋第二筆
先向藍新查單再決定
轉人工處理
建議:
設計審查三位都同意要多一層「同一付款人+同一訂閱+同一期只能成功一次」的業務鍵,或至少留一條主動向藍新查單對帳的路;加席另扣的單筆也要有自己的鍵(
#258
10/02 留言、
#283
)
誰裁:負責人
定期定額是藍新代排每期扣款,還是 Slate 每期主動去請款?
藍新代排
Slate 主動請款(要另開一張做扣款排程)
誰裁:負責人(問藍新)
藍新定期定額的實際手續費率是多少?
向藍新業務確認
建議:
(這段講成本或毛利,公開頁不放——看 GitHub
#258
)
誰裁:負責人(問藍新)
退款怎麼處理:全額還是部分、誰核准、發票作廢還是開折讓;要不要多一個「拒付(chargeback)」狀態;退款或拒付時,對應還沒用的點數(含加購點數)要不要收回
作廢重開
開立折讓
依退款類型分開處理
建議:
減席不退錢已經定了(
#316
);其他等會計師回覆
#316
第五節「各種退款走作廢還是折讓」
誰裁:負責人+會計師
訂閱到期日怎麼算、以台北時間還是 UTC 為準?
台北時間
UTC
建議:
repo 的慣例是「今天」一律用台北日期(CLAUDE.md〈已知陷阱〉),建議照台北
誰裁:負責人
付款人等太久、通知一直沒來(確認中逾時),之後怎麼辦?
人工向藍新查單
請付款人聯絡客服
系統自動查單
誰裁:負責人
原始通知可能含個資或卡片資訊:哪些欄位可以存、存多久、誰能看?
照律師/會計意見定
建議:
拿到答案前先擋,不自己訂保存年限;日誌只記去敏後的識別碼(
#283
第 8 點)
誰裁:負責人+律師
回了「收到」之後處理卡住或失敗:誰負責重試、告警、人工重放,多久要升級?
指定一位維運負責人與時限
建議:
ADR 接受前就寫明(
#283
給 PM 的第 1 題)
誰裁:負責人
付款成功後發點數,是不是一定要等看到「已付款」通知才發(不能在等待中、或使用者被導回的那一刻就發)?
寫進 ADR 當規則
留給點數帳本那張(
#243
)定
建議:
設計審查建議在 ADR 寫明(
#258
10/02 留言);機構帳本與付款人帳本先不互接已定(
#326
)
誰裁:負責人
怎麼驗收
9 項
前提:
骨架 PR 送上來之前
操作:
打開 repo 的 docs/adr/,找這張的 ADR(PR 說明會連過去)
應該看到:
檔頭寫 Accepted,旁邊有負責人的原話和日期;內容裡付款與發票是兩張不同的表、各有自己的狀態(付款:等待中 → 已付款/失敗/已退款;發票:未開 → 已開/作廢)
前提:
骨架 PR 已開
操作:
在 PR 頁往下看 Checks,再看 PR 說明
應該看到:
CI 五個項目全部綠勾;PR 說明寫著沒有接真的藍新/ezPay、沒有新增任何付款按鈕
前提:
同一張 PR
操作:
看 PR 說明的測試清單(或請工程把測試名稱貼出來),找「驗簽」
應該看到:
有三條:沒設密鑰拒絕、簽名錯拒絕、時間戳過期拒絕;而且寫明被拒絕的通知不改帳
前提:
同一張 PR
操作:
找「重複」的測試
應該看到:
同一封通知送兩次:第二次回「收到」,但處理只發生一次、錢只算一次;同一個 ID 但金額不同:判成衝突、不覆蓋
前提:
同一張 PR
操作:
找「亂序」的測試
應該看到:
有「先已付款、後到一封其實更早的失敗」和「先已付款、後到建立」兩個案例,最後狀態都還是已付款
前提:
同一張 PR
操作:
找「補償」的測試,並看 PR 說明怎麼重放
應該看到:
有「處理到一半寫入失敗」的案例:原始通知還在表裡;照說明的方法重放一次,最後狀態正確、錢沒有算兩次
前提:
同一張 PR
操作:
找「隔離」的測試
應該看到:
有「付款人 A 的登入讀不到付款人 B 的帳單/付款紀錄,換 ID 也讀不到」的測試,而且是綠的
前提:
審查者看過程式碼
操作:
請審查者在 PR 上回一句確認
應該看到:
寫明前端沒有任何地方憑導回網址上的參數或 HTTP 狀態就把付款寫成成功——所有「已付款」都來自後端處理過的通知(本文規定這條要人看,CI 綠不算)
前提:
PR 合併、部署完成
操作:
用測試帳號(farside_dev)登入正式站,走一遍左側欄、設定頁、管理台各分頁
應該看到:
找不到任何能真的訂閱、付款或扣款的按鈕;跟帳務有關的只有「管理台 → 功能展示」那個假模擬台,上面寫著「模擬模式:不會扣款」
這張不做
接真的藍新或 ezPay:真簽名格式、真 API、真金鑰都是之後另一張單
任何使用者能真的按下去被扣款或開通訂閱的按鈕;「確認中」畫面也留到接真金流那張
開收費開關(合併之前不收費)
綁卡流程與卡片代碼怎麼存(
#257
)
電子發票怎麼開、統編與載具規則(
#259
)
付款人與訂閱的資料模型(
#256
)
點數核發與點數帳本(
#243
)
儲值、加購點數包、自動加值(
#261
,先問律師)
如果是 Slate 每期主動去請款,那個扣款排程器另開單(
#283
)
用真卡測試
相關的單
#240
#243
#248
#254
#255
#256
#257
#259
#261
#283
#284
#285
#287
#316
#326