收款帳戶與結算
一筆錢「實際落在哪個帳戶」往往不是它「最終該歸屬的帳戶」。cairn 由每筆收款 + 費用類型路由自動推導各帳戶間的應補淨額,你登錄實際的補款/代墊/回填,並把跨月未結的欠款追到結清。
這層屬進階會計模組:未開模組的租戶只用核心對帳視圖,月結互抵與帳戶間移轉登錄需開模組。相關端點都掛在 reconciliation 與 settings 之下。
收款帳戶與分流
每個租戶自己維護一份收款帳戶目錄(銀行 / 現金 / 金流商沉澱帳),用 GET /reconciliation/receiving-accounts 取得。帳戶沒有內建枚舉——你想用幾個、怎麼組合都行。
每個帳戶帶一組能力旗標,決定它能做什麼(不是寫死帳戶名):
| 欄位 | 意義 |
|---|---|
canReceive | 可收款(幾乎都是 true) |
canRemit | 可對外匯款(退款匯出 / 補款匯出) |
canChargeback | 可刷退(退回原信用卡,通常只有金流商帳戶) |
isDeprecated | 廢帳戶:仍可零星收款,但其收款需由他帳戶代墊歸集 |
isSettlementMaster | 主結算帳戶:所有資金最終向它彙整,每租戶恰一個 |
currency | 帳戶幣別(ISO 4217,預設 TWD;外幣帳戶=外幣池) |
收款落帳時,金流商收款自動掛對應的沉澱帳戶;手動入帳(ATM / 臨櫃 / 現金)則由經手人從啟用帳戶中選一個——帳戶與產品線無關,不依產品線篩選。
帳戶目錄與能力是租戶配置,經 settings 維護:
GET /settings/receiving-accounts列出、POST新增、PATCH /settings/receiving-accounts/{id}改名 / 改能力 / 設幣別 / 停用。PUT /settings/fee-category-routes設定「費用類型 → 最終該歸哪個帳戶」的路由(如團費歸主結算帳戶、車費 / 住宿 / 裝備歸另一帳戶)。
帳戶停用不刪——被現金列引用的帳戶會被鎖住、不能硬刪,避免抹掉歷史歸戶。能力旗標與費用類型路由都需要 receiving_account.manage 權限。
逐帳戶對帳
對帳是「錢在哪」的視圖。用 GET /reconciliation/accounts(可帶 dateFrom / dateTo)取每個帳戶在期間內的進出與淨額:
| 欄位 | 意義 |
|---|---|
inTwd | 期間內收進的現金 |
outTwd | 退款 / 金流出的現金 |
payableOutTwd | 供應商 / 嚮導出款(與訂單收款分源呈現) |
netTwd | inTwd − outTwd − payableOutTwd |
txCount | 該帳戶的交易筆數 |
對帳是純讀派生——把現金紀錄與供應商出款依帳戶彙整,給你和銀行 / 金流商實際入帳核對。差異由你人工確認,系統不假設銀行端為真值。歸不到帳戶的收款會落「未歸戶桶」(accountId 為 null),提示你補歸戶,而不是靜默吞掉。
帳戶間移轉
帳戶之間的一切資金移動都記在同一張流水上,用 kind 區分。讀取走 GET /reconciliation/transfers(可依 kind / account / settlementPeriod / dateFrom / dateTo 篩),登錄走 POST /reconciliation/transfers:
kind | 是什麼 |
|---|---|
replenishment | 補款歸集(把代收的款補給最終帳戶) |
advance | 廢帳戶代墊(代墊帳戶先補給最終帳戶) |
backfill | 回填沖銷代墊 |
refund_payout | 退款匯出(從可匯款帳戶出) |
fx_conversion | 換匯(換出台幣 + 外幣實拿) |
opening | 外幣期初餘額 |
reversal | 沖正(反向對沖一筆原移轉) |
一筆移轉帶 amountTwd(實際移轉的台幣淨額)與 feeTwd(這筆轉帳本身的手續費,如匯款費)。amountTwd 已是淨額——金流收款手續費已在成本帳認列,這裡不重記。換匯則另帶 currency / foreignAmount / grossRate。
移轉登錄後不可修改或刪除。記錯就開一筆 kind 為 reversal 的沖正(反向 from / to + 對沖金額)指回原列,保留可稽核的鏈,而不是改寫歷史。
登錄移轉(POST)需要 account_transfer.manage 權限,且需開啟進階會計模組。換匯不是另一種資源——它只是 kind 為 fx_conversion 的一筆移轉,共用同一套權限與列表。
月結互抵
你不用手算各帳戶該補多少。選一個月份,cairn 由當月收款 + 費用類型路由派生互抵矩陣:
GET /reconciliation/settlement-overview?period=YYYY-MM取當期矩陣與掛帳(純讀,不寫入)。POST /reconciliation/settlement/compute跑派生並upsert掛帳,回傳每筆的action(created/updated/floored_to_settled)。
重跑同一期可覆蓋派生(你修正了歸戶或路由之後),但護欄不會把目標降到已結金額以下——若派生目標低於已沖減額,差額會以 floored_to_settled 保留為調整掛帳,不靜默改寫已結歷史。
派生出的帳戶間欠款是一級實體,用 GET /reconciliation/obligations(可帶 period / reason / status)追蹤到結清:
| 欄位 | 意義 |
|---|---|
debtorAccountId / creditorAccountId | 欠錢方 / 收錢方(方向只由這兩欄表達) |
amountTwd | 應補目標總額(恆正) |
settledAmountTwd | 已透過移轉沖減的累計 |
outstandingTwd | 尚欠 = amountTwd − settledAmountTwd |
reason | period_settlement(月結淨額)/ advance_repayment(代墊待回填)/ refund_advance(代墊退費待回補) |
status | outstanding / partially_settled / settled |
你登錄的補款 / 代墊 / 回填移轉(上一節)會沖減對應掛帳,outstandingTwd 隨之下降,直到結清。
退款執行
退多少、扣多少手續費由訂單退款流程決定;這裡管的是退款的執行帳戶與對帳。用 GET /reconciliation/refund-executions(可帶 status=approved|paid)取待執行與已執行的退款:
| 欄位 | 意義 |
|---|---|
executionMethod | chargeback(刷退)或 remit(匯出) |
originAccountId | 原收款落地帳戶 |
adminFeeTwd / remitFeeTwd | 行政手續費 / 匯款手續費 |
payeeAccountName / payeeBankCode / payeeAccountNumber | 匯出退款的收款人三欄 |
能力檢核:chargeback 只能走 canChargeback 的帳戶、remit 只能走 canRemit 的帳戶,違反會被擋下。remit 退款會產生一筆 kind 為 refund_payout 的帳戶間移轉並併入月結;chargeback 由金流商處理、不產生帳戶間移轉,只記對帳。
當執行帳戶不是退款該由的最終帳戶時(例如主結算帳戶先代墊另一帳戶該吐的退款),系統開一條 reason 為 refund_advance 的掛帳,按月彙整、追到回補。
下一步
- 內外帳與損益:成本可不可申報、淨利試算——與「錢在哪」正交的另一軸。
- 請款與出款:對供應商 / 嚮導的出款核簽,與帳戶間移轉的差別。
- 訂單與金流模型:應收、現金、退款生命週期的全貌。
- reconciliation API · settings API。