開立發票

開立一張電子發票(F0401),並交給 Turnkey 上傳財政部。

POSThttps://invoice.workat.studio/api/v1/invoices

呼叫成功時,發票已經合法開立、號碼已確定,系統會在背景交給 Turnkey 上傳財政部。上傳結果請用查詢發票的 status 追蹤。

Header

名稱值
X-Api-Key、X-Timestamp、X-Nonce、X-Signature簽章驗證,算法見簽章算法
Content-Typeapplication/json
Acceptapplication/json

請求內容

基本與買方

欄位型別說明
external_idstring ≤ 64選填強烈建議填寫,例如訂單編號。相同的值重送時不會重複開立,見防止重複開立
buyer_banstring,8 碼數字選填買方統一編號。有填就是 B2B 發票(打統編),會檢查統編檢查碼;不填就是 B2C
buyer_namestring ≤ 60選填買方名稱。B2B 沒填時以統編代替;B2C 沒填時以 4 碼隨機碼作為個人識別碼(財政部規定允許)
buyer_addressstring ≤ 100選填買方地址
buyer_emailemail ≤ 400選填買方 Email。只保存在本系統,不會上傳財政部

載具、捐贈、列印

欄位型別說明
carrier_typestring,6 碼選填載具類別:3J0002 手機條碼、CQ0001 自然人憑證條碼,或公司向財政部申請的會員載具類別號碼
carrier_idstring ≤ 400選填載具號碼,必須與 carrier_type 同時提供。手機條碼:/ 開頭共 8 碼、英文須大寫(例 /ABC+123);自然人憑證:2 碼大寫英文 + 14 碼數字。前後不可有空白
npobanstring,3–7 碼數字選填捐贈碼(愛心碼)。有填就是捐贈發票
printboolean選填是否列印電子發票證明聯。不填時自動判斷:沒有載具也沒有捐贈 → true,否則 false

課稅與備註

欄位型別說明
tax_typestring選填1 應稅(預設)、2 零稅率、3 免稅、9 混稅。同一張發票有應稅與免稅(或零稅率)的品項時用 9,並在每一項明細填 tax_type,見混稅
prices_include_taxboolean選填明細的單價、金額是否含稅,預設 true。見下方金額計算
zero_tax_rate_reasonstring條件必填零稅率原因 71–79(營業稅法第 7 條各款)。tax_type 為 2,或混稅發票有零稅率明細時必填
customs_clearance_markstring條件必填通關方式:1 非經海關出口、2 經海關出口。tax_type 為 2,或混稅發票有零稅率明細時必填
main_remarkstring ≤ 200選填發票總備註,會上傳財政部
relate_numberstring ≤ 20選填相關號碼,會上傳財政部

明細 items[]

至少 1 項、最多 9,999 項。

欄位型別說明
descriptionstring ≤ 500必填品名
quantitynumber > 0必填數量,可有小數(最多 7 位)
unit_pricenumber ≥ 0必填單價
amountnumber ≥ 0選填小計。不填時為 quantity × unit_price;有填時以此為準(例如有折扣時)
tax_typestring條件必填此項的課稅別 1 應稅、2 零稅率、3 免稅。混稅發票(tax_type: "9")每一項都必填;其他發票可省略,有填時必須與發票相同
unitstring ≤ 6選填單位,例如「個」「件」
remarkstring ≤ 120選填單項備註
relate_numberstring ≤ 50選填單項相關號碼,例如商品條碼 {Z2602970677234}

載具、捐贈、列印的規則

這三者依財政部規定互相限制,不符合時回應 422:

情境載具捐贈列印可以打統編?
存入手機條碼/自然人憑證✅—false只有手機條碼可以,見下一列
打統編+手機條碼(手機條碼報核)✅ 限手機條碼—true(必須列印)✅
捐贈—✅false❌ 打統編的發票不可捐贈
列印紙本證明聯——true✅
❌ 不合法有載具或捐贈卻要求列印;或沒有載具、沒有捐贈卻指定 print: false(消費者會拿不到發票)

金額計算

系統依財政部規定自動計算,金額四捨五入到整數元:

B2C(沒有 buyer_ban)B2B(有 buyer_ban)
發票開立方式含稅價未稅金額 + 5% 稅額
sales_amount= 總計= round(總計 ÷ 1.05)
tax_amount0= 總計 − 銷售額
明細金額維持原值換算成未稅;換算的尾差調整在最後一項,確保明細合計 = 銷售額

範例:B2B 含稅總計 1,000 元 → 銷售額 952、稅額 48。若你的系統提供的是未稅價,請帶 "prices_include_tax": false,系統會改為 未稅 1,000 → 稅額 50、總計 1,050。

混稅

同一張發票同時有應稅與免稅(或零稅率)的品項時,tax_type 填 9,每一項明細各自填 tax_type。 至少要有一項應稅、一項免稅或零稅率。系統依課稅別分組,各組以上表的方式計算後加總:

{
  "external_id": "ORDER-20261004-0005",
  "tax_type": "9",
  "items": [
    { "description": "便當",   "quantity": 1, "unit_price": 100, "tax_type": "1" },
    { "description": "雞蛋",   "quantity": 1, "unit_price": 60,  "tax_type": "3" }
  ]
}

回應中 sales_amount 為 100、free_tax_sales_amount 為 60、total_amount 為 160。實際哪些品項為免稅請依營業稅法並洽詢國稅局。

範例

以下為請求內容(JSON)。實際送出時需加上簽章 Header,完整程式見PHP 範例或bash 範例。

