Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/i18n/messages/wise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const wise = {
no_sync_from: { "zh-TW": "未設切換日", en: "no cutover date" },
account_missing: { "zh-TW": "帳本帳戶不存在", en: "ledger account missing" },
currency_mismatch: { "zh-TW": "幣別不符", en: "currency mismatch" },
sca_required: { "zh-TW": "Wise 要求強驗證(SCA),此帳戶無法以 API token 讀取對帳單", en: "Wise requires SCA for this statement; it can't be read with an API token" },
},
nothing: { "zh-TW": "沒有新的交易需要寫入。", en: "Nothing new to write." },
apply: { "zh-TW": "寫入 {count} 筆", en: "Write {count} entries" },
Expand Down
2 changes: 1 addition & 1 deletion src/lib/mcp/tools-wise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const SYNC_OUTPUT = {
currency: { type: "string" },
reason: {
type: "string",
enum: ["unmapped", "no_sync_from", "account_missing", "currency_mismatch"],
enum: ["unmapped", "no_sync_from", "account_missing", "currency_mismatch", "sca_required"],
},
},
},
Expand Down
16 changes: 12 additions & 4 deletions src/lib/wise-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { IntegrationConfig } from "@/lib/integrations/types";
import {
discoverAccounts,
withWiseClient,
WiseScaRequiredError,
type WiseBalanceSummary,
type WiseClient,
type WiseProfileSummary,
Expand Down Expand Up @@ -592,7 +593,7 @@ export type SkippedBalance = {
profileName: string;
balanceId: number;
currency: string;
reason: "unmapped" | "no_sync_from" | "account_missing" | "currency_mismatch";
reason: "unmapped" | "no_sync_from" | "account_missing" | "currency_mismatch" | "sca_required";
};

export type SyncResult = {
Expand Down Expand Up @@ -980,9 +981,16 @@ export async function syncWiseTransactions(orgId: string, opts: SyncOptions): Pr
skippedBalances.push(skippedEntry(m, profileName, check.reason));
continue;
}
const { result, rows } = await planAccount(ctx, m, check.acct, check.syncFrom);
planned.push(...rows);
results.push(result);
// 個人 profile 的對帳單常被 Wise 要求 SCA(本系統不實作 SCA 簽章):
// 只跳過這個餘額並列在結果裡,不讓整次同步失敗、其他帳戶照常同步。
try {
const { result, rows } = await planAccount(ctx, m, check.acct, check.syncFrom);
planned.push(...rows);
results.push(result);
} catch (e) {
if (!(e instanceof WiseScaRequiredError)) throw e;
skippedBalances.push(skippedEntry(m, profileName, "sca_required"));
}
}

const existing = await existingRefs(db, orgId, planned.map((p) => p.externalRef));
Expand Down
Loading