API 參考
進階套組全 292 個端點,依領域分類。每個標出 HTTP method、路徑、 所需權限與模組閘。按 ⌘K 搜尋。
開始使用
API 掛在你的租戶網域之下(base URL https://<your-tenant-domain>/api/v1)——打哪個網域就操作哪個租戶。 REST 語意、JSON 進出。
每個請求帶 Authorization: Bearer …。token 由 CLI 的 OAuth device flow 核發,權限沿用你帳號的角色——API 不會給你後台沒有的能力。
所有端點回傳同一個外殼:成功 { "ok": true, "data": … }、失敗 { "ok": false, "error": { "code", "message" } }(錯誤碼一覽見下方 錯誤碼)。部分端點掛方案模組閘,未啟用回 403 module_disabled。
機器可讀規格:openapi.json(OpenAPI 3.1,含參數型別與回應欄位)、llms-full.txt(全文件單檔)。
curl https://your-tenant.example.com/api/v1/orders \
-H "Authorization: Bearer $CAIRN_TOKEN"
{ "ok": true,
"data": { "rows": [ … ], "total": 42, "page": 1 } }錯誤碼
| HTTP | code | 意義 |
|---|---|---|
| 401 | unauthorized | 未帶 / 無效 bearer token |
| 403 | forbidden | 通過認證但無此權限 |
| 403 | module_disabled | 租戶未啟用該方案模組 |
| 404 | not_found | 資源不存在或不在你的 owner-scope 內 |
| 409 | conflict | 狀態機 / 業務規則衝突 |
| 409 | invariant | 金流不變式違反 |
| 422 | validation | 輸入驗證失敗(附 issues[]) |
| 500 | internal | 伺服器內部錯誤(細節不外洩) |
{ "ok": false,
"error": {
"code": "validation",
"message": "…",
"issues": [ … ] // 422 才有
} }/departures
設定梯次分配模式
/api/v1/departures/{depId}/allocation-mode參數
depId路徑梯次 ID
mode必填fcfslottery分配模式:fcfs(先到先得)或 lottery(抽籤)
回應欄位 · data
ok更新成功旗標,恆為 true。
departureId被更新的梯次 id。
mode更新後的佔位模式:fcfs 先到先得/lottery 抽籤。
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/allocation-mode \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mode": "fcfs"
}'{
"ok": true,
"data": {
"ok": true,
"departureId": "…",
"mode": "fcfs"
}
}登錄梯次成本
/api/v1/departures/{depId}/costs參數
depId路徑梯次 ID
category必填成本科目類別,決定歸入哪個分類帳
vendorName選填供應商/受款對象名稱
description選填成本說明備註
amountTwd必填成本金額(台幣,整數)
回應欄位 · data
ok建立成功旗標,恆為 true。
id新建立的梯次成本列 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/costs \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"category": "<category>",
"amountTwd": 0
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}/api/v1/departures/{depId}/costs/{costId}參數
costId路徑成本列 ID
category必填成本科目類別,決定歸入哪個分類帳
vendorName選填供應商/受款對象名稱
description選填成本說明備註
amountTwd必填成本金額(台幣,整數)
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/departures/{depId}/costs/<costId> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"category": "<category>",
"amountTwd": 0
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/departures/{depId}/costs/{costId}參數
costId路徑成本列 ID
回應欄位 · data
ok刪除成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/departures/{depId}/costs/<costId> \
-H "Authorization: Bearer $CAIRN_TOKEN"{
"ok": true,
"data": {
"ok": true
}
}該梯次財務摘要
/api/v1/departures/{depId}/finance-summary參數
depId路徑梯次 ID
回應欄位 · data
header梯次表頭(團號/行程名/出發日等基本資訊)。
id梯次 id(dep_ 前綴)。
tripTitle所屬行程標題。
tripSlug所屬行程網址 slug。
departureDate出發日(ISO 'YYYY-MM-DD')。
returnDate回程日(ISO 'YYYY-MM-DD')。
finance應收/已收金額彙整(TWD)。
receivableTwd梯次應收:tour 訂單 order_charge_lines 聚合(排除已取消單)。
collectedTwd實收:tour 訂單 payment_transactions(direction='in')。
cashReturnedTwd客戶現金退回(refund/chargeback/reversal)。
outstandingTwd待收 = 應收 − (實收 − 退回),floor 0。
costTwd成本:departure_costs 真實額(房費另計,見成本登記簿)。
costBilledTwd已轉請款成本。
costUnbilledTwd未轉請款成本。
anomalyOrderCount異常單數:overpaid / partially_refunded / refund pending 的 tour 訂單。
cost成本彙整(各類直接成本合計,TWD)。
totalTwd內帳真實成本合計(TWD 整數,各成本列金額加總)。
billedTwd已轉請款的成本合計(TWD 整數)。
unbilledTwd尚未轉請款的成本合計(TWD 整數)。
declarableTwd外帳可申報金額合計(TWD 整數,各列憑證金額加總)。
nonDeclarableTwd無憑證的不可申報成本合計(TWD 整數,逐列取 金額−憑證 的正值,不可跨列抵減)。
count成本列筆數。
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/finance-summary \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"header": {
"id": "…",
"tripTitle": "…",
"tripSlug": "…",
"departureDate": "…",
"returnDate": "…"
},
"finance": {
"receivableTwd": 0,
"collectedTwd": 0,
"cashReturnedTwd": 0,
"outstandingTwd": 0,
"costTwd": 0,
"costBilledTwd": 0,
"costUnbilledTwd": 0,
"anomalyOrderCount": 0
},
"cost": {
"totalTwd": 0,
"billedTwd": 0,
"unbilledTwd": 0,
"declarableTwd": 0,
"nonDeclarableTwd": 0,
"count": 0
}
}
}該梯次抽籤訂單清單
/api/v1/departures/{depId}/lottery-orders參數
depId路徑梯次 ID
回應欄位 · data[]
orderId訂單 id。
orderNumber訂單編號。
customerName訂購人姓名。
partySize佔位人數。
lotteryState抽籤狀態:applied 已應募/won 中籤/lost 未中籤。
backupChoiceCount客人自選的有序備案筆數(order_backup_choices;0 = 無備案)。
collectedTwd已收現金(payment_transactions direction='in');抽籤未中安置時的訂金結轉基準。
failoverFromOrderId落腳譜系:本單若是由某主單 force-place / cascade 落腳而成立的備案單,指向原主單 id。 null = 本單即主單(非備案落腳單)。供線控從備案列回溯主單。
awaitingPlacementtrue when lottery_state='lost' and still active (not cancelled). Means backup cascade exhausted — awaiting manual placement or explicit cancel.
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/lottery-orders \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"orderId": "…",
"orderNumber": "…",
"customerName": "…",
"partySize": 0,
"lotteryState": "applied",
"backupChoiceCount": 0,
"collectedTwd": 0,
"failoverFromOrderId": "…",
"awaitingPlacement": true
}
]
}該梯次旅客名單
/api/v1/departures/{depId}/manifest參數
depId路徑梯次 ID
回應欄位 · data[]
orderId所屬訂單 id。
orderNumber所屬訂單編號。
travelerName旅客姓名。
phone聯絡電話。
email聯絡 Email。
isPrimary是否為該訂單的主要聯絡人(訂購人)。
gender性別(明文 enum-like):'male'|'female'|'other'|null(未填)。
birthDate生日 ISO `YYYY-MM-DD`;null = 未填。
diet飲食需求(葷素)明文;null = 未填。
medicalNotes醫療 / 過敏 / 病史備註明文;null = 未填。
specialNeeds「飲食 · 特殊需求」欄的合併顯示字串(diet + medical_notes,以 ` · ` 併接)。 結構化欄落地後改吃 diet / medical_notes(不再湊 roommate_pref —— 分房需求回歸分房面板)。 兩者皆空 → null。
emergencyContactName緊急聯絡人姓名;null = 未填。
emergencyContactPhone緊急聯絡人電話;null = 未填。
consentPending該訂單是否仍缺最新版 PDPA 同意書(per-order,同訂單所有旅客共享此旗標)。 true = 未簽 / 只簽過舊版;與 dashboard KPI、催簽 badge 同一述詞。
orderStatusSingle display status (派生自三軸,與 deriveOrderDisplayStatus 同 precedence)。
amount該訂單應收金額(TWD;自 order_charge_lines 派生)。
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/manifest \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"orderId": "…",
"orderNumber": "…",
"travelerName": "…",
"phone": "…",
"email": "…",
"isPrimary": true,
"gender": "male",
"birthDate": "…",
"diet": "…",
"medicalNotes": "…",
"specialNeeds": "…",
"emergencyContactName": "…",
"emergencyContactPhone": "…",
"consentPending": true,
"orderStatus": "…",
"amount": 0
}
]
}成本轉請款:以選定的未轉成本列建立一張
/api/v1/departures/{depId}/payables參數
depId路徑梯次 ID
costIds必填要轉成請款單的成本列 ID 清單,至少一筆
payeeType必填supplierguidestaff_commissionother受款人類型:supplier(供應商)/ guide(領隊)/ staff_commission(員工佣金)/ other(其他)
payeeName必填受款人姓名/戶名(必填)
payeeBankAccount選填受款人銀行帳號
payeeBankName選填受款人銀行名稱
payeeTaxId選填受款人統一編號/稅籍編號
submitImmediately選填設為 true 時建立後立即送出核簽,否則僅存為草稿
回應欄位 · data
ok轉請款成功旗標,恆為 true。
payableId新建立的出款單(payable)id。
payableNumber出款單編號。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/payables \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"costIds": [],
"payeeType": "supplier",
"payeeName": "<payeeName>"
}'{
"ok": true,
"data": {
"ok": true,
"payableId": "…",
"payableNumber": "…"
}
}新增餐食紀錄
/api/v1/departures/{depId}/prep/catering參數
depId路徑梯次 ID
supplier選填餐食供應商名稱
mealPlan選填餐食安排說明(如餐數、菜色)
headcountNote選填人數備註(如素食、特殊餐需求)
status選填餐食安排狀態,預設 pending
回應欄位 · data
ok建立成功旗標,恆為 true。
id新建立的餐食紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/catering \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}更新餐食紀錄
/api/v1/departures/{depId}/prep/catering/{id}參數
depId路徑梯次 ID
id路徑餐食紀錄 ID
supplier選填餐食供應商名稱
mealPlan選填餐食安排說明(如餐數、菜色)
headcountNote選填人數備註(如素食、特殊餐需求)
status選填餐食安排狀態
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/prep/catering/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}刪除餐食紀錄
/api/v1/departures/{depId}/prep/catering/{id}參數
depId路徑梯次 ID
id路徑餐食紀錄 ID
回應欄位 · data
ok刪除成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/catering/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}設定行前總檢查某項勾選狀態
/api/v1/departures/{depId}/prep/checklist參數
depId路徑梯次 ID
itemKey必填行前檢查項目的代碼
checked必填該檢查項目是否已完成勾選
回應欄位 · data
ok設定成功旗標,恆為 true。
id行前檢查項紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/checklist \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"itemKey": "<itemKey>",
"checked": true
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}設定梯次期限警戒
/api/v1/departures/{depId}/prep/deadlines參數
depId路徑梯次 ID
permitApply選填入山申請截止日(ISO 日期);傳空字串或省略則清除此期限
permitDownload選填入山證下載截止日(ISO 日期);傳空字串或省略則清除此期限
climbingInsurance選填登山險送保截止日(ISO 日期);傳空字串或省略則清除此期限
liabilityInsurance選填旅責險送保截止日(ISO 日期);傳空字串或省略則清除此期限
回應欄位 · data
permitApply入山申請截止日(ISO 日期;null = 未設 / 已清除)。
permitDownload入山證下載截止日(ISO 日期;null = 未設 / 已清除)。
climbingInsurance登山險送保截止日(ISO 日期;null = 未設 / 已清除)。
liabilityInsurance旅責險送保截止日(ISO 日期;null = 未設 / 已清除)。
ok設定成功旗標,恆為 true。
departureId被設定期限的梯次 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/deadlines \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"permitApply": "…",
"permitDownload": "…",
"climbingInsurance": "…",
"liabilityInsurance": "…",
"ok": true,
"departureId": "…"
}
}upsert 一種證件追蹤狀態
/api/v1/departures/{depId}/prep/documents參數
depId路徑梯次 ID
docType必填證件/文件種類代碼(如入山申請、保險名冊)
applyStatus選填todoapplyingapproved申辦狀態:todo(待辦)/ applying(申請中)/ approved(已核准)
fileReady選填文件檔案是否已備妥
uploadedToCloud選填文件是否已上傳雲端
fileUri選填文件檔案連結;給 null 清空
note選填備註;給 null 清空
回應欄位 · data
okupsert 成功旗標,恆為 true。
id證件追蹤紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/documents \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"docType": "<docType>"
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}upsert 某裝備品項的需求數
/api/v1/departures/{depId}/prep/equipment-needs參數
depId路徑梯次 ID
equipmentItemId必填裝備品項 ID
quantity必填該品項的需求數量
note選填需求備註;給 null 清空
回應欄位 · data
okupsert 成功旗標,恆為 true。
id裝備需求紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/equipment-needs \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"equipmentItemId": "<equipmentItemId>",
"quantity": 0
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}刪除裝備需求列
/api/v1/departures/{depId}/prep/equipment-needs/{id}參數
depId路徑梯次 ID
id路徑裝備需求列 ID
回應欄位 · data
ok刪除成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/equipment-needs/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}指派 / 重派領隊到梯次
/api/v1/departures/{depId}/prep/guides參數
depId路徑梯次 ID
guideId必填領隊 ID
role必填leaderassistant指派角色:leader(領隊)或 assistant(隨隊/助理)
status選填tentativeconfirmed指派狀態:tentative(暫定)或 confirmed(已確認)
回應欄位 · data
ok指派成功旗標,恆為 true。
id領隊指派紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/guides \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"guideId": "<guideId>",
"role": "leader"
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}新增投保紀錄
/api/v1/departures/{depId}/prep/insurance參數
depId路徑梯次 ID
kind必填保險種類(如登山險、旅責險)
insurer選填保險公司名稱
policyNo選填保單號碼
status選填投保狀態,預設 pending
note選填備註;給 null 清空
回應欄位 · data
ok建立成功旗標,恆為 true。
id新建立的投保紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/insurance \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"kind": "<kind>"
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}更新投保紀錄
/api/v1/departures/{depId}/prep/insurance/{id}參數
depId路徑梯次 ID
id路徑投保紀錄 ID
insurer選填保險公司名稱
policyNo選填保單號碼
status選填投保狀態
note選填備註;給 null 清空
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/prep/insurance/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}刪除投保紀錄
/api/v1/departures/{depId}/prep/insurance/{id}參數
depId路徑梯次 ID
id路徑投保紀錄 ID
回應欄位 · data
ok刪除成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/insurance/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}從裝備需求開租借單
/api/v1/departures/{depId}/prep/rentals參數
depId路徑梯次 ID
orderId必填要掛這筆租借費用的訂單 ID
renterName選填租借人姓名;給 null 清空
lines必填租借品項明細(品項 + 數量),數量需大於 0 才計入
回應欄位 · data
ok開單成功旗標,恆為 true。
rentalId新開立的裝備租借單 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/rentals \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orderId": "<orderId>",
"lines": []
}'{
"ok": true,
"data": {
"ok": true,
"rentalId": "…"
}
}新增派車紀錄
/api/v1/departures/{depId}/prep/transport參數
depId路徑梯次 ID
description選填派車說明(如路線、接送地點)
driverName選填司機姓名
vehicleInfo選填車輛資訊(如車型、車牌)
fareNote選填車資備註
status選填派車狀態,預設 pending
回應欄位 · data
ok建立成功旗標,恆為 true。
id新建立的派車紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/transport \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}更新派車紀錄
/api/v1/departures/{depId}/prep/transport/{id}參數
depId路徑梯次 ID
id路徑派車紀錄 ID
description選填派車說明(如路線、接送地點)
driverName選填司機姓名
vehicleInfo選填車輛資訊(如車型、車牌)
fareNote選填車資備註
status選填派車狀態
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/prep/transport/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}刪除派車紀錄
/api/v1/departures/{depId}/prep/transport/{id}參數
depId路徑梯次 ID
id路徑派車紀錄 ID
回應欄位 · data
ok刪除成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/transport/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}分房表匯出資料列
/api/v1/departures/{depId}/rooming-export參數
depId路徑梯次 ID
回應欄位 · data[]
fullName旅客姓名。
gender性別(中文標籤:男/女/其他)。
roomLabel房號/房間標籤(未排房為「未分房」)。
bedInfo床位資訊(房型中文標籤 + 床位)。
roommates同房其他旅客姓名(依房號分組派生)。
specialRequest特殊需求(房友偏好等自由文字)。
contactSummary聯絡摘要(電話已遮罩,只露末 3 碼)。
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/rooming-export \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"fullName": "…",
"gender": "…",
"roomLabel": "…",
"bedInfo": "…",
"roommates": "…",
"specialRequest": "…",
"contactSummary": "…"
}
]
}該梯次分房檢視
/api/v1/departures/{depId}/rooms參數
depId路徑梯次 ID
回應欄位 · data
departure梯次表頭(id/起訖日/行程名/容量等)。
id梯次 id(dep_ 前綴)。
departureDate出發日(ISO 'YYYY-MM-DD')。
returnDate回程日(ISO 'YYYY-MM-DD')。
tripTitle所屬行程標題。
tripSlug所屬行程網址 slug。
capacity名額上限(人數)。
bookedCount已成團佔用名額(人數)。
rooms此梯次的所有房間(含入住旅客)。
id房間 id。
roomLabel房號/房間標籤。
roomType房型(如 single 單人/double 雙人/dorm 通舖)。
bedCount床位數。
bedConfig床位配置說明(可空)。
accommodationName住宿名稱(梯次配套派生房才有;可空)。
accommodationDate住宿日期(YYYY-MM-DD;可空)。
baseCostTwd房間底價成本(TWD)。
upgradeFeeTwd房型升等補款(TWD)。
notes備註(可空)。
departureLodgingIdnull = 手動建立的房;non-null = 梯次配套自動派生房的來源 ID。
assignedTravelers已入住此房的旅客。
unassignedTravelers尚未分房的旅客清單。
id旅客 id。
fullName旅客姓名。
orderId所屬訂單 id。
orderNumber所屬訂單編號。
isPrimary是否為該訂單的主要聯絡人(訂購人)。
gender性別:'male'|'female'|'other'|null。
birthDate選填出生日期(YYYY-MM-DD;可空)。
roomPreference下單登記的房型偏好(auto-pair 起點提示)。
roommatePref指定房友 id / 特殊需求自由文字。
stats分房統計彙總(總人數/已分房數/房間數/升等補款合計)。
totalTravelers此梯次旅客總人數。
assignedCount已分配房間的旅客數。
roomCount房間數。
totalUpgradeFee升等補款合計(TWD 整數)。
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/rooms \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"departure": {
"id": "…",
"departureDate": "…",
"returnDate": "…",
"tripTitle": "…",
"tripSlug": "…",
"capacity": 0,
"bookedCount": 0
},
"rooms": [
{
"id": "…",
"roomLabel": "…",
"roomType": "…",
"bedCount": 0,
"bedConfig": "…",
"accommodationName": "…",
"accommodationDate": "…",
"baseCostTwd": 0,
"upgradeFeeTwd": 0,
"notes": "…",
"departureLodgingId": "…",
"assignedTravelers": []
}
],
"unassignedTravelers": [
{
"id": "…",
"fullName": "…",
"orderId": "…",
"orderNumber": "…",
"isPrimary": true,
"gender": "…",
"birthDate": "…",
"roomPreference": "…",
"roommatePref": "…"
}
],
"stats": {
"totalTravelers": 0,
"assignedCount": 0,
"roomCount": 0,
"totalUpgradeFee": 0
}
}
}建立一間梯次房間
/api/v1/departures/{depId}/rooms參數
depId路徑梯次 ID
roomLabel必填房間代號/標籤(如 101、A 房)
roomType必填房型(如 雙人房、四人房)
bedCount必填床位數,必須大於 0
bedConfig選填床型配置說明(如 2 大床、1 大 2 小)
accommodationName選填住宿地點/旅宿名稱
accommodationDate選填入住日期(ISO 日期字串)
baseCostTwd選填房間基本成本(台幣),預設 0
upgradeFeeTwd選填房型升等補款金額(台幣),預設 0
notes選填房間備註
回應欄位 · data
ok建立成功旗標,恆為 true。
id新建立的房間 id。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/rooms \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"roomLabel": "<roomLabel>",
"roomType": "<roomType>",
"bedCount": 0
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}編輯房間
/api/v1/departures/{depId}/rooms/{roomId}參數
roomId路徑房間 ID
roomLabel選填房間代號/標籤;未給則不變
roomType選填房型;未給則不變
bedCount選填床位數;未給則不變
bedConfig選填床型配置說明;給 null 清空、未給則不變
accommodationName選填住宿地點名稱;給 null 清空、未給則不變
accommodationDate選填入住日期(ISO 字串);給 null 清空、未給則不變
baseCostTwd選填房間基本成本(台幣);未給則不變
upgradeFeeTwd選填房型升等補款金額(台幣);未給則不變
notes選填房間備註;給 null 清空、未給則不變
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/departures/{depId}/rooms/<roomId> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}刪除房間
/api/v1/departures/{depId}/rooms/{roomId}參數
roomId路徑房間 ID
回應欄位 · data
ok刪除成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/departures/{depId}/rooms/<roomId> \
-H "Authorization: Bearer $CAIRN_TOKEN"{
"ok": true,
"data": {
"ok": true
}
}線控確認 auto-pair 建議分組:
/api/v1/departures/{depId}/rooms/auto-pair-apply參數
depId路徑梯次 ID
travelerIds必填要編入同一房的旅客 ID 清單,至少一人
roomType選填建立房間的房型,預設 shared(合住)
回應欄位 · data
ok套用成功旗標,恆為 true。
roomId建議分組寫入後所在的房間 id。
travelerIds被排入該房的旅客 id 清單。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/rooms/auto-pair-apply \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"travelerIds": []
}'{
"ok": true,
"data": {
"ok": true,
"roomId": "…",
"travelerIds": [
"…"
]
}
}對某梯次「尚未排房」的旅客
/api/v1/departures/{depId}/rooms/auto-pair-preview參數
depId路徑梯次 ID
回應欄位 · data
suggestionauto-pair 引擎產出的分房建議(未寫入,供線控確認)。
groups建議的分房組合(每組一間房,含旅客與需確認註記)。
unmatched無法安全自動配對、待人工處理的旅客。
namestravelerId → 顯示名(建議分組渲染用)。
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/rooms/auto-pair-preview \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"suggestion": {
"groups": [],
"unmatched": []
},
"names": "…"
}
}該梯次套用的成本範本列
/api/v1/departures/{depId}/template-costs參數
depId路徑梯次 ID
回應欄位 · data[]
id梯次成本列 ID。
category成本分類(如 交通 / 餐費 / 保險)。
vendorName供應商 / 廠商名(可空)。
description摘要說明(可空)。
amountTwd內帳成本金額(TWD;數量 × 單價派生)。
invoiceAmountTwd報帳/發票金額(TWD;is_declarable=true 時同步 amount,否則 0)。
isDeclarable是否有合法憑證可報帳(開發票)。
quantityMode數量模式:fixed 固定值 / headcount 依人頭公式(ceil(Σ人頭 / 組距))。
headcountComponentsheadcount 模式選定的人頭 component(passenger / leader / assistant / driver);fixed 為 null。
groupDivisorheadcount 模式的組距(每 N 人一組,ceil 進位);null = 直接加總。
quantity實際套用的數量(依 quantityMode 派生)。
unitPriceTwd內帳單價(TWD;外幣列可為 null)。
currency幣別('TWD' = 台幣列)。
unitPriceForeign外幣單價;TWD 列 null。
foreignAmount外幣金額快照 = unit_price_foreign × quantity;TWD 列 null。
internalRate內帳匯率快照(numeric 字串);TWD 列 null。
externalRate外帳匯率快照(numeric 字串);TWD 列 null。
isManualOverride是否為線控手動改寫(true 時重算會跳過此列,不覆蓋手改值)。
payableId已轉請款 → 鎖定(不可手改 / 重算)。
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/template-costs \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"category": "…",
"vendorName": "…",
"description": "…",
"amountTwd": 0,
"invoiceAmountTwd": 0,
"isDeclarable": true,
"quantityMode": null,
"headcountComponents": null,
"groupDivisor": 0,
"quantity": 0,
"unitPriceTwd": 0,
"currency": "…",
"unitPriceForeign": 0,
"foreignAmount": 0,
"internalRate": "…",
"externalRate": "…",
"isManualOverride": true,
"payableId": "…"
}
]
}重設為範本算法
/api/v1/departures/{depId}/template-costs/{id}/clear-override參數
id路徑範本成本列 ID
回應欄位 · data
ok清除手改鎖並重算成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/departures/{depId}/template-costs/<id>/clear-override \
-H "Authorization: Bearer $CAIRN_TOKEN"{
"ok": true,
"data": {
"ok": true
}
}線控手改某範本成本列
/api/v1/departures/{depId}/template-costs/{id}/override參數
id路徑範本成本列 ID
amountTwd必填手動指定的成本金額(台幣),設定後停止自動重算
回應欄位 · data
ok手改金額成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/departures/{depId}/template-costs/<id>/override \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amountTwd": 0
}'{
"ok": true,
"data": {
"ok": true
}
}套用行程綁定範本到本梯次
/api/v1/departures/{depId}/template-costs/apply參數
depId路徑梯次 ID
回應欄位 · data
ok套用成功旗標,恆為 true。
inserted本次新補插入的範本成本行數(冪等,已存在的不重複插)。
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/template-costs/apply \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true,
"inserted": 0
}
}該梯次各訂單旅客資料完整度
/api/v1/departures/{depId}/validation-summary參數
depId路徑梯次 ID
回應欄位 · data[]
orderId訂單 id。
orderNumber訂單編號。
errorCount該訂單的 error(必補缺漏)項目數。
warningCount該訂單的 warning(建議補齊)項目數。
incompleteTravelerCount至少有一項 error 或 warning 的旅客數(資料待補人數)。
errorTravelerCount含 error 的旅客數(出團前置紅標用)。
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/validation-summary \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"orderId": "…",
"orderNumber": "…",
"errorCount": 0,
"warningCount": 0,
"incompleteTravelerCount": 0,
"errorTravelerCount": 0
}
]
}團控主列表:以出發日為主軸、彙整 order/付款/同意書
/api/v1/departures/control參數
range選填future_60this_monthnext_month時間視窗:future_60(未來 60 天)/ this_month(本月)/ next_month(下個月),預設不限
trip選填行程 ID,只看該行程的梯次
status選填梯次狀態篩選(如 open / closed)
attention選填設為 true 時只回傳付款或同意書有異常、需要關注的梯次
回應欄位 · data[]
id梯次 id。
tripId所屬行程 id。
tripTitle行程名稱。
tripSlug行程公開頁網址代稱(slug)。
groupCode團號(可空)。
departureDate出發日(YYYY-MM-DD)。
returnDate回程日(YYYY-MM-DD)。
capacity團位容量(總名額)。
bookedCount已佔位人數。
status梯次狀態(如 open 開放/closed 關閉)。
allocationMode佔位模式:fcfs 先到先得/lottery 抽籤。
leaderNames已排領隊姓名(confirmed + tentative 皆列;空 = 未指派)。
assistantNames已排協作 / 助教姓名(空 = 未指派協作)。
priceTwd定價(TWD)。
agencyPriceTwd同業/旅行社報價(TWD;未設為 null)。
promoActive是否有進行中的促銷價。
promoPriceTwd促銷價(TWD;無促銷為 null)。
promoAgencyPriceTwd同業促銷價(TWD;無促銷為 null)。
daysUntilDeparture距出發天數(負值表示已出發)。
travelerCount旅客總人數(未取消訂單的 party_size 加總)。
paidCount已付款人數(party_size 加總)。
pendingCount未結清人數(未付/部分付/已付訂金;不含取消)。
cancelledCount已取消人數(僅供參考,不計入總數)。
ordersWithoutConsent尚未簽署同意書(PDPA)的訂單數。
codedRevenueTwd有折扣訂單的應收營收合計(TWD;排除取消/退款)。
discountTotalTwd折扣金額合計(TWD)。
profitShareTotalTwd利潤分潤金額合計(TWD)。
curl -X GET https://your-tenant.example.com/api/v1/departures/control \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"tripId": "…",
"tripTitle": "…",
"tripSlug": "…",
"groupCode": "…",
"departureDate": "…",
"returnDate": "…",
"capacity": 0,
"bookedCount": 0,
"status": "…",
"allocationMode": "fcfs",
"leaderNames": [
"…"
],
"assistantNames": [
"…"
],
"priceTwd": 0,
"agencyPriceTwd": 0,
"promoActive": true,
"promoPriceTwd": 0,
"promoAgencyPriceTwd": 0,
"daysUntilDeparture": 0,
"travelerCount": 0,
"paidCount": 0,
"pendingCount": 0,
"cancelledCount": 0,
"ordersWithoutConsent": 0,
"codedRevenueTwd": 0,
"discountTotalTwd": 0,
"profitShareTotalTwd": 0
}
]
}多梯次的分房進度統計
/api/v1/departures/room-stats參數
ids必填要查詢的梯次 ID 清單,以逗號分隔(例:a,b,c)
curl -X GET "https://your-tenant.example.com/api/v1/departures/room-stats?ids=<ids>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {}
}/discount-codes
list all discount codes
/api/v1/discount-codes回應欄位 · data[]
id折扣碼 id(disc_ 前綴)。
code折扣碼字串(客戶結帳輸入用,租戶內唯一)。
label折扣碼顯示名稱(後台辨識用)。
discountType折扣型別:fixed 定額折抵 / percentage 比例折抵。
discountValue折扣值:fixed 為 TWD 整數,percentage 為百分比數字。
profitShareType分潤型別:fixed 定額 / percentage 比例;null = 無分潤。
profitShareValue分潤值:fixed 為 TWD 整數,percentage 為百分比;null = 無分潤。
profitSharePayee分潤受款對象(如合作夥伴名稱);null = 無。
isActive是否啟用(停用後不可再兌換)。
validFrom生效起始時間;null = 無下限。
validUntil生效截止時間;null = 無上限。
maxRedemptions總兌換次數上限;null = 不限。
redemptionCount已兌換次數(不含已取消訂單)。
minOrderTwd最低訂單金額門檻(TWD 整數);null = 無門檻。
appliesToAll是否適用所有行程(true = 全站,false = 僅限 tripIds 名單)。
maxRedemptionsPerCustomer每位客戶兌換次數上限;null = 不限。
allowedPriceChannels限用的價格通路清單(如 direct / agency);null = 不限。
allowedCustomerTypes限用的客戶類型清單;null = 不限。
stackable是否可與其他折扣疊加使用。
notes內部備註;null = 無。
createdAt建立時間。
curl -X GET https://your-tenant.example.com/api/v1/discount-codes \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"code": "…",
"label": "…",
"discountType": "…",
"discountValue": 0,
"profitShareType": null,
"profitShareValue": 0,
"profitSharePayee": "…",
"isActive": true,
"validFrom": null,
"validUntil": null,
"maxRedemptions": 0,
"redemptionCount": 0,
"minOrderTwd": 0,
"appliesToAll": true,
"maxRedemptionsPerCustomer": 0,
"allowedPriceChannels": "…",
"allowedCustomerTypes": "…",
"stackable": true,
"notes": "…",
"createdAt": "2026-06-30T08:00:00.000Z"
}
]
}create a discount code
/api/v1/discount-codes參數
code必填折扣碼字串(前台結帳輸入,不分大小寫須唯一)
label必填折扣碼顯示名稱(後台與報表辨識用)
discountType必填fixedpercentage折抵方式:fixed 固定金額(TWD)或 percentage 百分比
discountValue必填折抵數值;fixed 為折抵金額(TWD),percentage 為百分比(1–100)
profitShareType選填fixedpercentage分潤方式:fixed 固定金額或 percentage 百分比;null 為不分潤
profitShareValue選填分潤數值;搭配 profitShareType,percentage 須 1–100,null 為不分潤
profitSharePayee選填分潤對象名稱(如合作推廣者),供出款對帳辨識
isActive選填是否啟用;停用後前台無法套用
validFrom選填生效起日(YYYY-MM-DD);留空為不限起日
validUntil選填生效迄日(YYYY-MM-DD);留空為不限迄日
maxRedemptions選填全碼可使用總次數上限;null 為不限
minOrderTwd選填最低訂單金額門檻(TWD),未達門檻不可套用;null 為不限
appliesToAll選填是否適用全部行程;true 時忽略 tripIds
tripIds選填指定可套用的行程 id 清單(appliesToAll=false 時生效)
maxRedemptionsPerCustomer選填每位客戶可使用次數上限;null 為不限
allowedPriceChannels選填可套用的價格渠道(direct 直客 / agency 同業 / promo 優惠);空陣列為不限
allowedCustomerTypes選填可套用的客戶類型(direct 直客 / agency_contact 同業聯絡人);空陣列為不限
stackable選填是否可與其他折扣碼疊加使用
notes選填內部備註(不對外顯示)
回應欄位 · data
id新建立折扣碼的 id(disc_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/discount-codes \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"label": "<label>",
"discountType": "fixed",
"discountValue": 0
}'{
"ok": true,
"data": {
"id": "…"
}
}full discount code detail
/api/v1/discount-codes/{id}參數
id路徑折扣碼 id(路徑參數)
回應欄位 · data
id折扣碼 id(disc_ 前綴)。
code折扣碼字串(客戶結帳輸入用,租戶內唯一)。
label折扣碼顯示名稱(後台辨識用)。
discountType折扣型別:fixed 定額折抵 / percentage 比例折抵。
discountValue折扣值:fixed 為 TWD 整數,percentage 為百分比數字。
profitShareType分潤型別:fixed 定額 / percentage 比例;null = 無分潤。
profitShareValue分潤值:fixed 為 TWD 整數,percentage 為百分比;null = 無分潤。
profitSharePayee分潤受款對象(如合作夥伴名稱);null = 無。
isActive是否啟用(停用後不可再兌換)。
validFrom生效起始時間;null = 無下限。
validUntil生效截止時間;null = 無上限。
maxRedemptions總兌換次數上限;null = 不限。
redemptionCount已兌換次數(不含已取消訂單)。
minOrderTwd最低訂單金額門檻(TWD 整數);null = 無門檻。
appliesToAll是否適用所有行程(true = 全站,false = 僅限 tripIds 名單)。
maxRedemptionsPerCustomer每位客戶兌換次數上限;null = 不限。
allowedPriceChannels限用的價格通路清單(如 direct / agency);null = 不限。
allowedCustomerTypes限用的客戶類型清單;null = 不限。
stackable是否可與其他折扣疊加使用。
notes內部備註;null = 無。
createdAt建立時間。
tripIds限定適用的行程 id 清單(appliesToAll=false 時生效)。
redemptions逐筆兌換紀錄。
orderId兌換該折扣碼的訂單 id(ord_ 前綴)。
orderNumber訂單編號(人類可讀流水號)。
codeSnapshot兌換當下的折扣碼字串快照。
originalTotalTwd套用折扣前的原始應收總額(TWD 整數)。
discountTwd本次折抵金額(TWD 整數)。
profitShareTwd本次分潤金額(TWD 整數)。
orderStatus訂單當前狀態。
createdAt兌換(下單)時間。
totalDiscountTwd累計折抵金額合計(TWD 整數)。
totalProfitShareTwd累計分潤金額合計(TWD 整數)。
totalPaidTwd兌換訂單累計已收金額合計(TWD 整數)。
curl -X GET https://your-tenant.example.com/api/v1/discount-codes/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"code": "…",
"label": "…",
"discountType": "…",
"discountValue": 0,
"profitShareType": null,
"profitShareValue": 0,
"profitSharePayee": "…",
"isActive": true,
"validFrom": null,
"validUntil": null,
"maxRedemptions": 0,
"redemptionCount": 0,
"minOrderTwd": 0,
"appliesToAll": true,
"maxRedemptionsPerCustomer": 0,
"allowedPriceChannels": "…",
"allowedCustomerTypes": "…",
"stackable": true,
"notes": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"tripIds": [
"…"
],
"redemptions": [
{
"orderId": "…",
"orderNumber": "…",
"codeSnapshot": "…",
"originalTotalTwd": 0,
"discountTwd": 0,
"profitShareTwd": 0,
"orderStatus": "…",
"createdAt": "2026-06-30T08:00:00.000Z"
}
],
"totalDiscountTwd": 0,
"totalProfitShareTwd": 0,
"totalPaidTwd": 0
}
}update a discount code
/api/v1/discount-codes/{id}參數
id路徑折扣碼 id(路徑參數)
code必填折扣碼字串(前台結帳輸入,不分大小寫須唯一)
label必填折扣碼顯示名稱(後台與報表辨識用)
discountType必填fixedpercentage折抵方式:fixed 固定金額(TWD)或 percentage 百分比
discountValue必填折抵數值;fixed 為折抵金額(TWD),percentage 為百分比(1–100)
profitShareType選填fixedpercentage分潤方式:fixed 固定金額或 percentage 百分比;null 為不分潤
profitShareValue選填分潤數值;搭配 profitShareType,percentage 須 1–100,null 為不分潤
profitSharePayee選填分潤對象名稱(如合作推廣者),供出款對帳辨識
isActive選填是否啟用;停用後前台無法套用
validFrom選填生效起日(YYYY-MM-DD);留空為不限起日
validUntil選填生效迄日(YYYY-MM-DD);留空為不限迄日
maxRedemptions選填全碼可使用總次數上限;null 為不限
minOrderTwd選填最低訂單金額門檻(TWD),未達門檻不可套用;null 為不限
appliesToAll選填是否適用全部行程;true 時忽略 tripIds
tripIds選填指定可套用的行程 id 清單(appliesToAll=false 時生效)
maxRedemptionsPerCustomer選填每位客戶可使用次數上限;null 為不限
allowedPriceChannels選填可套用的價格渠道(direct 直客 / agency 同業 / promo 優惠);空陣列為不限
allowedCustomerTypes選填可套用的客戶類型(direct 直客 / agency_contact 同業聯絡人);空陣列為不限
stackable選填是否可與其他折扣碼疊加使用
notes選填內部備註(不對外顯示)
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/discount-codes/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"label": "<label>",
"discountType": "fixed",
"discountValue": 0
}'{
"ok": true,
"data": {
"ok": true
}
}redemption/profit-share report for
/api/v1/discount-codes/{id}/redemptions參數
id路徑折扣碼 id(路徑參數)
回應欄位 · data
id折扣碼 id(disc_ 前綴)。
code折扣碼字串。
label折扣碼顯示名稱。
redemptionCount已兌換次數(不含已取消訂單)。
totalDiscountTwd累計折抵金額合計(TWD 整數)。
totalProfitShareTwd累計分潤金額合計(TWD 整數)。
totalPaidTwd兌換訂單累計已收金額合計(TWD 整數)。
redemptions逐筆兌換紀錄。
orderId兌換該折扣碼的訂單 id(ord_ 前綴)。
orderNumber訂單編號(人類可讀流水號)。
codeSnapshot兌換當下的折扣碼字串快照。
originalTotalTwd套用折扣前的原始應收總額(TWD 整數)。
discountTwd本次折抵金額(TWD 整數)。
profitShareTwd本次分潤金額(TWD 整數)。
orderStatus訂單當前狀態。
createdAt兌換(下單)時間。
curl -X GET https://your-tenant.example.com/api/v1/discount-codes/<id>/redemptions \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"code": "…",
"label": "…",
"redemptionCount": 0,
"totalDiscountTwd": 0,
"totalProfitShareTwd": 0,
"totalPaidTwd": 0,
"redemptions": [
{
"orderId": "…",
"orderNumber": "…",
"codeSnapshot": "…",
"originalTotalTwd": 0,
"discountTwd": 0,
"profitShareTwd": 0,
"orderStatus": "…",
"createdAt": "2026-06-30T08:00:00.000Z"
}
]
}
}activate / deactivate a discount
/api/v1/discount-codes/{id}/set-active參數
id路徑折扣碼 id(路徑參數)
isActive必填目標啟用狀態:true 啟用、false 停用
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/discount-codes/<id>/set-active \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"isActive": true
}'{
"ok": true,
"data": {
"ok": true
}
}read-only checkout preview of a code's
/api/v1/discount-codes/preview參數
code必填欲試算的折扣碼字串
kind必填tourlodging產品種類:tour 行程或 lodging 住宿
tripId選填行程 id(kind=tour 時必填)
total必填試算用原始金額(TWD,未折扣前)
priceChannel選填價格渠道(direct / agency / promo),用於折扣碼資格判定
customerType選填客戶類型(direct / agency_contact),用於折扣碼資格判定
userId選填客戶 user id,用於每客戶使用次數限制判定
curl -X GET "https://your-tenant.example.com/api/v1/discount-codes/preview?code=<code>&kind=<kind>&total=<total>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": "…"
}/group-codes
航空碼對照表
/api/v1/group-codes/airlines參數
activeOnly選填truefalse10傳 true 或 1 時只列出啟用中的航空碼
回應欄位 · data[]
code航空公司代碼(團號組成,通常大寫縮寫,如 EG)。
name航空公司名稱。
isActive是否啟用(停用後不可再指派給新梯次)。
displayOrder顯示排序(由小到大)。
usedCount被多少梯次引用。
curl -X GET https://your-tenant.example.com/api/v1/group-codes/airlines \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"code": "…",
"name": "…",
"isActive": true,
"displayOrder": 0,
"usedCount": 0
}
]
}/api/v1/group-codes/airlines參數
code必填對照表碼,2–3 碼大寫英數(自動轉大寫)
name必填碼的顯示名稱(如地區或航空公司全名)
isActive選填是否啟用(停用後不再供新團號選用)
displayOrder選填排序權重,數字越小越前面
回應欄位 · data
ok操作成功旗標,恆為 true。
code新增或更新的航空公司代碼。
curl -X POST https://your-tenant.example.com/api/v1/group-codes/airlines \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true,
"code": "…"
}
}/api/v1/group-codes/airlines參數
code必填要更新的對照表碼(不可變更碼本身)
name必填碼的顯示名稱(如地區或航空公司全名)
isActive選填是否啟用(停用後不再供新團號選用)
displayOrder選填排序權重,數字越小越前面
回應欄位 · data
ok操作成功旗標,恆為 true。
code新增或更新的航空公司代碼。
curl -X PATCH https://your-tenant.example.com/api/v1/group-codes/airlines \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true,
"code": "…"
}
}前綴團號反查多梯次
/api/v1/group-codes/departures參數
prefix必填團號前綴,反查同地區同航空的所有梯次(如 26EGTK)
回應欄位 · data[]
id梯次 id(dep_ 前綴)。
tripId所屬行程 id(trip_ 前綴)。
tripTitle所屬行程標題。
tripSlug所屬行程網址 slug。
departureDate出發日(ISO 'YYYY-MM-DD')。
groupCode完整團號。
regionCode地區代碼;null = 未設。
airlineCode航空公司代碼;null = 國內團或未設。
curl -X GET "https://your-tenant.example.com/api/v1/group-codes/departures?prefix=<prefix>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"tripId": "…",
"tripTitle": "…",
"tripSlug": "…",
"departureDate": "…",
"groupCode": "…",
"regionCode": "…",
"airlineCode": "…"
}
]
}精確團號反查單一梯次
/api/v1/group-codes/departures/{id}參數
id路徑完整團號,反查單一梯次(大小寫不敏感)
回應欄位 · data
id梯次 id(dep_ 前綴)。
tripId所屬行程 id(trip_ 前綴)。
tripTitle所屬行程標題。
tripSlug所屬行程網址 slug。
departureDate出發日(ISO 'YYYY-MM-DD')。
groupCode完整團號。
regionCode地區代碼;null = 未設。
airlineCode航空公司代碼;null = 國內團或未設。
curl -X GET https://your-tenant.example.com/api/v1/group-codes/departures/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"tripId": "…",
"tripTitle": "…",
"tripSlug": "…",
"departureDate": "…",
"groupCode": "…",
"regionCode": "…",
"airlineCode": "…"
}
}地區碼對照表
/api/v1/group-codes/regions參數
activeOnly選填truefalse10傳 true 或 1 時只列出啟用中的地區碼
回應欄位 · data[]
code地區代碼(團號組成,通常大寫縮寫,如 YS)。
name地區名稱(如「玉山」)。
isActive是否啟用(停用後不可再指派給新梯次)。
displayOrder顯示排序(由小到大)。
usedCount被多少梯次引用 —— UI 鎖頭 / 「使用中 N」。
curl -X GET https://your-tenant.example.com/api/v1/group-codes/regions \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"code": "…",
"name": "…",
"isActive": true,
"displayOrder": 0,
"usedCount": 0
}
]
}/api/v1/group-codes/regions參數
code必填對照表碼,2–3 碼大寫英數(自動轉大寫)
name必填碼的顯示名稱(如地區或航空公司全名)
isActive選填是否啟用(停用後不再供新團號選用)
displayOrder選填排序權重,數字越小越前面
回應欄位 · data
ok操作成功旗標,恆為 true。
code新增或更新的地區代碼。
curl -X POST https://your-tenant.example.com/api/v1/group-codes/regions \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true,
"code": "…"
}
}/api/v1/group-codes/regions參數
code必填要更新的對照表碼(不可變更碼本身)
name必填碼的顯示名稱(如地區或航空公司全名)
isActive選填是否啟用(停用後不再供新團號選用)
displayOrder選填排序權重,數字越小越前面
回應欄位 · data
ok操作成功旗標,恆為 true。
code新增或更新的地區代碼。
curl -X PATCH https://your-tenant.example.com/api/v1/group-codes/regions \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true,
"code": "…"
}
}/holidays
per-tenant national-holiday / makeup-workday table
/api/v1/holidays參數
year選填篩選的西元年份(1000..9999);省略則回傳所有年份
回應欄位 · data
rows假日列(依日期排序)。
date日期(ISO 'YYYY-MM-DD')。
name名稱(如「國慶日」「補班」)。
isWorkday是否為補班日(true = 該日照常上班,false = 放假)。
curl -X GET https://your-tenant.example.com/api/v1/holidays \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"date": "…",
"name": "…",
"isWorkday": true
}
]
}
}upsert / delete a single per-tenant
/api/v1/holidays/{date}參數
date路徑假日 / 補班日的日期(YYYY-MM-DD,路徑參數),作為該筆紀錄的自然鍵
name必填假日 / 補班日名稱(如「春節」「補行上班」)
isWorkday選填是否為補班日:true 表示原假日改上班、false 表示國定假日;影響行前作業工作日倒數
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X PUT https://your-tenant.example.com/api/v1/holidays/<date> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/holidays/{date}參數
date路徑要刪除的假日 / 補班日日期(YYYY-MM-DD,路徑參數)
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/holidays/<date> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}holiday / makeup-workday counts for a
/api/v1/holidays/stats參數
year必填要統計的西元年份(1000..9999,必填)
回應欄位 · data
holidayCount該年度放假日數。
makeupCount該年度補班日數。
curl -X GET "https://your-tenant.example.com/api/v1/holidays/stats?year=<year>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"holidayCount": 0,
"makeupCount": 0
}
}/images
list/search the trip image gallery
/api/v1/images參數
tripId選填行程 ID 篩選,僅回傳掛在該行程的圖片
q選填關鍵字,模糊比對行程標題、slug、圖說或網址
page選填分頁頁碼,從 1 起算,預設第 1 頁
pageSize選填每頁筆數,上限 200,預設由後端決定
回應欄位 · data
rows當頁圖片列。
id圖片資源 id(timg_ 前綴)。
tripId所屬行程 id(trip_ 前綴)。
tripTitle所屬行程標題。
tripSlug所屬行程網址 slug。
url圖片公開 URL。
caption圖說文字;null = 無。
displayOrder在行程相簿中的排序(由小到大)。
createdAt上傳建立時間。
total符合條件的總筆數(跨頁)。
page目前頁碼(1 起算)。
pageSize每頁筆數。
curl -X GET https://your-tenant.example.com/api/v1/images \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"tripId": "…",
"tripTitle": "…",
"tripSlug": "…",
"url": "…",
"caption": "…",
"displayOrder": 0,
"createdAt": "2026-06-30T08:00:00.000Z"
}
],
"total": 0,
"page": 0,
"pageSize": 0
}
}/api/v1/images參數
tripId必填要掛上此圖片的行程 ID
url必填圖片網址(http 或 https),以引用方式掛載,非檔案上傳
caption選填圖片說明文字,選填
displayOrder選填排序權重,數字越小越前面,預設 0
回應欄位 · data
id新建立圖片的 id(timg_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/images \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tripId": "<tripId>",
"url": "<url>"
}'{
"ok": true,
"data": {
"id": "…"
}
}remove a trip image
/api/v1/images/{id}參數
id路徑欲刪除的行程圖片 ID
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/images/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}the trip picker for attaching images: draft +
/api/v1/images/trips回應欄位 · data[]
id行程 id(trip_ 前綴)。
title行程標題。
curl -X GET https://your-tenant.example.com/api/v1/images/trips \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"title": "…"
}
]
}/lodging
list staff-side direct lodging bookings
/api/v1/lodging/bookings參數
status選填依訂單狀態篩選(省略則回全部)
q選填自由文字關鍵字(訂房人、旅宿等)
回應欄位 · data[]
orderId訂單 id(ord_ 前綴)。
orderNumber訂單編號(人類可讀流水號)。
status顯示狀態(派生自三軸,沿用舊欄名供 UI badge / canCancel 相容)。
bookingState訂位軸狀態(如 confirmed / cancelled)。
paymentState付款軸狀態(如 unpaid / partial / paid)。
refundState退款軸狀態。
totalTwd應收總額(TWD 整數,訂單各應收明細加總)。
createdAt訂單建立時間。
bookerName訂購人姓名。
bookerEmail訂購人 email。
propertyId住宿館 id(prop_ 前綴)。
propertyName住宿館名稱。
roomTypeId房型 id(rt_ 前綴)。
roomTypeName房型名稱。
checkIn入住日(ISO 'YYYY-MM-DD')。
checkOut退房日(ISO 'YYYY-MM-DD')。
units訂購房間數。
guestCount入住總人數。
curl -X GET https://your-tenant.example.com/api/v1/lodging/bookings \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"orderId": "…",
"orderNumber": "…",
"status": "…",
"bookingState": "…",
"paymentState": "…",
"refundState": "…",
"totalTwd": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"bookerName": "…",
"bookerEmail": "…",
"propertyId": "…",
"propertyName": "…",
"roomTypeId": "…",
"roomTypeName": "…",
"checkIn": "…",
"checkOut": "…",
"units": 0,
"guestCount": 0
}
]
}/api/v1/lodging/bookings參數
propertyId必填旅宿物件 ID
roomTypeId必填房型 ID(須屬於該旅宿物件)
checkIn必填入住日(YYYY-MM-DD,含此晚)
checkOut必填退房日(YYYY-MM-DD,不含此晚,須晚於入住日)
units必填預訂單元數(房數或床位數,1-50)
guestCount必填入住人數(1-100,不得超過房型總容納人數)
bookerEmail必填訂房人 Email(須為已註冊會員)
paymentMethod必填cashatmmanual付款方式:cash 現金/atm 轉帳/manual 其他人工
receivingAccountId選填收款帳戶 ID(搭配付款方式記帳,可省略)
notes選填代訂備註
回應欄位 · data
orderId新建立住宿訂單的 id(ord_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/lodging/bookings \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"propertyId": "<propertyId>",
"roomTypeId": "<roomTypeId>",
"checkIn": "<checkIn>",
"checkOut": "<checkOut>",
"units": 0,
"guestCount": 0,
"bookerEmail": "<bookerEmail>",
"paymentMethod": "cash"
}'{
"ok": true,
"data": {
"orderId": "…"
}
}single lodging booking detail.
/api/v1/lodging/bookings/{orderId}參數
orderId路徑旅宿訂單 ID
回應欄位 · data
orderId訂單 id(ord_ 前綴)。
orderNumber訂單編號(人類可讀流水號)。
status顯示狀態(派生自三軸,沿用舊欄名供 UI badge / canCancel 相容)。
bookingState訂位軸狀態(如 confirmed / cancelled)。
paymentState付款軸狀態(如 unpaid / partial / paid)。
refundState退款軸狀態。
totalTwd應收總額(TWD 整數,訂單各應收明細加總)。
createdAt訂單建立時間。
bookerName訂購人姓名。
bookerEmail訂購人 email。
propertyId住宿館 id(prop_ 前綴)。
propertyName住宿館名稱。
roomTypeId房型 id(rt_ 前綴)。
roomTypeName房型名稱。
checkIn入住日(ISO 'YYYY-MM-DD')。
checkOut退房日(ISO 'YYYY-MM-DD')。
units訂購房間數。
guestCount入住總人數。
curl -X GET https://your-tenant.example.com/api/v1/lodging/bookings/<orderId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"orderId": "…",
"orderNumber": "…",
"status": "…",
"bookingState": "…",
"paymentState": "…",
"refundState": "…",
"totalTwd": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"bookerName": "…",
"bookerEmail": "…",
"propertyId": "…",
"propertyName": "…",
"roomTypeId": "…",
"roomTypeName": "…",
"checkIn": "…",
"checkOut": "…",
"units": 0,
"guestCount": 0
}
}cancel a direct lodging
/api/v1/lodging/bookings/{orderId}/cancel參數
orderId路徑旅宿訂單 ID
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/lodging/bookings/<orderId>/cancel \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}delete a gallery
/api/v1/lodging/images/{id}參數
id路徑圖片 ID
kind必填propertyroom-type圖片所屬相簿:property 旅宿相簿/room-type 房型相簿
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X DELETE "https://your-tenant.example.com/api/v1/lodging/images/<id>?kind=<kind>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}list tenant lodging properties
/api/v1/lodging/properties回應欄位 · data[]
id住宿館 id(prop_ 前綴)。
lengthReturns the length of a String object.
slug網址 slug(公開站路徑,租戶內唯一)。
name住宿館名稱。
kind類型:hotel 旅館 / camp 營地。
isOverseas是否為海外住宿。
location地點描述;null = 未設。
description簡介文字;null = 未設。
contentMdx內文(MDX 原始碼);null = 未設。
facilities設施清單(JSON);null = 未設。
coverImageUrl封面圖 URL;null = 未設。
usageHint用途:direct 散客直訂 / package 梯次配套 / both 兩者皆可。
checkInTime入住時間文字(如「15:00」);null = 未設。
checkOutTime退房時間文字(如「11:00」);null = 未設。
checkInInfo入住須知;null = 未設。
houseRules館內規範;null = 未設。
cancellationPolicy取消政策;null = 未設。
addressRegion地址:縣市/區域;null = 未設。
addressLocality地址:鄉鎮/地區;null = 未設。
streetAddress街道地址;null = 未設。
postalCode郵遞區號;null = 未設。
latitude緯度;null = 未設。
longitude經度;null = 未設。
phone聯絡電話;null = 未設。
petsAllowed是否允許攜帶寵物;null = 未設。
smokingAllowed是否允許吸菸;null = 未設。
status狀態:active 啟用 / inactive 停用。
seoTitleSEO 標題覆寫;null = 沿用內容欄。
seoDescriptionSEO 描述;null = 未設。
ogImageUrlOpen Graph 分享圖 URL;null = 未設。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": {
"length": 0
},
"slug": "…",
"name": "…",
"kind": "…",
"isOverseas": true,
"location": "…",
"description": "…",
"contentMdx": "…",
"facilities": "…",
"coverImageUrl": "…",
"usageHint": "…",
"checkInTime": "…",
"checkOutTime": "…",
"checkInInfo": "…",
"houseRules": "…",
"cancellationPolicy": "…",
"addressRegion": "…",
"addressLocality": "…",
"streetAddress": "…",
"postalCode": "…",
"latitude": 0,
"longitude": 0,
"phone": "…",
"petsAllowed": true,
"smokingAllowed": true,
"status": "…",
"seoTitle": "…",
"seoDescription": "…",
"ogImageUrl": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}create a property
/api/v1/lodging/properties參數
slug必填旅宿代稱(小寫英數與連字號,2-63 字,租戶內唯一,用於網址)
name必填旅宿名稱(對外顯示)
kind選填camphotel旅宿類型:camp 營地/hotel 旅館,預設 hotel
isOverseas選填是否為海外旅宿,預設否
location選填所在地點概述(如縣市、區域)
description選填旅宿介紹文字
usageHint選填directpackageboth銷售用途:direct 僅直接訂房/package 僅併入套裝行程/both 兩者皆可,預設 both
回應欄位 · data
id新建立住宿館的 id(prop_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "<slug>",
"name": "<name>"
}'{
"ok": true,
"data": {
"id": "…"
}
}single lodging property
/api/v1/lodging/properties/{id}參數
id路徑旅宿物件 ID
回應欄位 · data
id住宿館 id(prop_ 前綴)。
lengthReturns the length of a String object.
slug網址 slug(公開站路徑,租戶內唯一)。
name住宿館名稱。
kind類型:hotel 旅館 / camp 營地。
isOverseas是否為海外住宿。
location地點描述;null = 未設。
description簡介文字;null = 未設。
contentMdx內文(MDX 原始碼);null = 未設。
facilities設施清單(JSON);null = 未設。
coverImageUrl封面圖 URL;null = 未設。
usageHint用途:direct 散客直訂 / package 梯次配套 / both 兩者皆可。
checkInTime入住時間文字(如「15:00」);null = 未設。
checkOutTime退房時間文字(如「11:00」);null = 未設。
checkInInfo入住須知;null = 未設。
houseRules館內規範;null = 未設。
cancellationPolicy取消政策;null = 未設。
addressRegion地址:縣市/區域;null = 未設。
addressLocality地址:鄉鎮/地區;null = 未設。
streetAddress街道地址;null = 未設。
postalCode郵遞區號;null = 未設。
latitude緯度;null = 未設。
longitude經度;null = 未設。
phone聯絡電話;null = 未設。
petsAllowed是否允許攜帶寵物;null = 未設。
smokingAllowed是否允許吸菸;null = 未設。
status狀態:active 啟用 / inactive 停用。
seoTitleSEO 標題覆寫;null = 沿用內容欄。
seoDescriptionSEO 描述;null = 未設。
ogImageUrlOpen Graph 分享圖 URL;null = 未設。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": {
"length": 0
},
"slug": "…",
"name": "…",
"kind": "…",
"isOverseas": true,
"location": "…",
"description": "…",
"contentMdx": "…",
"facilities": "…",
"coverImageUrl": "…",
"usageHint": "…",
"checkInTime": "…",
"checkOutTime": "…",
"checkInInfo": "…",
"houseRules": "…",
"cancellationPolicy": "…",
"addressRegion": "…",
"addressLocality": "…",
"streetAddress": "…",
"postalCode": "…",
"latitude": 0,
"longitude": 0,
"phone": "…",
"petsAllowed": true,
"smokingAllowed": true,
"status": "…",
"seoTitle": "…",
"seoDescription": "…",
"ogImageUrl": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}update a property
/api/v1/lodging/properties/{id}參數
id路徑旅宿物件 ID
name選填旅宿名稱(對外顯示)
location選填所在地點概述(如縣市、區域)
description選填旅宿介紹文字
usageHint選填directpackageboth銷售用途:direct 僅直接訂房/package 僅併入套裝行程/both 兩者皆可
checkInTime選填入住時間(如 15:00)
checkOutTime選填退房時間(如 11:00)
checkInInfo選填入住須知與報到說明
houseRules選填住宿規範
cancellationPolicy選填取消政策說明
addressRegion選填地址行政區(縣市層級)
addressLocality選填地址鄉鎮市區
streetAddress選填街道地址
postalCode選填郵遞區號
latitude選填緯度(-90 至 90)
longitude選填經度(-180 至 180)
phone選填聯絡電話
petsAllowed選填allowdisallowunset是否允許攜帶寵物:allow 允許/disallow 不允許/unset 清除設定,省略則不變更
smokingAllowed選填allowdisallowunset是否允許吸菸:allow 允許/disallow 不允許/unset 清除設定,省略則不變更
facilities選填設施代碼陣列(須為合法 amenity key;送空陣列代表清空)
seoTitle選填SEO 標題(送空字串代表清空,退回預設)
seoDescription選填SEO 描述(送空字串代表清空,退回預設)
ogImageUrl選填社群分享圖 URL(須為 http/https,送空字串代表清空)
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/lodging/properties/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}archive
/api/v1/lodging/properties/{id}/archive參數
id路徑旅宿物件 ID
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties/<id>/archive \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}property gallery images.
/api/v1/lodging/properties/{id}/images參數
id路徑旅宿物件 ID
回應欄位 · data[]
id圖片資源 id(pimg_ / rtimg_ 前綴)。
url圖片公開 URL。
caption圖說文字;null = 無。
displayOrder相簿中的排序(由小到大)。
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties/<id>/images \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"url": "…",
"caption": "…",
"displayOrder": 0
}
]
}add a property gallery image
/api/v1/lodging/properties/{id}/images參數
id路徑旅宿物件 ID
url必填圖片網址
caption選填圖片說明文字(可省略)
displayOrder選填在相簿中的排序序號,數字越小越前面,預設 0
回應欄位 · data
id新建立住宿館圖片的 id(pimg_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties/<id>/images \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "<url>"
}'{
"ok": true,
"data": {
"id": "…"
}
}room types for one property
/api/v1/lodging/properties/{id}/room-types參數
id路徑旅宿物件 ID
回應欄位 · data[]
id房型 id(rt_ 前綴)。
lengthReturns the length of a String object.
propertyId所屬住宿館 id(prop_ 前綴)。
lengthReturns the length of a String object.
name房型名稱。
inventoryUnit庫存單位:room 以房計 / bed 以床位計。
unitsTotal總庫存量(房間數或床位數)。
capacityPerUnit每單位可住人數。
basePriceTwd底價(TWD 整數,每晚每單位;可被逐晚覆寫)。
description房型描述;null = 未設。
facilities設施清單(JSON);null = 未設。
bedConfig床型配置(JSON);null = 未設。
floorSizeSqm房間坪數(平方公尺);null = 未設。
status狀態:active 啟用 / inactive 停用。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties/<id>/room-types \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": {
"length": 0
},
"propertyId": {
"length": 0
},
"name": "…",
"inventoryUnit": "…",
"unitsTotal": 0,
"capacityPerUnit": 0,
"basePriceTwd": 0,
"description": "…",
"facilities": "…",
"bedConfig": "…",
"floorSizeSqm": 0,
"status": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}create a room type under this property
/api/v1/lodging/properties/{id}/room-types參數
id路徑所屬旅宿物件 ID
name必填房型名稱(如標準雙人房)
inventoryUnit選填roombed庫存單位:room 以房計/bed 以床位計,預設 room
unitsTotal必填此房型可售總單元數(房數或床位數)
capacityPerUnit選填每單元可容納人數,預設 1
basePriceTwd必填每晚每單元基準售價(新台幣)
description選填房型介紹文字
floorSizeSqm選填房間坪數(平方公尺)
bedType選填床型代碼(須為合法 bed type,搭配 bedCount 才生效)
bedCount選填該床型數量(須大於 0 才生效)
facilities選填房型設施代碼陣列(須為合法 amenity key)
回應欄位 · data
id新建立房型的 id(rt_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties/<id>/room-types \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>",
"unitsTotal": 0,
"basePriceTwd": 0
}'{
"ok": true,
"data": {
"id": "…"
}
}single room type
/api/v1/lodging/room-types/{id}參數
id路徑房型 ID
回應欄位 · data
id房型 id(rt_ 前綴)。
lengthReturns the length of a String object.
propertyId所屬住宿館 id(prop_ 前綴)。
lengthReturns the length of a String object.
name房型名稱。
inventoryUnit庫存單位:room 以房計 / bed 以床位計。
unitsTotal總庫存量(房間數或床位數)。
capacityPerUnit每單位可住人數。
basePriceTwd底價(TWD 整數,每晚每單位;可被逐晚覆寫)。
description房型描述;null = 未設。
facilities設施清單(JSON);null = 未設。
bedConfig床型配置(JSON);null = 未設。
floorSizeSqm房間坪數(平方公尺);null = 未設。
status狀態:active 啟用 / inactive 停用。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/lodging/room-types/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": {
"length": 0
},
"propertyId": {
"length": 0
},
"name": "…",
"inventoryUnit": "…",
"unitsTotal": 0,
"capacityPerUnit": 0,
"basePriceTwd": 0,
"description": "…",
"facilities": "…",
"bedConfig": "…",
"floorSizeSqm": 0,
"status": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}update a room type
/api/v1/lodging/room-types/{id}參數
id路徑房型 ID
name選填房型名稱(如標準雙人房)
inventoryUnit選填roombed庫存單位:room 以房計/bed 以床位計
unitsTotal選填此房型可售總單元數(房數或床位數)
capacityPerUnit選填每單元可容納人數
basePriceTwd選填每晚每單元基準售價(新台幣)
description選填房型介紹文字
floorSizeSqm選填房間坪數(平方公尺)
bedType選填床型代碼(須為合法 bed type,搭配 bedCount 才生效)
bedCount選填該床型數量(須大於 0 才生效)
facilities選填房型設施代碼陣列(須為合法 amenity key;送空陣列代表清空)
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/lodging/room-types/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}archive
/api/v1/lodging/room-types/{id}/archive參數
id路徑房型 ID
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/lodging/room-types/<id>/archive \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}per-night availability +
/api/v1/lodging/room-types/{id}/availability參數
id路徑房型 ID
checkIn必填入住日(YYYY-MM-DD,含此晚)
checkOut必填退房日(YYYY-MM-DD,不含此晚)
回應欄位 · data
available整段住宿期間可訂房間數(各晚剩餘取最小;任一晚關閉則為 0)。
nights住宿晚數。
totalPriceTwd整段期間房價合計(TWD 整數,逐晚牌價加總)。
perNight逐晚可售明細。
night該晚日期(ISO 'YYYY-MM-DD')。
capacity該晚可售容量(房間數;有覆寫則用覆寫值,否則房型總數)。
booked該晚已訂數。
remaining該晚剩餘可訂數(capacity − booked,不小於 0)。
priceTwd該晚房價(TWD 整數;有逐晚覆寫則用覆寫值,否則房型底價)。
status該晚販售狀態:open 開放 / closed 關閉。
curl -X GET "https://your-tenant.example.com/api/v1/lodging/room-types/<id>/availability?checkIn=<checkIn>&checkOut=<checkOut>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"available": 0,
"nights": 0,
"totalPriceTwd": 0,
"perNight": [
{
"night": "…",
"capacity": 0,
"booked": 0,
"remaining": 0,
"priceTwd": 0,
"status": "…"
}
]
}
}per-night
/api/v1/lodging/room-types/{id}/availability/breakdown參數
id路徑房型 ID
from必填起始日(YYYY-MM-DD,含此晚)
to必填結束日(YYYY-MM-DD,不含此晚)
回應欄位 · data[]
night該晚日期(ISO 'YYYY-MM-DD')。
directBooked該晚散客直訂的已訂數。
packageBooked該晚梯次配套佔用的已訂數。
curl -X GET "https://your-tenant.example.com/api/v1/lodging/room-types/<id>/availability/breakdown?from=<from>&to=<to>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"night": "…",
"directBooked": 0,
"packageBooked": 0
}
]
}room-type gallery images.
/api/v1/lodging/room-types/{id}/images參數
id路徑房型 ID
回應欄位 · data[]
id圖片資源 id(pimg_ / rtimg_ 前綴)。
url圖片公開 URL。
caption圖說文字;null = 無。
displayOrder相簿中的排序(由小到大)。
curl -X GET https://your-tenant.example.com/api/v1/lodging/room-types/<id>/images \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"url": "…",
"caption": "…",
"displayOrder": 0
}
]
}add a room-type gallery image
/api/v1/lodging/room-types/{id}/images參數
id路徑房型 ID
url必填圖片網址
caption選填圖片說明文字(可省略)
displayOrder選填在相簿中的排序序號,數字越小越前面,預設 0
回應欄位 · data
id新建立房型圖片的 id(rtimg_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/lodging/room-types/<id>/images \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "<url>"
}'{
"ok": true,
"data": {
"id": "…"
}
}batch-override the
/api/v1/lodging/room-types/{id}/nights/override參數
id路徑房型 ID
from必填套用起始日(YYYY-MM-DD,含此日)
to必填套用結束日(YYYY-MM-DD,含此日;須不早於起始日)
priceTwd選填覆寫的每晚售價(新台幣),省略則不調整價格
capacity選填覆寫的每晚可售單元數,若低於已訂數量會回 409 衝突
status選填openclosed每晚開關房狀態:open 開放/closed 封房
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/lodging/room-types/<id>/nights/override \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"from": "<from>",
"to": "<to>"
}'{
"ok": true,
"data": {
"ok": true
}
}旅宿 dashboard overview
/api/v1/lodging/stats回應欄位 · data
tonightCheckInUnits今晚入住房間數(Asia/Taipei)。
tonightCheckInGuests今晚入住總人數(Asia/Taipei)。
weekOccupancyPct未來 7 晚住房率(已訂 / 可售,0–100)。
next7AvailableUnits未來 7 晚仍可售的房晚數。
pendingPaymentCount待收款訂單筆數。
pendingPaymentTwd待收款金額合計(TWD 整數)。
curl -X GET https://your-tenant.example.com/api/v1/lodging/stats \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"tonightCheckInUnits": 0,
"tonightCheckInGuests": 0,
"weekOccupancyPct": 0,
"next7AvailableUnits": 0,
"pendingPaymentCount": 0,
"pendingPaymentTwd": 0
}
}/trips
/api/v1/trips參數
status選填依行程狀態篩選(draft 草稿/published 上架/archived 封存)
q選填自由文字搜尋(行程標題/代稱/目的地)
groupCode選填依團號篩選,列出含該團號梯次的行程
回應欄位 · data[]
id行程 id(trip_ 前綴)。
slug行程網址 slug。
title行程標題。
destination目的地名稱。
durationDays天數。
priceFromTwd「NT$ X 起」起價(TWD 整數)。
status上架狀態:draft 草稿 / published 已上架 / archived 封存。
updatedAt最後更新時間。
isClimbing是否登山團(行程層模組旗標)。
isOverseas是否海外團(行程層模組旗標)。
activeDepartureCountCount of departures with status='selling'.
nextDepartureDateEarliest selling departure_date, ISO date string, or null.
representativeGroupCode代表團號(group-code §8.2):最新一筆有團號的梯次;無則 null(UI 顯示 —)。
curl -X GET https://your-tenant.example.com/api/v1/trips \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"slug": "…",
"title": "…",
"destination": "…",
"durationDays": 0,
"priceFromTwd": 0,
"status": "…",
"updatedAt": "2026-06-30T08:00:00.000Z",
"isClimbing": true,
"isOverseas": true,
"activeDepartureCount": 0,
"nextDepartureDate": "…",
"representativeGroupCode": "…"
}
]
}same core op + audit as the back office
/api/v1/trips參數
slug必填行程網址代稱(slug),用於前台路徑與後台識別,只能小寫英數與連字號
title必填行程標題,顯示於前台與訂單
summary選填行程摘要,前台列表卡片用的一句話簡介
contentMdx選填行程詳細內容(MDX 格式),前台行程頁主文
destination必填目的地名稱
durationDays必填行程天數
priceFromTwd必填起價(新台幣),前台「OOO 元起」顯示用
directPriceTwd選填直客定價(新台幣),留空(null)則退回起價繼承
agencyPriceTwd選填同業定價(新台幣),留空(null)則退回直客/起價繼承
depositMode選填nonefixedpercent訂金計算方式(none 不收/fixed 固定金額/percent 百分比)
depositAmountTwd選填訂金固定金額(新台幣),depositMode 為 fixed 時生效
depositPercent選填訂金百分比(1–100),depositMode 為 percent 時生效
balanceDueDaysBeforeDeparture選填尾款應繳截止日(出發前幾天)
feeInclusions選填費用包含項目清單,每項含勾選狀態(ok)與說明文字(text)
isClimbing選填是否為登山團(啟用登山相關模組欄位)
isOverseas選填是否為海外團
gradeScore選填登山難度評分(0–100),null 表示未評級
requiresAlpineExperience選填是否需具備高山經驗
gradeLabel選填難度等級標籤文字
confirmGroupMultiple選填成團人數倍數(如國內高山團為 7 的倍數),null 表示不限
restrictedQuotaEnabled選填是否啟用每人使用次數限制
quotaPerPersonLimit選填每人於限制窗內可使用次數上限,null 表示不限
quotaWindow選填次數限制的計算窗口
waitlistEnabled選填是否開放候補
coverImageUrl選填行程封面圖網址(http/https)
seoTitle選填SEO 標題,覆寫前台頁面 title
seoDescription選填SEO 描述,覆寫前台 meta description
ogImageUrl選填Open Graph 社群分享圖網址(http/https)
status選填行程狀態(draft 草稿/published 上架/archived 封存)
pnlRegionId選填損益分區 id(pnl_regions),null 表示未指派、退回系統派生
回應欄位 · data
id新建立行程的 id(trip_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/trips \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "<slug>",
"title": "<title>",
"destination": "<destination>",
"durationDays": 0,
"priceFromTwd": 0
}'{
"ok": true,
"data": {
"id": "…"
}
}full admin trip detail
/api/v1/trips/{id}參數
id路徑行程 ID(路徑參數)
回應欄位 · data
id行程 id(trip_ 前綴)。
lengthReturns the length of a String object.
slug行程網址 slug(公開站路徑)。
title行程標題。
summary一句話摘要;null = 未設。
contentMdx行程內文(MDX 原始碼);null = 未設。
destination目的地名稱。
durationDays天數。
priceFromTwd「NT$ X 起」起價(TWD 整數)。
coverImageUrl封面圖 URL;null = 未設。
status上架狀態:draft 草稿 / published 已上架 / archived 封存。
createdAt建立時間。
updatedAt最後更新時間。
isClimbing是否登山團(行程層模組旗標)。
isOverseas是否海外團(行程層模組旗標)。
gradeScore難度評鑑分數(climbing-screening §3.1);null = 未評級。
requiresAlpineExperience是否要求具備高山經驗(報名審核用)。
gradeLabel難度標籤(如「B+」);null = 未設。
feeInclusions團費包含/不包含(前台費用區唯一來源);null = 未設。
seoTitleSEO 標題覆寫;null = 沿用 title。
seoDescriptionSEO 描述;null = 未設。
ogImageUrlOpen Graph 分享圖 URL;null = 未設。
images行程相簿圖片(依 displayOrder 排序)。
id圖片資源 id(timg_ 前綴)。
url圖片公開 URL。
caption圖說文字;null = 無。
displayOrder在行程相簿中的排序(由小到大)。
departuresActive (selling, future) departures only on the public side; all on admin.
id梯次 id(dep_ 前綴)。
tripId所屬行程 id(trip_ 前綴)。
departureDate出發日(ISO 'YYYY-MM-DD')。
returnDate回程日(ISO 'YYYY-MM-DD')。
priceTwd售價(TWD 整數,未稅牌價)。
capacity名額上限(人數)。
bookedCount已成團佔用名額(人數)。
status梯次狀態:selling 販售中 / closed 關閉 / cancelled 取消 / completed 已結團。
notes內部備註;null = 無。
allocationMode抽籤分配模式(lottery-integration §2.1):fcfs=先到先得 / lottery=抽籤制。
agencyPriceTwd選填同業價(TWD 整數);admin-only,公開站不映射。
depositMode選填訂金規則模式:none 免訂金 / fixed 定額 / percent 比例;admin-only。
depositAmountTwd選填訂金定額(TWD 整數,depositMode=fixed 時適用);admin-only。
depositPercent選填訂金比例(百分比,depositMode=percent 時適用);admin-only。
groupCode選填團號(group-code §3.3);admin-only,公開站不映射。
regionCode選填地區代碼(團號組成);admin-only。
airlineCode選填航空公司代碼(團號組成);admin-only。
promoActive選填梯次促銷是否啟用(trip-pricing);admin-only。
promoPriceTwd選填促銷覆寫售價(TWD 整數);admin-only。
promoAgencyPriceTwd選填促銷覆寫同業價(TWD 整數);admin-only。
curl -X GET https://your-tenant.example.com/api/v1/trips/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": {
"length": 0
},
"slug": "…",
"title": "…",
"summary": "…",
"contentMdx": "…",
"destination": "…",
"durationDays": 0,
"priceFromTwd": 0,
"coverImageUrl": "…",
"status": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z",
"isClimbing": true,
"isOverseas": true,
"gradeScore": 0,
"requiresAlpineExperience": true,
"gradeLabel": "…",
"feeInclusions": "…",
"seoTitle": "…",
"seoDescription": "…",
"ogImageUrl": "…",
"images": [
{
"id": "…",
"url": "…",
"caption": "…",
"displayOrder": 0
}
],
"departures": [
{
"id": "…",
"tripId": "…",
"departureDate": "…",
"returnDate": "…",
"priceTwd": 0,
"capacity": 0,
"bookedCount": 0,
"status": "…",
"notes": "…",
"allocationMode": "fcfs",
"agencyPriceTwd": 0,
"depositMode": null,
"depositAmountTwd": 0,
"depositPercent": 0,
"groupCode": "…",
"regionCode": "…",
"airlineCode": "…",
"promoActive": true,
"promoPriceTwd": 0,
"promoAgencyPriceTwd": 0
}
]
}
}/api/v1/trips/{id}參數
id路徑行程 ID(路徑參數)
slug必填行程網址代稱(slug),用於前台路徑與後台識別,只能小寫英數與連字號
title必填行程標題,顯示於前台與訂單
summary選填行程摘要,前台列表卡片用的一句話簡介
contentMdx選填行程詳細內容(MDX 格式),前台行程頁主文
destination必填目的地名稱
durationDays必填行程天數
priceFromTwd必填起價(新台幣),前台「OOO 元起」顯示用
directPriceTwd選填直客定價(新台幣),留空(null)則退回起價繼承
agencyPriceTwd選填同業定價(新台幣),留空(null)則退回直客/起價繼承
depositMode選填nonefixedpercent訂金計算方式(none 不收/fixed 固定金額/percent 百分比)
depositAmountTwd選填訂金固定金額(新台幣),depositMode 為 fixed 時生效
depositPercent選填訂金百分比(1–100),depositMode 為 percent 時生效
balanceDueDaysBeforeDeparture選填尾款應繳截止日(出發前幾天)
feeInclusions選填費用包含項目清單,每項含勾選狀態(ok)與說明文字(text)
isClimbing選填是否為登山團(啟用登山相關模組欄位)
isOverseas選填是否為海外團
gradeScore選填登山難度評分(0–100),null 表示未評級
requiresAlpineExperience選填是否需具備高山經驗
gradeLabel選填難度等級標籤文字
confirmGroupMultiple選填成團人數倍數(如國內高山團為 7 的倍數),null 表示不限
restrictedQuotaEnabled選填是否啟用每人使用次數限制
quotaPerPersonLimit選填每人於限制窗內可使用次數上限,null 表示不限
quotaWindow選填次數限制的計算窗口
waitlistEnabled選填是否開放候補
coverImageUrl選填行程封面圖網址(http/https)
seoTitle選填SEO 標題,覆寫前台頁面 title
seoDescription選填SEO 描述,覆寫前台 meta description
ogImageUrl選填Open Graph 社群分享圖網址(http/https)
status選填行程狀態(draft 草稿/published 上架/archived 封存)
pnlRegionId選填損益分區 id(pnl_regions),null 表示未指派、退回系統派生
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/trips/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "<slug>",
"title": "<title>",
"destination": "<destination>",
"durationDays": 0,
"priceFromTwd": 0
}'{
"ok": true,
"data": {
"ok": true
}
}bind / unbind a trip's cost templates
/api/v1/trips/{id}/cost-template參數
id路徑行程 ID(路徑參數)
templateIds選填要綁定的成本範本 ID 陣列(依序疊加);[] 或省略表示解除全部綁定
templateId選填(向後相容,單一)要綁定的成本範本 ID;null 表示解綁
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X PUT https://your-tenant.example.com/api/v1/trips/<id>/cost-template \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}add a departure to a trip
/api/v1/trips/{id}/departures參數
id路徑行程 ID(路徑參數),新梯次所屬的行程
departureDate必填出發日期(YYYY-MM-DD)
returnDate必填回程日期(YYYY-MM-DD),須晚於出發日
priceTwd必填梯次直客售價(新台幣)
capacity必填梯次總名額(座位上限)
agencyPriceTwd選填梯次同業售價(新台幣)
depositMode選填nonefixedpercent訂金計算方式(none 不收/fixed 固定金額/percent 百分比)
depositAmountTwd選填訂金固定金額(新台幣),depositMode 為 fixed 時生效
depositPercent選填訂金百分比(1–100),depositMode 為 percent 時生效
status選填梯次狀態(selling 銷售中/closed 關閉/cancelled 取消/completed 完成)
regionCode選填團號地區來源碼(2–3 碼大寫英數),用於產生團號,可不指定
airlineCode選填團號航空來源碼(2–3 碼大寫英數),用於產生團號,可不指定
回應欄位 · data
id新建立梯次的 id(dep_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/trips/<id>/departures \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"departureDate": "<departureDate>",
"returnDate": "<returnDate>",
"priceTwd": 0,
"capacity": 0
}'{
"ok": true,
"data": {
"id": "…"
}
}為某梯次預留自家旅宿配套
/api/v1/trips/{id}/departures/{depId}/lodging參數
id路徑行程 ID(路徑參數),梯次所屬的行程
depId路徑梯次 ID(路徑參數),要預留旅宿的梯次
propertyId必填自家旅宿物件 ID
roomTypeId必填該旅宿的房型 ID
checkIn必填入住日(YYYY-MM-DD)
checkOut必填退房日(YYYY-MM-DD),須晚於入住日
blockUnits必填整塊預留的房間間數
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/trips/<id>/departures/<depId>/lodging \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"propertyId": "<propertyId>",
"roomTypeId": "<roomTypeId>",
"checkIn": "<checkIn>",
"checkOut": "<checkOut>",
"blockUnits": 0
}'{
"ok": true,
"data": {
"ok": true
}
}釋回某梯次的自家旅宿配套預留
/api/v1/trips/{id}/lodging/{dlId}參數
id路徑行程 ID(路徑參數),預留所屬的行程
dlId路徑梯次旅宿配套預留 ID(路徑參數),要釋回的預留
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/trips/<id>/lodging/<dlId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}active cost templates for
/api/v1/trips/cost-templates參數
status選填成本範本狀態篩選;目前僅回傳啟用中(active)範本
回應欄位 · data[]
id成本範本 id(ct_ 前綴)。
name成本範本名稱。
curl -X GET https://your-tenant.example.com/api/v1/trips/cost-templates \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"name": "…"
}
]
}group-code lookup over HTTP.
/api/v1/trips/departures參數
groupCode選填完整團號,精確比對單一梯次
groupCodePrefix選填團號前綴,前綴比對列出多個梯次
curl -X GET https://your-tenant.example.com/api/v1/trips/departures \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": "…"
}per-row pricing / deposit /
/api/v1/trips/departures/{departureId}參數
departureId路徑梯次 ID(路徑參數)
priceTwd必填梯次直客售價(新台幣)
agencyPriceTwd選填梯次同業售價(新台幣),留空則退回常規定價鏈
depositMode選填nonefixedpercent訂金計算方式(none 不收/fixed 固定金額/percent 百分比)
depositAmountTwd選填訂金固定金額(新台幣),depositMode 為 fixed 時生效
depositPercent選填訂金百分比(1–100),depositMode 為 percent 時生效
promoActive選填是否啟用梯次促銷覆寫價
promoPriceTwd選填直客促銷價(新台幣),啟用促銷時必填,null 表示清空
promoAgencyPriceTwd選填同業促銷價(新台幣),null 表示同業退回常規鏈
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/trips/departures/<departureId> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"priceTwd": 0
}'{
"ok": true,
"data": {
"ok": true
}
}manual group-code
/api/v1/trips/departures/{departureId}/group-code參數
departureId路徑要覆寫團號的梯次 ID
groupCode必填完整團號,格式為 YY+地區+航空+MMDD+序號(如 26EGTK1010A,自動轉大寫)
回應欄位 · data
ok操作成功旗標,恆為 true。
groupCode設定後的團號。
curl -X POST https://your-tenant.example.com/api/v1/trips/departures/<departureId>/group-code \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"groupCode": "<groupCode>"
}'{
"ok": true,
"data": {
"ok": true,
"groupCode": "…"
}
}auto
/api/v1/trips/departures/{departureId}/group-code/generate參數
departureId路徑要產生團號的梯次 ID
regionCode必填地區碼,2–3 碼大寫英數(自動轉大寫)
airlineCode選填航空碼(選填),2–3 碼大寫英數;國內團留空省略航空段
departureDate必填出發日期(ISO 格式 YYYY-MM-DD,取 MMDD 組成團號)
回應欄位 · data
groupCode自動產生的團號。
curl -X POST https://your-tenant.example.com/api/v1/trips/departures/<departureId>/group-code/generate \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"regionCode": "<regionCode>",
"departureDate": "<departureDate>"
}'{
"ok": true,
"data": {
"groupCode": "…"
}
}change a departure's
/api/v1/trips/departures/{departureId}/status參數
departureId路徑梯次 ID(路徑參數)
status必填目標梯次狀態(selling 銷售中/closed 關閉/cancelled 取消/completed 完成)
回應欄位 · data
ok操作成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/trips/departures/<departureId>/status \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "<status>"
}'{
"ok": true,
"data": {
"ok": true
}
}匯出行程
/api/v1/trips/export參數
status選填依行程狀態篩選(draft 草稿/published 上架/archived 封存)
q選填自由文字搜尋(行程標題/代稱/目的地)
groupCode選填依團號篩選,匯出含該團號梯次的行程
回應欄位 · data
rows匯出的行程列(套用相同 filter,無分頁)。
id行程 id(trip_ 前綴)。
slug行程網址 slug。
title行程標題。
destination目的地名稱。
durationDays天數。
priceFromTwd「NT$ X 起」起價(TWD 整數)。
status上架狀態:draft 草稿 / published 已上架 / archived 封存。
updatedAt最後更新時間。
isClimbing是否登山團(行程層模組旗標)。
isOverseas是否海外團(行程層模組旗標)。
activeDepartureCountCount of departures with status='selling'.
nextDepartureDateEarliest selling departure_date, ISO date string, or null.
representativeGroupCode代表團號(group-code §8.2):最新一筆有團號的梯次;無則 null(UI 顯示 —)。
total匯出總筆數。
truncated是否因上限被截斷(此端點回全列,恆為 false)。
curl -X GET https://your-tenant.example.com/api/v1/trips/export \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"slug": "…",
"title": "…",
"destination": "…",
"durationDays": 0,
"priceFromTwd": 0,
"status": "…",
"updatedAt": "2026-06-30T08:00:00.000Z",
"isClimbing": true,
"isOverseas": true,
"activeDepartureCount": 0,
"nextDepartureDate": "…",
"representativeGroupCode": "…"
}
],
"total": 0,
"truncated": true
}
}行程批次匯入 commit:上傳檔
/api/v1/trips/import參數
filename必填上傳檔名,副檔名須為 .xlsx 或 .csv
contentBase64必填檔案內容的 base64 編碼字串(上限 5 MB)
回應欄位 · data
filename已匯入的檔名。
result匯入結果(建檔筆數與逐列結果)。
importBatchId本次匯入批次 id(imp_ 前綴),供稽核追溯。
createdTripCount新建行程數。
createdDepartureCount新建梯次數。
skippedCount略過列數(重複/無需匯入)。
errorCount失敗列數。
results逐列匯入結果。
curl -X POST https://your-tenant.example.com/api/v1/trips/import \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filename": "<filename>",
"contentBase64": "<contentBase64>"
}'{
"ok": true,
"data": {
"filename": "…",
"result": {
"importBatchId": "…",
"createdTripCount": 0,
"createdDepartureCount": 0,
"skippedCount": 0,
"errorCount": 0,
"results": []
}
}
}行程批次匯入 dry-run:上傳檔
/api/v1/trips/import/validate參數
filename必填上傳檔名,副檔名須為 .xlsx 或 .csv
contentBase64必填檔案內容的 base64 編碼字串(上限 5 MB)
回應欄位 · data
filename已驗證的檔名。
result試算(dry-run)結果(逐列預覽 + 彙總,不寫入)。
rows逐列預覽結果。
summary各狀態列數彙總。
fileError整檔層級的致命錯誤(如超列上限、空檔、無法解析),非空時 rows 為空。
curl -X POST https://your-tenant.example.com/api/v1/trips/import/validate \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filename": "<filename>",
"contentBase64": "<contentBase64>"
}'{
"ok": true,
"data": {
"filename": "…",
"result": {
"rows": [],
"summary": "…",
"fileError": "…"
}
}
}/agencies
同業
/api/v1/agencies參數
status選填activearchived同業狀態篩選(active 啟用中/archived 已封存;省略為全部)
owner選填負責業務篩選(傳明確使用者 ID;none=只列尚未指派負責業務者;all 或省略=全部)
hasTaxId選填yesno是否有統一編號篩選(yes 僅列有統編者/no 僅列無統編者)
回應欄位 · data[]
id同業 id(前綴 `agc_`)。
name同業公司名 / 個人團主名稱。
taxId統一編號(個人團主可留空)。
contactName主要聯絡人姓名(未填 → null)。
phone聯絡電話(未填 → null)。
email聯絡 Email(未填 → null)。
address公司地址(未填 → null)。
paymentTerm帳期 / 結算方式(自由文字,例:'月結 30 天')。
ownerUserId負責業務 user id(NULL = 未指派)。
ownerName負責業務顯示名;未指派為 null。
status同業狀態:active 啟用中 / archived 已封存。
note內部備註(未填 → null)。
orderCount累計訂單數(COUNT orders WHERE agency_id = id)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/agencies \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"name": "…",
"taxId": "…",
"contactName": "…",
"phone": "…",
"email": "…",
"address": "…",
"paymentTerm": "…",
"ownerUserId": "…",
"ownerName": "…",
"status": "active",
"note": "…",
"orderCount": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/agencies參數
name必填同業公司名稱(B2B 旅行社或個人團主名稱)
taxId選填統一編號(選填)
contactName選填主要聯絡人姓名(選填)
phone選填聯絡電話(選填)
email選填聯絡 Email(選填;留空字串視為未填)
address選填公司地址(選填)
paymentTerm選填付款條件/帳期約定(選填,如月結 30 天)
ownerUserId選填指派的負責業務使用者 ID(選填)
status選填同業狀態(active 啟用中/archived 已封存;預設 active)
note選填內部備註(選填)
回應欄位 · data
id新建立同業的 ID(agc_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/agencies \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"id": "…"
}
}單一同業完整資料
/api/v1/agencies/{id}參數
id路徑同業 ID
回應欄位 · data
id同業 id(前綴 `agc_`)。
name同業公司名 / 個人團主名稱。
taxId統一編號(個人團主可留空)。
contactName主要聯絡人姓名(未填 → null)。
phone聯絡電話(未填 → null)。
email聯絡 Email(未填 → null)。
address公司地址(未填 → null)。
paymentTerm帳期 / 結算方式(自由文字,例:'月結 30 天')。
ownerUserId負責業務 user id(NULL = 未指派)。
ownerName負責業務顯示名;未指派為 null。
status同業狀態:active 啟用中 / archived 已封存。
note內部備註(未填 → null)。
orderCount累計訂單數(COUNT orders WHERE agency_id = id)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/agencies/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"name": "…",
"taxId": "…",
"contactName": "…",
"phone": "…",
"email": "…",
"address": "…",
"paymentTerm": "…",
"ownerUserId": "…",
"ownerName": "…",
"status": "active",
"note": "…",
"orderCount": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}/api/v1/agencies/{id}參數
id路徑要更新的同業 ID
name選填同業公司名稱(省略則不更動)
taxId選填統一編號(省略則不更動)
contactName選填主要聯絡人姓名(省略則不更動)
phone選填聯絡電話(省略則不更動)
email選填聯絡 Email(省略則不更動;空字串視為清空)
address選填公司地址(省略則不更動)
paymentTerm選填付款條件/帳期約定(省略則不更動)
ownerUserId選填指派的負責業務使用者 ID(省略則不更動)
status選填同業狀態(active 啟用中/archived 已封存;省略則不更動)
note選填內部備註(省略則不更動)
回應欄位 · data
ok固定為 true:同業資料已更新。
curl -X PATCH https://your-tenant.example.com/api/v1/agencies/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}上下架同業
/api/v1/agencies/{id}/status參數
id路徑同業 ID
status必填目標狀態(active 上架啟用/archived 下架封存)
回應欄位 · data
ok固定為 true:同業啟用/停用狀態已更新。
curl -X POST https://your-tenant.example.com/api/v1/agencies/<id>/status \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "<status>"
}'{
"ok": true,
"data": {
"ok": true
}
}負責業務指派候選清單
/api/v1/agencies/assignable-staff回應欄位 · data[]
userId員工使用者 id(可作為負責業務指派的 ownerUserId)。
name員工顯示名。
role角色代碼(admin / sales / op / accountant)。
curl -X GET https://your-tenant.example.com/api/v1/agencies/assignable-staff \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"userId": "…",
"name": "…",
"role": "…"
}
]
}同業名單匯出
/api/v1/agencies/export參數
status選填activearchived同業狀態篩選(active 啟用中/archived 已封存;省略為全部)
owner選填負責業務篩選(傳明確使用者 ID;none=只列尚未指派負責業務者;all 或省略=全部)
hasTaxId選填yesno是否有統一編號篩選(yes 僅列有統編者/no 僅列無統編者)
回應欄位 · data
rows同業匯出資料列(依 owner 篩選後的全表快照,供試算表匯出)。
id同業 id(前綴 `agc_`)。
name同業公司名 / 個人團主名稱。
taxId統一編號(個人團主可留空)。
contactName主要聯絡人姓名(未填 → null)。
phone聯絡電話(未填 → null)。
email聯絡 Email(未填 → null)。
address公司地址(未填 → null)。
paymentTerm帳期 / 結算方式(自由文字,例:'月結 30 天')。
ownerUserId負責業務 user id(NULL = 未指派)。
ownerName負責業務顯示名;未指派為 null。
status同業狀態:active 啟用中 / archived 已封存。
note內部備註(未填 → null)。
orderCount累計訂單數(COUNT orders WHERE agency_id = id)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/agencies/export \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"name": "…",
"taxId": "…",
"contactName": "…",
"phone": "…",
"email": "…",
"address": "…",
"paymentTerm": "…",
"ownerUserId": "…",
"ownerName": "…",
"status": "active",
"note": "…",
"orderCount": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}
}/consent-templates
list every consent-document template version
/api/v1/consent-templates參數
kind選填同意書類別代碼,指定時僅列出該類別的範本版本
回應欄位 · data[]
id同意書範本 id(前綴 `ct_`)。同一 kind 每個版本各有一個 id。
kind同意書類型:pdpa(個資)/ tour_agreement(旅遊契約)/ cancellation_policy / refund_policy。
version版本號,同一 kind 從 1 遞增;範本 append-only,編輯即新增下一版。
contentMdx範本內容(MDX 原始碼),可含 {{...}} merge 變數。
effectiveFrom此版本生效起始時間。
createdAt此版本建立時間。
signatureCount引用此版本的已簽署份數(COUNT consent_signatures)。
curl -X GET https://your-tenant.example.com/api/v1/consent-templates \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"kind": "…",
"version": 0,
"contentMdx": "…",
"effectiveFrom": "2026-06-30T08:00:00.000Z",
"createdAt": "2026-06-30T08:00:00.000Z",
"signatureCount": 0
}
]
}/api/v1/consent-templates參數
kind必填同意書類別代碼,決定此範本綁定的文件種類
contentMdx必填同意書內文(MDX 格式),即此版本的條款全文
回應欄位 · data
id新建立同意書範本的 ID。
version範本版本號(每次發布遞增,簽署時綁定當下版本)。
curl -X POST https://your-tenant.example.com/api/v1/consent-templates \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"kind": "<kind>",
"contentMdx": "<contentMdx>"
}'{
"ok": true,
"data": {
"id": "…",
"version": 0
}
}a single consent-template version
/api/v1/consent-templates/{id}參數
id路徑同意書範本版本的 ID
回應欄位 · data
id同意書範本 id(前綴 `ct_`)。同一 kind 每個版本各有一個 id。
kind同意書類型:pdpa(個資)/ tour_agreement(旅遊契約)/ cancellation_policy / refund_policy。
version版本號,同一 kind 從 1 遞增;範本 append-only,編輯即新增下一版。
contentMdx範本內容(MDX 原始碼),可含 {{...}} merge 變數。
effectiveFrom此版本生效起始時間。
createdAt此版本建立時間。
signatureCount引用此版本的已簽署份數(COUNT consent_signatures)。
curl -X GET https://your-tenant.example.com/api/v1/consent-templates/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"kind": "…",
"version": 0,
"contentMdx": "…",
"effectiveFrom": "2026-06-30T08:00:00.000Z",
"createdAt": "2026-06-30T08:00:00.000Z",
"signatureCount": 0
}
}/members
list/search the tenant customer
/api/v1/members參數
q選填關鍵字,模糊比對會員姓名、Email 或電話
county選填縣市篩選,僅回傳通訊地址在該縣市的會員
year選填加入年份(西元四位數),僅回傳該年註冊的會員
page選填分頁頁碼,從 1 起算,預設第 1 頁
pageSize選填每頁筆數,上限 200,預設由後端決定
回應欄位 · data
rows當前頁的會員列。
userId會員(顧客)的 user id。
email會員 Email(登入帳號)。
name會員姓名。
createdAt會員註冊時間。
phone聯絡電話(未填 → null)。
address通訊地址(未填 → null)。
birthDate生日 YYYY-MM-DD(未填 → null)。
orderCount累計訂單數(含所有狀態與 kind)。
paidOrderCount已付清 / 已完成的訂單數(payment_state in paid/overpaid 或 booking_state=completed)。
totalSpent累計消費(上述已付清訂單的應收總額,TWD 整數)。
lastOrderAt最後一筆訂單建立時間(無訂單 → null)。
pdpaSignedAt最新版 PDPA 同意書簽署時間(未簽 → null)。
anonymizedAtPDPA 匿名化時間;非空 = 已匿名化。
total符合篩選的會員總數。
page當前頁碼(從 1 起算)。
pageSize每頁筆數。
curl -X GET https://your-tenant.example.com/api/v1/members \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"userId": "…",
"email": "…",
"name": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"phone": "…",
"address": "…",
"birthDate": "…",
"orderCount": 0,
"paidOrderCount": 0,
"totalSpent": 0,
"lastOrderAt": null,
"pdpaSignedAt": null,
"anonymizedAt": null
}
],
"total": 0,
"page": 0,
"pageSize": 0
}
}full member detail
/api/v1/members/{id}參數
id路徑會員(顧客)的使用者 ID
回應欄位 · data
profile會員基本資料 + 訂單彙整。
userId會員(顧客)的 user id。
email會員 Email(登入帳號)。
name會員姓名。
createdAt會員註冊時間。
phone聯絡電話(未填 → null)。
address通訊地址(未填 → null)。
birthDate生日 YYYY-MM-DD(未填 → null)。
orderCount累計訂單數(含所有狀態與 kind)。
paidOrderCount已付清 / 已完成的訂單數(payment_state in paid/overpaid 或 booking_state=completed)。
totalSpent累計消費(上述已付清訂單的應收總額,TWD 整數)。
lastOrderAt最後一筆訂單建立時間(無訂單 → null)。
pdpaSignedAt最新版 PDPA 同意書簽署時間(未簽 → null)。
anonymizedAtPDPA 匿名化時間;非空 = 已匿名化。
orders近期訂單列表(上限 50 筆,含 lodging)。
id訂單 id。
orderNumber人類可讀訂單編號。
status金流模型 v2:deriveOrderDisplayStatus(booking/payment/refund) 派生的單一顯示狀態。
total該會員所有訂單的應收總額(TWD 整數)。
createdAt訂單建立時間。
tripTitle行程 / 產品標題。
consents已簽署的同意書紀錄(上限 50 筆)。
id簽署紀錄 id。
kind同意書類型(pdpa / tour_agreement / cancellation_policy / refund_policy)。
version簽署當下的範本版本號。
signedAt簽署時間。
ipAddress簽署時來源 IP(未記錄 → null)。
curl -X GET https://your-tenant.example.com/api/v1/members/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"profile": {
"userId": "…",
"email": "…",
"name": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"phone": "…",
"address": "…",
"birthDate": "…",
"orderCount": 0,
"paidOrderCount": 0,
"totalSpent": 0,
"lastOrderAt": null,
"pdpaSignedAt": null,
"anonymizedAt": null
},
"orders": [
{
"id": "…",
"orderNumber": "…",
"status": "…",
"total": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"tripTitle": "…"
}
],
"consents": [
{
"id": "…",
"kind": "…",
"version": 0,
"signedAt": "2026-06-30T08:00:00.000Z",
"ipAddress": "…"
}
]
}
}irreversible PDPA anonymization of one
/api/v1/members/{id}/anonymize參數
id路徑欲匿名化的會員(顧客)使用者 ID
reason選填匿名化原因,記入稽核紀錄備查
回應欄位 · data
ok固定為 true:會員個資已匿名化(PDPA 刪除權)。
curl -X POST https://your-tenant.example.com/api/v1/members/<id>/anonymize \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}given a batch of member
/api/v1/members/expiry-warnings參數
ids必填以逗號分隔的會員使用者 ID 批次,上限 200 個,回傳其中護照即將到期者
回應欄位 · data
userIds證件即將到期(或已過期)需提醒的會員 user id 清單。
curl -X GET "https://your-tenant.example.com/api/v1/members/expiry-warnings?ids=<ids>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"userIds": [
"…"
]
}
}member directory KPI cards
/api/v1/members/stats回應欄位 · data
totalMembers會員(顧客)總數(排除員工帳號)。
newThisMonth本月新註冊會員數。
withOrders有下過訂單的會員數。
averageOrders平均訂單數(只計有訂單者,避免零訂單稀釋)。
curl -X GET https://your-tenant.example.com/api/v1/members/stats \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"totalMembers": 0,
"newThisMonth": 0,
"withOrders": 0,
"averageOrders": 0
}
}/orders
list/search/filter orders
/api/v1/orders參數
status選填依訂單顯示狀態篩選(如 pending、paid、cancelled)
assignment選填依派發狀態篩選(如 unassigned、assigned)
rooming選填依分房狀態篩選
dateFrom選填出發日期區間起(格式 YYYY-MM-DD,含當日)
dateTo選填出發日期區間迄(格式 YYYY-MM-DD,含當日)
q選填關鍵字搜尋(訂單編號、訂購人姓名或 Email 等)
agencyId選填依合作旅行社 ID 篩選(同業單)
page選填頁碼,從 1 起算,預設第 1 頁
pageSize選填每頁筆數,上限 200
回應欄位 · data
rows當前頁的訂單列(tour-centric,每筆 tour line 一列)。
id訂單 id(前綴 `ord_`)。
orderNumber人類可讀訂單編號(每租戶 sequence 產生,如 `20260707-0001`)。
bookingState預訂狀態(真相軸):pending_payment → confirmed → completed;cancelled 為終態。
paymentState付款狀態(派生自分類帳、快取於此供過濾):unpaid / partially_paid / deposit_paid / paid / overpaid。paid 只代表「應收被現金覆蓋」,不代表錢未退。
refundState退款狀態(派生快取,只算會影響應收的已付退款):none / partially_refunded / refunded。
grossReceivableTwd應收(TWD 整數,派生自應收分類帳)。
collectedTwd收到現金(TWD 整數,派生)。
customerCashAppliedTwd客戶現金淨套用(收款減已退現金,TWD 整數,派生)。
outstandingTwd未收(應收減客戶現金淨套用,TWD 整數,派生)。
partySize參團人數(tour 訂單)。
createdAt訂單建立時間。
notes訂單備註(未填 → null)。
userId下單客戶的 user id(同庫 user 表)。
userName下單客戶顯示名。
userEmail下單客戶 Email。
primaryTravelerName主要旅客姓名(is_primary,未登記 → null)。
primaryTravelerPhone主要旅客電話(未登記 → null)。
tripId行程 id(tour 訂單經梯次反查;lodging 為空字串)。
tripTitle行程 / 產品標題。
tripSlug行程 slug。
departureId梯次 id(tour 訂單;lodging 為空字串)。
departureDate出發日 YYYY-MM-DD(lodging 為入住日)。
returnDate回程日 YYYY-MM-DD(lodging 為退房日)。
assignedToUserId派發給哪位業務的 user id(未派發 → null)。
assigneeName承辦業務顯示名(未派發 / 查無 → null)。
assignmentStatus派發狀態:unassigned / assigned / reassigned / pending_review。
assignedAt最近一次派發時間(未派發 → null)。
assignedByUserId執行派發者的 user id(未派發 → null)。
createdByUserIdS5: who created the order. null / equal to `userId` = customer self-service (自助下單); a staff id ≠ userId = 業務代訂 / K單. Distinct from assignment — a self-service order can still be assigned to a sales rep.
pendingConsent是否尚缺最新版 PDPA 同意書簽署(true = 待客戶重簽)。
roomingStatus分房狀態:由訂單旅客的分房偏好與已分配房間派生。 'unregistered' | 'registered' | 'needs_single' | 'assigned'。
lotteryState抽籤狀態(null = FCFS 非抽籤)。'applied'|'won'|'lost'。
failoverFromOrderId備案單反查主單用:備案單的 failover_from_order_id 指向主單 id。
isOverdue逾期旗標:存在 status='open' 且 due_at 已過的收款計畫(未收齊的到期款)。 供列表列以 `bg-destructive/5` 標紅提示。由 OVERDUE_SUBSELECT 一次算回。
total符合篩選的訂單總數(DISTINCT 訂單,非列數)。
page當前頁碼(從 1 起算)。
pageSize每頁筆數。
curl -X GET https://your-tenant.example.com/api/v1/orders \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"orderNumber": "…",
"bookingState": "…",
"paymentState": "…",
"refundState": "…",
"grossReceivableTwd": 0,
"collectedTwd": 0,
"customerCashAppliedTwd": 0,
"outstandingTwd": 0,
"partySize": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"notes": "…",
"userId": "…",
"userName": "…",
"userEmail": "…",
"primaryTravelerName": "…",
"primaryTravelerPhone": "…",
"tripId": "…",
"tripTitle": "…",
"tripSlug": "…",
"departureId": "…",
"departureDate": "…",
"returnDate": "…",
"assignedToUserId": "…",
"assigneeName": "…",
"assignmentStatus": "…",
"assignedAt": null,
"assignedByUserId": "…",
"createdByUserId": "…",
"pendingConsent": true,
"roomingStatus": "…",
"lotteryState": "…",
"failoverFromOrderId": "…",
"isOverdue": true
}
],
"total": 0,
"page": 0,
"pageSize": 0
}
}/api/v1/orders參數
tripId必填行程 ID
departureId必填梯次 ID,決定佔位的出發團
primaryEmail必填訂購人 Email,須對應已註冊會員
partySize必填報名人數,決定佔位數,須為 1 至 20 之間整數
travelers必填旅客名單,筆數須與報名人數一致
paymentMethod必填cashatmmanual收款方式:cash 現金、atm 轉帳、manual 人工
customerType選填directagency客戶類型:direct 直客、agency 同業,預設直客
paymentPlan選填fulldeposit付款方案:full 全額、deposit 訂金,預設全額
receivingAccountId選填收款帳戶 ID,指定本筆款項入帳的帳戶
notes選填訂單備註
assigneeUserId選填指定業績歸屬業務的使用者 ID,省略或等於自己則歸屬建單者;指定他人需具備訂單指派權限
回應欄位 · data
orderId新建立訂單的 ID(ord_ 前綴)。
orderNumber訂單編號(租戶內流水序號,對外顯示用)。
curl -X POST https://your-tenant.example.com/api/v1/orders \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tripId": "<tripId>",
"departureId": "<departureId>",
"primaryEmail": "<primaryEmail>",
"partySize": 0,
"travelers": [],
"paymentMethod": "cash"
}'{
"ok": true,
"data": {
"orderId": "…",
"orderNumber": "…"
}
}full kind-aware order detail
/api/v1/orders/{id}參數
id路徑訂單 ID
回應欄位 · data
id訂單 id(前綴 `ord_`)。
orderNumber人類可讀訂單編號(每租戶 sequence 產生,如 `20260707-0001`)。
bookingState預訂狀態(真相軸):pending_payment → confirmed → completed;cancelled 為終態。
paymentState付款狀態(派生自分類帳、快取於此供過濾):unpaid / partially_paid / deposit_paid / paid / overpaid。paid 只代表「應收被現金覆蓋」,不代表錢未退。
refundState退款狀態(派生快取,只算會影響應收的已付退款):none / partially_refunded / refunded。
grossReceivableTwd應收(TWD 整數,派生自應收分類帳)。
collectedTwd收到現金(TWD 整數,派生)。
customerCashAppliedTwd客戶現金淨套用(收款減已退現金,TWD 整數,派生)。
outstandingTwd未收(應收減客戶現金淨套用,TWD 整數,派生)。
partySize參團人數(tour 訂單)。
createdAt訂單建立時間。
notes訂單備註(未填 → null)。
userId下單客戶的 user id(同庫 user 表)。
userName下單客戶顯示名。
userEmail下單客戶 Email。
primaryTravelerName主要旅客姓名(is_primary,未登記 → null)。
primaryTravelerPhone主要旅客電話(未登記 → null)。
tripId行程 id(tour 訂單經梯次反查;lodging 為空字串)。
tripTitle行程 / 產品標題。
tripSlug行程 slug。
departureId梯次 id(tour 訂單;lodging 為空字串)。
departureDate出發日 YYYY-MM-DD(lodging 為入住日)。
returnDate回程日 YYYY-MM-DD(lodging 為退房日)。
assignedToUserId派發給哪位業務的 user id(未派發 → null)。
assigneeName承辦業務顯示名(未派發 / 查無 → null)。
assignmentStatus派發狀態:unassigned / assigned / reassigned / pending_review。
assignedAt最近一次派發時間(未派發 → null)。
assignedByUserId執行派發者的 user id(未派發 → null)。
createdByUserIdS5: who created the order. null / equal to `userId` = customer self-service (自助下單); a staff id ≠ userId = 業務代訂 / K單. Distinct from assignment — a self-service order can still be assigned to a sales rep.
pendingConsent是否尚缺最新版 PDPA 同意書簽署(true = 待客戶重簽)。
roomingStatus分房狀態:由訂單旅客的分房偏好與已分配房間派生。 'unregistered' | 'registered' | 'needs_single' | 'assigned'。
lotteryState抽籤狀態(null = FCFS 非抽籤)。'applied'|'won'|'lost'。
failoverFromOrderId備案單反查主單用:備案單的 failover_from_order_id 指向主單 id。
isOverdue逾期旗標:存在 status='open' 且 due_at 已過的收款計畫(未收齊的到期款)。 供列表列以 `bg-destructive/5` 標紅提示。由 OVERDUE_SUBSELECT 一次算回。
kind訂單種類(kind-agnostic 外殼)。'tour' 用既有 tour 區塊(梯次/分房/登山審核); 'lodging' 隱藏 tour-only 區、改顯示住宿 header(見 `lodging`)。共用的金流/旅客/ 派發/同意書區塊兩者皆 order-scoped 通用。
lodginglodging 住宿 header(房型/住期/房數/人數);tour 為 null。
travelers旅客名單(含 PII 遮罩欄;主要旅客排前)。
id旅客 id(前綴 `trv_`)。
fullName旅客姓名。
idNumberMask遮罩碼(jsonb→mask,零解密);NULL = 未填。全碼走 reveal action(Task 7)。
passportNoMask護照號碼遮罩碼(零解密);NULL = 未填。全碼走 order-scoped reveal。
birthDate生日 YYYY-MM-DD(未填 → null)。
phone聯絡電話(未填 → null)。
email聯絡 Email(未填 → null)。
emergencyContactName緊急聯絡人姓名(未填 → null)。
emergencyContactPhone緊急聯絡人電話(未填 → null)。
isPrimary是否為主要旅客(訂單聯絡人)。
gender性別(分房硬約束 + 顯示):'male'|'female'|'other'|null。明文。
roomPreference分房房型偏好(下單登記)。
roommatePref指定房友 / 特殊需求自由文字。
diet飲食需求(葷素)明文;null = 未填。非 PII,不走 reveal。
medicalNotes醫療 / 過敏 / 病史備註明文;null = 未填。非 PII,不走 reveal。
address通訊地址(未填 → null)。
roomLabel團控已排房號的房間 label(null = 待團控分房)。
chargeLines應收分類帳(itemized)。
id應收明細列 id。
type應收類型:base(原始價)/ room_upgrade(房升補款)/ adjustment / failover_deposit_credit 等。
amountTwd金額(TWD 整數,signed;credit / 沖銷為負)。
description明細說明文字。
sourceType來源:system(系統派生)/ manual(人工登錄)等。
reversesChargeLineId若為沖銷列,指向被沖銷的應收明細列 id(否則 null)。
createdAt建立時間。
transactions現金分類帳。
id現金交易列 id。
direction金流方向:in(收款)/ out(退款、扣款、沖銷)。
type交易類型:payment / refund / chargeback / reversal。
amountTwd交易金額(TWD 整數,正值)。
feeTwd金流商手續費(TWD 整數)。
netTwd淨額 = amount − fee(TWD 整數)。
provider金流商:manual / ecpay / test 等。
providerTradeNo金流商交易序號(manual 入帳可能為 null)。
refundId若屬退款,指向 refunds 列 id(否則 null)。
occurredAt交易發生時間。
schedules收款計畫(current + historical)。
id收款計畫列 id。
purpose用途:full(全額)/ deposit(訂金)/ balance(尾款)/ adjustment(補款)。
targetAmountTwd應收目標金額(TWD 整數)。
status計畫狀態:open(未收齊)/ satisfied(已收齊)。
dueAt到期日(null = 未設)。
sequence排序序號(deposit → balance → adjustment)。
curl -X GET https://your-tenant.example.com/api/v1/orders/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"orderNumber": "…",
"bookingState": "…",
"paymentState": "…",
"refundState": "…",
"grossReceivableTwd": 0,
"collectedTwd": 0,
"customerCashAppliedTwd": 0,
"outstandingTwd": 0,
"partySize": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"notes": "…",
"userId": "…",
"userName": "…",
"userEmail": "…",
"primaryTravelerName": "…",
"primaryTravelerPhone": "…",
"tripId": "…",
"tripTitle": "…",
"tripSlug": "…",
"departureId": "…",
"departureDate": "…",
"returnDate": "…",
"assignedToUserId": "…",
"assigneeName": "…",
"assignmentStatus": "…",
"assignedAt": null,
"assignedByUserId": "…",
"createdByUserId": "…",
"pendingConsent": true,
"roomingStatus": "…",
"lotteryState": "…",
"failoverFromOrderId": "…",
"isOverdue": true,
"kind": "lodging",
"lodging": null,
"travelers": [
{
"id": "…",
"fullName": "…",
"idNumberMask": "…",
"passportNoMask": "…",
"birthDate": "…",
"phone": "…",
"email": "…",
"emergencyContactName": "…",
"emergencyContactPhone": "…",
"isPrimary": true,
"gender": "…",
"roomPreference": "…",
"roommatePref": "…",
"diet": "…",
"medicalNotes": "…",
"address": "…",
"roomLabel": "…"
}
],
"chargeLines": [
{
"id": "…",
"type": "…",
"amountTwd": 0,
"description": "…",
"sourceType": "…",
"reversesChargeLineId": "…",
"createdAt": "2026-06-30T08:00:00.000Z"
}
],
"transactions": [
{
"id": "…",
"direction": "…",
"type": "…",
"amountTwd": 0,
"feeTwd": 0,
"netTwd": 0,
"provider": "…",
"providerTradeNo": "…",
"refundId": "…",
"occurredAt": "2026-06-30T08:00:00.000Z"
}
],
"schedules": [
{
"id": "…",
"purpose": "…",
"targetAmountTwd": 0,
"status": "…",
"dueAt": null,
"sequence": 0
}
]
}
}manual charge adjustment
/api/v1/orders/{id}/adjust參數
id路徑訂單 ID
kind必填surchargeallowance調整類型:surcharge 加收、allowance 減免
amountTwd必填調整金額(新台幣,正整數)
description必填調整事由說明
回應欄位 · data
ok固定為 true:訂單金額調整已套用。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/adjust \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"kind": "surcharge",
"amountTwd": 0,
"description": "<description>"
}'{
"ok": true,
"data": {
"ok": true
}
}首次派發訂單給承辦業務
/api/v1/orders/{id}/assign參數
id路徑訂單 ID
assigneeUserId必填受派業務的使用者 ID
reason選填派發事由說明(上限 500 字)
回應欄位 · data
ok固定為 true:訂單已指派承辦。
idempotenttrue = 該訂單原已指派給同一承辦,本次為冪等無變更。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/assign \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"assigneeUserId": "<assigneeUserId>"
}'{
"ok": true,
"data": {
"ok": true,
"idempotent": true
}
}產生/重用尾款
/api/v1/orders/{id}/balance-link參數
id路徑訂單 ID
回應欄位 · data
ok固定為 true:尾款付款連結已產生。
amountTwd本次尾款金額(TWD 整數)。
scheduleId對應的收款計畫 ID。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/balance-link \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true,
"amountTwd": 0,
"scheduleId": "…"
}
}cancel a tour order
/api/v1/orders/{id}/cancel參數
id路徑訂單 ID
reason選填取消事由說明
回應欄位 · data
ok固定為 true:訂單已取消(座位釋出、booking_state 轉 cancelled)。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/cancel \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}業務自派搶單
/api/v1/orders/{id}/claim參數
id路徑訂單 ID
回應欄位 · data
ok固定為 true:訂單已由當前承辦認領。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/claim \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}線控手動抽籤裁決:won
/api/v1/orders/{id}/lottery/resolve參數
id路徑訂單 ID
outcome必填wonlost抽籤裁決結果:won 中籤確認、lost 未中籤(啟動備案或取消)
回應欄位 · data
ok固定為 true:抽籤結果已登錄。
outcome抽籤結果:won 中籤 / lost 未中籤。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/lottery/resolve \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"outcome": "won"
}'{
"ok": true,
"data": {
"ok": true,
"outcome": "won"
}
}mark an order paid by manual
/api/v1/orders/{id}/mark-paid參數
id路徑訂單 ID
note選填對帳備註,記錄人工核款說明
receivingAccountId選填收款帳戶 ID,指定本筆款項入帳的帳戶
回應欄位 · data
idempotenttrue = 訂單原已為已付狀態,本次為冪等無變更。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/mark-paid \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"idempotent": true
}
}重新指派已派發訂單
/api/v1/orders/{id}/reassign參數
id路徑訂單 ID
assigneeUserId必填重新指派的承接業務使用者 ID
reason選填重派事由說明(上限 500 字)
回應欄位 · data
ok固定為 true:訂單已改派承辦。
idempotenttrue = 目標承辦與原承辦相同,本次為冪等無變更。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/reassign \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"assigneeUserId": "<assigneeUserId>"
}'{
"ok": true,
"data": {
"ok": true,
"idempotent": true
}
}create + submit a customer refund
/api/v1/orders/{id}/refunds參數
id路徑訂單 ID
refundKind必填receivable_reductionoverpayment_return退款種類:receivable_reduction 應收減免、overpayment_return 溢收退還
reason必填退款事由說明
amountTwd必填退款總金額(新台幣,正整數)
executionMethod選填chargebackremit退款執行方式:chargeback 原路退刷、remit 銀行匯款
originAccountId選填出款來源帳戶 ID(匯款退款時指定)
adminFeeTwd選填手續費/行政費(新台幣,非負整數)
remitFeeTwd選填匯款轉帳費(新台幣,非負整數)
payeeAccountName選填受款人戶名(匯款退款時填寫)
payeeBankCode選填受款銀行代碼(匯款退款時填寫)
payeeAccountNumber選填受款銀行帳號(匯款退款時填寫)
lines選填退款明細列;省略時依退款總額處理
回應欄位 · data
id退款單 id(前綴 `rfnd_`)。
refundNumber人類可讀退款單號。
status退款工作流狀態:draft → submitted → approved → processing → paid。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/refunds \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"refundKind": "receivable_reduction",
"reason": "<reason>",
"amountTwd": 0
}'{
"ok": true,
"data": {
"id": "…",
"refundNumber": "…",
"status": "…"
}
}approve a submitted
/api/v1/orders/{id}/refunds/{refundId}/approve參數
refundId路徑退款單 ID
回應欄位 · data
ok固定為 true:退款申請已核准。
curl -X POST https://your-tenant.example.com/api/v1/orders/{id}/refunds/<refundId>/approve \
-H "Authorization: Bearer $CAIRN_TOKEN"{
"ok": true,
"data": {
"ok": true
}
}mark an approved
/api/v1/orders/{id}/refunds/{refundId}/mark-paid參數
id路徑訂單 ID(path)
refundId路徑退款單 ID
bankReference選填出款的銀行交易參考號(匯款憑證)
receivingAccountId選填出款帳戶 ID;remit 退款須指定具匯款能力的帳戶
回應欄位 · data
ok固定為 true:退款已標記為完成出款。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/refunds/<refundId>/mark-paid \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}reject a submitted
/api/v1/orders/{id}/refunds/{refundId}/reject參數
refundId路徑退款單 ID
reason選填退件事由說明
回應欄位 · data
ok固定為 true:退款申請已駁回。
curl -X POST https://your-tenant.example.com/api/v1/orders/{id}/refunds/<refundId>/reject \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}reverse an existing charge line
/api/v1/orders/{id}/reverse參數
id路徑訂單 ID
chargeLineId必填欲沖正的應收項目(charge line)ID
description必填沖正事由說明
回應欄位 · data
ok固定為 true:訂單已沖銷(沖回應收與已認列項)。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/reverse \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"chargeLineId": "<chargeLineId>",
"description": "<description>"
}'{
"ok": true,
"data": {
"ok": true
}
}人工核可/駁回登山資格審核
/api/v1/orders/{id}/review-screening參數
id路徑訂單 ID
decision必填approvereject登山資格審核裁決:approve 核可、reject 駁回
note選填審核註記說明(上限 500 字)
回應欄位 · data
ok固定為 true:名單複核結果已登錄。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/review-screening \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"decision": "approve"
}'{
"ok": true,
"data": {
"ok": true
}
}新增旅客到訂單
/api/v1/orders/{id}/travelers參數
fullName選填旅客全名,須與證件一致;新增旅客時必填,更新時可省略
phone選填旅客聯絡電話
email選填旅客電子郵件
birthDate選填旅客出生日期(格式 YYYY-MM-DD)
emergencyContactName選填緊急聯絡人姓名
emergencyContactPhone選填緊急聯絡人電話
gender選填malefemaleother旅客性別:male 男、female 女、other 其他
roomPreference選填房型偏好(用於分房作業)
roommatePref選填指定同住室友(用於分房作業)
diet選填飲食需求(葷 / 素 / 蛋奶素… 自由值),供餐食葷素彙總
medicalNotes選填醫療 / 過敏 / 病史備註(自由文字),供出團安全警示
address選填旅客通訊地址
idNumber選填身分證字號,屬個資將加密保存
passportNo選填護照號碼,屬個資將加密保存
id路徑訂單 ID
回應欄位 · data
ok固定為 true:旅客已新增至訂單。
travelerId新建立旅客的 ID(trv_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/travelers \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true,
"travelerId": "…"
}
}更新旅客資料
/api/v1/orders/{id}/travelers/{travelerId}參數
fullName選填旅客全名,須與證件一致;新增旅客時必填,更新時可省略
phone選填旅客聯絡電話
email選填旅客電子郵件
birthDate選填旅客出生日期(格式 YYYY-MM-DD)
emergencyContactName選填緊急聯絡人姓名
emergencyContactPhone選填緊急聯絡人電話
gender選填malefemaleother旅客性別:male 男、female 女、other 其他
roomPreference選填房型偏好(用於分房作業)
roommatePref選填指定同住室友(用於分房作業)
diet選填飲食需求(葷 / 素 / 蛋奶素… 自由值),供餐食葷素彙總
medicalNotes選填醫療 / 過敏 / 病史備註(自由文字),供出團安全警示
address選填旅客通訊地址
idNumber選填身分證字號,屬個資將加密保存
passportNo選填護照號碼,屬個資將加密保存
id路徑訂單 ID
travelerId路徑旅客 ID
回應欄位 · data
ok固定為 true:旅客資料已更新。
curl -X PATCH https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}移除旅客
/api/v1/orders/{id}/travelers/{travelerId}參數
id路徑訂單 ID
travelerId路徑旅客 ID
回應欄位 · data
ok固定為 true:旅客已自訂單移除。
curl -X DELETE https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}顯示旅客證號/護照全碼
/api/v1/orders/{id}/travelers/{travelerId}/reveal參數
id路徑訂單 ID
travelerId路徑旅客 ID
field必填idNumberpassportNo欲顯示全碼的個資欄位:idNumber 身分證字號、passportNo 護照號碼
回應欄位 · data
field本次解密的欄位:idNumber 身分證字號 / passportNo 護照號碼。
value解密後的證件明碼;null = 該欄未填。每次呼叫都會寫入解密稽核紀錄。
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId>/reveal \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"field": "idNumber"
}'{
"ok": true,
"data": {
"field": "idNumber",
"value": "…"
}
}更新旅客分房需求
/api/v1/orders/{id}/travelers/{travelerId}/rooming參數
roomPreference選填房型偏好(用於分房作業)
roommatePref選填指定同住室友(用於分房作業)
id路徑訂單 ID
travelerId路徑旅客 ID
回應欄位 · data
ok固定為 true:旅客分房設定已更新。
curl -X PATCH https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId>/rooming \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}批次把多張訂單派給同一位業務
/api/v1/orders/bulk-assign參數
orderIds必填欲批次派發的訂單 ID 陣列(1 至 100 筆)
assigneeUserId必填受派業務的使用者 ID(所有訂單派給同一人)
reason選填派發事由說明(上限 500 字)
回應欄位 · data
ok固定為 true:批次指派已執行。
assignedCount成功指派的訂單筆數。
skippedCount略過的訂單筆數(如已指派或不在可指派範圍)。
curl -X POST https://your-tenant.example.com/api/v1/orders/bulk-assign \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orderIds": [],
"assigneeUserId": "<assigneeUserId>"
}'{
"ok": true,
"data": {
"ok": true,
"assignedCount": 0,
"skippedCount": 0
}
}匯出訂單
/api/v1/orders/export參數
status選填依訂單顯示狀態篩選(如 pending、paid、cancelled)
assignment選填依派發狀態篩選(如 unassigned、assigned)
rooming選填依分房狀態篩選
dateFrom選填出發日期區間起(格式 YYYY-MM-DD,含當日)
dateTo選填出發日期區間迄(格式 YYYY-MM-DD,含當日)
q選填關鍵字搜尋(訂單編號、訂購人姓名或 Email 等)
agencyId選填依合作旅行社 ID 篩選(同業單)
回應欄位 · data
rows符合篩選條件的所有列(逐頁累積;達安全上限時截斷)。
id訂單 id(前綴 `ord_`)。
orderNumber人類可讀訂單編號(每租戶 sequence 產生,如 `20260707-0001`)。
bookingState預訂狀態(真相軸):pending_payment → confirmed → completed;cancelled 為終態。
paymentState付款狀態(派生自分類帳、快取於此供過濾):unpaid / partially_paid / deposit_paid / paid / overpaid。paid 只代表「應收被現金覆蓋」,不代表錢未退。
refundState退款狀態(派生快取,只算會影響應收的已付退款):none / partially_refunded / refunded。
grossReceivableTwd應收(TWD 整數,派生自應收分類帳)。
collectedTwd收到現金(TWD 整數,派生)。
customerCashAppliedTwd客戶現金淨套用(收款減已退現金,TWD 整數,派生)。
outstandingTwd未收(應收減客戶現金淨套用,TWD 整數,派生)。
partySize參團人數(tour 訂單)。
createdAt訂單建立時間。
notes訂單備註(未填 → null)。
userId下單客戶的 user id(同庫 user 表)。
userName下單客戶顯示名。
userEmail下單客戶 Email。
primaryTravelerName主要旅客姓名(is_primary,未登記 → null)。
primaryTravelerPhone主要旅客電話(未登記 → null)。
tripId行程 id(tour 訂單經梯次反查;lodging 為空字串)。
tripTitle行程 / 產品標題。
tripSlug行程 slug。
departureId梯次 id(tour 訂單;lodging 為空字串)。
departureDate出發日 YYYY-MM-DD(lodging 為入住日)。
returnDate回程日 YYYY-MM-DD(lodging 為退房日)。
assignedToUserId派發給哪位業務的 user id(未派發 → null)。
assigneeName承辦業務顯示名(未派發 / 查無 → null)。
assignmentStatus派發狀態:unassigned / assigned / reassigned / pending_review。
assignedAt最近一次派發時間(未派發 → null)。
assignedByUserId執行派發者的 user id(未派發 → null)。
createdByUserIdS5: who created the order. null / equal to `userId` = customer self-service (自助下單); a staff id ≠ userId = 業務代訂 / K單. Distinct from assignment — a self-service order can still be assigned to a sales rep.
pendingConsent是否尚缺最新版 PDPA 同意書簽署(true = 待客戶重簽)。
roomingStatus分房狀態:由訂單旅客的分房偏好與已分配房間派生。 'unregistered' | 'registered' | 'needs_single' | 'assigned'。
lotteryState抽籤狀態(null = FCFS 非抽籤)。'applied'|'won'|'lost'。
failoverFromOrderId備案單反查主單用:備案單的 failover_from_order_id 指向主單 id。
isOverdue逾期旗標:存在 status='open' 且 due_at 已過的收款計畫(未收齊的到期款)。 供列表列以 `bg-destructive/5` 標紅提示。由 OVERDUE_SUBSELECT 一次算回。
total符合篩選條件的總筆數。
truncated是否因達安全上限而截斷(true 表未回傳完整結果,呼叫端應提示)。
curl -X GET https://your-tenant.example.com/api/v1/orders/export \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"orderNumber": "…",
"bookingState": "…",
"paymentState": "…",
"refundState": "…",
"grossReceivableTwd": 0,
"collectedTwd": 0,
"customerCashAppliedTwd": 0,
"outstandingTwd": 0,
"partySize": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"notes": "…",
"userId": "…",
"userName": "…",
"userEmail": "…",
"primaryTravelerName": "…",
"primaryTravelerPhone": "…",
"tripId": "…",
"tripTitle": "…",
"tripSlug": "…",
"departureId": "…",
"departureDate": "…",
"returnDate": "…",
"assignedToUserId": "…",
"assigneeName": "…",
"assignmentStatus": "…",
"assignedAt": null,
"assignedByUserId": "…",
"createdByUserId": "…",
"pendingConsent": true,
"roomingStatus": "…",
"lotteryState": "…",
"failoverFromOrderId": "…",
"isOverdue": true
}
],
"total": 0,
"truncated": true
}
}order KPI counts
/api/v1/orders/stats回應欄位 · data
pendingPayment待付款訂單數(未取消 / 未完成 / 未退款且 payment_state=unpaid)。
depositPaid已付訂金訂單數(payment_state=deposit_paid)。
paid已收齊訂單數(payment_state in paid/overpaid)。
cancelled已取消訂單數(booking_state=cancelled)。
refunded有退款的訂單數(refund_state in refunded/partially_refunded)。
completed已完成訂單數(booking_state=completed)。
thisMonthPaidTwd本月實收現金(payment_transactions direction=in 加總,TWD 整數)。
thisMonthNewOrders本月新建訂單數。
thisMonthCancelled本月取消訂單數。
curl -X GET https://your-tenant.example.com/api/v1/orders/stats \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"pendingPayment": 0,
"depositPaid": 0,
"paid": 0,
"cancelled": 0,
"refunded": 0,
"completed": 0,
"thisMonthPaidTwd": 0,
"thisMonthNewOrders": 0,
"thisMonthCancelled": 0
}
}/equipment
list the equipment master
/api/v1/equipment/items參數
activeOnly選填只列出啟用中(可租借)的品項
回應欄位 · data[]
id裝備主檔品項 id(equipmentItem_ 前綴)。
name品名。
category分類(如帳篷/睡袋/爐具;未分類為 null)。
spec規格描述(尺寸/型號等;可空)。
rentPriceTwd每日租金單價(TWD)。
depositTwd每件押金(TWD)。
totalCount庫存總件數。
outCount目前在外(已借出未歸還)件數。
maintenanceCount維修中件數(不可借出)。
availableCount可租 = total − out − maintenance(派生,便利 UI)。
isActive是否啟用(可租借)。
createdAt建檔時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/equipment/items \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"name": "…",
"category": "…",
"spec": "…",
"rentPriceTwd": 0,
"depositTwd": 0,
"totalCount": 0,
"outCount": 0,
"maintenanceCount": 0,
"availableCount": 0,
"isActive": true,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}create a master item
/api/v1/equipment/items參數
name必填裝備品項名稱
category選填裝備分類(如帳篷、睡袋;選填)
spec選填規格說明(如尺寸、型號;選填)
rentPriceTwd選填每日租金(台幣)
depositTwd選填每件押金(台幣)
totalCount選填總庫存數量
maintenanceCount選填維修中而不可租借的數量
isActive選填是否啟用(可供租借)
回應欄位 · data
id新建立的裝備品項 id。
curl -X POST https://your-tenant.example.com/api/v1/equipment/items \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"id": "…"
}
}single equipment master item detail.
/api/v1/equipment/items/{id}參數
id路徑裝備品項 ID
回應欄位 · data
id裝備主檔品項 id(equipmentItem_ 前綴)。
name品名。
category分類(如帳篷/睡袋/爐具;未分類為 null)。
spec規格描述(尺寸/型號等;可空)。
rentPriceTwd每日租金單價(TWD)。
depositTwd每件押金(TWD)。
totalCount庫存總件數。
outCount目前在外(已借出未歸還)件數。
maintenanceCount維修中件數(不可借出)。
availableCount可租 = total − out − maintenance(派生,便利 UI)。
isActive是否啟用(可租借)。
createdAt建檔時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/equipment/items/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"name": "…",
"category": "…",
"spec": "…",
"rentPriceTwd": 0,
"depositTwd": 0,
"totalCount": 0,
"outCount": 0,
"maintenanceCount": 0,
"availableCount": 0,
"isActive": true,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}update a master item
/api/v1/equipment/items/{id}參數
id路徑要更新的裝備品項 ID
name必填裝備品項名稱
category選填裝備分類(如帳篷、睡袋;選填)
spec選填規格說明(如尺寸、型號;選填)
rentPriceTwd選填每日租金(台幣)
depositTwd選填每件押金(台幣)
totalCount選填總庫存數量
maintenanceCount選填維修中而不可租借的數量
isActive選填是否啟用(可供租借)
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/equipment/items/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true
}
}list rental tickets
/api/v1/equipment/rentals參數
returnState選填rentedreturnedoverdue依歸還狀態篩選:rented 在租中、returned 已歸還、overdue 逾期
reconState選填pendingreconcileddeposit_pending依驗收結算狀態篩選:pending 待驗收、reconciled 已結算、deposit_pending 待退押金
orderId選填只列出綁定此訂單 ID 的租借單
departureId選填只列出綁定此梯次 ID 的租借單
回應欄位 · data[]
id租借單 id(equipmentRental_ 前綴)。
orderId掛載的訂單 id。
orderNumber訂單編號(JOIN;可空)。
departureId綁定的梯次 id(可不綁梯次時 null)。
departureLabel梯次可讀標籤:團號 ‧ 行程名 ‧ 出發日(無綁梯次時 null)。
renterName租借人姓名(可空)。
rentStartDate租期起日(YYYY-MM-DD;可空)。
rentEndDate租期迄日(YYYY-MM-DD;可空)。
returnedAt歸還驗收時間(尚未歸還為 null)。
returnState歸還狀態:rented 租借中/returned 已歸還/overdue 逾期。
inspectedAt驗收時間(尚未驗收為 null)。
damageCostTwd破損/遺失賠償金額(TWD;無為 null)。
reconState對款狀態:pending 待對款/reconciled 已結清/deposit_pending 押金待退或待扣。
notes備註(可空)。
createdAt建單時間。
updatedAt最後更新時間。
lines租借明細(借出的品項清單)。
id租借明細 id(equipmentRentalLine_ 前綴)。
equipmentItemId借出的裝備主檔品項 id。
itemName主檔品名快照(JOIN,便利顯示;改主檔不回寫單)。
quantity借出數量。
rentPriceTwdSnapshot成交單位總價快照(每日單價 × 計價日數;TWD)。
depositTwdSnapshot成交每件押金快照(TWD,不乘天數)。
returnedQuantity已歸還數量(尚未歸還為 null)。
rentTotalTwd成交租金合計(Σ rent snapshot × qty)。
depositTotalTwd成交押金合計(Σ deposit snapshot × qty)。
curl -X GET https://your-tenant.example.com/api/v1/equipment/rentals \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"orderId": "…",
"orderNumber": "…",
"departureId": "…",
"departureLabel": "…",
"renterName": "…",
"rentStartDate": "…",
"rentEndDate": "…",
"returnedAt": null,
"returnState": "…",
"inspectedAt": null,
"damageCostTwd": 0,
"reconState": "…",
"notes": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z",
"lines": [
{
"id": "…",
"equipmentItemId": "…",
"itemName": "…",
"quantity": 0,
"rentPriceTwdSnapshot": 0,
"depositTwdSnapshot": 0,
"returnedQuantity": 0
}
],
"rentTotalTwd": 0,
"depositTotalTwd": 0
}
]
}open a rental ticket
/api/v1/equipment/rentals參數
orderId必填租借單綁定的訂單 ID(租金與押金會掛入該訂單金流)
departureId選填關聯的梯次 ID(選填)
renterName選填租借人姓名(選填)
rentStartDate選填租借起始日,格式 YYYY-MM-DD(選填)
rentEndDate選填租借結束日,格式 YYYY-MM-DD(選填)
notes選填租借單備註(選填)
lines必填租借明細清單(至少一筆品項)
回應欄位 · data
rentalId新開立的租借單 id。
curl -X POST https://your-tenant.example.com/api/v1/equipment/rentals \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orderId": "<orderId>",
"lines": []
}'{
"ok": true,
"data": {
"rentalId": "…"
}
}single rental ticket detail
/api/v1/equipment/rentals/{id}參數
id路徑租借單 ID
回應欄位 · data
id租借單 id(equipmentRental_ 前綴)。
orderId掛載的訂單 id。
orderNumber訂單編號(JOIN;可空)。
departureId綁定的梯次 id(可不綁梯次時 null)。
departureLabel梯次可讀標籤:團號 ‧ 行程名 ‧ 出發日(無綁梯次時 null)。
renterName租借人姓名(可空)。
rentStartDate租期起日(YYYY-MM-DD;可空)。
rentEndDate租期迄日(YYYY-MM-DD;可空)。
returnedAt歸還驗收時間(尚未歸還為 null)。
returnState歸還狀態:rented 租借中/returned 已歸還/overdue 逾期。
inspectedAt驗收時間(尚未驗收為 null)。
damageCostTwd破損/遺失賠償金額(TWD;無為 null)。
reconState對款狀態:pending 待對款/reconciled 已結清/deposit_pending 押金待退或待扣。
notes備註(可空)。
createdAt建單時間。
updatedAt最後更新時間。
lines租借明細(借出的品項清單)。
id租借明細 id(equipmentRentalLine_ 前綴)。
equipmentItemId借出的裝備主檔品項 id。
itemName主檔品名快照(JOIN,便利顯示;改主檔不回寫單)。
quantity借出數量。
rentPriceTwdSnapshot成交單位總價快照(每日單價 × 計價日數;TWD)。
depositTwdSnapshot成交每件押金快照(TWD,不乘天數)。
returnedQuantity已歸還數量(尚未歸還為 null)。
rentTotalTwd成交租金合計(Σ rent snapshot × qty)。
depositTotalTwd成交押金合計(Σ deposit snapshot × qty)。
curl -X GET https://your-tenant.example.com/api/v1/equipment/rentals/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"orderId": "…",
"orderNumber": "…",
"departureId": "…",
"departureLabel": "…",
"renterName": "…",
"rentStartDate": "…",
"rentEndDate": "…",
"returnedAt": null,
"returnState": "…",
"inspectedAt": null,
"damageCostTwd": 0,
"reconState": "…",
"notes": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z",
"lines": [
{
"id": "…",
"equipmentItemId": "…",
"itemName": "…",
"quantity": 0,
"rentPriceTwdSnapshot": 0,
"depositTwdSnapshot": 0,
"returnedQuantity": 0
}
],
"rentTotalTwd": 0,
"depositTotalTwd": 0
}
}flag a single rented ticket
/api/v1/equipment/rentals/{id}/mark-overdue參數
id路徑要標記為逾期的租借單 ID
回應欄位 · data
ok標記逾期成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/equipment/rentals/<id>/mark-overdue \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}receive a rental back
/api/v1/equipment/rentals/{id}/return參數
id路徑要驗收歸還的租借單 ID
returnedLines必填各明細的歸還數量清單
damageCostTwd選填損壞賠償金額(台幣,選填)
回應欄位 · data
ok驗收歸還成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/equipment/rentals/<id>/return \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"returnedLines": []
}'{
"ok": true,
"data": {
"ok": true
}
}the minimal order picker
/api/v1/equipment/rentals/order-options參數
limit選填回傳訂單筆數上限(最多 200,預設取最近多筆)
回應欄位 · data[]
orderId訂單 id。
orderNumber訂單編號(可空)。
customerName訂購人姓名(可空)。
curl -X GET https://your-tenant.example.com/api/v1/equipment/rentals/order-options \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"orderId": "…",
"orderNumber": "…",
"customerName": "…"
}
]
}/guide-roster
指派 / 重派 guide 到梯次
/api/v1/guide-roster/assignments參數
departureId必填指派的目標梯次 ID
guideId必填被指派的領隊/嚮導 ID
role必填指派角色(leader 領隊/assistant 隨隊助理)
status必填指派狀態(tentative 預塞暫定/confirmed 正式確認)
回應欄位 · data
id新建立(或重派後)的指派紀錄 id。
curl -X POST https://your-tenant.example.com/api/v1/guide-roster/assignments \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"departureId": "<departureId>",
"guideId": "<guideId>",
"role": "<role>",
"status": "<status>"
}'{
"ok": true,
"data": {
"id": "…"
}
}移除某筆指派
/api/v1/guide-roster/assignments/{id}參數
id路徑要移除的指派紀錄 ID
回應欄位 · data
ok移除成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/guide-roster/assignments/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}正式確認某筆指派
/api/v1/guide-roster/assignments/{id}/confirm參數
id路徑要正式確認的指派紀錄 ID
回應欄位 · data
ok確認成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/guide-roster/assignments/<id>/confirm \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}換領隊
/api/v1/guide-roster/change-leader參數
departureId必填要換領隊的目標梯次 ID
fromGuideId選填原領隊嚮導 ID(選填;省略表示該梯次原本無領隊)
toGuideId必填新任領隊嚮導 ID
reason必填換領隊的原因(必填,記入稽核)
回應欄位 · data
id新任領隊的指派紀錄 id。
removedGuideIds被移除的舊領隊嚮導 id 清單(DB 權威)。
curl -X POST https://your-tenant.example.com/api/v1/guide-roster/change-leader \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"departureId": "<departureId>",
"toGuideId": "<toGuideId>",
"reason": "<reason>"
}'{
"ok": true,
"data": {
"id": "…",
"removedGuideIds": [
"…"
]
}
}pre-check whether assigning a guide
/api/v1/guide-roster/conflict-check參數
departureId必填欲指派的目標梯次 ID
guideId必填欲檢查檔期衝突的領隊/嚮導 ID
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/conflict-check?departureId=<departureId>&guideId=<guideId>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": null
}schedule conflicts for the selected
/api/v1/guide-roster/conflicts參數
month必填查詢月份(YYYY-MM 格式)
回應欄位 · data[]
guideId發生衝突的嚮導 id。
guideName發生衝突的嚮導姓名。
a衝突梯次之一(含梯次 id/行程名/起訖日)。
departureId梯次 id。
tripTitle行程名稱。
departureDate出發日(YYYY-MM-DD)。
returnDate回程日(YYYY-MM-DD)。
b與 a 日期重疊的另一梯次(含梯次 id/行程名/起訖日)。
departureId梯次 id。
tripTitle行程名稱。
departureDate出發日(YYYY-MM-DD)。
returnDate回程日(YYYY-MM-DD)。
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/conflicts?month=<month>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"guideId": "…",
"guideName": "…",
"a": {
"departureId": "…",
"tripTitle": "…",
"departureDate": "…",
"returnDate": "…"
},
"b": {
"departureId": "…",
"tripTitle": "…",
"departureDate": "…",
"returnDate": "…"
}
}
]
}the selected month's departures
/api/v1/guide-roster/departures參數
month必填查詢月份(YYYY-MM 格式)
includeCancelled選填是否一併納入已取消的梯次(預設不納入)
回應欄位 · data[]
id梯次 id。
tripId所屬行程 id。
tripTitle行程名稱。
departureDate出發日(YYYY-MM-DD)。
returnDate回程日(YYYY-MM-DD)。
days帶團天數(含頭尾)。
capacity團位容量(總名額)。
bookedCount已成團報名人數。
status梯次狀態(如 open 開放/full 已滿/cancelled 已取消)。
assignments該梯次所有指派(領隊在前)。
id指派紀錄 id。
guideId被指派的嚮導 id。
guideName被指派的嚮導姓名。
role指派角色:leader 領隊/assistant 隨隊助理。
status指派狀態:tentative 預塞暫定/confirmed 正式確認。
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/departures?month=<month>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"tripId": "…",
"tripTitle": "…",
"departureDate": "…",
"returnDate": "…",
"days": 0,
"capacity": 0,
"bookedCount": 0,
"status": "…",
"assignments": [
{
"id": "…",
"guideId": "…",
"guideName": "…",
"role": "leader",
"status": "tentative"
}
]
}
]
}roster
/api/v1/guide-roster/guides參數
month必填查詢月份(YYYY-MM 格式)
includeInactive選填是否一併列出已停用的嚮導(預設不列出)
回應欄位 · data[]
id嚮導 id。
name嚮導姓名。
rosterRole名冊職能:leader 領隊/assistant 隨隊助理/both 皆可。
specialties可帶路線 / 專長;未設為空陣列。
status嚮導狀態:active 啟用/inactive 停用。
maxDaysPerMonth單月可帶上限(天);NULL = 不限。
monthDays本月 confirmed 指派的帶團天數彙總。
monthTrips本月 confirmed 帶團梯次數。
hasTentative本月是否含 tentative(預塞)指派。
availability派生載量狀態。
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/guides?month=<month>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"name": "…",
"rosterRole": "leader",
"specialties": [
"…"
],
"status": "…",
"maxDaysPerMonth": 0,
"monthDays": 0,
"monthTrips": 0,
"hasTentative": true,
"availability": "…"
}
]
}/guides
list/search guides
/api/v1/guides參數
slug選填依嚮導公開頁網址代稱(slug)精確查單筆(選填)
status選填allactiveinactive嚮導狀態篩選(all 全部/active 啟用/inactive 停用)
q選填關鍵字搜尋(比對嚮導姓名等欄位)
page選填頁碼(從 1 起算)
pageSize選填每頁筆數(上限 200)
curl -X GET https://your-tenant.example.com/api/v1/guides \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": "…"
}create a guide
/api/v1/guides參數
name必填嚮導/領隊姓名
slug選填公開頁網址代稱(選填,小寫英數與連字號;省略則自動產生)
bio選填嚮導簡介/經歷(選填)
avatarUrl選填大頭照圖片網址(選填,http/https)
specialties選填專長領域(選填,以逗號分隔多項)
yearsExperience選填帶團年資(年數,0~80;選填)
contactPhone選填聯絡電話(選填)
contactEmail選填聯絡 Email(選填)
status選填activeinactive嚮導狀態(active 啟用/inactive 停用;預設 active)
回應欄位 · data
id新建立的嚮導 id。
slug嚮導公開頁網址代稱(未帶則系統自動產生)。
curl -X POST https://your-tenant.example.com/api/v1/guides \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"id": "…",
"slug": "…"
}
}single guide detail
/api/v1/guides/{id}參數
id路徑嚮導 ID
回應欄位 · data
id嚮導 id(guide_ 前綴)。
name嚮導/領隊姓名。
slug公開頁網址代稱(slug;小寫英數與連字號)。
bio簡介/經歷(可空)。
avatarUrl大頭照圖片網址(可空)。
specialties專長領域清單。
yearsExperience帶團年資(年數;可空)。
contactPhone聯絡電話(可空)。
contactEmail聯絡 Email(可空)。
status嚮導狀態:active 啟用/inactive 停用。
engagementType僱用型態:full_time 正式/partner 協作/external 外聘。
createdAt建檔時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/guides/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"name": "…",
"slug": "…",
"bio": "…",
"avatarUrl": "…",
"specialties": [
"…"
],
"yearsExperience": 0,
"contactPhone": "…",
"contactEmail": "…",
"status": "…",
"engagementType": "external",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}update a guide
/api/v1/guides/{id}參數
id路徑要更新的嚮導 ID
name選填嚮導/領隊姓名(省略則不更動)
slug選填公開頁網址代稱(小寫英數與連字號;省略則不更動)
bio選填嚮導簡介/經歷(省略則不更動)
avatarUrl選填大頭照圖片網址(http/https;省略則不更動)
specialties選填專長領域(以逗號分隔多項;省略則不更動)
yearsExperience選填帶團年資(年數,0~80;省略則不更動)
contactPhone選填聯絡電話(省略則不更動)
contactEmail選填聯絡 Email(省略則不更動)
status選填activeinactive嚮導狀態(active 啟用/inactive 停用;省略則不更動)
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/guides/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}archive a guide
/api/v1/guides/{id}/archive參數
id路徑要封存(狀態改為停用)的嚮導 ID
回應欄位 · data
ok封存成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/guides/<id>/archive \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}開通某既有 guide 的嚮導 portal 登入帳號
/api/v1/guides/{id}/invite-account參數
id路徑要開通登入帳號的嚮導 ID
email必填嚮導 portal 登入帳號的 Email
name必填嚮導帳號的顯示姓名
回應欄位 · data
tempPassword一次性明文暫時密碼(僅此次回傳,請立即轉交嚮導並要求首次登入改密)。
email已開通登入帳號的 Email。
curl -X POST https://your-tenant.example.com/api/v1/guides/<id>/invite-account \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "<email>",
"name": "<name>"
}'{
"ok": true,
"data": {
"tempPassword": "…",
"email": "…"
}
}/journal
list/search 嚮導手記 posts
/api/v1/journal參數
status選填alldraftpublishedarchived依狀態篩選:all 全部、draft 草稿、published 已發佈、archived 已封存
q選填關鍵字搜尋(標題/內容)
page選填頁碼(從 1 起)
pageSize選填每頁筆數(上限 200)
回應欄位 · data
rows本頁的手記文章列表。
id手記文章 id(journalPost_ 前綴)。
slug文章公開頁網址代稱(slug)。
title文章標題。
excerpt摘要(列表/SEO 用;可空)。
coverImageUrl封面圖網址(可空)。
contentMdx內文原始 MDX 內容。
authorGuideId作者嚮導 id(未指定作者時 null)。
seoTitleSEO 標題(覆寫 <title>;可空)。
seoDescriptionSEO 描述(meta description;可空)。
ogImageUrlOpen Graph 分享圖網址(可空)。
status文章狀態:draft 草稿/published 已發佈/archived 已封存。
publishedAt首次發佈時間(尚未發佈為 null)。
createdAt建檔時間。
updatedAt最後更新時間。
total符合條件的文章總數(跨頁)。
page目前頁碼(從 1 起)。
pageSize每頁筆數。
curl -X GET https://your-tenant.example.com/api/v1/journal \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"slug": "…",
"title": "…",
"excerpt": "…",
"coverImageUrl": "…",
"contentMdx": "…",
"authorGuideId": "…",
"seoTitle": "…",
"seoDescription": "…",
"ogImageUrl": "…",
"status": "…",
"publishedAt": null,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
],
"total": 0,
"page": 0,
"pageSize": 0
}
}create a 嚮導手記 post
/api/v1/journal參數
title必填手記標題,顯示於前台與後台列表
slug選填網址代稱(slug);僅小寫英數與連字號,省略時由系統依標題產生
excerpt選填摘要,列表與分享預覽用;null 清除
coverImageUrl選填封面圖網址(http/https);null 清除
contentMdx必填內文(MDX 格式)
authorGuideId選填作者嚮導 ID;null 表示無指定作者
seoTitle選填SEO 標題,省略時用 title;null 清除
seoDescription選填SEO 描述(meta description);null 清除
ogImageUrl選填Open Graph 分享圖網址(http/https);null 清除
status選填draftpublishedarchived發佈狀態:draft 草稿、published 已發佈、archived 已封存
回應欄位 · data
id新建立的手記文章 id。
slug文章公開頁網址代稱(slug)。
curl -X POST https://your-tenant.example.com/api/v1/journal \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "<title>",
"contentMdx": "<contentMdx>"
}'{
"ok": true,
"data": {
"id": "…",
"slug": "…"
}
}full 嚮導手記 post detail
/api/v1/journal/{id}參數
id路徑嚮導手記文章 ID
回應欄位 · data
id手記文章 id(journalPost_ 前綴)。
slug文章公開頁網址代稱(slug)。
title文章標題。
excerpt摘要(列表/SEO 用;可空)。
coverImageUrl封面圖網址(可空)。
contentMdx內文原始 MDX 內容。
authorGuideId作者嚮導 id(未指定作者時 null)。
seoTitleSEO 標題(覆寫 <title>;可空)。
seoDescriptionSEO 描述(meta description;可空)。
ogImageUrlOpen Graph 分享圖網址(可空)。
status文章狀態:draft 草稿/published 已發佈/archived 已封存。
publishedAt首次發佈時間(尚未發佈為 null)。
createdAt建檔時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/journal/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"slug": "…",
"title": "…",
"excerpt": "…",
"coverImageUrl": "…",
"contentMdx": "…",
"authorGuideId": "…",
"seoTitle": "…",
"seoDescription": "…",
"ogImageUrl": "…",
"status": "…",
"publishedAt": null,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}update a 嚮導手記 post
/api/v1/journal/{id}參數
title必填手記標題,顯示於前台與後台列表
slug選填網址代稱(slug);僅小寫英數與連字號,省略時由系統依標題產生
excerpt選填摘要,列表與分享預覽用;null 清除
coverImageUrl選填封面圖網址(http/https);null 清除
contentMdx必填內文(MDX 格式)
authorGuideId選填作者嚮導 ID;null 表示無指定作者
seoTitle選填SEO 標題,省略時用 title;null 清除
seoDescription選填SEO 描述(meta description);null 清除
ogImageUrl選填Open Graph 分享圖網址(http/https);null 清除
status選填draftpublishedarchived發佈狀態:draft 草稿、published 已發佈、archived 已封存
id路徑嚮導手記文章 ID
回應欄位 · data
ok更新成功旗標,恆為 true。
curl -X PATCH https://your-tenant.example.com/api/v1/journal/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "<title>",
"contentMdx": "<contentMdx>"
}'{
"ok": true,
"data": {
"ok": true
}
}archive a 嚮導手記 post
/api/v1/journal/{id}/archive參數
id路徑嚮導手記文章 ID
回應欄位 · data
ok封存成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/journal/<id>/archive \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}/rooms
指派旅客進房
/api/v1/rooms/{roomId}/travelers參數
roomId路徑目標房間 ID,旅客將被指派入住此房
travelerId必填欲指派的旅客 ID,須與房間屬於同一梯次
回應欄位 · data
ok指派入房成功旗標,恆為 true。
curl -X POST https://your-tenant.example.com/api/v1/rooms/<roomId>/travelers \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"travelerId": "<travelerId>"
}'{
"ok": true,
"data": {
"ok": true
}
}把旅客移出房間
/api/v1/rooms/travelers/{travelerId}參數
travelerId路徑欲移出房間的旅客 ID
回應欄位 · data
ok移出房間成功旗標,恆為 true。
curl -X DELETE https://your-tenant.example.com/api/v1/rooms/travelers/<travelerId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}/exchange-rates
list the Bank-of-Taiwan published FX rate board
/api/v1/exchange-rates參數
currency選填幣別篩選(ISO 4217 三碼,如 JPY / USD);省略則回傳所有幣別
monthFrom選填起始月份(YYYY-MM,含當月);省略則不設下界
monthTo選填結束月份(YYYY-MM,含當月);省略則不設上界
回應欄位 · data[]
id匯率牌價列 ID。
rateDate掛牌日期('YYYY-MM-DD',Asia/Taipei)。
currencyISO 4217('JPY' / 'IDR' / 'USD'…)。
cashBuy各報價 canonical「1 外幣 = ? 台幣」(numeric → 字串原值保精度;NULL = 該幣別無此報價)。
cashSell現金賣出匯率「1 外幣 = ? 台幣」(字串保精度;null = 無此報價)。
spotBuy即期買入匯率「1 外幣 = ? 台幣」(字串保精度;null = 無此報價)。
spotSell即期賣出匯率「1 外幣 = ? 台幣」(字串保精度;null = 無此報價)。
source牌價來源:bot 台銀自動抓取 / manual 租戶手動覆蓋。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/exchange-rates \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"rateDate": "…",
"currency": "…",
"cashBuy": "…",
"cashSell": "…",
"spotBuy": "…",
"spotSell": "…",
"source": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}manual FX rate override
/api/v1/exchange-rates/manual參數
rateDate必填匯率掛牌日期(YYYY-MM-DD),與幣別共同決定覆蓋哪一筆牌價
currency必填幣別(ISO 4217 三碼大寫,如 JPY / USD)
cashBuy選填現金買入匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null
cashSell選填現金賣出匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null
spotBuy選填即期買入匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null
spotSell選填即期賣出匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null
回應欄位 · data
ok是否覆蓋寫入成功。
id寫入 / 更新的 manual 匯率牌價列 ID。
curl -X PUT https://your-tenant.example.com/api/v1/exchange-rates/manual \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rateDate": "<rateDate>",
"currency": "<currency>"
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}resolve the canonical "1 foreign unit =
/api/v1/exchange-rates/resolve參數
currency必填要換算的外幣幣別(ISO 4217 三碼,如 JPY / USD)
date必填換算基準日期(YYYY-MM-DD),套用手動優先 + 往前承接的解析規則
quote選填cash_buycash_sellspot_buyspot_sell報價類型:cash_buy 現金買入、cash_sell 現金賣出、spot_buy 即期買入、spot_sell 即期賣出;省略預設 spot_sell
回應欄位 · data
currency換算的外幣幣別(ISO 4217 三碼)。
date換算基準日期(YYYY-MM-DD)。
quote使用的報價類型(cash_buy / cash_sell / spot_buy / spot_sell)。
rate解析出的匯率「1 外幣 = ? 台幣」(字串保精度);查無適用牌價為 null。
curl -X GET "https://your-tenant.example.com/api/v1/exchange-rates/resolve?currency=<currency>&date=<date>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"currency": "…",
"date": "…",
"quote": "cash_buy",
"rate": "…"
}
}/payment-requests
list/search/filter 對外應付
/api/v1/payment-requests參數
status選填draftsubmittedapprovedpaidrejectedcancelledall依狀態篩選(draft 草稿 / submitted 已送審 / approved 已核准 / paid 已付款 / rejected 已退件 / cancelled 已取消 / all 全部)
payeeType選填supplierguidestaff_commissionotherall依收款對象類型篩選(supplier 供應商 / guide 領隊嚮導 / staff_commission 員工獎金 / other 其他 / all 全部)
departureId選填依關聯梯次 id 篩選
createdByUserId選填依建單人 user id 篩選
q選填關鍵字搜尋(請款單號、收款對象名稱等)
page選填頁碼(從 1 起算)
pageSize選填每頁筆數(上限 200)
回應欄位 · data
rows本頁請款單列。
id請款單 ID。
requestNumber請款單號(人可讀,每租戶流水號)。
status核簽工作流狀態:draft / submitted / approved / paid / rejected / cancelled。
payeeType收款對象類型:supplier 供應商 / guide 領隊嚮導 / staff_commission 員工獎金 / other 其他。
payeeName收款對象名稱。
amountTwd請款總額(TWD 整數;= 細項小計合計,代扣稅前)。
netAmountTwd實付淨額(TWD 整數;= 請款總額 − 代扣稅額,即實際匯款金額)。
taxAmountTwd代扣稅額(TWD 整數)。
departureId關聯梯次 ID;未歸屬特定出團為 null。
departureLabel關聯梯次顯示標籤(行程名稱+出發日);無則為 null。
description請款單摘要說明。
createdAt建立時間。
updatedAt最後更新時間。
createdByUserId建單人 user ID。
createdByName建單人姓名;查無為 null。
paidAt標記付款完成時間;未付為 null。
submittedAt送審時間;未送審為 null。
approvedAt核准時間;未核准為 null。
total符合篩選條件的總筆數(跨全部分頁)。
page目前頁碼(從 1 起算)。
pageSize每頁筆數。
curl -X GET https://your-tenant.example.com/api/v1/payment-requests \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"requestNumber": "…",
"status": "…",
"payeeType": "…",
"payeeName": "…",
"amountTwd": 0,
"netAmountTwd": 0,
"taxAmountTwd": 0,
"departureId": "…",
"departureLabel": "…",
"description": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z",
"createdByUserId": "…",
"createdByName": "…",
"paidAt": null,
"submittedAt": null,
"approvedAt": null
}
],
"total": 0,
"page": 0,
"pageSize": 0
}
}/api/v1/payment-requests參數
payeeType必填supplierguidestaff_commissionother收款對象類型(supplier 供應商 / guide 領隊嚮導 / staff_commission 員工獎金 / other 其他)
payeeName必填收款對象名稱
payeeBankAccount選填收款銀行帳號
payeeBankName選填收款銀行名稱
payeeBankBranch選填收款銀行分行
payeeTaxId選填收款對象統一編號 / 稅籍編號
departureId選填關聯梯次 id(將此請款歸屬至特定出團)
description必填請款單摘要說明
taxAmountTwd選填稅額(TWD),未填視為 0
items必填請款細項陣列(至少一筆)
submitImmediately選填是否建立後立即送審(true 則同交易送出,跳過草稿)
回應欄位 · data
id新建立請款單的 id。
requestNumber新建立請款單的單號(人可讀)。
status建立後狀態(draft,或 submitImmediately 時為 submitted)。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"payeeType": "supplier",
"payeeName": "<payeeName>",
"description": "<description>",
"items": []
}'{
"ok": true,
"data": {
"id": "…",
"requestNumber": "…",
"status": "…"
}
}單一對外應付請款單完整明細
/api/v1/payment-requests/{id}參數
id路徑請款單 id(路徑參數)
回應欄位 · data
payeeBankAccount收款銀行帳號。
payeeBankName收款銀行名稱。
payeeBankBranch收款銀行分行。
payeeTaxId收款對象統一編號 / 稅籍編號。
submittedByUserId送審人 user ID;未送審為 null。
submittedByName送審人姓名;無則為 null。
approvedByUserId核准人 user ID;未核准為 null。
approvedByName核准人姓名;無則為 null。
paidByUserId標記付款人 user ID;未付為 null。
paidByName標記付款人姓名;無則為 null。
rejectedAt退件時間;未退件為 null。
rejectedByName退件人姓名;無則為 null。
rejectionReason退件原因;無則為 null。
cancelledAt取消時間;未取消為 null。
cancelledByName取消人姓名;無則為 null。
cancellationReason取消原因;無則為 null。
pdfGeneratedAt請款單 PDF 產生時間;未產生為 null。
paperPrintedAt紙本列印時間;未列印為 null。
paperSignedBy紙本簽核人;未簽為 null。
bankReference銀行匯款交易參考號(付款後回填);無則為 null。
items請款細項清單。
id請款細項 ID。
category細項類別(如住宿、交通、餐食)。
description細項說明。
quantity數量。
unitPriceTwd單價(TWD 整數;負值表折讓)。
totalTwd細項小計(TWD 整數;= 數量 × 單價)。
notes細項備註;無則為 null。
sortOrder顯示排序(由小到大)。
audit稽核軌跡(狀態機每次轉移一筆,時間新到舊或建立序)。
id稽核記錄 ID。
action動作代號(如 payable.create、payable.submit、payable.approve)。
createdAt動作發生時間。
actorUserId操作者 user ID;系統動作為 null。
actorName操作者姓名;無則為 null。
metadata動作附帶的結構化資料(欄位隨 action 而定)。
ipAddress操作來源 IP;無則為 null。
id請款單 ID。
requestNumber請款單號(人可讀,每租戶流水號)。
status核簽工作流狀態:draft / submitted / approved / paid / rejected / cancelled。
payeeType收款對象類型:supplier 供應商 / guide 領隊嚮導 / staff_commission 員工獎金 / other 其他。
payeeName收款對象名稱。
amountTwd請款總額(TWD 整數;= 細項小計合計,代扣稅前)。
netAmountTwd實付淨額(TWD 整數;= 請款總額 − 代扣稅額,即實際匯款金額)。
taxAmountTwd代扣稅額(TWD 整數)。
departureId關聯梯次 ID;未歸屬特定出團為 null。
departureLabel關聯梯次顯示標籤(行程名稱+出發日);無則為 null。
description請款單摘要說明。
createdAt建立時間。
updatedAt最後更新時間。
createdByUserId建單人 user ID。
createdByName建單人姓名;查無為 null。
paidAt標記付款完成時間;未付為 null。
submittedAt送審時間;未送審為 null。
approvedAt核准時間;未核准為 null。
curl -X GET https://your-tenant.example.com/api/v1/payment-requests/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"payeeBankAccount": "…",
"payeeBankName": "…",
"payeeBankBranch": "…",
"payeeTaxId": "…",
"submittedByUserId": "…",
"submittedByName": "…",
"approvedByUserId": "…",
"approvedByName": "…",
"paidByUserId": "…",
"paidByName": "…",
"rejectedAt": null,
"rejectedByName": "…",
"rejectionReason": "…",
"cancelledAt": null,
"cancelledByName": "…",
"cancellationReason": "…",
"pdfGeneratedAt": null,
"paperPrintedAt": null,
"paperSignedBy": "…",
"bankReference": "…",
"items": [
{
"id": "…",
"category": "…",
"description": "…",
"quantity": 0,
"unitPriceTwd": 0,
"totalTwd": 0,
"notes": "…",
"sortOrder": 0
}
],
"audit": [
{
"id": "…",
"action": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"actorUserId": "…",
"actorName": "…",
"metadata": "…",
"ipAddress": "…"
}
],
"id": "…",
"requestNumber": "…",
"status": "…",
"payeeType": "…",
"payeeName": "…",
"amountTwd": 0,
"netAmountTwd": 0,
"taxAmountTwd": 0,
"departureId": "…",
"departureLabel": "…",
"description": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z",
"createdByUserId": "…",
"createdByName": "…",
"paidAt": null,
"submittedAt": null,
"approvedAt": null
}
}核可請款單
/api/v1/payment-requests/{id}/approve參數
id路徑請款單 id(路徑參數)
回應欄位 · data
ok是否核可成功(submitted→approved)。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/approve \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}取消請款單
/api/v1/payment-requests/{id}/cancel參數
id路徑請款單 id(路徑參數)
reason選填取消原因;留空預設為「使用者取消」(上限 200 字)
回應欄位 · data
ok是否取消成功(idempotent,已取消再呼叫仍為 true)。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/cancel \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}標記請款單已付
/api/v1/payment-requests/{id}/mark-paid參數
id路徑請款單 id(路徑參數)
bankReference必填網銀交易序號 / 轉帳憑證號(必填)
paperSignedBy選填紙本簽核人姓名
receivingAccountId選填出款帳戶 id(從哪個收款帳戶付出)
回應欄位 · data
ok是否標記付款成功(approved→paid)。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/mark-paid \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bankReference": "<bankReference>"
}'{
"ok": true,
"data": {
"ok": true
}
}標記 PDF/紙本已產生
/api/v1/payment-requests/{id}/mark-printed參數
id路徑請款單 id(路徑參數)
回應欄位 · data
ok是否標記 PDF / 紙本已產生成功(idempotent)。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/mark-printed \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}記錄紙本簽核人
/api/v1/payment-requests/{id}/mark-signed參數
id路徑請款單 id(路徑參數)
signedBy必填紙本簽核人姓名(必填)
回應欄位 · data
ok是否記錄紙本簽核人成功。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/mark-signed \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"signedBy": "<signedBy>"
}'{
"ok": true,
"data": {
"ok": true
}
}退件請款單
/api/v1/payment-requests/{id}/reject參數
id路徑請款單 id(路徑參數)
reason必填退件原因(必填,回饋給建單人)
回應欄位 · data
ok是否退件成功(submitted→draft)。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/reject \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "<reason>"
}'{
"ok": true,
"data": {
"ok": true
}
}送審請款單
/api/v1/payment-requests/{id}/submit參數
id路徑請款單 id(路徑參數)
回應欄位 · data
ok是否送審成功(draft→submitted)。
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/submit \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}對外應付請款單 KPI 計數
/api/v1/payment-requests/stats回應欄位 · data
draftCount草稿狀態的請款單數。
submittedCount已送審待核准的請款單數。
approvedCount已核准待付款的請款單數。
paidCount已付款的請款單數。
thisMonthPaidCount本月已付款的請款單數。
thisMonthAmount本月已付款的實付淨額合計(TWD 整數;台北月起算)。
totalApprovedAmount已核准未付的實付淨額合計(TWD 整數;待出款金額)。
curl -X GET https://your-tenant.example.com/api/v1/payment-requests/stats \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"draftCount": 0,
"submittedCount": 0,
"approvedCount": 0,
"paidCount": 0,
"thisMonthPaidCount": 0,
"thisMonthAmount": 0,
"totalApprovedAmount": 0
}
}由某梯次的
/api/v1/payment-requests/supplier-suggestions參數
departureId必填梯次 id;用於推導該梯次住宿供應商的請款細項建議
回應欄位 · data[]
category建議的請款細項類別(如住宿)。
description建議的細項說明(住宿廠商 × 房型 × 晚數)。
quantity建議數量(間數 × 晚數)。
unitPriceTwd建議單價(TWD 整數;每間每晚成本)。
totalTwd建議小計(TWD 整數;= 數量 × 單價)。
suggestedPayee建議的收款對象(住宿供應商名稱);查無為 null。
curl -X GET "https://your-tenant.example.com/api/v1/payment-requests/supplier-suggestions?departureId=<departureId>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"category": "…",
"description": "…",
"quantity": 0,
"unitPriceTwd": 0,
"totalTwd": 0,
"suggestedPayee": "…"
}
]
}/payments
list/search/filter the customer→agency payment ledger
/api/v1/payments參數
status選填依金流狀態篩選(如 paid 已收款 / pending 待付 / failed 失敗 / refunded 已退款)
method選填依付款方式篩選(如信用卡、ATM 轉帳)
dateFrom選填收款日期區間起日(YYYY-MM-DD)
dateTo選填收款日期區間迄日(YYYY-MM-DD)
q選填關鍵字搜尋(訂單編號、客戶名稱等)
page選填頁碼(從 1 起算)
pageSize選填每頁筆數(上限 200)
回應欄位 · data
rows本頁付款嘗試列。
id付款嘗試(payment attempt)ID,此列的唯一識別。
orderId所屬訂單 ID。
orderNumber所屬訂單編號(人可讀)。
merchantTradeNoprovider_order_ref(= 我們產的 MerchantTradeNo)。
providerTradeNo金流商回傳的交易序號(未成交或手動入帳為 null)。
provider金流商代號(如 ecpay、test;手動入帳為 manual)。
paymentMethod付款方式(如信用卡、ATM 虛擬帳號)。
amountTwd此筆嘗試的金額(TWD 整數)。
statusattempt 狀態:pending | submitted | succeeded | failed | expired。
refunded此 attempt 是否關聯到任何退款 / 退單交易(out 方向)。
paidAt實際入帳(現金結算)時間;未結算為 null。
createdAt此筆付款嘗試的建立時間。
customerName付款客戶姓名。
customerEmail付款客戶 email。
tripTitle訂單對應的行程名稱。
total符合篩選條件的總筆數(跨全部分頁)。
page目前頁碼(從 1 起算)。
pageSize每頁筆數。
curl -X GET https://your-tenant.example.com/api/v1/payments \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"orderId": "…",
"orderNumber": "…",
"merchantTradeNo": "…",
"providerTradeNo": "…",
"provider": "…",
"paymentMethod": "…",
"amountTwd": 0,
"status": "…",
"refunded": true,
"paidAt": null,
"createdAt": "2026-06-30T08:00:00.000Z",
"customerName": "…",
"customerEmail": "…",
"tripTitle": "…"
}
],
"total": 0,
"page": 0,
"pageSize": 0
}
}匯出金流分類帳
/api/v1/payments/export參數
status選填依金流狀態篩選(如 paid 已收款 / pending 待付 / failed 失敗 / refunded 已退款)
method選填依付款方式篩選(如信用卡、ATM 轉帳)
dateFrom選填收款日期區間起日(YYYY-MM-DD)
dateTo選填收款日期區間迄日(YYYY-MM-DD)
q選填關鍵字搜尋(訂單編號、客戶名稱等)
回應欄位 · data
rows符合篩選條件的所有列(逐頁累積;達安全上限時截斷)。
id付款嘗試(payment attempt)ID,此列的唯一識別。
orderId所屬訂單 ID。
orderNumber所屬訂單編號(人可讀)。
merchantTradeNoprovider_order_ref(= 我們產的 MerchantTradeNo)。
providerTradeNo金流商回傳的交易序號(未成交或手動入帳為 null)。
provider金流商代號(如 ecpay、test;手動入帳為 manual)。
paymentMethod付款方式(如信用卡、ATM 虛擬帳號)。
amountTwd此筆嘗試的金額(TWD 整數)。
statusattempt 狀態:pending | submitted | succeeded | failed | expired。
refunded此 attempt 是否關聯到任何退款 / 退單交易(out 方向)。
paidAt實際入帳(現金結算)時間;未結算為 null。
createdAt此筆付款嘗試的建立時間。
customerName付款客戶姓名。
customerEmail付款客戶 email。
tripTitle訂單對應的行程名稱。
total符合篩選條件的總筆數。
truncated是否因達安全上限而截斷(true 表未回傳完整結果,呼叫端應提示)。
curl -X GET https://your-tenant.example.com/api/v1/payments/export \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"orderId": "…",
"orderNumber": "…",
"merchantTradeNo": "…",
"providerTradeNo": "…",
"provider": "…",
"paymentMethod": "…",
"amountTwd": 0,
"status": "…",
"refunded": true,
"paidAt": null,
"createdAt": "2026-06-30T08:00:00.000Z",
"customerName": "…",
"customerEmail": "…",
"tripTitle": "…"
}
],
"total": 0,
"truncated": true
}
}payment KPI counts
/api/v1/payments/stats回應欄位 · data
totalAmount累計實收現金(payment_transactions in)。
paidCount已成功收款的付款嘗試數。
pendingCount待付 / 處理中的付款嘗試數(pending、submitted)。
failedCount失敗或逾期的付款嘗試數(failed、expired)。
refundedCount有關聯退款 / 退單的付款嘗試數。
thisMonthAmount本月累計實收現金(TWD 整數)。
curl -X GET https://your-tenant.example.com/api/v1/payments/stats \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"totalAmount": 0,
"paidCount": 0,
"pendingCount": 0,
"failedCount": 0,
"refundedCount": 0,
"thisMonthAmount": 0
}
}/reconciliation
逐收款帳戶現金進出對帳
/api/v1/reconciliation/accounts參數
dateFrom選填對帳期間起日(YYYY-MM-DD,含當日),以 Asia/Taipei 牆鐘日界計;省略則不設下界
dateTo選填對帳期間迄日(YYYY-MM-DD,含整日),以 Asia/Taipei 牆鐘日界計;省略則不設上界
回應欄位 · data[]
accountId收款帳戶 id;null = 未歸戶桶。
code帳戶代碼;未歸戶桶為 null。
displayName帳戶顯示名;未歸戶桶為 null。
kind帳戶類型(bank / cash / gateway);未歸戶桶為 null。
inTwd期間內 direction='in' 的金額合計。
outTwd期間內 payment_transactions direction='out' 的金額合計(客戶退款 / gateway 出)。
payableOutTwd期間內供應商出款合計(payables paid 的 net_amount_twd;非 order-scoped,獨立來源 §3.1)。
netTwd淨額 = in − out − payableOut(不扣手續費,純現金流向;對帳找銀行入帳用毛額)。
txCount期間內這帳戶的活動筆數(payment_transactions + payables paid)。
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/accounts \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"accountId": "…",
"code": "…",
"displayName": "…",
"kind": null,
"inTwd": 0,
"outTwd": 0,
"payableOutTwd": 0,
"netTwd": 0,
"txCount": 0
}
]
}未結掛帳追蹤
/api/v1/reconciliation/obligations參數
period選填月結來源期間(YYYY-MM),篩選由該期月結互抵推導出的掛帳;省略則不限期間
reason選填掛帳原因代碼,篩選特定成因的掛帳;省略則不限原因
status選填掛帳狀態(如未結清 / 已結清),篩選特定結清狀態;省略則含全部
回應欄位 · data[]
id帳戶間掛帳 ID。
debtorAccountId欠款方(債務人)收款帳戶 ID。
creditorAccountId收款方(債權人)收款帳戶 ID。
amountTwd應補目標總額(TWD 整數,恆正)。
settledAmountTwd已結清金額(TWD 整數,0 ≤ settled ≤ amount)。
outstandingTwd待結餘額(派生 = amount − settled,>= 0)。
reason掛帳成因:period_settlement 月結互抵 / advance_repayment 代墊償還 / refund_advance 退款代墊 / adjustment 手動調整。
originPeriod產生月份(YYYY-MM,Asia/Taipei)。
status結清狀態:outstanding 未結 / partially_settled 部分結清 / settled 已結清。
note備註;無則為 null。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/obligations \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"debtorAccountId": "…",
"creditorAccountId": "…",
"amountTwd": 0,
"settledAmountTwd": 0,
"outstandingTwd": 0,
"reason": "…",
"originPeriod": "…",
"status": "…",
"note": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}收款帳戶目錄清單
/api/v1/reconciliation/receiving-accounts參數
activeOnly選填是否只回傳啟用中的收款帳戶(true/false);省略則含停用
回應欄位 · data[]
id收款帳戶 ID。
code帳戶代碼(租戶內唯一穩定識別)。
displayName帳戶顯示名。
kind帳戶類型:bank 銀行 / cash 現金 / gateway 金流閘道。
bankName銀行名稱;現金/閘道帳戶為 null。
accountNo銀行帳號;現金/閘道帳戶為 null。
canReceive可收款(幾乎都 true)。
canRemit可對外匯款(ATM / 匯出退款 / 補款匯出)。荒野只有永豐。
canChargeback可刷退(退回原信用卡)。荒野只有綠界(gateway)。
isDeprecated廢帳戶:仍可零星收款,但其收款需由他帳戶代墊歸集。荒野=RU 台銀 / 登山社。
isSettlementMaster主結算帳戶:所有資金最終向它彙整。每租戶恰一個(partial unique index)。荒野=永豐。
currency帳戶幣別(ISO 4217;既有帳戶皆 'TWD',外幣帳戶如 IDR / USD)。
isActive此帳戶是否啟用。
displayOrder後台清單排序序位(小者在前)。
usedCount被多少 payment_transactions 引用(UI 鎖頭 / 「使用中 N」)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/receiving-accounts \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"code": "…",
"displayName": "…",
"kind": "…",
"bankName": "…",
"accountNo": "…",
"canReceive": true,
"canRemit": true,
"canChargeback": true,
"isDeprecated": true,
"isSettlementMaster": true,
"currency": "…",
"isActive": true,
"displayOrder": 0,
"usedCount": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}退款執行清單
/api/v1/reconciliation/refund-executions參數
status選填approvedpaid退款狀態篩選:approved 待執行(已核准)、paid 已執行(已出款);省略則合併回傳兩者
回應欄位 · data
rows退款執行列(合併 approved 待執行 + paid 已執行,或收斂為指定段)。
id退款單 ID。
refundNumber退款單號(人可讀,每租戶流水號)。
orderId所屬訂單 ID。
orderNumber所屬訂單編號(人可讀);無則為 null。
status退款工作流狀態:draft / submitted / approved / processing / paid / failed / cancelled。
refundKind退款種類:receivable_reduction 減應收退款(取消 / 降價 / 服務失敗)/ overpayment_return 溢收退還(不動應收,只退多收現金)。
affectsReceivable是否減少應收(receivable_reduction 為 true、overpayment_return 為 false;溢收退還不列入 refund_state)。
amountTwd退款金額(TWD 整數,正值)。
method退款方式:original_gateway 原路退刷 / bank_transfer 銀行匯款 / cash 現金 / manual 手動。
reason退款原因說明。
createdAt退款單建立時間。
paidAt實際退款出款(現金結算)時間;未執行為 null。
createdByName建單人姓名;無則為 null。
executionMethod退款執行方法:chargeback 原信用卡刷退 / remit 匯出;未指定為 null。
originAccountId出款來源帳戶 ID(從哪個收款帳戶退出);未指定為 null。
adminFeeTwd內扣手續費(TWD 整數;自退款金額中扣除的行政費)。
remitFeeTwd匯款手續費(TWD 整數;銀行匯出的轉帳費)。
payeeAccountName收款人戶名(匯款退款用);無則為 null。
payeeBankCode收款銀行代碼(匯款退款用);無則為 null。
payeeAccountNumber收款帳號(匯款退款用);無則為 null。
total回傳的退款執行筆數。
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/refund-executions \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"rows": [
{
"id": "…",
"refundNumber": "…",
"orderId": "…",
"orderNumber": "…",
"status": "…",
"refundKind": "…",
"affectsReceivable": true,
"amountTwd": 0,
"method": "…",
"reason": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"paidAt": null,
"createdByName": "…",
"executionMethod": null,
"originAccountId": "…",
"adminFeeTwd": 0,
"remitFeeTwd": 0,
"payeeAccountName": "…",
"payeeBankCode": "…",
"payeeAccountNumber": "…"
}
],
"total": 0
}
}子系統 B 月結互抵派生總覽
/api/v1/reconciliation/settlement-overview參數
period必填要查詢月結互抵總覽的結算期(YYYY-MM)
回應欄位 · data
period結算月份(YYYY-MM,Asia/Taipei)。
matrix兩層互抵矩陣(各帳戶對主結算帳戶的有向淨額 + 未分類彙總)。
lines各帳戶對主結算帳戶(或其類別 final)的有向淨額;恆正、方向由 debtor/creditor。
unclassified未分類(未標費用類型)收款彙總,不進互抵,供 UI 提示補 tag。
obligations本期相關掛帳(period_settlement,含結清進度)。
id帳戶間掛帳 ID。
debtorAccountId欠款方(債務人)收款帳戶 ID。
creditorAccountId收款方(債權人)收款帳戶 ID。
amountTwd應補目標總額(TWD 整數,恆正)。
settledAmountTwd已結清金額(TWD 整數,0 ≤ settled ≤ amount)。
outstandingTwd待結餘額(派生 = amount − settled,>= 0)。
reason掛帳成因:period_settlement 月結互抵 / advance_repayment 代墊償還 / refund_advance 退款代墊 / adjustment 手動調整。
originPeriod產生月份(YYYY-MM,Asia/Taipei)。
status結清狀態:outstanding 未結 / partially_settled 部分結清 / settled 已結清。
note備註;無則為 null。
createdAt建立時間。
updatedAt最後更新時間。
carriedForward跨期掛帳結轉基數(上期未結 period_settlement 殘額,已種入 matrix 淨額;此處供顯示明細 + 小計)。
lines上期未結 period_settlement 殘額逐筆明細(已種入本期互抵基數)。
totalTwd結轉殘額小計(TWD 整數)。
curl -X GET "https://your-tenant.example.com/api/v1/reconciliation/settlement-overview?period=<period>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"period": "…",
"matrix": {
"lines": [],
"unclassified": "…"
},
"obligations": [
{
"id": "…",
"debtorAccountId": "…",
"creditorAccountId": "…",
"amountTwd": 0,
"settledAmountTwd": 0,
"outstandingTwd": 0,
"reason": "…",
"originPeriod": "…",
"status": "…",
"note": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
],
"carriedForward": {
"lines": [],
"totalTwd": 0
}
}
}跑當期月結互抵派生 + upsert
/api/v1/reconciliation/settlement/compute參數
period必填要計算月結互抵的結算期(YYYY-MM),可重跑且冪等(不回退已結額)
回應欄位 · data
period結算月份(YYYY-MM,Asia/Taipei)。
matrix兩層互抵矩陣(各帳戶對主結算帳戶的有向淨額 + 未分類彙總)。
lines各帳戶對主結算帳戶(或其類別 final)的有向淨額;恆正、方向由 debtor/creditor。
unclassified未分類(未標費用類型)收款彙總,不進互抵,供 UI 提示補 tag。
upserts本次 run 對每條互抵列 upsert 的結果(含冪等護欄調整)。
debtorAccountId欠款方(債務人)收款帳戶 ID。
creditorAccountId收款方(債權人)收款帳戶 ID。
derivedAmountTwd本次派生的目標淨額。
appliedAmountTwd實際落地的掛帳 amount_twd(受冪等護欄約束,不低於已 settled)。
obligationId對應的帳戶間掛帳 ID(本次 upsert 的目標列)。
action本次動作:created 新建 / updated 更新 / floored_to_settled 派生低於已結被護欄下限鎖住。
adjustmentTwd派生目標低於已結額、被 floor 時的差額(保留為 adjustment 線索;> 0 表示有缺口)。
adjustmentObligationIdfloor 缺口另記的 adjustment 掛帳 id(action='floored_to_settled' 時非 null)。
deletedObligationIds本次 run 刪除的失效派生掛帳 id(settled=0 且不在新派生)。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/settlement/compute \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"period": "<period>"
}'{
"ok": true,
"data": {
"period": "…",
"matrix": {
"lines": [],
"unclassified": "…"
},
"upserts": [
{
"debtorAccountId": "…",
"creditorAccountId": "…",
"derivedAmountTwd": 0,
"appliedAmountTwd": 0,
"obligationId": "…",
"action": "created",
"adjustmentTwd": 0,
"adjustmentObligationId": "…"
}
],
"deletedObligationIds": [
"…"
]
}
}/api/v1/reconciliation/statement-imports參數
account必填收款帳戶 ID,回傳該帳戶的對帳單批次 / 行 / 進度彙總
回應欄位 · data
imports該帳戶的對帳單批次清單(新到舊)。
id對帳單批次 ID。
periodStart批次期間起日('YYYY-MM-DD',含當日)。
periodEnd批次期間迄日('YYYY-MM-DD',含當日)。
filename匯入的檔名。
createdAt匯入時間。
lineCount批內總行數。
autoCount自動配對的行數。
manualCount人工配對的行數。
unmatchedCount尚未配對的行數。
ignoredCount已略過(ignored)的行數。
excludedCount已解除配對(excluded)的行數。
lines該帳戶所有對帳單行(跨批次)。
id對帳單行 ID。
importId所屬對帳單批次 ID。
lineNo檔案內行號(1 起算)。
txnDate交易日期('YYYY-MM-DD')。
direction現金流向:in 存入 / out 支出。
amountTwd金額(TWD 整數)。
memo摘要 / 備註文字。
status配對狀態:unmatched 未配 / auto 自動 / manual 人工 / ignored 略過 / excluded 已解除。
matchedSourceType已配對來源種類(payment_transaction / payable / account_transfer);未配為 null。
matchedSourceId已配對來源 ID;未配為 null。
ignoredReason略過原因;非 ignored 為 null。
progress配對進度彙總。
total總行數。
matched已配對行數(auto + manual)。
unmatched未配對行數。
ignored已略過行數。
excluded已解除配對行數。
curl -X GET "https://your-tenant.example.com/api/v1/reconciliation/statement-imports?account=<account>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"imports": [
{
"id": "…",
"periodStart": "…",
"periodEnd": "…",
"filename": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"lineCount": 0,
"autoCount": 0,
"manualCount": 0,
"unmatchedCount": 0,
"ignoredCount": 0,
"excludedCount": 0
}
],
"lines": [
{
"id": "…",
"importId": "…",
"lineNo": 0,
"txnDate": "…",
"direction": "out",
"amountTwd": 0,
"memo": "…",
"status": "…",
"matchedSourceType": "…",
"matchedSourceId": "…",
"ignoredReason": "…"
}
],
"progress": {
"total": 0,
"matched": 0,
"unmatched": 0,
"ignored": 0,
"excluded": 0
}
}
}/api/v1/reconciliation/statement-imports參數
receivingAccountId必填收款帳戶 ID(僅支援 TWD 的 bank / cash 帳戶)
periodStart必填對帳單期間起日(含當日)
periodEnd必填對帳單期間迄日(含當日)
filename必填上傳檔名,副檔名須為 .xlsx 或 .csv
contentBase64必填對帳單檔案內容的 base64 編碼字串(固定範本填好後另存)
回應欄位 · data
importId新建立的對帳單批次 ID。
autoMatched匯入後即自動配對成功的行數。
unmatched匯入後仍未配對的行數。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/statement-imports \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"receivingAccountId": "<receivingAccountId>",
"periodStart": "<periodStart>",
"periodEnd": "<periodEnd>",
"filename": "<filename>",
"contentBase64": "<contentBase64>"
}'{
"ok": true,
"data": {
"importId": "…",
"autoMatched": 0,
"unmatched": 0
}
}刪整批
/api/v1/reconciliation/statement-imports/{importId}參數
importId路徑對帳單批次 ID
回應欄位 · data
ok是否刪除整批成功(批內無人工痕跡才可刪)。
curl -X DELETE https://your-tenant.example.com/api/v1/reconciliation/statement-imports/<importId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}對該批
/api/v1/reconciliation/statement-imports/{importId}/auto-match參數
importId路徑對帳單批次 ID
回應欄位 · data
matched本輪新增自動配對的行數。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/statement-imports/<importId>/auto-match \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"matched": 0
}
}某帳戶內、未被
/api/v1/reconciliation/statement-imports/candidates參數
account必填收款帳戶 ID,回傳該帳戶未配對的 ERP 現金流水候選
回應欄位 · data[]
sourceTypeERP 來源種類:payment_transaction 收款交易 / payable 出款 / account_transfer 帳戶移轉。
sourceIdERP 來源紀錄 ID。
date'YYYY-MM-DD'(Asia/Taipei 牆鐘日)。
direction現金流向:in 進帳 / out 出帳。
amountTwd金額(TWD 整數)。
label顯示標籤(來源摘要,供人工配對時辨識)。
curl -X GET "https://your-tenant.example.com/api/v1/reconciliation/statement-imports/candidates?account=<account>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"sourceType": "…",
"sourceId": "…",
"date": "…",
"direction": "out",
"amountTwd": 0,
"label": "…"
}
]
}銀行對帳單匯入固定範本下載
/api/v1/reconciliation/statement-imports/template回應欄位 · data
filename建議另存的檔名(.xlsx,含日期戳)。
contentBase64範本 .xlsx 內容的 base64 編碼字串(CLI 端解碼另存)。
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/statement-imports/template \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"filename": "…",
"contentBase64": "…"
}
}兩階段匯入的第一階段 dry-run
/api/v1/reconciliation/statement-imports/validate參數
receivingAccountId必填收款帳戶 ID(僅支援 TWD 的 bank / cash 帳戶)
periodStart必填對帳單期間起日(含當日)
periodEnd必填對帳單期間迄日(含當日)
filename必填上傳檔名,副檔名須為 .xlsx 或 .csv
contentBase64必填對帳單檔案內容的 base64 編碼字串
回應欄位 · data
accountId對帳的收款帳戶 ID。
periodStart對帳單期間起日('YYYY-MM-DD',含當日)。
periodEnd對帳單期間迄日('YYYY-MM-DD',含當日)。
filename上傳檔名。
lines解析後的各行預覽(含「若 commit 是否會被自動配對」)。
lineNo檔案內行號(1 起算)。
txnDate交易日期('YYYY-MM-DD')。
direction現金流向:in 存入 / out 支出。
amountTwd金額(TWD 整數)。
memo摘要 / 備註文字。
willAuto若現在 commit,這行是否會被自動配對(同語意孤立邊)。
parseErrors解析錯誤 + 期間外的行(依行號排序;commit 端會 fail-closed 拒)。
lineNo出錯的對帳單行號(原始列,從 1 起算)。
message錯誤說明(解析失敗原因或期間外提示)。
willAutoCount若現在 commit,預計會被自動配對的行數。
willUnmatchedCount若現在 commit,預計仍未配對的行數。
periodOverlap宣告期間是否與既有批次重疊(commit 會被擋)。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/statement-imports/validate \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"receivingAccountId": "<receivingAccountId>",
"periodStart": "<periodStart>",
"periodEnd": "<periodEnd>",
"filename": "<filename>",
"contentBase64": "<contentBase64>"
}'{
"ok": true,
"data": {
"accountId": "…",
"periodStart": "…",
"periodEnd": "…",
"filename": "…",
"lines": [
{
"lineNo": 0,
"txnDate": "…",
"direction": "out",
"amountTwd": 0,
"memo": "…",
"willAuto": true
}
],
"parseErrors": [
{
"lineNo": 0,
"message": "…"
}
],
"willAutoCount": 0,
"willUnmatchedCount": 0,
"periodOverlap": true
}
}略過一條對帳單行 →
/api/v1/reconciliation/statement-lines/{lineId}/ignore參數
lineId路徑對帳單行 ID
reason必填略過原因(必填;如「手續費」「利息」)
回應欄位 · data
ok是否標記略過成功(狀態轉為 ignored)。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/statement-lines/<lineId>/ignore \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "<reason>"
}'{
"ok": true,
"data": {
"ok": true
}
}人工配對一條對帳單行到指定
/api/v1/reconciliation/statement-lines/{lineId}/match參數
lineId路徑對帳單行 ID
sourceType必填配對來源種類:payment_transaction / payable / account_transfer
sourceId必填配對來源 ID(該帳戶內未被配對的 ERP 候選)
回應欄位 · data
ok是否人工配對成功(同帳戶 / 同金額 / 同方向)。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/statement-lines/<lineId>/match \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sourceType": "<sourceType>",
"sourceId": "<sourceId>"
}'{
"ok": true,
"data": {
"ok": true
}
}解除配對 → 'excluded'
/api/v1/reconciliation/statement-lines/{lineId}/unmatch參數
lineId路徑對帳單行 ID
回應欄位 · data
ok是否解除配對成功(狀態轉為 excluded)。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/statement-lines/<lineId>/unmatch \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}帳戶間移轉統一分類帳查詢
/api/v1/reconciliation/transfers參數
kind選填移轉類型篩選(fx_conversion 換匯 / replenishment 補款 / advance 代墊 / backfill 回填 / refund_payout 退款匯出 / reversal 沖正);省略則含全部
account選填帳戶 ID 篩選,回傳該帳戶為出帳或進帳方的移轉;省略則不限帳戶
dateFrom選填移轉日期起日(YYYY-MM-DD,含當日);省略則不設下界
dateTo選填移轉日期迄日(YYYY-MM-DD,含當日);省略則不設上界
settlementPeriod選填對應月結期間(YYYY-MM)篩選;省略則不限月結
obligation選填掛帳 ID 篩選,回傳沖減該筆掛帳的移轉;省略則不限掛帳
回應欄位 · data[]
id帳戶間移轉 ID。
kind移轉類型:fx_conversion 換匯 / replenishment 補款 / advance 代墊 / backfill 回填 / refund_payout 退款匯出 / opening 期初 / reversal 沖正。
fromAccountId出帳帳戶 ID;期初等單邊移轉為 null。
toAccountId進帳帳戶 ID;單邊移轉為 null。
amountTwd移轉金額(TWD 整數)。
feeTwd手續費(TWD 整數)。
currency外幣幣別(ISO 4217;純台幣移轉為 null)。
foreignAmount外幣金額(整數;非外幣移轉為 null)。
feeForeign外幣手續費(整數;無則為 null)。
grossRate換匯牌價(numeric → 字串原值保精度;顯示/溯源用)。
settlementPeriod對應月結期間(YYYY-MM);未歸屬月結為 null。
obligationId沖減的帳戶間掛帳 ID;未沖減掛帳為 null。
reversesTransferId被本筆沖正的原移轉 ID(kind='reversal' 時非 null)。
occurredAt移轉日期('YYYY-MM-DD',date 欄)。
note備註;無則為 null。
createdByUserId登錄人 user ID。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/transfers \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"kind": "…",
"fromAccountId": "…",
"toAccountId": "…",
"amountTwd": 0,
"feeTwd": 0,
"currency": "…",
"foreignAmount": 0,
"feeForeign": 0,
"grossRate": "…",
"settlementPeriod": "…",
"obligationId": "…",
"reversesTransferId": "…",
"occurredAt": "…",
"note": "…",
"createdByUserId": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/reconciliation/transfers參數
kind選填移轉類型:fx_conversion 換匯、replenishment 補款、advance 代墊、backfill 回填、refund_payout 退款匯出、reversal 沖正
fromAccountId選填出帳(轉出)帳戶 ID;與進帳帳戶至少填一個,null 表示無出帳方
toAccountId選填進帳(轉入)帳戶 ID;與出帳帳戶至少填一個,null 表示無進帳方
amountTwd選填移轉台幣淨額(整數,不可為負);沖減掛帳時須大於 0
feeTwd選填此筆移轉產生的手續費(台幣整數,不可為負)
occurredAt選填移轉發生日期(YYYY-MM-DD)
settlementPeriod選填對應月結期間(YYYY-MM),標記此移轉沖減哪一期互抵;換匯不掛單一月結,傳 null
currency選填換匯外幣幣別(ISO 4217 三碼);非換匯傳 null
foreignAmount選填換匯外幣金額(整數最小單位,須大於 0);非換匯傳 null
grossRate選填換匯牌價(正數,最多 6 位小數,以字串表達避免精度遺失);非換匯傳 null
obligationId選填選填沖減的掛帳 ID(aob_ 開頭);換匯不沖減掛帳須傳 null
回應欄位 · data
ok是否登錄成功(移轉 + 沖減掛帳的原子交易皆完成)。
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/transfers \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}/accrual-ledger
掛帳台帳
/api/v1/accrual-ledger參數
period必填出團月(格式 YYYY-MM,Asia/Taipei 時區)
回應欄位 · data
period結算期間(YYYY-MM,Asia/Taipei 出團月)。
departureSummary梯次彙總(區塊 1):出團月落於 period 的各梯次收入 / 成本 / 毛利。
departureId梯次 ID。
tripTitle團名。
departureDate出團日期(YYYY-MM-DD)。
pax出團人數(該梯次確認人數)。
revenueTwd總收入(梯次成交應收,排除已取消訂單,TWD 整數)。
realCostTwd真實成本合計(TWD 整數)= 房費底價成本 + 已核准的逐筆成本。逐筆成本區塊不含房費 (房費由分房資料另計),故逐筆成本加總會小於此值,差額即房費(設計如此)。
grossProfitTwd毛利毛估 = revenue − realCost(含房費)。
costLines成本掛帳逐筆(區塊 2):該期梯次上所有 departure_costs 成本列。
id成本列 ID。
tripTitle團名。
departureDate所屬梯次出團日期(YYYY-MM-DD)。
category成本分類(如 交通 / 餐費 / 保險 / 嚮導)。
vendor廠商:已建檔廠商名優先,否則用成本列上填寫的廠商名;null = 未填。
amountTwd代墊額(真實成本,TWD 整數)。
invoiceAmountTwd憑證額(外帳可申報金額,TWD 整數)。
isDeclarable有無發票憑證。
reviewStatus覆核狀態:掛了支出證明單則用其 status(pending/approved),否則由有無憑證派生。
payables應付清單(區塊 3):該期歸屬的請款單(payables)。
payableNumber請款單號(人類可讀)。
tripTitle團名(未綁定梯次的手動請款顯示「未綁定梯次」)。
payeeName受款對象(供應商 / 嚮導 / 派車人等)。
amountTwd請款金額(整數 TWD)。
statusdraft | submitted | approved | paid | cancelled | rejected。
receivables應收清單(區塊 4):該期梯次上的 tour 訂單應收 / 實收 / 待收。
orderNumber訂單編號。
tripTitle團名(該訂單在期間內任一梯次的團名)。
receivableTwd應收金額(TWD 整數)。
receivedTwd實收金額(收款減退款,TWD 整數)。
outstandingTwd待收 = receivable − received。
curl -X GET "https://your-tenant.example.com/api/v1/accrual-ledger?period=<period>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"period": "…",
"departureSummary": [
{
"departureId": "…",
"tripTitle": "…",
"departureDate": "…",
"pax": 0,
"revenueTwd": 0,
"realCostTwd": 0,
"grossProfitTwd": 0
}
],
"costLines": [
{
"id": "…",
"tripTitle": "…",
"departureDate": "…",
"category": "…",
"vendor": "…",
"amountTwd": 0,
"invoiceAmountTwd": 0,
"isDeclarable": true,
"reviewStatus": "…"
}
],
"payables": [
{
"payableNumber": "…",
"tripTitle": "…",
"payeeName": "…",
"amountTwd": 0,
"status": "…"
}
],
"receivables": [
{
"orderNumber": "…",
"tripTitle": "…",
"receivableTwd": 0,
"receivedTwd": 0,
"outstandingTwd": 0
}
]
}
}掛帳台帳的「梯次彙總」
/api/v1/accrual-ledger/departure-summary參數
period必填出團月(格式 YYYY-MM,Asia/Taipei 時區)
回應欄位 · data
period結算期間(YYYY-MM,Asia/Taipei 出團月),回聲請求參數。
departureSummary梯次彙總:出團月落於 period 的各梯次收入 / 真實成本 / 毛估毛利。
departureId梯次 ID。
tripTitle團名。
departureDate出團日期(YYYY-MM-DD)。
pax出團人數(該梯次確認人數)。
revenueTwd總收入(梯次成交應收,排除已取消訂單,TWD 整數)。
realCostTwd真實成本合計(TWD 整數)= 房費底價成本 + 已核准的逐筆成本。逐筆成本區塊不含房費 (房費由分房資料另計),故逐筆成本加總會小於此值,差額即房費(設計如此)。
grossProfitTwd毛利毛估 = revenue − realCost(含房費)。
curl -X GET "https://your-tenant.example.com/api/v1/accrual-ledger/departure-summary?period=<period>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"period": "…",
"departureSummary": [
{
"departureId": "…",
"tripTitle": "…",
"departureDate": "…",
"pax": 0,
"revenueTwd": 0,
"realCostTwd": 0,
"grossProfitTwd": 0
}
]
}
}/cost-templates
list reusable series-tour cost templates
/api/v1/cost-templates參數
status選填activearchived依狀態篩選:active 啟用、archived 已封存
active選填啟用時只回傳輕量的 { id, name } 綁定挑選清單(行程設定的成本範本下拉用)
回應欄位 · data[]
id成本範本 id(ct_ 前綴)。
name成本範本名稱。
curl -X GET https://your-tenant.example.com/api/v1/cost-templates \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"name": "…"
}
]
}/api/v1/cost-templates參數
name必填成本範本名稱
description選填成本範本說明
status選填activearchived範本狀態:active 啟用、archived 已封存
回應欄位 · data
id新建成本範本 ID(ct_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/cost-templates \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"id": "…"
}
}full cost-template detail
/api/v1/cost-templates/{id}參數
id路徑成本範本 ID
回應欄位 · data
lines成本行明細(品項 × 單價 × 數量模型)。
id成本行 ID。
templateId所屬成本範本 ID。
category成本分類(如 交通 / 餐費 / 保險)。
vendorName供應商 / 廠商名(選填)。
description摘要說明(選填)。
unitPriceTwdTWD 行的單價;外幣行 null。
currency幣別('TWD' = 台幣行)。
unitPriceForeign外幣行的外幣單價;TWD 行 null。
internalRateSource外幣行的內帳匯率來源;TWD 行 null。
fxAccountIdinternalRateSource='fx_account' 時的外幣帳戶 id。
quantityMode數量模式:fixed 固定值 / headcount 依人頭公式(ceil(Σ人頭 / 組距))。
quantityFixedfixed 模式的固定數量;headcount 模式為 null。
headcountComponentsheadcount 模式選定的人頭 component(passenger / leader / assistant / driver);fixed 為 null。
groupDivisorheadcount 模式的組距(每 N 人一組,ceil 進位);null = 直接加總。
isDeclarable是否預設有合法憑證(帶入成本列的 is_declarable 初值)。
sortOrder顯示排序。
id成本範本 ID。
name範本名稱。
description範本說明(選填)。
status狀態:active 啟用 / archived 已封存。
lineCount成本行數(派生)。
boundTripCount綁定行程數(派生)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/cost-templates/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"lines": [
{
"id": "…",
"templateId": "…",
"category": "…",
"vendorName": "…",
"description": "…",
"unitPriceTwd": 0,
"currency": "…",
"unitPriceForeign": 0,
"internalRateSource": null,
"fxAccountId": "…",
"quantityMode": "…",
"quantityFixed": 0,
"headcountComponents": null,
"groupDivisor": 0,
"isDeclarable": true,
"sortOrder": 0
}
],
"id": "…",
"name": "…",
"description": "…",
"status": "active",
"lineCount": 0,
"boundTripCount": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}/api/v1/cost-templates/{id}參數
name必填成本範本名稱
description選填成本範本說明
status選填activearchived範本狀態:active 啟用、archived 已封存
id路徑成本範本 ID
回應欄位 · data
ok是否更新成功。
curl -X PATCH https://your-tenant.example.com/api/v1/cost-templates/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true
}
}add a cost line to a template.
/api/v1/cost-templates/{id}/lines參數
id路徑成本範本 ID
line必填成本明細列:含 category 科目、vendorName 廠商、unitPriceTwd 單價、quantityMode 計量方式(fixed 固定/headcount 人數)與對應數量/人數組成、isDeclarable 是否可報帳等欄位
回應欄位 · data
id新建成本明細行 ID。
curl -X POST https://your-tenant.example.com/api/v1/cost-templates/<id>/lines \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"line": "<line>"
}'{
"ok": true,
"data": {
"id": "…"
}
}update or delete a
/api/v1/cost-templates/lines/{lineId}參數
lineId路徑成本範本明細行 ID
line必填成本明細列更新內容:含 category 科目、vendorName 廠商、unitPriceTwd 單價、quantityMode 計量方式(fixed 固定/headcount 人數)與對應數量/人數組成、isDeclarable 是否可報帳等欄位
回應欄位 · data
ok是否更新成功。
curl -X PATCH https://your-tenant.example.com/api/v1/cost-templates/lines/<lineId> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"line": "<line>"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/cost-templates/lines/{lineId}參數
lineId路徑成本範本明細行 ID
回應欄位 · data
ok是否刪除成功。
curl -X DELETE https://your-tenant.example.com/api/v1/cost-templates/lines/<lineId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}/internal-external-ledger
取消梯次待結轉列表
/api/v1/internal-external-ledger/cancelled-departures回應欄位 · data[]
departureId取消梯次 ID。
tripTitle團名。
tripSlug行程 slug(URL 識別)。
departureDate原出團日期(YYYY-MM-DD)。
returnDate原回程日期(YYYY-MM-DD)。
groupCode團號(group-code),未產生為 null。
residualCostTwd殘餘成本(TWD 整數):已核准的逐筆成本合計 + 房費底價成本合計。
approvedCostCount已核准成本筆數。
pendingCostCount待覆核成本筆數(UI 提示「還有待覆核成本」)。
roomCostTwd房費殘餘成本(房費底價成本合計,整數 TWD)。
conversion結轉狀態:已結轉為特殊損益時的費用列資訊(expenseId / 金額 / 歸屬月 / 摘要);未結轉為 null。
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/cancelled-departures \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"departureId": "…",
"tripTitle": "…",
"tripSlug": "…",
"departureDate": "…",
"returnDate": "…",
"groupCode": "…",
"residualCostTwd": 0,
"approvedCostCount": 0,
"pendingCostCount": 0,
"roomCostTwd": 0,
"conversion": "…"
}
]
}結轉取消
/api/v1/internal-external-ledger/cancelled-departures/convert參數
departureId必填梯次 ID
categoryId必填特殊損益費用科目 ID(kind=special)
period必填歸屬月(取消月,格式 YYYY-MM)
amountTwd必填結轉金額(整數 TWD,預設殘餘成本)
description必填摘要
note選填備註(選填)
回應欄位 · data
id新建立的殘餘成本營業費用列 ID(opx_ 前綴)。
residualCostTwd結轉的殘餘成本金額(TWD 整數)。
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/cancelled-departures/convert \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"departureId": "<departureId>",
"categoryId": "<categoryId>",
"period": "<period>",
"amountTwd": 0,
"description": "<description>"
}'{
"ok": true,
"data": {
"id": "…",
"residualCostTwd": 0
}
}撤銷取消
/api/v1/internal-external-ledger/cancelled-departures/revert參數
departureId必填梯次 ID
回應欄位 · data
ok固定為 true:已還原取消梯次的轉列,回到未轉列狀態。
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/cancelled-departures/revert \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"departureId": "<departureId>"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/internal-external-ledger/costs/{costId}參數
category必填成本類別代碼(須為有效的成本分類)
vendorName選填廠商/供應商名稱
description選填成本摘要說明
amountTwd選填真實成本(台幣整數)。台幣路徑必填;外幣路徑忽略,改由外幣金額乘匯率換算
currency選填幣別;TWD 或留空走台幣路徑,其他幣別走外幣路徑
foreignAmount選填外幣金額(整數);僅外幣路徑使用
internalRateSource選填fx_accountpublishedmanual內帳匯率來源:fx_account 外幣帳戶加權成本、published 台銀牌告、manual 手填成交率
fxAccountId選填外幣帳戶 ID;內帳匯率來源為 fx_account 時使用
manualRate選填手填成交匯率(字串保精度);內帳匯率來源為 manual 時使用
hasReceipt選填是否有發票憑證;預設 true,false 表示無發票並強制可申報額為 0、改填支出證明單欄位
invoiceAmountTwd選填外帳可申報額覆寫(台幣整數,須大於等於 0、無上限)
payeeName選填受款人姓名;無發票時的支出證明單欄位
reasonNoReceipt選填無發票原因;無發票時的支出證明單欄位
proofSummary選填支出證明摘要;無發票時的支出證明單欄位
quantityMode選填fixedheadcount計價方式;未給=一次性總額,fixed=單價×固定數量,headcount=單價×ceil(Σ人頭/組距)
headcountComponents選填依人頭計價的人頭組合(passenger/leader/assistant/driver,至少一項)
groupDivisor選填依人頭計價的組距(≥ 1;空=直接加總)
quantityFixed選填固定數量計價的數量(≥ 0)
unitPriceTwd選填單價(台幣整數);計價方式給值時必填
costId路徑成本列 ID
回應欄位 · data
ok固定為 true:成本列已更新。
curl -X PATCH https://your-tenant.example.com/api/v1/internal-external-ledger/costs/<costId> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"category": "<category>"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/internal-external-ledger/costs/{costId}參數
costId路徑成本列 ID
回應欄位 · data
ok固定為 true:成本列已刪除。
curl -X DELETE https://your-tenant.example.com/api/v1/internal-external-ledger/costs/<costId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}/api/v1/internal-external-ledger/costs/{costId}/approve-declaration參數
costId路徑成本列 ID
回應欄位 · data
ok固定為 true:成本自主申報已核准。
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/costs/<costId>/approve-declaration \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}待覆核的嚮導申報
/api/v1/internal-external-ledger/declarations/pending回應欄位 · data[]
id成本列 ID。
departureId所屬梯次 ID。
tripTitle團名。
departureDate出團日期(YYYY-MM-DD)。
category成本分類。
vendorName供應商 / 廠商名(選填)。
amountTwd代墊 / 實付額(內帳真實成本,整數 TWD)。
invoiceAmountTwd憑證 / 發票額(外帳可申報,整數 TWD)。
isDeclarable是否取得合法憑證。
createdByName登記者(經手人)姓名。
createdAt建立時間(嚮導送出時間)。
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/declarations/pending \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"departureId": "…",
"tripTitle": "…",
"departureDate": "…",
"category": "…",
"vendorName": "…",
"amountTwd": 0,
"invoiceAmountTwd": 0,
"isDeclarable": true,
"createdByName": "…",
"createdAt": "2026-06-30T08:00:00.000Z"
}
]
}per-departure 內外帳列表
/api/v1/internal-external-ledger/departures參數
windowDays選填回看天數;只列出近 N 天內的梯次
tripId選填行程 ID;只列出該行程的梯次
period選填出團月(格式 YYYY-MM);只列出該月的梯次
回應欄位 · data[]
tripTitle梯次標題(trip title)。
tripSlug行程 slug(URL 識別)。
departureDate出團日期(YYYY-MM-DD)。
returnDate回程日期(YYYY-MM-DD)。
groupCode團號(group-code),未產生為 null。
pax報名人數(非取消單 party_size 合計)。
departureId梯次 ID。
revenueTwd本團收入(梯次應收,排除已取消訂單,TWD 整數)。
realCostTwd內帳真實成本(TWD 整數)= 房費底價成本 + 已核准的逐筆成本合計。
declarableCostTwd外帳可申報成本(各成本列憑證額合計,TWD 整數)。
nonDeclarableCostTwd不可申報(無憑證)真實成本,逐列 Σ GREATEST(amount − invoice, 0)(非跨列 realCost − declarableCost)。
costBilledTwd已轉請款成本。
costUnbilledTwd未轉請款成本。
grossProfitTwd**每梯次權威數=毛利** = revenue − realCost(不扣手續費 / 稅,operating-expenses §2.3)。 公司月損益(computeCompanyPnL)的「各區毛利」即逐梯次此值按區彙整;手續費 / 稅在公司層 用實際值扣一次,**不**用下面的預估費率重扣(避免雙重計)。
feeEcpayTwd預估綠界手續費(**參考預估**,非權威;公司層用實際值,§2.3)。
feeFongshouTwd預估豐收款手續費(**參考預估**,非權威)。
taxEstTwd預估發票 / 營所稅(**參考預估**,非權威;公司層用實繳值)。
estimatedNetProfitTwd**參考預估淨利**(非權威)= grossProfit − feeEcpay − feeFongshou − taxEst。純給現場 快速感覺(毛利扣預估費率),**非公司財務真相** —— 公司淨利以 operating-expenses 月損益表 (實際 overhead)為準。權威數請用 `grossProfitTwd`。
marginPct毛利率(grossProfit / revenue),revenue=0 時為 null。
pendingProofCount待核(pending)支出證明單數。
feeRates套用的費率(呈現用)。
ecpayFeeBps預估綠界手續費率(basis points,270 = 2.70%)。
fongshouFeeBps預估豐收款手續費率(basis points,50 = 0.50%)。
profitTaxBps預估發票 / 營所稅率(basis points,500 = 5.00%)。
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"tripTitle": "…",
"tripSlug": "…",
"departureDate": "…",
"returnDate": "…",
"groupCode": "…",
"pax": 0,
"departureId": "…",
"revenueTwd": 0,
"realCostTwd": 0,
"declarableCostTwd": 0,
"nonDeclarableCostTwd": 0,
"costBilledTwd": 0,
"costUnbilledTwd": 0,
"grossProfitTwd": 0,
"feeEcpayTwd": 0,
"feeFongshouTwd": 0,
"taxEstTwd": 0,
"estimatedNetProfitTwd": 0,
"marginPct": 0,
"pendingProofCount": 0,
"feeRates": {
"ecpayFeeBps": 0,
"fongshouFeeBps": 0,
"profitTaxBps": 0
}
}
]
}single
/api/v1/internal-external-ledger/departures/{departureId}參數
departureId路徑梯次 ID
回應欄位 · data
departureId梯次 ID。
revenueTwd本團收入(梯次應收,排除已取消訂單,TWD 整數)。
realCostTwd內帳真實成本(TWD 整數)= 房費底價成本 + 已核准的逐筆成本合計。
declarableCostTwd外帳可申報成本(各成本列憑證額合計,TWD 整數)。
nonDeclarableCostTwd不可申報(無憑證)真實成本,逐列 Σ GREATEST(amount − invoice, 0)(非跨列 realCost − declarableCost)。
costBilledTwd已轉請款成本。
costUnbilledTwd未轉請款成本。
grossProfitTwd**每梯次權威數=毛利** = revenue − realCost(不扣手續費 / 稅,operating-expenses §2.3)。 公司月損益(computeCompanyPnL)的「各區毛利」即逐梯次此值按區彙整;手續費 / 稅在公司層 用實際值扣一次,**不**用下面的預估費率重扣(避免雙重計)。
feeEcpayTwd預估綠界手續費(**參考預估**,非權威;公司層用實際值,§2.3)。
feeFongshouTwd預估豐收款手續費(**參考預估**,非權威)。
taxEstTwd預估發票 / 營所稅(**參考預估**,非權威;公司層用實繳值)。
estimatedNetProfitTwd**參考預估淨利**(非權威)= grossProfit − feeEcpay − feeFongshou − taxEst。純給現場 快速感覺(毛利扣預估費率),**非公司財務真相** —— 公司淨利以 operating-expenses 月損益表 (實際 overhead)為準。權威數請用 `grossProfitTwd`。
marginPct毛利率(grossProfit / revenue),revenue=0 時為 null。
pendingProofCount待核(pending)支出證明單數。
feeRates套用的費率(呈現用)。
ecpayFeeBps預估綠界手續費率(basis points,270 = 2.70%)。
fongshouFeeBps預估豐收款手續費率(basis points,50 = 0.50%)。
profitTaxBps預估發票 / 營所稅率(basis points,500 = 5.00%)。
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"departureId": "…",
"revenueTwd": 0,
"realCostTwd": 0,
"declarableCostTwd": 0,
"nonDeclarableCostTwd": 0,
"costBilledTwd": 0,
"costUnbilledTwd": 0,
"grossProfitTwd": 0,
"feeEcpayTwd": 0,
"feeFongshouTwd": 0,
"taxEstTwd": 0,
"estimatedNetProfitTwd": 0,
"marginPct": 0,
"pendingProofCount": 0,
"feeRates": {
"ecpayFeeBps": 0,
"fongshouFeeBps": 0,
"profitTaxBps": 0
}
}
}/api/v1/internal-external-ledger/departures/{departureId}/convert-to-payable參數
departureId路徑梯次 ID
costIds必填要轉成請款核簽的成本列 ID 陣列(至少一筆,須為尚未轉請款者)
payeeType選填supplierguidestaff_commissionother受款對象類型:supplier 供應商、guide 嚮導、staff_commission 員工佣金、other 其他
payeeName必填受款對象名稱
payeeBankAccount選填受款銀行帳號
payeeBankName選填受款銀行名稱
payeeBankBranch選填受款銀行分行
payeeTaxId選填受款對象統一編號/稅籍編號
taxAmountTwd選填代扣稅額(台幣整數)
submitImmediately選填是否建立後立即送出核簽(true 直接送審)
回應欄位 · data
payableId新建立應付單的 ID(pay_ 前綴)。
payableNumber應付單編號(租戶內流水序號,出款核簽用)。
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/convert-to-payable \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"costIds": [],
"payeeName": "<payeeName>"
}'{
"ok": true,
"data": {
"payableId": "…",
"payableNumber": "…"
}
}/api/v1/internal-external-ledger/departures/{departureId}/costs參數
departureId路徑梯次 ID
createdBy選填登記者使用者 ID;只列出該人登記的成本列
回應欄位 · data[]
id成本列 ID。
departureId所屬梯次 ID。
category成本分類(如 交通 / 餐費 / 保險 / 嚮導)。
vendorName供應商 / 廠商名(選填)。
description摘要說明(選填)。
receiptImageUrl憑證照片 URL(G3-2);未附照片 null。app-route 私有 URL,讀取經 route 權限閘。
amountTwd代墊 / 實付額(內帳真實成本,整數 TWD)。
invoiceAmountTwd外帳可申報額(internal-external-ledger §2.1)。
isDeclarable是否取得合法憑證。
reviewStatus覆核狀態 'pending' | 'approved'(L'):pending 不計入淨利 / 可申報(UI 須標示、停用轉請款)。
currency成本幣別(ISO 4217);'TWD' = 台幣列。
foreignAmount外幣金額(最小單位整數);TWD 列 null。
internalRateSource內帳匯率來源;TWD 列 null。
fxAccountIdinternalRateSource='fx_account' 時的外幣帳戶 id。
internalRate內帳匯率快照(numeric 字串);TWD 列 null。
externalRate外帳匯率快照(numeric 字串,台銀牌告);TWD 列 null。
feeCategory費用類型 tag(account-settlement §3.4,成本側類別→領域帳戶映射;null = 未 tag)。
quantityMode計價方式 'fixed' / 'headcount';一次性總額列 null。
headcountComponentsheadcount 人頭組合;非 headcount 列 null。
groupDivisorheadcount 組距;非 headcount 列 null。
quantity解析後(headcount)或自訂(fixed)的數量;一次性總額列 null。
unitPriceTwd單價(台幣整數);一次性總額列 null。
expenseProofId無發票支出掛的支出證明單 id(null = 有憑證)。
proofNumber支出證明單單號(join expense_proofs,null = 無)。
proofStatus支出證明單狀態 'pending' | 'approved'(null = 無)。
payableId已轉請款時連結的請款單 ID(null = 未轉請款)。
payableNumber連結請款單的人類可讀單號(null = 未轉請款)。
payableStatus連結請款單的狀態(draft / submitted / approved / paid…;null = 未轉請款)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/costs \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"departureId": "…",
"category": "…",
"vendorName": "…",
"description": "…",
"receiptImageUrl": "…",
"amountTwd": 0,
"invoiceAmountTwd": 0,
"isDeclarable": true,
"reviewStatus": "…",
"currency": "…",
"foreignAmount": 0,
"internalRateSource": "…",
"fxAccountId": "…",
"internalRate": "…",
"externalRate": "…",
"feeCategory": "…",
"quantityMode": null,
"headcountComponents": null,
"groupDivisor": 0,
"quantity": 0,
"unitPriceTwd": 0,
"expenseProofId": "…",
"proofNumber": "…",
"proofStatus": "…",
"payableId": "…",
"payableNumber": "…",
"payableStatus": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/internal-external-ledger/departures/{departureId}/costs參數
category必填成本類別代碼(須為有效的成本分類)
vendorName選填廠商/供應商名稱
description選填成本摘要說明
amountTwd選填真實成本(台幣整數)。台幣路徑必填;外幣路徑忽略,改由外幣金額乘匯率換算
currency選填幣別;TWD 或留空走台幣路徑,其他幣別走外幣路徑
foreignAmount選填外幣金額(整數);僅外幣路徑使用
internalRateSource選填fx_accountpublishedmanual內帳匯率來源:fx_account 外幣帳戶加權成本、published 台銀牌告、manual 手填成交率
fxAccountId選填外幣帳戶 ID;內帳匯率來源為 fx_account 時使用
manualRate選填手填成交匯率(字串保精度);內帳匯率來源為 manual 時使用
hasReceipt選填是否有發票憑證;預設 true,false 表示無發票並強制可申報額為 0、改填支出證明單欄位
invoiceAmountTwd選填外帳可申報額覆寫(台幣整數,須大於等於 0、無上限)
payeeName選填受款人姓名;無發票時的支出證明單欄位
reasonNoReceipt選填無發票原因;無發票時的支出證明單欄位
proofSummary選填支出證明摘要;無發票時的支出證明單欄位
quantityMode選填fixedheadcount計價方式;未給=一次性總額,fixed=單價×固定數量,headcount=單價×ceil(Σ人頭/組距)
headcountComponents選填依人頭計價的人頭組合(passenger/leader/assistant/driver,至少一項)
groupDivisor選填依人頭計價的組距(≥ 1;空=直接加總)
quantityFixed選填固定數量計價的數量(≥ 0)
unitPriceTwd選填單價(台幣整數);計價方式給值時必填
departureId路徑梯次 ID
回應欄位 · data
id新建立成本列的 ID(dc_ 前綴)。
expenseProofId隨附憑證的 ID(若本次一併登記),無則為 null。
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/costs \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"category": "<category>"
}'{
"ok": true,
"data": {
"id": "…",
"expenseProofId": "…"
}
}支出
/api/v1/internal-external-ledger/departures/{departureId}/proofs參數
departureId路徑梯次 ID
回應欄位 · data[]
id支出證明單 ID。
proofNumber人類可讀單號(EP-YYMMDD-NNN)。
departureId所屬梯次 ID。
payeeName受款對象(自然人 / 廠商)。
amountTwd金額(整數 TWD,對應所掛成本列的 amount_twd)。
reasonNoReceipt無法取得單據的原因(如「自然人」)。
summary支出內容及摘要(選填)。
handlerUserId經手人(建單者)user ID。
approverUserId核准人 user ID(強制 ≠ 經手人);未核准為 null。
status狀態:pending 待核准 / approved 已核准(核准後 append-only)。
approvedAt核准時間;未核准為 null。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/proofs \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"proofNumber": "…",
"departureId": "…",
"payeeName": "…",
"amountTwd": 0,
"reasonNoReceipt": "…",
"summary": "…",
"handlerUserId": "…",
"approverUserId": "…",
"status": "…",
"approvedAt": null,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/internal-external-ledger/departures/{departureId}/proofs/{proofId}參數
departureId路徑梯次 ID
proofId路徑支出證明單 ID
回應欄位 · data
id支出證明單 ID。
proofNumber人類可讀單號(EP-YYMMDD-NNN)。
departureId所屬梯次 ID。
payeeName受款對象(自然人 / 廠商)。
amountTwd金額(整數 TWD,對應所掛成本列的 amount_twd)。
reasonNoReceipt無法取得單據的原因(如「自然人」)。
summary支出內容及摘要(選填)。
handlerUserId經手人(建單者)user ID。
approverUserId核准人 user ID(強制 ≠ 經手人);未核准為 null。
status狀態:pending 待核准 / approved 已核准(核准後 append-only)。
approvedAt核准時間;未核准為 null。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/proofs/<proofId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"proofNumber": "…",
"departureId": "…",
"payeeName": "…",
"amountTwd": 0,
"reasonNoReceipt": "…",
"summary": "…",
"handlerUserId": "…",
"approverUserId": "…",
"status": "…",
"approvedAt": null,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}/api/v1/internal-external-ledger/proofs/{proofId}/approve參數
proofId路徑支出證明單 ID
回應欄位 · data
ok固定為 true:憑證已核准。
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/proofs/<proofId>/approve \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}/payouts
派生當月
/api/v1/payouts/aggregate參數
period必填出款月份(YYYY-MM),彙整該月已核准未付的應付
scope必填guidesupplierstaff收款對象範圍(guide 領隊嚮導 / supplier 供應商 / staff 員工)
回應欄位 · data[]
payeeType收款對象類型:guide 領隊嚮導 / supplier 供應商 / staff 員工。
payeeRefId收款對象識別 key:供應商為其 ID,領隊 / 員工為收款人姓名。
payeeName收款對象名稱。
payeeAccountName收款人戶名(supplier 取 suppliers / guide 取 guides;staff 暫無主檔 → null)。
payeeBankCode收款銀行代號(同上來源;無主檔為 null)。
payeeAccountNumber收款帳號(同上來源;無主檔為 null,遮罩回傳)。
grossTwd當月已核准未付的請款單淨額合計(TWD 整數)。
items彙整明細(日期 + 團名 + 金額,唯讀派生,不另存)。
payableId請款單 ID。
payableNumber請款單人類可讀單號。
date梯次出發日('YYYY-MM-DD');無連梯次時 null。
tripLabel團名;無連梯次時 null。
amountTwd該請款單的應付淨額(TWD 整數)。
curl -X GET "https://your-tenant.example.com/api/v1/payouts/aggregate?period=<period>&scope=<scope>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"payeeType": "…",
"payeeRefId": "…",
"payeeName": "…",
"payeeAccountName": "…",
"payeeBankCode": "…",
"payeeAccountNumber": "…",
"grossTwd": 0,
"items": [
{
"payableId": "…",
"payableNumber": "…",
"date": "…",
"tripLabel": "…",
"amountTwd": 0
}
]
}
]
}建立出款批次草稿
/api/v1/payouts/batches參數
period必填出款月份(YYYY-MM)
payeeScope必填收款對象範圍(guide 領隊嚮導 / supplier 供應商 / staff 員工)
paidFromAccountId選填出帳帳戶 id(從哪個收款帳戶付出);可留空待確認時指定
lines必填納入批次的出款列(至少一列)
回應欄位 · data
id新建立出款批次的 ID(pob_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/payouts/batches \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"period": "<period>",
"payeeScope": "<payeeScope>",
"lines": []
}'{
"ok": true,
"data": {
"id": "…"
}
}確認出款批次
/api/v1/payouts/batches/{id}/confirm參數
id路徑出款批次 id(路徑參數,格式 pob_…)
bankReference選填網銀交易序號 / 轉帳憑證號(可選)
回應欄位 · data
ok固定為 true:出款批次已確認送出。
curl -X POST https://your-tenant.example.com/api/v1/payouts/batches/<id>/confirm \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}出款批次的標準四欄批次轉帳檔
/api/v1/payouts/batches/{id}/transfer-file參數
id路徑出款批次 id(路徑參數)
format選填csvjson輸出格式:json 完整匯出(預設)或 csv 僅回傳轉帳檔字串
curl -X GET https://your-tenant.example.com/api/v1/payouts/batches/<id>/transfer-file \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": "…"
}為某出款批次列簽發廠商自助確認
/api/v1/payouts/lines/{lineId}/confirm-token參數
lineId路徑出款批次列 id(路徑參數,格式 pobl_…)
回應欄位 · data
token廠商自助確認 token(拼成對外確認頁網址;idempotent,重複簽發回原 token)。
curl -X POST https://your-tenant.example.com/api/v1/payouts/lines/<lineId>/confirm-token \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"token": "…"
}
}出款批次的「出帳帳戶」選項
/api/v1/payouts/remit-accounts回應欄位 · data[]
id收款帳戶 ID。
code帳戶代碼(租戶內唯一穩定識別)。
displayName帳戶顯示名。
kind帳戶類型:bank 銀行 / cash 現金 / gateway 金流閘道。
bankName銀行名稱;現金/閘道帳戶為 null。
accountNo銀行帳號;現金/閘道帳戶為 null。
canReceive可收款(幾乎都 true)。
canRemit可對外匯款(ATM / 匯出退款 / 補款匯出)。荒野只有永豐。
canChargeback可刷退(退回原信用卡)。荒野只有綠界(gateway)。
isDeprecated廢帳戶:仍可零星收款,但其收款需由他帳戶代墊歸集。荒野=RU 台銀 / 登山社。
isSettlementMaster主結算帳戶:所有資金最終向它彙整。每租戶恰一個(partial unique index)。荒野=永豐。
currency帳戶幣別(ISO 4217;既有帳戶皆 'TWD',外幣帳戶如 IDR / USD)。
isActive此帳戶是否啟用。
displayOrder後台清單排序序位(小者在前)。
usedCount被多少 payment_transactions 引用(UI 鎖頭 / 「使用中 N」)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/payouts/remit-accounts \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"code": "…",
"displayName": "…",
"kind": "…",
"bankName": "…",
"accountNo": "…",
"canReceive": true,
"canRemit": true,
"canChargeback": true,
"isDeprecated": true,
"isSettlementMaster": true,
"currency": "…",
"isActive": true,
"displayOrder": 0,
"usedCount": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/pnl
list the company expense-category
/api/v1/pnl/expense-categories參數
activeOnly選填是否只回傳啟用中的費用類別;預設含停用列
回應欄位 · data[]
id費用類別 ID。
code科目代碼(租戶內唯一穩定識別,如 rent / salary_admin / tax_vat)。
displayName顯示名(如 房租 / 行政薪資 / 營業稅)。
kind費用大類:opex 營業費用 / tax 稅 / platform_fee 平台手續費 / special 特殊損益(損益表據此 roll-up)。
isActive是否啟用(停用不刪,既有費用列仍引用得到)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/pnl/expense-categories \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"code": "…",
"displayName": "…",
"kind": "opex",
"isActive": true,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}list company operating-expense ledger rows
/api/v1/pnl/expenses參數
period選填歸屬月(格式 YYYY-MM);只列出該月的費用
category選填費用類別 ID;只列出該類別的費用
kind選填opextaxplatform_feespecial費用大類:opex 營業費用、tax 稅、platform_fee 平台手續費、special 特殊損益
回應欄位 · data[]
id費用列 ID。
categoryId費用科目 ID。
categoryCode費用科目代碼(如 rent / salary_admin)。
categoryDisplayName費用科目顯示名。
categoryKind費用科目大類(opex / tax / platform_fee / special)。
period歸屬月(YYYY-MM,損益表據此彙整;可與支付日不同月)。
incurredOn發生 / 支付日期(YYYY-MM-DD);金流商內扣 / 攤提無單一發生日者為 null。
amountTwd金額(整數 TWD)。
description摘要(廠商 / 品名,如 台中房租 / 委外廣告投放)。
paidFromAccountId出帳帳戶 ID;金流商內扣者為 null。
paidFromAccountName出帳帳戶顯示名。
frontedByUserId代墊者 user ID;非空代表由此人代墊待回補(走請款回補代墊者)。
frontedByName代墊者姓名。
payableId若走出款核簽,連結的請款單 ID;否則 null。
payableNumber連結請款單的人類可讀單號。
recurring月固定標記(人工登記時備註「月固定」;自動生成走範本表,非此欄)。
status'draft'(月固定範本自動生成、待確認,不入損益)| 'confirmed'(計入損益)。
origin'manual'(手動登記)| 'recurring'(月固定範本自動生成)| 'departure_conversion'(取消梯次結轉,§3.4)。
sourceTemplateId生成來源範本(origin='recurring');手動登記為 null。
note備註。
createdByUserId經手人 user ID(建立此費用列者)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/pnl/expenses \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"categoryId": "…",
"categoryCode": "…",
"categoryDisplayName": "…",
"categoryKind": "…",
"period": "…",
"incurredOn": "…",
"amountTwd": 0,
"description": "…",
"paidFromAccountId": "…",
"paidFromAccountName": "…",
"frontedByUserId": "…",
"frontedByName": "…",
"payableId": "…",
"payableNumber": "…",
"recurring": true,
"status": "confirmed",
"origin": "manual",
"sourceTemplateId": "…",
"note": "…",
"createdByUserId": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/pnl/expenses參數
categoryId必填費用類別 ID(對應公司費用類別目錄)
period必填歸屬月(格式 YYYY-MM),供月損益表彙整
description必填費用摘要
amountTwd必填費用金額(台幣非負整數)
incurredOn選填費用發生日期(格式 YYYY-MM-DD)
paidFromAccountId選填支付來源帳戶 ID
frontedByUserId選填代墊人使用者 ID(由員工先行墊付時填寫)
note選填備註
recurring選填是否為週期性費用
回應欄位 · data
ok固定為 true:營業費用列已新增。
id新建立營業費用列的 ID(opx_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/pnl/expenses \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"categoryId": "<categoryId>",
"period": "<period>",
"description": "<description>",
"amountTwd": 0
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}更正一筆公司營業費用
/api/v1/pnl/expenses/{id}參數
categoryId必填費用類別 ID(對應公司費用類別目錄)
period必填歸屬月(格式 YYYY-MM),供月損益表彙整
description必填費用摘要
amountTwd必填費用金額(台幣非負整數)
incurredOn選填費用發生日期(格式 YYYY-MM-DD)
paidFromAccountId選填支付來源帳戶 ID
frontedByUserId選填代墊人使用者 ID(由員工先行墊付時填寫)
note選填備註
recurring選填是否為週期性費用
id路徑營業費用列 ID
payableId選填關聯的請款核簽 ID;整列覆寫時須原樣帶回,省略則清為 null
回應欄位 · data
ok固定為 true:營業費用列已更新。
curl -X PATCH https://your-tenant.example.com/api/v1/pnl/expenses/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"categoryId": "<categoryId>",
"period": "<period>",
"description": "<description>",
"amountTwd": 0
}'{
"ok": true,
"data": {
"ok": true
}
}the company monthly P&L statement
/api/v1/pnl/statement參數
period必填損益表結算月(格式 YYYY-MM)
extraIncome選填額外收入(台幣非負整數),併入公司淨利計算;預設 0
回應欄位 · data
period結算期間(YYYY-MM)。
regions各區毛利明細(出團月落 period 的梯次按區 roll-up)。
region派生 region key(穩定,由 trip 屬性派生)。
label顯示標籤(destination 原文 / 衍生)。
revenueTwd本區成交應收(出團月落 period 的梯次合計,TWD 整數)。
directCostTwd本區真實直接成本(TWD 整數)= 房費底價成本 + 已核准的逐筆成本合計。
marginTwd本區毛利 = revenue − directCost。
departures本區梯次數(出團月落 period)。
grossMarginTwd各區毛利加總(整數 TWD)。
revenueTotalTwd各區營收加總(整數 TWD)。
extraIncomeTwd額外收入(GS 二、額外收入總計;本批無 schema 載體 → 0,見 §5)。
adminFeeIncomeTwd行政手續費收入(退款收取的行政手續費,只計未出團 / 取消單,TWD 整數)。
otherIncomeTwd其他收入合計 = extraIncome + adminFeeIncome(整數 TWD)。
expensesByKind公司營業費用按 kind roll-up(opex / tax / platform_fee,只計已確認)。
kind'opex' / 'tax' / 'platform_fee'。
amountTwd該 kind 本期費用合計(整數 TWD)。
count該 kind 本期費用筆數。
operatingExpenseTotalTwd公司營業費用合計 = Σ opex / tax / platform_fee(整數 TWD)。
special特殊損益逐筆(kind='special',一次性、獨立列,只計已確認)。
id費用列 ID。
categoryId費用科目 ID(特殊損益科目)。
categoryDisplayName費用科目顯示名。
description摘要(如 取消神山床位沒收訂金)。
amountTwd金額(整數 TWD ≥ 0,DB CHECK operating_expenses_amount_nonneg)。**第一版 special 一律視為「損」**(扣減淨利,與營業費用同向)——對齊 GS 五月事件「取消神山床位沒收」= 損。schema 無 sign 欄,無法表達一次性「益」;一次性收益(§3.4)落地 sign 欄後再分流, 屆時 specialTotal 改帶號。當前 specialTotalTwd 一律從淨利扣減。
specialTotalTwd特殊損益加總(整數 TWD,第一版一律視為損)。
netProfitTwd公司淨利 = grossMargin + otherIncome − operatingExpenseTotal − specialTotal。
netMarginPct淨利率(netProfit / revenueTotal),revenue=0 時 null。
curl -X GET "https://your-tenant.example.com/api/v1/pnl/statement?period=<period>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"period": "…",
"regions": [
{
"region": "…",
"label": "…",
"revenueTwd": 0,
"directCostTwd": 0,
"marginTwd": 0,
"departures": 0
}
],
"grossMarginTwd": 0,
"revenueTotalTwd": 0,
"extraIncomeTwd": 0,
"adminFeeIncomeTwd": 0,
"otherIncomeTwd": 0,
"expensesByKind": [
{
"kind": "…",
"amountTwd": 0,
"count": 0
}
],
"operatingExpenseTotalTwd": 0,
"special": [
{
"id": "…",
"categoryId": "…",
"categoryDisplayName": "…",
"description": "…",
"amountTwd": 0
}
],
"specialTotalTwd": 0,
"netProfitTwd": 0,
"netMarginPct": 0
}
}/reports
tenant monthly
/api/v1/reports/monthly參數
year必填報表年份(西元四位數),月界以台北時區計
month必填報表月份,1 至 12
回應欄位 · data
year報表年份(西元四位數)。
month報表月份(1-12,月界以 Asia/Taipei 計)。
totalOrders本月建立的 tour 訂單數(依 created_at 計)。
paidOrders本月有實收現金的 tour 訂單數(月內有 inbound 交易)。
cancelledOrders本月取消的 tour 訂單數(依 updated_at 計)。
totalRevenuecollected_cash:本月實收現金 = SUM(payment_transactions in) within month。
refundedAmountrefunded_cash:本月退還現金 = SUM(payment_transactions out, refund/chargeback) within month。
netCashnet_cash:本月淨現金 = SUM(in:+amount, out:-amount) - SUM(fee) within month。
newCustomers本月新註冊會員數(排除 staff 角色)。
byTrip依行程銷售排行(前 10 名,按本月實收現金)。
tripId行程 ID。
tripTitle團名。
orderCount該行程本月有實收現金的訂單數。
revenuecollected_cash by trip:本月實收現金(tour-scoped)。
byProvider依金流商分組的本月實收現金。
provider金流商代碼(如 ecpay / test)。
orderCount該金流商本月有實收現金的訂單數。
amountcollected_cash by provider:本月實收現金(tour-scoped)。
dailyRevenuecollected_cash by day:本月逐日實收現金(tour-scoped,Asia/Taipei 日界), 整月零填滿(無入帳的日子 amount=0)。Σ amount === totalRevenue,與 KPI 對帳。
day日期(YYYY-MM-DD,Asia/Taipei 日界)。
amount當日實收現金(tour-scoped,整數 TWD)。
curl -X GET "https://your-tenant.example.com/api/v1/reports/monthly?year=<year>&month=<month>" \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"year": 0,
"month": 0,
"totalOrders": 0,
"paidOrders": 0,
"cancelledOrders": 0,
"totalRevenue": 0,
"refundedAmount": 0,
"netCash": 0,
"newCustomers": 0,
"byTrip": [
{
"tripId": "…",
"tripTitle": "…",
"orderCount": 0,
"revenue": 0
}
],
"byProvider": [
{
"provider": "…",
"orderCount": 0,
"amount": 0
}
],
"dailyRevenue": [
{
"day": "…",
"amount": 0
}
]
}
}/suppliers
廠商目錄列表
/api/v1/suppliers參數
status選填activeinactiveall依狀態篩選(active 啟用 / inactive 停用 / all 全部,預設 active)
q選填關鍵字搜尋(廠商名稱或類別)
回應欄位 · data[]
id廠商 ID。
name廠商名稱。
categoryHint慣用類別提示(租戶自定,非硬枚舉)。
payeeAccountName收款人戶名(批次轉帳檔欄 (1))。
payeeBankCode收款銀行代號(批次轉帳檔欄 (3))。
payeeAccountNumber收款帳號(批次轉帳檔欄 (2),遮罩回傳)。
status狀態:active 啟用 / inactive 停用(停用不刪)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/suppliers \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"name": "…",
"categoryHint": "…",
"payeeAccountName": "…",
"payeeBankCode": "…",
"payeeAccountNumber": "…",
"status": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/suppliers參數
name必填廠商名稱(出款對象顯示名)
categoryHint選填類別提示(如住宿、交通、餐飲),供分類與搜尋
payeeAccountName選填收款戶名(須與銀行帳戶登記名一致)
payeeBankCode選填銀行代號(3~7 碼數字,台銀通用四欄轉帳檔用)
payeeAccountNumber選填收款銀行帳號(純數字,write-only 寫入後僅回遮罩)
回應欄位 · data
ok固定為 true:廠商已新增。
id新建立廠商的 ID(sup_ 前綴)。
curl -X POST https://your-tenant.example.com/api/v1/suppliers \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>"
}'{
"ok": true,
"data": {
"ok": true,
"id": "…"
}
}單一廠商主檔
/api/v1/suppliers/{id}參數
id路徑廠商 id(路徑參數)
回應欄位 · data
id廠商 ID。
name廠商名稱。
categoryHint慣用類別提示(租戶自定,非硬枚舉)。
payeeAccountName收款人戶名(批次轉帳檔欄 (1))。
payeeBankCode收款銀行代號(批次轉帳檔欄 (3))。
payeeAccountNumber收款帳號(批次轉帳檔欄 (2),遮罩回傳)。
status狀態:active 啟用 / inactive 停用(停用不刪)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/suppliers/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"name": "…",
"categoryHint": "…",
"payeeAccountName": "…",
"payeeBankCode": "…",
"payeeAccountNumber": "…",
"status": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}/api/v1/suppliers/{id}參數
name選填廠商名稱(出款對象顯示名)
categoryHint選填類別提示(如住宿、交通、餐飲),供分類與搜尋
payeeAccountName選填收款戶名(須與銀行帳戶登記名一致)
payeeBankCode選填銀行代號(3~7 碼數字,台銀通用四欄轉帳檔用)
payeeAccountNumber選填收款銀行帳號(純數字,write-only 寫入後僅回遮罩)
id路徑廠商 id(路徑參數)
回應欄位 · data
ok固定為 true:廠商資料已更新。
curl -X PATCH https://your-tenant.example.com/api/v1/suppliers/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}/audit
list/filter the append-only tenant audit trail
/api/v1/audit/log參數
action選填動作代碼篩選,例如 order.update(比對稽核事件的動作)
actor選填操作者篩選,比對執行該動作的使用者 ID
entity選填目標實體篩選,比對被操作對象的類型或 ID
from選填起始時間(ISO 8601),僅回傳此時間之後的事件
to選填結束時間(ISO 8601),僅回傳此時間之前的事件
limit選填回傳筆數上限,最多 1000 筆
回應欄位 · data[]
id稽核事件 ID。
actorUserId操作者的使用者 ID;系統事件(webhook/排程等非人為列)為 null。
actorEmail操作者 Email;系統事件或帳號已刪時為 null。
actorName操作者顯示名;系統事件或帳號已刪時為 null。
action動作代碼,例如 order.create、traveler.decrypt。
targetType被操作對象的類型,例如 order、member。
targetId被操作對象的 ID。
metadata該事件的附帶內容(欄位隨動作而異的自由結構 JSON)。
ipAddress發起請求的來源 IP;無法取得時為 null。
createdAt事件發生時間。
curl -X GET https://your-tenant.example.com/api/v1/audit/log \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"actorUserId": "…",
"actorEmail": "…",
"actorName": "…",
"action": "…",
"targetType": "…",
"targetId": "…",
"metadata": "…",
"ipAddress": "…",
"createdAt": "2026-06-30T08:00:00.000Z"
}
]
}audit KPI counts
/api/v1/audit/stats參數
actor選填操作者使用者 ID,指定時將統計數據限縮至該操作者
回應欄位 · data
eventsThisMonth本月(Asia/Taipei)稽核事件總數。
eventsToday今日(Asia/Taipei)稽核事件總數。
writesThisMonth本月寫入類事件數(排除 *.read 讀取事件)。
distinctActorsThisMonth本月有動作紀錄的不重複操作者人數。
curl -X GET https://your-tenant.example.com/api/v1/audit/stats \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"eventsThisMonth": 0,
"eventsToday": 0,
"writesThisMonth": 0,
"distinctActorsThisMonth": 0
}
}/leaderboard
全公司業務業績排行
/api/v1/leaderboard參數
period選填monthquarteryearall業績統計區間:當月、當季、當年或全部,預設 month
回應欄位 · data[]
userId業務的使用者 ID。
name業務顯示姓名。
email業務登入 Email。
role業務角色代碼(admin/sales/op/accountant)。
orderCount承作訂單總數(歸屬此業務、含各狀態的旅遊團訂單)。
paidCount已成交訂單數(已付款或履約完成)。
cancelledCount已取消訂單數。
revenue業績額(TWD 整數):歸屬於該業務、未取消訂單的應收合計。
commissionTwd估算佣金 = round(revenue × sales_commission_bps / 10000)(tenant_settings 費率)。
bonusTwd月度第一名加碼 = round(revenue × monthly_top_bonus_bps / 10000),僅當期 rank 1 且 revenue > 0;其餘為 0。與 isMonthlyTop 同步。
isMonthlyTop當期 rank 1(revenue > 0)=月度第一,享 bonus。
avgOrderTwd客單均價 = round(revenue / orderCount);0 單為 0。
curl -X GET https://your-tenant.example.com/api/v1/leaderboard \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"userId": "…",
"name": "…",
"email": "…",
"role": "…",
"orderCount": 0,
"paidCount": 0,
"cancelledCount": 0,
"revenue": 0,
"commissionTwd": 0,
"bonusTwd": 0,
"isMonthlyTop": true,
"avgOrderTwd": 0
}
]
}待派發訂單 KPI
/api/v1/leaderboard/review-stats回應欄位 · data
pendingCount待派發(pending_review)訂單筆數。
pendingTotalTwd待派發訂單的應收金額合計(新台幣)。
longestWaitHours目前待派發訂單中,最長已等待的時數。
thisMonthAssigned本月(Asia/Taipei)已完成派發的訂單數。
curl -X GET https://your-tenant.example.com/api/v1/leaderboard/review-stats \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"pendingCount": 0,
"pendingTotalTwd": 0,
"longestWaitHours": 0,
"thisMonthAssigned": 0
}
}/message-templates
list canned message templates
/api/v1/message-templates參數
channel選填lineemail依發送管道篩選範本(line 或 email)
回應欄位 · data[]
id範本 ID。
key穩定識別碼(NULL = 未指定)。
stageSOP 階段(受理 → 出團完成)。
channel發送管道:line 或 email。
title範本標題。
bodySingle單人版內文(含 {{...}} 合併變數)。
bodyMulti多人版變體;NULL = 只有單人版。
isActive是否為該階段目前啟用的範本。
createdAt建立時間。
updatedAt最後更新時間。
updatedBy最後更新者姓名(LEFT JOIN 同庫 user;未知 / 帳號已刪為 null)。
curl -X GET https://your-tenant.example.com/api/v1/message-templates \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"key": "…",
"stage": "受理",
"channel": "email",
"title": "…",
"bodySingle": "…",
"bodyMulti": "…",
"isActive": true,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z",
"updatedBy": "…"
}
]
}/api/v1/message-templates參數
key選填範本識別碼,2–64 碼大寫英數 / _ / -(用於程式化引用,選填,自動轉大寫)
stage必填訊息對應的 SOP 階段
channel必填發送管道(line 或 email)
title必填範本標題(供後台辨識)
bodySingle必填單人版訊息內文
bodyMulti選填多人版訊息內文(留空表示沿用單人版;選填)
isActive選填是否啟用(停用後不出現在可選範本中)
回應欄位 · data
id新建立的訊息範本 ID。
curl -X POST https://your-tenant.example.com/api/v1/message-templates \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"stage": "<stage>",
"channel": "<channel>",
"title": "<title>",
"bodySingle": "<bodySingle>"
}'{
"ok": true,
"data": {
"id": "…"
}
}single canned message template detail.
/api/v1/message-templates/{id}參數
id路徑訊息範本 ID
回應欄位 · data
id範本 ID。
key穩定識別碼(NULL = 未指定)。
stageSOP 階段(受理 → 出團完成)。
channel發送管道:line 或 email。
title範本標題。
bodySingle單人版內文(含 {{...}} 合併變數)。
bodyMulti多人版變體;NULL = 只有單人版。
isActive是否為該階段目前啟用的範本。
createdAt建立時間。
updatedAt最後更新時間。
updatedBy最後更新者姓名(LEFT JOIN 同庫 user;未知 / 帳號已刪為 null)。
curl -X GET https://your-tenant.example.com/api/v1/message-templates/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"key": "…",
"stage": "受理",
"channel": "email",
"title": "…",
"bodySingle": "…",
"bodyMulti": "…",
"isActive": true,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z",
"updatedBy": "…"
}
}/api/v1/message-templates/{id}參數
id路徑要更新的訊息範本 ID
key選填範本識別碼,2–64 碼大寫英數 / _ / -(用於程式化引用,選填,自動轉大寫)
stage必填訊息對應的 SOP 階段
channel必填發送管道(line 或 email)
title必填範本標題(供後台辨識)
bodySingle必填單人版訊息內文
bodyMulti選填多人版訊息內文(留空表示沿用單人版;選填)
isActive選填是否啟用(停用後不出現在可選範本中)
回應欄位 · data
ok是否成功更新訊息範本。
curl -X PATCH https://your-tenant.example.com/api/v1/message-templates/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"stage": "<stage>",
"channel": "<channel>",
"title": "<title>",
"bodySingle": "<bodySingle>"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/message-templates/{id}參數
id路徑訊息範本 ID
回應欄位 · data
ok是否成功刪除訊息範本。
curl -X DELETE https://your-tenant.example.com/api/v1/message-templates/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}enable / disable
/api/v1/message-templates/{id}/active參數
id路徑要啟用 / 停用的訊息範本 ID
isActive必填true 啟用、false 停用(軟刪除)此範本
回應欄位 · data
ok是否成功切換訊息範本的啟用狀態。
curl -X POST https://your-tenant.example.com/api/v1/message-templates/<id>/active \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"isActive": true
}'{
"ok": true,
"data": {
"ok": true
}
}/roles
list all roles
/api/v1/roles參數
system選填truefalse是否只列內建角色:true 僅內建、false 僅自訂,省略則全部
回應欄位 · data[]
id角色 ID(內建角色為其代碼)。
name角色代碼(小寫英數與底線,建立後不可改;即帳號綁定的角色值)。
label角色顯示名稱。
isSystem是否為系統內建角色(內建角色不可修改或刪除)。
permissionCount該角色目前擁有的 (resource, action) 數量。
memberCount持有此角色的使用者人數。
curl -X GET https://your-tenant.example.com/api/v1/roles \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"name": "…",
"label": "…",
"isSystem": true,
"permissionCount": 0,
"memberCount": 0
}
]
}/api/v1/roles參數
name必填角色代碼,小寫英數與底線、2–32 字且須以字母開頭,建立後不可改
label必填角色顯示名稱,呈現於後台角色清單
permissions選填此角色授予的權限清單,每筆為一組資源與動作
回應欄位 · data
id新建立的角色 ID。
curl -X POST https://your-tenant.example.com/api/v1/roles \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "<name>",
"label": "<label>"
}'{
"ok": true,
"data": {
"id": "…"
}
}one role + its full
/api/v1/roles/{id}參數
id路徑角色 ID(內建角色為其代碼)
回應欄位 · data
id角色 ID(內建角色為其代碼)。
name角色代碼(小寫英數與底線,建立後不可改;即帳號綁定的角色值)。
label角色顯示名稱。
isSystem是否為系統內建角色(內建角色不可修改或刪除)。
permissions此角色授予的完整 (resource, action) 權限清單。
resource權限資源代碼,例如 order、member。
action權限動作代碼,例如 read、update。
curl -X GET https://your-tenant.example.com/api/v1/roles/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"name": "…",
"label": "…",
"isSystem": true,
"permissions": [
{
"resource": "…",
"action": "…"
}
]
}
}/api/v1/roles/{id}參數
id路徑欲更新的角色 ID
label必填角色顯示名稱,呈現於後台角色清單
permissions選填完整取代後的權限清單,會整批覆寫此角色現有權限
回應欄位 · data
ok是否成功更新角色。
curl -X PATCH https://your-tenant.example.com/api/v1/roles/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "<label>"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/roles/{id}參數
id路徑角色 ID(內建角色為其代碼)
回應欄位 · data
ok是否成功刪除角色。
curl -X DELETE https://your-tenant.example.com/api/v1/roles/<id> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}the code-defined permission catalog: every legal
/api/v1/roles/catalog回應欄位 · data[]
resource權限資源代碼,例如 order、member。
actions此資源可授予的動作代碼清單,例如 read、update。
curl -X GET https://your-tenant.example.com/api/v1/roles/catalog \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"resource": "…",
"actions": [
"…"
]
}
]
}/settings
the tenant_settings singleton
/api/v1/settings回應欄位 · data
id設定列 ID(單例,恆為 'singleton')。
companyName公司全名,顯示於發票、合約與對外信件抬頭;null = 未設定。
companyPhone公司聯絡電話,顯示於對外文件;null = 未設定。
taxId公司統一編號(8 位數字),用於開立發票;null = 未設定。
companyAddress公司登記地址,顯示於對外文件;null = 未設定。
logoUrl公司 Logo 圖片網址,用於後台與對外頁面品牌呈現;null = 未設定。
siteTagline公開站標語(SEO/首頁);null = 未設定。
seoDefaultDescription公開站預設 SEO meta description;null = 未設定。
ogImageUrl社群分享預設 Open Graph 圖片網址;null = 未設定。
emailReplyTo系統寄信時的回覆收件信箱;null = 未設定。
assignmentModeS5: 'auto_round_robin' | 'auto_customer_choice' | 'manual_review'
defaultAssigneeUserIdS5: fallback assignee when round-robin finds no active sales, etc.
allowSalesClaimorder-assignment §6:業務自派搶單開關(per-tenant opt-in,預設 false)。
passportExpiryWarningDays護照效期提醒天數(document-expiry §4.1;NOT NULL DEFAULT 180)。
groupCodePattern團號 token 樣板(如 '{YY}{region}{airline?}{MMDD}{seq}')。NULL = 內建預設。
groupCodeSeqStyle序號樣式:'alpha' | 'alpha_no_io' | 'numeric'(NOT NULL DEFAULT 'alpha')。
groupCodeSeqWidthnumeric 序號補零寬度(NOT NULL DEFAULT 2;alpha 樣式忽略)。
ecpayFeeBps預估綠界手續費率(270 = 2.70%)。NOT NULL DEFAULT 270。
fongshouFeeBps預估豐收款手續費率(50 = 0.50%)。NOT NULL DEFAULT 50。
profitTaxBps預估發票 / 營所稅率(500 = 5.00%)。NOT NULL DEFAULT 500。
salesCommissionBps業務抽成率(1000 = 10.00%)。NOT NULL DEFAULT 1000。
monthlyTopBonusBps月度第一名加碼率(500 = 5.00%)。NOT NULL DEFAULT 500。
ecpayMerchantIdECPay 特店 ID(明文,顯示用)。null = 未綁定租戶憑證(走 env 過渡)。
ecpaySecretsMaskECPay HashKey/HashIV 的遮罩碼(`****` + 末 4)。DTO **只暴露 mask**, 整包 EncryptedField(含密文)永不出 repo —— 顯示用零 KMS 呼叫。
travelinvoiceMerchantId代收轉付 travelinvoice 特店 ID(明文,顯示用)。null = 未綁定租戶憑證(fail-closed)。
travelinvoiceSecretsMasktravelinvoice HashKey/HashIV 的遮罩碼(`****` + 末 4)。DTO **只暴露 mask**, 整包 EncryptedField(含密文)永不出 repo —— 顯示用零 KMS 呼叫。
sendingDomain自有寄件 domain 快照;server 派生(enableSendingDomain),非自由輸入。
resendDomainId寄件服務商(Resend)的 domain 識別碼;null = 未設定自有寄件網域。
sendingDomainStatus自有寄件網域的驗證狀態(如 pending/verified);null = 未設定。
senderLocalPart寄件人 local-part,未填視為 'info'。
updatedAt設定最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/settings \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"id": "…",
"companyName": "…",
"companyPhone": "…",
"taxId": "…",
"companyAddress": "…",
"logoUrl": "…",
"siteTagline": "…",
"seoDefaultDescription": "…",
"ogImageUrl": "…",
"emailReplyTo": "…",
"assignmentMode": "…",
"defaultAssigneeUserId": "…",
"allowSalesClaim": true,
"passportExpiryWarningDays": 0,
"groupCodePattern": "…",
"groupCodeSeqStyle": "…",
"groupCodeSeqWidth": 0,
"ecpayFeeBps": 0,
"fongshouFeeBps": 0,
"profitTaxBps": 0,
"salesCommissionBps": 0,
"monthlyTopBonusBps": 0,
"ecpayMerchantId": "…",
"ecpaySecretsMask": "…",
"travelinvoiceMerchantId": "…",
"travelinvoiceSecretsMask": "…",
"sendingDomain": "…",
"resendDomainId": "…",
"sendingDomainStatus": "…",
"senderLocalPart": "…",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
}/api/v1/settings參數
companyName選填公司全名,顯示於發票、合約與對外信件抬頭;傳 null 或空字串清除
companyPhone選填公司聯絡電話,顯示於對外文件;傳 null 或空字串清除
taxId選填公司統一編號(8 位數字),用於開立發票;傳 null 或空字串清除
companyAddress選填公司登記地址,顯示於對外文件;傳 null 或空字串清除
logoUrl選填公司 Logo 圖片網址(http/https),用於後台與對外頁面品牌呈現;傳 null 或空字串清除
emailReplyTo選填系統寄信時的回覆收件信箱,客戶回信會寄到此處;傳 null 或空字串清除
senderLocalPart選填寄件人信箱的帳號部分(@ 前段),與寄件網域組成完整寄件地址;傳 null 或空字串清除
passportExpiryWarningDays選填護照到期前提早幾天提醒(1 至 3650 天),用於行前護照效期預警
回應欄位 · data
ok是否成功更新租戶設定。
curl -X PATCH https://your-tenant.example.com/api/v1/settings \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}the staff pool eligible to be an
/api/v1/settings/assignable-staff回應欄位 · data[]
userId員工的使用者 ID(作為指派對象)。
name員工顯示姓名。
email員工登入 Email。
role員工角色代碼(sales/admin 等可指派角色)。
thisMonthAssigned本月(Asia/Taipei)已指派給此員工的訂單數(供輪派負載參考)。
curl -X GET https://your-tenant.example.com/api/v1/settings/assignable-staff \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"userId": "…",
"name": "…",
"email": "…",
"role": "…",
"thisMonthAssigned": 0
}
]
}S5 order-assignment mode + default
/api/v1/settings/assignment參數
assignmentMode必填auto_round_robinauto_customer_choiceauto_by_destinationmanual_review訂單指派模式:auto_round_robin 輪流自動指派、auto_customer_choice 依客戶選擇指派、auto_by_destination 依目的地地區碼對應規則指派、manual_review 進待審由人工指派
defaultAssigneeUserId選填預設承辦人員的使用者 ID,自動指派找不到對象時的兜底承辦人;空字串表示不設預設
allowSalesClaim選填是否開放業務自派搶單(從待派發池自行搶單);未提供則不變更
回應欄位 · data
ok是否成功更新訂單指派模式設定。
curl -X PATCH https://your-tenant.example.com/api/v1/settings/assignment \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"assignmentMode": "auto_round_robin"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/settings/ecpay-credentials參數
merchantId必填綠界 ECPay 特店編號(MerchantID),用於金流請款與簽章
hashKey必填綠界 ECPay HashKey,CheckMacValue 簽章用密鑰;寫入後即 KMS 加密儲存且永不回傳
hashIv必填綠界 ECPay HashIV,CheckMacValue 簽章用初始向量;寫入後即 KMS 加密儲存且永不回傳
回應欄位 · data
ok是否成功儲存 ECPay 憑證(HashKey/HashIV 已 KMS 加密,永不回傳)。
curl -X PUT https://your-tenant.example.com/api/v1/settings/ecpay-credentials \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"merchantId": "<merchantId>",
"hashKey": "<hashKey>",
"hashIv": "<hashIv>"
}'{
"ok": true,
"data": {
"ok": true
}
}/api/v1/settings/ecpay-credentials回應欄位 · data
ok是否成功清除 ECPay 憑證。
curl -X DELETE https://your-tenant.example.com/api/v1/settings/ecpay-credentials \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}公司營業費用類別目錄
/api/v1/settings/expense-categories參數
activeOnly選填是否只回傳啟用中的費用類別(true/false);省略則含停用
回應欄位 · data[]
id費用類別 ID。
code科目代碼(租戶內唯一穩定識別,如 rent / salary_admin / tax_vat)。
displayName顯示名(如 房租 / 行政薪資 / 營業稅)。
kind費用大類:opex 營業費用 / tax 稅 / platform_fee 平台手續費 / special 特殊損益(損益表據此 roll-up)。
isActive是否啟用(停用不刪,既有費用列仍引用得到)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/settings/expense-categories \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"code": "…",
"displayName": "…",
"kind": "opex",
"isActive": true,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/settings/expense-categories參數
code必填費用類別代碼(小寫英數與底線),建立後不可變更,作為類別的穩定識別
displayName必填費用類別顯示名稱,呈現於後台費用登錄與報表
kind必填費用類別種類:opex 營業費用、tax 稅務、platform_fee 平台手續費、special 特殊,影響損益表歸類
回應欄位 · data
id新建立的費用類別 ID。
curl -X POST https://your-tenant.example.com/api/v1/settings/expense-categories \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"displayName": "<displayName>",
"kind": "<kind>"
}'{
"ok": true,
"data": {
"id": "…"
}
}更新費用類別的顯示名 / kind +
/api/v1/settings/expense-categories/{id}參數
id路徑費用類別 ID(路徑參數),指定要更新的類別
displayName必填費用類別顯示名稱,呈現於後台費用登錄與報表
kind必填費用類別種類:opex 營業費用、tax 稅務、platform_fee 平台手續費、special 特殊,影響損益表歸類
isActive必填是否啟用此費用類別;false 為停用(停用而非刪除)
回應欄位 · data
ok是否成功更新費用類別。
curl -X PATCH https://your-tenant.example.com/api/v1/settings/expense-categories/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"displayName": "<displayName>",
"kind": "<kind>",
"isActive": true
}'{
"ok": true,
"data": {
"ok": true
}
}toggle a費用類別
/api/v1/settings/expense-categories/{id}/active參數
id路徑費用類別 ID(路徑參數),指定要切換啟用狀態的類別
isActive必填目標啟用狀態:true 啟用、false 停用(停用而非刪除)
回應欄位 · data
ok是否成功切換費用類別的啟用狀態。
curl -X PATCH https://your-tenant.example.com/api/v1/settings/expense-categories/<id>/active \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"isActive": true
}'{
"ok": true,
"data": {
"ok": true
}
}fee-category → final receiving
/api/v1/settings/fee-category-routes回應欄位 · data[]
id路由設定 ID。
feeCategory費用類型代碼(租戶自定唯一鍵,如 tour_fee/lodging/equipment)。
displayName費用類型顯示名。
finalAccountId此費用類型最終結算進的收款帳戶 ID。
finalAccountNamefinal 帳戶顯示名(JOIN receiving_accounts;帳戶被刪則 null,但 FK restrict 一般不會)。
finalAccountCodefinal 帳戶代號。
isActive此路由是否啟用。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/settings/fee-category-routes \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"feeCategory": "…",
"displayName": "…",
"finalAccountId": "…",
"finalAccountName": "…",
"finalAccountCode": "…",
"isActive": true,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/settings/fee-category-routes參數
feeCategory必填費用類型代碼(小寫英數與底線),此 upsert 的唯一鍵;決定該手續費類型最終結算到哪個帳戶
displayName必填費用類型路由的顯示名稱,呈現於對帳設定
finalAccountId必填此費用類型最終結算進的收款帳戶 ID
isActive選填是否啟用此費用類型路由;省略則維持預設啟用
回應欄位 · data
id新建立或更新的費用類型路由 ID。
curl -X PUT https://your-tenant.example.com/api/v1/settings/fee-category-routes \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"feeCategory": "<feeCategory>",
"displayName": "<displayName>",
"finalAccountId": "<finalAccountId>"
}'{
"ok": true,
"data": {
"id": "…"
}
}toggle a fee-category
/api/v1/settings/fee-category-routes/{id}/active參數
id路徑費用類型路由 ID(路徑參數,非 feeCategory 代碼),指定要切換啟用狀態的路由
isActive必填目標啟用狀態:true 啟用、false 停用(停用而非刪除)
回應欄位 · data
ok是否成功切換費用類型路由的啟用狀態。
curl -X PATCH https://your-tenant.example.com/api/v1/settings/fee-category-routes/<id>/active \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"isActive": true
}'{
"ok": true,
"data": {
"ok": true
}
}internal/external-ledger profit estimate
/api/v1/settings/ledger-fees參數
ecpayFeeBps選填綠界 ECPay 金流手續費率,單位 basis points(0..10000,10000=100%),用於內外帳淨利試算;留空不變更
fongshouFeeBps選填豐收金流手續費率,單位 basis points(0..10000,10000=100%),用於內外帳淨利試算;留空不變更
profitTaxBps選填淨利稅率,單位 basis points(0..10000,10000=100%),用於內外帳淨利試算;留空不變更
回應欄位 · data
ok是否成功更新內外帳淨利試算的預估費率。
curl -X PATCH https://your-tenant.example.com/api/v1/settings/ledger-fees \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}the tenant's enabled plan modules
/api/v1/settings/modules回應欄位 · data
climbing是否啟用登山團功能模組。
overseas是否啟用海外/出國團功能模組。
lodging是否啟用訂房子系統模組。
accounting是否啟用進階會計子系統模組。
lottery是否啟用抽籤子系統模組。
curl -X GET https://your-tenant.example.com/api/v1/settings/modules \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"climbing": true,
"overseas": true,
"lodging": true,
"accounting": true,
"lottery": true
}
}the收款帳戶目錄
/api/v1/settings/receiving-accounts參數
activeOnly選填是否只回傳啟用中的收款帳戶(true/false);省略則含停用
回應欄位 · data[]
id收款帳戶 ID。
code帳戶代碼(租戶內唯一穩定識別)。
displayName帳戶顯示名。
kind帳戶類型:bank 銀行 / cash 現金 / gateway 金流閘道。
bankName銀行名稱;現金/閘道帳戶為 null。
accountNo銀行帳號;現金/閘道帳戶為 null。
canReceive可收款(幾乎都 true)。
canRemit可對外匯款(ATM / 匯出退款 / 補款匯出)。荒野只有永豐。
canChargeback可刷退(退回原信用卡)。荒野只有綠界(gateway)。
isDeprecated廢帳戶:仍可零星收款,但其收款需由他帳戶代墊歸集。荒野=RU 台銀 / 登山社。
isSettlementMaster主結算帳戶:所有資金最終向它彙整。每租戶恰一個(partial unique index)。荒野=永豐。
currency帳戶幣別(ISO 4217;既有帳戶皆 'TWD',外幣帳戶如 IDR / USD)。
isActive此帳戶是否啟用。
displayOrder後台清單排序序位(小者在前)。
usedCount被多少 payment_transactions 引用(UI 鎖頭 / 「使用中 N」)。
createdAt建立時間。
updatedAt最後更新時間。
curl -X GET https://your-tenant.example.com/api/v1/settings/receiving-accounts \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"id": "…",
"code": "…",
"displayName": "…",
"kind": "…",
"bankName": "…",
"accountNo": "…",
"canReceive": true,
"canRemit": true,
"canChargeback": true,
"isDeprecated": true,
"isSettlementMaster": true,
"currency": "…",
"isActive": true,
"displayOrder": 0,
"usedCount": 0,
"createdAt": "2026-06-30T08:00:00.000Z",
"updatedAt": "2026-06-30T08:00:00.000Z"
}
]
}/api/v1/settings/receiving-accounts參數
code必填收款帳戶代號,建立後不可變更,作為帳戶的穩定識別
displayName必填收款帳戶顯示名稱,呈現於收款與對帳介面
kind必填bankcashgateway帳戶種類:bank 銀行帳戶、cash 現金、gateway 金流閘道
bankName選填銀行名稱(bank 類別適用);空字串清除
accountNo選填銀行帳號(bank 類別適用);空字串清除
currency選填帳戶幣別,ISO 4217 三碼(如 TWD / JPY / IDR);空字串預設 TWD,非 TWD 即為外幣池
displayOrder選填排序權重(0..9999),數字越小越前面;預設 0
isActive選填是否啟用此帳戶;省略維持預設
canReceive選填是否可作為收款(進帳)帳戶
canRemit選填是否可作為出款(匯出)帳戶
canChargeback選填是否可作為退款 / 退刷帳戶
isDeprecated選填是否標記為已淘汰(保留歷史紀錄但不再新用)
isSettlementMaster選填是否為主結算帳戶;每租戶僅能有一個,月結互抵以此為彙整中心
回應欄位 · data
id新建立的收款帳戶 ID。
curl -X POST https://your-tenant.example.com/api/v1/settings/receiving-accounts \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "<code>",
"displayName": "<displayName>",
"kind": "bank"
}'{
"ok": true,
"data": {
"id": "…"
}
}update a收款帳戶
/api/v1/settings/receiving-accounts/{id}參數
id路徑收款帳戶 ID(路徑參數),指定要更新的帳戶
displayName必填收款帳戶顯示名稱,呈現於收款與對帳介面
kind必填bankcashgateway帳戶種類:bank 銀行帳戶、cash 現金、gateway 金流閘道
bankName選填銀行名稱(bank 類別適用);空字串清除
accountNo選填銀行帳號(bank 類別適用);空字串清除
currency選填帳戶幣別,ISO 4217 三碼(如 TWD / JPY / IDR);空字串預設 TWD,非 TWD 即為外幣池
displayOrder必填排序權重(0..9999),數字越小越前面
isActive選填是否啟用此帳戶;省略維持原值
canReceive選填是否可作為收款(進帳)帳戶
canRemit選填是否可作為出款(匯出)帳戶
canChargeback選填是否可作為退款 / 退刷帳戶
isDeprecated選填是否標記為已淘汰(保留歷史紀錄但不再新用)
isSettlementMaster選填是否為主結算帳戶;每租戶僅能有一個,月結互抵以此為彙整中心
回應欄位 · data
ok是否成功更新收款帳戶。
curl -X PATCH https://your-tenant.example.com/api/v1/settings/receiving-accounts/<id> \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"displayName": "<displayName>",
"kind": "bank",
"displayOrder": 0
}'{
"ok": true,
"data": {
"ok": true
}
}the tenant's custom email sending-domain
/api/v1/settings/sending-domain回應欄位 · data
sendingDomain自有寄件網域;未設定時為 null。
resendDomainId寄件服務商(Resend)的網域識別碼;未設定時為 null。
sendingDomainStatus網域驗證狀態(如 pending/verified);未設定時為 null。
senderLocalPart寄件人信箱的帳號部分(@ 前段);未填視為 info。
records待設定的 DNS 記錄清單(SPF/DKIM 等);Resend 不可達或未設定時為空陣列。
recordDNS 記錄用途分類(如 DKIM/SPF 等,來自 Resend)。
name記錄主機名(需在網域 DNS 新增的 host)。
type記錄類型(如 TXT/MX/CNAME)。
value記錄值(需填入 DNS 的內容)。
ttl選填存活時間(TTL);未指定時省略。
status選填此筆記錄的驗證狀態(如 pending/verified);未指定時省略。
priority選填MX 記錄優先權;非 MX 記錄省略。
curl -X GET https://your-tenant.example.com/api/v1/settings/sending-domain \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"sendingDomain": "…",
"resendDomainId": "…",
"sendingDomainStatus": "…",
"senderLocalPart": "…",
"records": [
{
"record": "…",
"name": "…",
"type": "…",
"value": "…",
"ttl": "…",
"status": "…",
"priority": 0
}
]
}
}tear down the tenant's custom
/api/v1/settings/sending-domain/disable回應欄位 · data
ok是否成功停用自有寄件網域。
curl -X POST https://your-tenant.example.com/api/v1/settings/sending-domain/disable \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}provision the tenant's custom
/api/v1/settings/sending-domain/enable回應欄位 · data
ok是否成功啟用自有寄件網域。
domain啟用的寄件網域(由綁定的站台網域派生)。
curl -X POST https://your-tenant.example.com/api/v1/settings/sending-domain/enable \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true,
"domain": "…"
}
}re-sync DNS verification status
/api/v1/settings/sending-domain/verify回應欄位 · data
ok是否成功觸發驗證狀態同步。
status從 Resend 同步回來的最新網域驗證狀態(如 pending/verified)。
curl -X POST https://your-tenant.example.com/api/v1/settings/sending-domain/verify \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true,
"status": "…"
}
}SEO defaults subset of tenant_settings
/api/v1/settings/seo參數
siteTagline選填網站標語,顯示於公開站標題與品牌呈現;空字串清除
seoDefaultDescription選填SEO 預設頁面描述(meta description),未個別設定的頁面套用此值;空字串清除
ogImageUrl選填社群分享預設縮圖(Open Graph image)網址(http/https);空字串清除
回應欄位 · data
ok是否成功更新公開站 SEO 設定。
curl -X PATCH https://your-tenant.example.com/api/v1/settings/seo \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
}'{
"ok": true,
"data": {
"ok": true
}
}/staff
list every staffer in the tenant DB
/api/v1/staff回應欄位 · data[]
userId員工的使用者 ID。
email員工登入 Email(帳號識別)。
name員工顯示姓名。
role員工角色代碼(admin/sales/op/accountant)。
createdAt帳號建立時間。
bannedAccount frozen via ban (離職 / 停權).
twoFactorEnabled是否已完成 TOTP 兩步驟驗證註冊。
emailVerifiedEmail 是否已驗證(可視為「受邀者至少完成過一次登入」)。
pending派生的「邀請待完成」狀態:帳號已建立,但受邀者尚未驗證 Email 也未註冊 2FA(未完成首次登入)。
curl -X GET https://your-tenant.example.com/api/v1/staff \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": [
{
"userId": "…",
"email": "…",
"name": "…",
"role": "…",
"createdAt": "2026-06-30T08:00:00.000Z",
"banned": true,
"twoFactorEnabled": true,
"emailVerified": true,
"pending": true
}
]
}remove a staffer
/api/v1/staff/{userId}參數
userId路徑欲移除員工身分的使用者 ID(將降為一般顧客)
回應欄位 · data
ok是否成功移除員工身分(降為一般顧客)。
curl -X DELETE https://your-tenant.example.com/api/v1/staff/<userId> \ -H "Authorization: Bearer $CAIRN_TOKEN"
{
"ok": true,
"data": {
"ok": true
}
}change a staffer's role
/api/v1/staff/{userId}/role參數
userId路徑欲變更角色的員工使用者 ID
role必填變更後的員工角色(admin/sales/op/accountant),決定權限範圍
回應欄位 · data
ok是否成功變更員工角色。
curl -X PATCH https://your-tenant.example.com/api/v1/staff/<userId>/role \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"role": "<role>"
}'{
"ok": true,
"data": {
"ok": true
}
}建立一個新員工帳號
/api/v1/staff/invite參數
email必填受邀員工的登入 Email,作為帳號識別
name必填員工顯示姓名
role必填指派的員工角色(admin/sales/op/accountant),決定權限範圍
回應欄位 · data
userId新建立員工的使用者 ID。
tempPassword一次性明文暫時密碼,僅此次回傳(請立即轉交並要求員工首次登入改密)。
email新員工的登入 Email。
role指派的員工角色(admin/sales/op/accountant)。
curl -X POST https://your-tenant.example.com/api/v1/staff/invite \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "<email>",
"name": "<name>",
"role": "<role>"
}'{
"ok": true,
"data": {
"userId": "…",
"tempPassword": "…",
"email": "…",
"role": "…"
}
}