B2C:存入手機條碼

{
  "external_id": "ORDER-20261004-0001",
  "carrier_type": "3J0002",
  "carrier_id": "/ABC+123",
  "items": [
    { "description": "綠茶", "quantity": 10, "unit_price": 25 },
    { "description": "拿鐵", "quantity": 1,  "unit_price": 75 }
  ]
}

B2C:捐贈

{
  "external_id": "ORDER-20261004-0002",
  "npoban": "8999",
  "items": [{ "description": "會員月費", "quantity": 1, "unit_price": 299 }]
}

B2C:列印紙本證明聯

{
  "external_id": "ORDER-20261004-0003",
  "buyer_name": "王小明",
  "items": [{ "description": "商品", "quantity": 2, "unit_price": 150 }]
}

沒有載具也沒有捐贈,print 會自動為 true。

B2B:打統編

{
  "external_id": "ORDER-20261004-0004",
  "buyer_ban": "22099131",
  "buyer_name": "台灣積體電路製造股份有限公司",
  "items": [{ "description": "顧問服務費", "quantity": 1, "unit_price": 10500, "unit": "式" }]
}

回應中 sales_amount 為 10000、tax_amount 為 500、total_amount 為 10500。

回應

201 Created 新開立一張發票。200 OK 相同 external_id 已開立過,回傳原本那張。

{
  "data": {
    "invoice_number": "KZ10000000",
    "invoice_date": "2026-10-04",
    "invoice_time": "18:35:50",
    "random_number": "7887",
    "status": "sent",
    "external_id": "ORDER-20261004-0001",
    "seller_ban": "85426409",
    "buyer_ban": null,
    "buyer_name": "7887",
    "carrier_type": "3J0002",
    "carrier_id": "/ABC+123",
    "npoban": null,
    "print": false,
    "tax_type": "1",
    "sales_amount": 325,
    "zero_tax_sales_amount": 0,
    "free_tax_sales_amount": 0,
    "tax_amount": 0,
    "total_amount": 325,
    "items": [
      { "sequence": 1, "description": "綠茶", "quantity": 10, "unit_price": 25, "unit": null, "amount": 250, "tax_type": "1", "remark": null },
      { "sequence": 2, "description": "拿鐵", "quantity": 1,  "unit_price": 75, "unit": null, "amount": 75, "tax_type": "1", "remark": null }
    ]
  }
}

回應欄位

欄位型別說明
invoice_numberstring發票號碼,2 碼英文 + 8 碼數字,例如 KZ10000000
invoice_datestring開立日期 YYYY-MM-DD(台灣時間)
invoice_timestring開立時間 HH:MM:SS(台灣時間)
random_numberstring4 碼防偽隨機碼。消費者查詢發票、列印證明聯時會用到
statusstring開立的上傳進度:issued / sent / uploaded / failed,註銷重開進行中為 cancelling(見發票狀態)
voidobject|null未作廢為 null;已作廢時為 {voided_at, reason, remark, approval_number, status, upload_error?},status 為作廢的上傳進度 pending / sent / uploaded / failed(見作廢發票)
cancellationobject只在 status 為 cancelling 時出現:{cancelled_at, reason, status, upload_error},status 為註銷的上傳進度(見註銷重開)
upload_errorobject只在 status 為 failed 時出現:{"code": "…", "message": "…"},為 Turnkey 或財政部平台回報的錯誤
external_idstring|null開立時帶入的冪等鍵
seller_banstring賣方統編(即 API 金鑰所屬公司)
buyer_banstring|null買方統編;B2C 為 null
buyer_namestring買方名稱
carrier_typestring|null載具類別
carrier_idstring|null載具號碼
npobanstring|null捐贈碼;未捐贈為 null
printboolean是否需要列印電子發票證明聯
tax_typestring課稅別:1 應稅、2 零稅率、3 免稅、9 混稅
sales_amountinteger應稅銷售額。B2C 為含稅金額;B2B 為未稅金額;沒有應稅品項為 0
zero_tax_sales_amountinteger零稅率銷售額
free_tax_sales_amountinteger免稅銷售額
tax_amountinteger稅額。B2C 一律為 0
total_amountinteger總計(消費者實付金額)
items[]array明細:sequence、description、quantity、unit_price、unit、amount、tax_type、remark。B2B 發票應稅品項的金額為換算後的未稅金額

錯誤

狀態碼常見原因
401/403/429驗證失敗、IP 不在允許清單、請求過於頻繁,見錯誤回應
409當期沒有可用的字軌,例如:「統編 85426409 在期別 202609 沒有可用的字軌(發票類別 07),請先匯入字軌或確認號碼是否用完」
422items:沒有明細、數量為 0、金額為負數、總額為 0
items:混稅發票的每一項明細都要指定課稅別;必須同時有應稅與免稅(或零稅率)的明細
items:明細的課稅別與發票不同(請將發票課稅別設為 9)
carrier_type:打統編的發票只能搭配手機條碼(手機條碼報核)
buyer_ban:買方統一編號檢查碼錯誤
carrier_id:手機條碼格式錯誤:必須是 / 開頭共 8 碼,英文須大寫
carrier_id:載具類別與載具號碼必須同時提供
npoban:捐贈碼必須是 3–7 碼數字
npoban:打統編的發票不可捐贈
print:列印證明聯時不可同時使用載具或捐贈
print:未使用載具也未捐贈時,必須列印證明聯
zero_tax_rate_reason、customs_clearance_mark:零稅率發票必須填寫

發生 409、422 時不會消耗發票號碼,修正後可直接重送。