你可能常聽到「這個購物網站有串接電子發票」「我們系統要串接發票功能」這種說法。
但串接的「對方」到底是誰?串接之後系統之間到底在傳什麼資料?為什麼有些公司自己接財政部的 API,有些公司卻寧願花錢找第三方服務?
如果你正準備在自己的系統裡加上開立發票的功能,這篇文章會從最基礎的「電子發票是什麼」開始,一路講到「串接的時候程式碼長什麼樣子」,讓你把整個脈絡串起來。
電子發票是什麼?
在談「串接」之前,要先搞懂被串接的東西是什麼。
電子發票的正式名稱是「電子計算機統一發票」,概念上跟你在超商拿到的紙本統一發票是同一件事,差別只在於它不是印在紙上,而是以電子資料的形式產生、傳輸、保存。
每一張電子發票都會有一組「發票號碼」,格式是 2 碼英文字母加上 8 碼數字,例如 AB-12345678。
這個 2 碼英文字母的部分,業界叫做「字軌」。
字軌白話一點說,就是「這批號碼是哪個系列的」。
國稅局會核發給每家公司一段一段的字軌跟號碼範圍,公司要先申請到這些額度,之後開立發票時,才能依序把號碼用掉。
這件事很重要,因為它直接影響到「串接」的本質:發票號碼不是你的系統自己亂數產生的,而是要跟有配號權限的單位要來的。
一張發票從產生到結束,大致會經過這幾個階段:
- 配號:公司先跟國稅局申請一批字軌與號碼範圍。
- 開立:實際交易發生時,系統把這筆交易的金額、品項等資訊,對應到一個發票號碼上,正式產生一張發票。
- 上傳:開立後的發票資料要回報給財政部的平台,讓財政部知道這個號碼已經被用掉、用在哪筆交易。
- 作廢 / 折讓:如果交易取消或退貨,發票不能直接刪除,而是要透過「作廢」或「折讓」的動作,留下完整的紀錄。
搞懂這個生命週期之後,你會發現「開發票」這件事,其實從頭到尾都需要跟外部單位保持聯繫,這也是為什麼會需要「串接」。
為什麼要「串接」?
什麼是串接
前面提到,發票號碼要跟有配號權限的單位要回來,不能自己生成。
那「跟對方要號碼」這件事,具體來說要怎麼做?
系統要拿到這組號碼,就必須主動呼叫這個有配號權限的單位,送出交易資料、再接收對方回傳的結果,這個「系統之間互相呼叫、互相傳資料」的動作,就是「串接」。
白話一點說,串接就是:你的系統對外面說「我要開一張發票,金額是 500 元,品項是這些」,外面的系統回覆你「好,這是你的發票號碼 AB-12345678,證明聯資料在這裡」,這個「對話」的規則,就是所謂的 API(應用程式介面)。
也就是說,只要一個地方能開立發票,背後就一定已經有串接在運作了,不管是超商的收銀機,還是你正在規劃的電商網站,都不例外。
真正決定「要不要自己動手寫串接程式」的關鍵,不是有沒有串接,而是「誰去觸發這個串接動作」,還有「這個串接是誰幫你寫好的」,這也是接下來要拆解的重點。
手動開立 vs 系統自動開立
依照觸發串接的方式,開發票可以分成「手動開立」跟「系統自動開立」兩種,差別在於「誰觸發那次 API 呼叫」。
手動開立
店員在收銀機上輸入品項與金額後按下「結帳」,收銀機(背後早已串接好發票功能)同步呼叫一次開立發票的 API,取得發票號碼;如果客人出示手機條碼,發票直接存進載具,否則印出紙本「證明聯」。
證明聯不是發票本身,發票的正式資料已經記錄在財政部的系統裡,證明聯只是印出來給你拿在手上、用來對獎或當作購買憑證的一張紙。
這種模式下,串接被觸發的頻率跟著「人的動作」走,一次結帳觸發一次 API 呼叫,一家小店一天賣幾十筆完全撐得住。
系統自動開立
串接被改成「事件驅動」,由訂單系統的某個事件(通常是付款成功的 webhook 或 callback)自動觸發同一組 API,不需要人力介入。
這也是電商網站能夠一天處理上千筆訂單、卻不需要對應增加人力去開發票的原因;至於要不要印出證明聯,通常會改成把電子發票證明聯做成 PDF 或圖檔寄到客人的信箱。
具體的 API 要怎麼呼叫、資料格式長什麼樣、怎麼做簽章驗證,會放在後面「API 串接的基本組成」一節詳細說明,這裡先建立「誰觸發、多常觸發」的整體概念就好。
API 串接的基本組成
不管之後選擇自己串接還是用現成服務,只要牽涉到「自己寫程式呼叫 API」,就一定會碰到下面這幾個基本概念。我們用財政部的 API 規範來說明,但這套邏輯在第三方服務上也通用。
AppID 跟 APIKey
AppID 跟 APIKey 可以想成是「帳號」跟「密碼」。
AppID 用來識別「是哪個開發者 / 哪套軟體」在呼叫這個 API,APIKey 則是用來證明「你有權限使用這個 AppID」。
申請流程上,開發者要先向財政資訊中心提出申請,審核通過後,才會核發這兩組資訊。
測試環境跟正式環境
大部分 API 服務都會提供兩個環境:測試環境(Sandbox)跟正式環境(Production)。
測試環境的資料不會真的產生具有法律效力的發票,單純是讓開發者驗證程式邏輯有沒有寫對。
等程式在測試環境跑通了,才會切換到正式環境的網址跟金鑰,開始產生真正生效的發票。
這個習慣不只出現在發票 API,幾乎所有金流、金融相關的 API 都會有這種「先在安全的地方試,確定沒問題再上正式環境」的設計。
簡單的 Request 範例
下面用一段簡化過的程式碼,示範呼叫發票 API 開立一張發票的基本樣子(實際欄位以你使用的 API 文件為準,這裡只是示意串接的結構):
// 呼叫發票 API,開立一張發票(示意用,非真實欄位)
async function issueInvoice(orderData) {
const response = await fetch("https://api.example-einvoice.gov/issue", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
appId: "YOUR_APP_ID",
timestamp: Date.now(), // 時間戳記,防止資料被竄改後重送
buyerName: orderData.buyerName,
amount: orderData.totalAmount,
items: orderData.items, // 品項清單
}),
});
const result = await response.json();
return result; // 裡面會包含配發的發票號碼
}這段程式碼做的事情很單純:把一筆訂單的金額跟品項打包成 JSON,連同 AppID 一起送出去,然後把回傳的結果(裡面會包含系統幫你配好的發票號碼)接回來。
留意這裡的 timestamp 欄位,它的作用是記錄這次請求發送的時間點。
如果同一筆請求被有心人士攔截後重複發送,伺服器可以透過比對時間戳記,判斷這是不是一筆「太舊」的請求,藉此降低資料被竄改或重放攻擊的風險。
對比:發票號碼絕對不能自己生成
這裡有一個新手很容易誤踩的地雷,值得用對比的方式特別說明。
有問題的寫法
// 錯誤示範:自己用亂數產生發票號碼
function generateInvoiceNumber() {
const prefix = "AB";
const number = Math.floor(10000000 + Math.random() * 90000000);
return `${prefix}${number}`;
}這種寫法看起來可以跑,但發票號碼本質上是國稅局配發給你的「額度」,不是你自己可以決定的數字。
如果自己亂數生成,很可能跟別人配到的號碼重複,或是跟根本沒申請過的字軌對不上,這張發票在法律上是無效的。
改善後的寫法
// 正確做法:一律呼叫官方或加值中心的 API,取得配發的發票號碼
const result = await issueInvoice(orderData);
const invoiceNumber = result.invoiceNumber; // 由對方系統配發,不是自己生成正確的做法永遠是把「配號」這件事,交給有權限做這件事的單位(財政部或第三方加值中心),你的系統只負責把交易資料送出去,再把對方回傳的號碼記錄下來就好。
搞懂這些技術組件之後,你可能會想:這麼多細節,難道全部都要自己處理嗎?其實不一定,接下來看看實務上有哪三條路徑,可以幫你分擔這些工作。
串接的三種路徑
當你的系統要開立電子發票時,實務上有三條路可以走,差別在於「哪些技術細節要自己扛」。
路徑一:直接串財政部電子發票整合服務平台 API(自建 Turnkey)
財政部財政資訊中心提供官方的「電子發票應用 API」,這種自己申請帳號、直接跟財政部系統對接的做法,業界慣稱為「自建 Turnkey」。
要走這條路,除了申請開發者帳號(AppID)跟金鑰(APIKey)之外,通常還需要準備「電子發票字軌號碼申請書」「使用電子發票承諾書」等文件。
並且要有工商憑證或自然人憑證,通過財政部的資格審核後才能正式使用。
申請通過之後,你就可以直接呼叫這組 API 來開立、查詢、作廢發票,不需要透過任何中間業者。
這是最「源頭」的做法,沒有中間商賺價差,其他所有第三方服務背後,實際上也都是遵循同一套財政部規範在運作。
優點:不需額外支付第三方手續費,資料流最單純,長期使用的單張成本最低。
缺點:需要自己完成憑證申請、字軌申請、簽章驗證、傳輸軟體維護等一整套流程,前期投入的時間與技術門檻都比較高。
適合:交易量大、有自己 IT 團隊、希望長期壓低單張發票成本的中大型公司。
路徑二:透過第三方加值中心(例如綠界、藍新等業者)
第三方加值中心本身已經完成跟財政部之間的 Turnkey 串接,並且把憑證、簽章、傳輸這些複雜細節,包裝成一般開發者更容易上手的 API 或後台介面,再提供給商家使用。
你不用自己申請憑證、也不用處理簽章驗證,只要照著加值中心的 API 文件串接就好,通常幾天內就能上線。
由於底層都遵循財政部公開的電子發票資料規範,各家加值中心提供的 API 欄位其實大同小異,差別主要在串接文件好不好懂、技術支援完不完整,還有每張發票收取的手續費高低。
優點:串接文件比政府 API 更好懂,技術支援完整,上線速度快。
缺點:通常需要依張數支付手續費,交易量越大,長期成本可能比自建 Turnkey 更高。
適合:中小型網站、新創團隊,或是想快速上線、不想投入資源處理憑證與簽章細節的公司。
路徑三:透過 ERP / POS 系統內建的發票模組
如果公司本來就在用某套 ERP(企業資源規劃系統)或 POS(收銀)系統,而這套系統本身就內建發票功能,那背後其實已經幫你選好了路徑一或路徑二,你只需要設定帳號跟參數,不需要自己寫任何串接程式。
優點:幾乎不用寫程式,設定好帳號跟參數即可使用,導入速度最快。
缺點:客製化彈性較低,受限於系統本身支援的功能,遇到特殊需求時可能無法調整。
適合:已經導入 ERP / POS、不想額外開發,只想把發票功能直接打開來用的公司。
三種路徑比較
值得一提的是,不管走哪一條路徑,最終資料格式都是依照財政部公開的電子發票資料規範,所以三種路徑之間的核心欄位其實大同小異,差別主要在「誰幫你處理跟財政部溝通的細節」。
選定路徑之後,接下來把前面幾個概念串起來,看看一次完整的串接流程實際上長什麼樣子。
一次串接的完整流程
把前面幾個概念串起來,一個典型的「線上購物 → 自動開發票」流程大概會長這樣:
- 使用者在網站完成付款。
- 網站後端把這筆訂單的金額、品項,打包成 API 需要的格式。
- 呼叫發票 API(不管是財政部、第三方加值中心,或是 ERP 內建功能),送出開立請求。
- 對方回傳這筆發票的發票號碼、發票日期等資訊。
- 網站把這些資訊存進自己的資料庫,通常也會同步顯示或寄送給使用者(例如證明聯的電子檔)。
- 後續如果有退貨,系統要再呼叫一次「作廢」或「折讓」的 API,而不是直接把資料庫紀錄刪掉。
你會發現,整個串接工作的重點,其實不是在「發明」什麼新技術,而是把交易系統跟發票系統這兩邊的資料,依照規範對接起來,讓原本要人工處理的步驟自動化。
常見的坑
在實際串接的過程中,有幾個地方特別容易出問題。
字軌用完卻沒提前申請
字軌跟號碼範圍是有限額度,一旦用完,系統會沒有號碼可以配,導致無法開立新發票。
申請新字軌通常需要幾個工作天的處理時間,所以額度快用完時就要提前申請,不能等到號碼真的用光才處理。
把作廢跟折讓搞混
作廢通常適用於發票開立後,交易當下就發現有誤或整筆取消;折讓則適用於發票已經正式生效一段時間後,因為退貨或金額調整而需要更正金額。
兩者對應的 API 動作跟後續資料紀錄方式不一樣,不能互相取代。
測試環境資料誤送到正式環境
因為測試環境跟正式環境的網址、金鑰通常長得很像,如果程式沒有把環境設定切分清楚,很容易在測試時不小心呼叫到正式環境。
這麼一來,就會產生一張具有法律效力、但其實不該存在的發票。
實務應用:什麼時候該選哪一種?
回到最一開始的三條路徑,實務上可以用下面的方式簡單判斷:
如果你是剛起步的網站或新創團隊,交易量還不大,選第三方加值中心通常是最快上線的方式,不需要自己處理跟財政部之間繁瑣的申請跟簽章邏輯。
如果公司已經有一定規模、交易量大,並且有自己的 IT 團隊,直接串接財政部的 API 可以省下第三方服務的手續費,長期下來成本更低,但前期需要投入時間處理申請跟開發。
如果公司本來就已經導入 ERP 或 POS 系統,而且這套系統本身就有發票模組,通常不需要自己額外開發,設定好相關參數即可使用,除非有特殊客製化需求,否則不建議重新造輪子。
重點整理
- 電子發票就是統一發票的電子化版本,每張發票都有一組「字軌 + 號碼」,這組號碼是跟國稅局申請來的額度,不能自己生成。
- 一張發票的生命週期是:配號 → 開立 → 上傳 → (視情況)作廢或折讓。
- 「串接」指的是讓你的系統自動跟外部發票系統對話,取代人工手動開票的流程。
- 串接有三條路徑:直接串財政部 API、透過第三方加值中心、透過 ERP/POS 內建模組,差別在於誰幫你處理跟財政部溝通的細節。
- 呼叫 API 需要 AppID 跟 APIKey 來識別身分,並且要區分測試環境跟正式環境,避免在測試階段就產生具有法律效力的發票。
- 發票號碼一定要透過 API 呼叫取得,絕對不能自己用亂數或規則生成。
- 作廢跟折讓是兩種不同情境下的更正方式,不能互相取代,也不能直接刪除發票紀錄。
- 選擇哪一種串接路徑,取決於團隊技術能力、交易量,以及是否已經有 ERP/POS 系統。