taiwan-invoice-skill 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/taiwan-invoice/EXAMPLES.md +633 -0
- package/assets/taiwan-invoice/references/AMEGO_API_REFERENCE.md +1115 -0
- package/assets/taiwan-invoice/references/ECPAY_API_REFERENCE.md +647 -0
- package/assets/taiwan-invoice/references/SMILEPAY_API_REFERENCE.md +492 -0
- package/assets/taiwan-invoice/scripts/generate-invoice-service.py +192 -0
- package/assets/taiwan-invoice/scripts/test-invoice-amounts.py +129 -0
- package/assets/templates/base/skill-content.md +361 -0
- package/assets/templates/platforms/antigravity.json +21 -0
- package/assets/templates/platforms/claude.json +22 -0
- package/assets/templates/platforms/codebuddy.json +18 -0
- package/assets/templates/platforms/codex.json +21 -0
- package/assets/templates/platforms/continue.json +21 -0
- package/assets/templates/platforms/copilot.json +18 -0
- package/assets/templates/platforms/cursor.json +21 -0
- package/assets/templates/platforms/gemini.json +21 -0
- package/assets/templates/platforms/kiro.json +18 -0
- package/assets/templates/platforms/opencode.json +18 -0
- package/assets/templates/platforms/qoder.json +18 -0
- package/assets/templates/platforms/roocode.json +18 -0
- package/assets/templates/platforms/trae.json +18 -0
- package/assets/templates/platforms/windsurf.json +21 -0
- package/dist/index.js +15428 -0
- package/package.json +56 -0
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
# 綠界科技電子發票 API 完整技術規格 (ECPay Invoice API)
|
|
2
|
+
|
|
3
|
+
> 官方文檔來源:https://developers.ecpay.com.tw/
|
|
4
|
+
> GitHub SDK:https://github.com/ECPay/SDK_PHP
|
|
5
|
+
> 支援 B2C (二聯式) 與 B2B (三聯式) 電子發票
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 目錄
|
|
10
|
+
1. [基本說明](#基本說明)
|
|
11
|
+
2. [參數加密方式](#參數加密方式-checkmacvalue)
|
|
12
|
+
3. [B2C 電子發票](#b2c-電子發票二聯式)
|
|
13
|
+
4. [B2B 電子發票](#b2b-電子發票三聯式)
|
|
14
|
+
5. [共用功能](#共用功能)
|
|
15
|
+
6. [錯誤代碼](#錯誤代碼)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 基本說明
|
|
20
|
+
|
|
21
|
+
### 環境資訊
|
|
22
|
+
| 環境 | 說明 | URL 前綴 |
|
|
23
|
+
|------|------|---------|
|
|
24
|
+
| **測試環境** | 測試用,不會上傳財政部 | `https://einvoice-stage.ecpay.com.tw` |
|
|
25
|
+
| **正式環境** | 正式開立,上傳財政部 | `https://einvoice.ecpay.com.tw` |
|
|
26
|
+
|
|
27
|
+
### 測試環境資料
|
|
28
|
+
| 項目 | 測試值 |
|
|
29
|
+
|------|--------|
|
|
30
|
+
| **特店編號 (MerchantID)** | `2000132` |
|
|
31
|
+
| **HashKey** | `ejCk326UnaZWKisg` |
|
|
32
|
+
| **HashIV** | `q9jcZX8Ib9LM8wYk` |
|
|
33
|
+
|
|
34
|
+
> **重要**:正式環境的 HashKey 和 HashIV 需向綠界申請取得
|
|
35
|
+
|
|
36
|
+
### API 編碼格式
|
|
37
|
+
- **Content-Type**:`application/json`
|
|
38
|
+
- **字元編碼**:`UTF-8`
|
|
39
|
+
- **傳輸方式**:`POST`(JSON 格式)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 參數加密方式 (CheckMacValue)
|
|
44
|
+
|
|
45
|
+
綠界採用 **AES 加密** + **URL Encode** 的方式保護傳輸資料。
|
|
46
|
+
|
|
47
|
+
### 加密步驟
|
|
48
|
+
|
|
49
|
+
#### 1. 準備 Data JSON 資料
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"MerchantID": "2000132",
|
|
53
|
+
"RelateNumber": "TEST20240101001",
|
|
54
|
+
"CustomerIdentifier": "12345678",
|
|
55
|
+
"InvType": "07",
|
|
56
|
+
"TaxType": "1",
|
|
57
|
+
"SalesAmount": 9524,
|
|
58
|
+
"TaxAmount": 476,
|
|
59
|
+
"TotalAmount": 10000,
|
|
60
|
+
"Items": [
|
|
61
|
+
{
|
|
62
|
+
"ItemSeq": 1,
|
|
63
|
+
"ItemName": "測試商品",
|
|
64
|
+
"ItemCount": 1,
|
|
65
|
+
"ItemPrice": 9524,
|
|
66
|
+
"ItemAmount": 9524,
|
|
67
|
+
"ItemTax": 476
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### 2. URL Encode
|
|
74
|
+
將 JSON 字串進行 URL Encode(大寫格式):
|
|
75
|
+
```
|
|
76
|
+
%7B%22MerchantID%22%3A%222000132%22%2C...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### 3. AES 加密
|
|
80
|
+
**加密設定:**
|
|
81
|
+
- **演算法**:AES-128-CBC
|
|
82
|
+
- **金鑰**:HashKey (`ejCk326UnaZWKisg`)
|
|
83
|
+
- **IV**:HashIV (`q9jcZX8Ib9LM8wYk`)
|
|
84
|
+
- **Padding**:PKCS7
|
|
85
|
+
|
|
86
|
+
**加密範例(Node.js):**
|
|
87
|
+
```javascript
|
|
88
|
+
const crypto = require('crypto')
|
|
89
|
+
|
|
90
|
+
function encryptData(data, hashKey, hashIV) {
|
|
91
|
+
// 1. JSON 轉字串並 URL Encode
|
|
92
|
+
const jsonString = JSON.stringify(data)
|
|
93
|
+
const urlEncoded = encodeURIComponent(jsonString)
|
|
94
|
+
|
|
95
|
+
// 2. AES 加密
|
|
96
|
+
const cipher = crypto.createCipheriv('aes-128-cbc', hashKey, hashIV)
|
|
97
|
+
let encrypted = cipher.update(urlEncoded, 'utf8', 'base64')
|
|
98
|
+
encrypted += cipher.final('base64')
|
|
99
|
+
|
|
100
|
+
return encrypted
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 範例
|
|
104
|
+
const hashKey = 'ejCk326UnaZWKisg'
|
|
105
|
+
const hashIV = 'q9jcZX8Ib9LM8wYk'
|
|
106
|
+
const data = { MerchantID: '2000132', RelateNumber: 'TEST001' }
|
|
107
|
+
const encryptedData = encryptData(data, hashKey, hashIV)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### 4. 解密步驟
|
|
111
|
+
```javascript
|
|
112
|
+
function decryptData(encryptedData, hashKey, hashIV) {
|
|
113
|
+
// 1. AES 解密
|
|
114
|
+
const decipher = crypto.createDecipheriv('aes-128-cbc', hashKey, hashIV)
|
|
115
|
+
let decrypted = decipher.update(encryptedData, 'base64', 'utf8')
|
|
116
|
+
decrypted += decipher.final('utf8')
|
|
117
|
+
|
|
118
|
+
// 2. URL Decode
|
|
119
|
+
const urlDecoded = decodeURIComponent(decrypted)
|
|
120
|
+
|
|
121
|
+
// 3. 解析 JSON
|
|
122
|
+
return JSON.parse(urlDecoded)
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## B2C 電子發票(二聯式)
|
|
129
|
+
|
|
130
|
+
### 1. 開立發票
|
|
131
|
+
|
|
132
|
+
**端點:** `POST /B2CInvoice/Issue`
|
|
133
|
+
|
|
134
|
+
#### 請求參數(最外層)
|
|
135
|
+
|
|
136
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
137
|
+
|------|------|------|------|
|
|
138
|
+
| `MerchantID` | String(10) | Y | 特店編號 |
|
|
139
|
+
| `RqHeader` | Object | Y | 傳輸資料容器 |
|
|
140
|
+
| `RqHeader.Timestamp` | Number(10) | Y | Unix 時間戳(驗證區間 10 分鐘) |
|
|
141
|
+
| `Data` | String | Y | AES 加密後的 JSON 字串 |
|
|
142
|
+
|
|
143
|
+
#### Data 欄位內容(加密前)
|
|
144
|
+
|
|
145
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
146
|
+
|------|------|------|------|
|
|
147
|
+
| `MerchantID` | String(10) | Y | 特店編號 |
|
|
148
|
+
| `RelateNumber` | String(50) | Y | 廠商自訂編號(唯一值,不可重複) |
|
|
149
|
+
| `CustomerID` | String(50) | N | 客戶編號 |
|
|
150
|
+
| `CustomerIdentifier` | String(8) | N | 買方統編(有值=B2B,空值=B2C) |
|
|
151
|
+
| `CustomerName` | String(60) | N | 買方名稱 |
|
|
152
|
+
| `CustomerAddr` | String(100) | N | 買方地址 |
|
|
153
|
+
| `CustomerPhone` | String(20) | N | 買方電話 |
|
|
154
|
+
| `CustomerEmail` | String(200) | N | 買方電子信箱(多組用分號`;`區隔) |
|
|
155
|
+
| `ClearanceMark` | String(1) | N | 通關方式:1 非經海關出口、2 經海關出口(零稅率必填) |
|
|
156
|
+
| `Print` | String(1) | Y | 列印註記:0 不列印、1 列印 |
|
|
157
|
+
| `Donation` | String(1) | Y | 捐贈註記:0 不捐贈、1 捐贈 |
|
|
158
|
+
| `LoveCode` | String(7) | N | 愛心碼(捐贈=1 時必填) |
|
|
159
|
+
| `CarrierType` | String(1) | N | 載具類別:'' 無、1 綠界電子發票載具、2 自然人憑證、3 手機條碼 |
|
|
160
|
+
| `CarrierNum` | String(64) | N | 載具編號(CarrierType 有值時必填) |
|
|
161
|
+
| `TaxType` | String(1) | Y | 課稅別:1 應稅、2 零稅率、3 免稅、9 混合應稅與免稅 |
|
|
162
|
+
| `SpecialTaxType` | String(1) | N | 特種稅額類別(免稅或應稅時填) |
|
|
163
|
+
| `InvType` | String(2) | Y | 字軌類別:07 一般稅額、08 特種稅額 |
|
|
164
|
+
| `SalesAmount` | Number | Y | 銷售額合計(含稅,整數) |
|
|
165
|
+
| `InvoiceRemark` | String(200) | N | 發票備註 |
|
|
166
|
+
| `Items` | Array | Y | 商品明細陣列 |
|
|
167
|
+
| `ItemName` | String(100) | Y | 商品名稱 |
|
|
168
|
+
| `ItemCount` | Number | Y | 商品數量 |
|
|
169
|
+
| `ItemWord` | String(6) | N | 商品單位 |
|
|
170
|
+
| `ItemPrice` | Number | Y | 商品單價(含稅) |
|
|
171
|
+
| `ItemTaxType` | String(1) | N | 商品課稅別(混合稅率時必填) |
|
|
172
|
+
| `ItemAmount` | Number | Y | 商品小計(含稅) |
|
|
173
|
+
| `ItemRemark` | String(40) | N | 商品備註 |
|
|
174
|
+
| `InvCreateDate` | String(20) | N | 發票開立日期(YYYY-MM-DD,過去 6 天內) |
|
|
175
|
+
| `DelayFlag` | String(1) | N | 延遲註記:0 即時開立、1 延遲開立 |
|
|
176
|
+
| `DelayDay` | Number | N | 延遲天數(1-15 天) |
|
|
177
|
+
| `Tsr` | String(30) | N | 交易單號(選填) |
|
|
178
|
+
| `PayType` | String(2) | N | 付款方式:01 現金、02 刷卡、03 支票、04 匯款 |
|
|
179
|
+
| `PayAct` | String(1) | N | 付款行為:1 付款、0 未付款 |
|
|
180
|
+
| `NotifyURL` | String(200) | N | 開立通知 URL |
|
|
181
|
+
|
|
182
|
+
#### 回應參數
|
|
183
|
+
|
|
184
|
+
**最外層:**
|
|
185
|
+
|
|
186
|
+
| 欄位 | 型別 | 說明 |
|
|
187
|
+
|------|------|------|
|
|
188
|
+
| `MerchantID` | String(10) | 特店編號 |
|
|
189
|
+
| `RpHeader` | Object | 回傳資料容器 |
|
|
190
|
+
| `RpHeader.Timestamp` | Number(10) | Unix 時間戳 |
|
|
191
|
+
| `TransCode` | Number | 1 傳輸成功、其他失敗 |
|
|
192
|
+
| `TransMsg` | String(200) | 回傳訊息 |
|
|
193
|
+
| `Data` | String | AES 加密的回應資料 |
|
|
194
|
+
|
|
195
|
+
**Data 解密後:**
|
|
196
|
+
|
|
197
|
+
| 欄位 | 型別 | 說明 |
|
|
198
|
+
|------|------|------|
|
|
199
|
+
| `RtnCode` | Number | 1 成功、其他失敗 |
|
|
200
|
+
| `RtnMsg` | String(200) | 回應訊息 |
|
|
201
|
+
| `InvoiceNo` | String(10) | 發票號碼(成功時回傳) |
|
|
202
|
+
| `InvoiceDate` | String(20) | 發票開立日期時間 |
|
|
203
|
+
| `RandomNumber` | String(4) | 隨機碼 |
|
|
204
|
+
|
|
205
|
+
#### 請求範例
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"MerchantID": "2000132",
|
|
210
|
+
"RqHeader": {
|
|
211
|
+
"Timestamp": 1640000000
|
|
212
|
+
},
|
|
213
|
+
"Data": "uvI4yrErM37XNQkXGAgRgJAgHn2t72jahaMZzYhWL1HmvH4WV18VJDP2i9pTbC+t..."
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Data 解密內容:**
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"MerchantID": "2000132",
|
|
221
|
+
"RelateNumber": "INV-20240101-001",
|
|
222
|
+
"CustomerName": "王小明",
|
|
223
|
+
"CustomerEmail": "test@example.com",
|
|
224
|
+
"Print": "0",
|
|
225
|
+
"Donation": "0",
|
|
226
|
+
"TaxType": "1",
|
|
227
|
+
"InvType": "07",
|
|
228
|
+
"SalesAmount": 10000,
|
|
229
|
+
"Items": [
|
|
230
|
+
{
|
|
231
|
+
"ItemName": "網站開發服務",
|
|
232
|
+
"ItemCount": 1,
|
|
233
|
+
"ItemWord": "式",
|
|
234
|
+
"ItemPrice": 10000,
|
|
235
|
+
"ItemAmount": 10000
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### 2. 作廢發票
|
|
244
|
+
|
|
245
|
+
**端點:** `POST /B2CInvoice/Invalid`
|
|
246
|
+
|
|
247
|
+
#### Data 欄位內容
|
|
248
|
+
|
|
249
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
250
|
+
|------|------|------|------|
|
|
251
|
+
| `MerchantID` | String(10) | Y | 特店編號 |
|
|
252
|
+
| `InvoiceNo` | String(10) | Y | 發票號碼 |
|
|
253
|
+
| `InvoiceDate` | String(20) | Y | 發票開立日期時間(YYYY-MM-DD HH:MM:SS) |
|
|
254
|
+
| `Reason` | String(20) | Y | 作廢原因 |
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
### 3. 開立折讓
|
|
259
|
+
|
|
260
|
+
**端點:** `POST /B2CInvoice/Allowance`
|
|
261
|
+
|
|
262
|
+
#### Data 欄位內容
|
|
263
|
+
|
|
264
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
265
|
+
|------|------|------|------|
|
|
266
|
+
| `MerchantID` | String(10) | Y | 特店編號 |
|
|
267
|
+
| `InvoiceNo` | String(10) | Y | 發票號碼 |
|
|
268
|
+
| `InvoiceDate` | String(20) | Y | 發票開立日期時間 |
|
|
269
|
+
| `AllowanceNotify` | String(1) | Y | 通知類別:S 簡訊、E 電子郵件、A 皆通知、N 皆不通知 |
|
|
270
|
+
| `CustomerName` | String(60) | N | 客戶名稱 |
|
|
271
|
+
| `NotifyMail` | String(100) | N | 通知信箱 |
|
|
272
|
+
| `NotifyPhone` | String(20) | N | 通知手機 |
|
|
273
|
+
| `AllowanceAmount` | Number | Y | 折讓單總金額(含稅) |
|
|
274
|
+
| `Items` | Array | Y | 折讓商品明細 |
|
|
275
|
+
| `ItemName` | String(100) | Y | 商品名稱 |
|
|
276
|
+
| `ItemCount` | Number | Y | 商品數量 |
|
|
277
|
+
| `ItemWord` | String(6) | N | 商品單位 |
|
|
278
|
+
| `ItemPrice` | Number | Y | 商品單價(含稅) |
|
|
279
|
+
| `ItemTaxType` | String(1) | N | 商品課稅別 |
|
|
280
|
+
| `ItemAmount` | Number | Y | 商品小計(含稅) |
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
### 4. 作廢折讓
|
|
285
|
+
|
|
286
|
+
**端點:** `POST /B2CInvoice/AllowanceInvalid`
|
|
287
|
+
|
|
288
|
+
#### Data 欄位內容
|
|
289
|
+
|
|
290
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
291
|
+
|------|------|------|------|
|
|
292
|
+
| `MerchantID` | String(10) | Y | 特店編號 |
|
|
293
|
+
| `InvoiceNo` | String(10) | Y | 發票號碼 |
|
|
294
|
+
| `AllowanceNo` | String(16) | Y | 折讓單號碼 |
|
|
295
|
+
| `Reason` | String(20) | Y | 作廢原因 |
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
### 5. 查詢發票
|
|
300
|
+
|
|
301
|
+
**端點:** `POST /B2CInvoice/GetIssue`
|
|
302
|
+
|
|
303
|
+
#### Data 欄位內容
|
|
304
|
+
|
|
305
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
306
|
+
|------|------|------|------|
|
|
307
|
+
| `MerchantID` | String(10) | Y | 特店編號 |
|
|
308
|
+
| `RelateNumber` | String(50) | Y | 廠商自訂編號 |
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### 6. 延遲開立發票
|
|
313
|
+
|
|
314
|
+
**端點:** `POST /B2CInvoice/DelayIssue`
|
|
315
|
+
|
|
316
|
+
延遲開立發票申請(需先用 `Issue` API 設定 `DelayFlag=1`)。
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
### 7. 觸發開立
|
|
321
|
+
|
|
322
|
+
**端點:** `POST /B2CInvoice/TriggerIssue`
|
|
323
|
+
|
|
324
|
+
觸發延遲開立的發票正式開立。
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
### 8. 取消延遲開立
|
|
329
|
+
|
|
330
|
+
**端點:** `POST /B2CInvoice/CancelDelayIssue`
|
|
331
|
+
|
|
332
|
+
取消延遲開立的發票申請。
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### 9. 查詢手機條碼
|
|
337
|
+
|
|
338
|
+
**端點:** `POST /B2CInvoice/CheckBarcode`
|
|
339
|
+
|
|
340
|
+
驗證手機條碼是否有效。
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
### 10. 查詢愛心碼
|
|
345
|
+
|
|
346
|
+
**端點:** `POST /B2CInvoice/CheckLoveCode`
|
|
347
|
+
|
|
348
|
+
驗證愛心碼是否有效。
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
### 11. 發票通知
|
|
353
|
+
|
|
354
|
+
**端點:** `POST /B2CInvoice/InvoiceNotify`
|
|
355
|
+
|
|
356
|
+
補寄發票開立通知信/簡訊。
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
### 12. 字軌設定查詢
|
|
361
|
+
|
|
362
|
+
**端點:** `POST /B2CInvoice/GetInvoiceWordSetting`
|
|
363
|
+
|
|
364
|
+
查詢發票字軌設定。
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## B2B 電子發票(三聯式)
|
|
369
|
+
|
|
370
|
+
### 1. 開立發票
|
|
371
|
+
|
|
372
|
+
**端點:** `POST /B2BInvoice/Issue`
|
|
373
|
+
|
|
374
|
+
#### Data 欄位內容(與 B2C 差異)
|
|
375
|
+
|
|
376
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
377
|
+
|------|------|------|------|
|
|
378
|
+
| `CustomerIdentifier` | String(8) | Y | 買方統編(**B2B 必填**) |
|
|
379
|
+
| `CustomerName` | String(60) | Y | 買方名稱(**B2B 必填**) |
|
|
380
|
+
| `CustomerAddress` | String(100) | N | 買方地址 |
|
|
381
|
+
| `CustomerEmail` | String(200) | N | 買方電子信箱 |
|
|
382
|
+
| `Print` | String(1) | - | **B2B 一律列印(固定=1)** |
|
|
383
|
+
| `Donation` | String(1) | - | **B2B 不可捐贈(固定=0)** |
|
|
384
|
+
| `CarrierType` | String(1) | - | **B2B 不可使用載具(固定=空值)** |
|
|
385
|
+
| `SalesAmount` | Number | Y | 銷售額合計(**未稅**) |
|
|
386
|
+
| `TaxAmount` | Number | Y | 稅額合計 |
|
|
387
|
+
| `TotalAmount` | Number | Y | 發票金額合計(SalesAmount + TaxAmount) |
|
|
388
|
+
| `ItemPrice` | Number | Y | 商品單價(**未稅**) |
|
|
389
|
+
| `ItemAmount` | Number | Y | 商品小計(**未稅**) |
|
|
390
|
+
| `ItemTax` | Number | N | 商品稅額 |
|
|
391
|
+
|
|
392
|
+
**B2B 與 B2C 主要差異:**
|
|
393
|
+
|
|
394
|
+
| 項目 | B2C | B2B |
|
|
395
|
+
|------|-----|-----|
|
|
396
|
+
| 統編 | 選填 | **必填** |
|
|
397
|
+
| 列印 | 可選 0/1 | **固定=1(一律列印)** |
|
|
398
|
+
| 捐贈 | 可選 0/1 | **固定=0(不可捐贈)** |
|
|
399
|
+
| 載具 | 可填 | **不可使用** |
|
|
400
|
+
| 金額 | 含稅 | **未稅** |
|
|
401
|
+
| 稅額 | 系統計算 | **必填** |
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
### 2. 作廢發票
|
|
406
|
+
|
|
407
|
+
**端點:** `POST /B2BInvoice/Invalid`
|
|
408
|
+
|
|
409
|
+
參數與 B2C 相同。
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
### 3. 開立折讓
|
|
414
|
+
|
|
415
|
+
**端點:** `POST /B2BInvoice/Allowance`
|
|
416
|
+
|
|
417
|
+
參數與 B2C 相同。
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### 4. 作廢折讓
|
|
422
|
+
|
|
423
|
+
**端點:** `POST /B2BInvoice/AllowanceInvalid`
|
|
424
|
+
|
|
425
|
+
參數與 B2C 相同。
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## 共用功能
|
|
430
|
+
|
|
431
|
+
### 1. 發票列印
|
|
432
|
+
|
|
433
|
+
**端點:** `POST /Invoice/Print`
|
|
434
|
+
|
|
435
|
+
開啟發票列印頁面(使用 POST 表單跳轉)。
|
|
436
|
+
|
|
437
|
+
#### 表單參數
|
|
438
|
+
|
|
439
|
+
| 欄位 | 型別 | 必填 | 說明 |
|
|
440
|
+
|------|------|------|------|
|
|
441
|
+
| `MerchantID` | String(10) | Y | 特店編號 |
|
|
442
|
+
| `InvoiceNo` | String(10) | Y | 發票號碼 |
|
|
443
|
+
| `InvoiceDate` | String(20) | Y | 發票開立日期時間 |
|
|
444
|
+
| `PrintStyle` | String(1) | N | 列印樣式:1 一般格式、2 簡易格式 |
|
|
445
|
+
|
|
446
|
+
**使用方式:**
|
|
447
|
+
```html
|
|
448
|
+
<form method="POST" action="https://einvoice-stage.ecpay.com.tw/Invoice/Print" target="_blank">
|
|
449
|
+
<input type="hidden" name="MerchantID" value="2000132">
|
|
450
|
+
<input type="hidden" name="InvoiceNo" value="AB12345678">
|
|
451
|
+
<input type="hidden" name="InvoiceDate" value="2024-01-01 10:00:00">
|
|
452
|
+
<button type="submit">列印發票</button>
|
|
453
|
+
</form>
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## 錯誤代碼
|
|
459
|
+
|
|
460
|
+
### 通用錯誤
|
|
461
|
+
|
|
462
|
+
| 代碼 | 說明 |
|
|
463
|
+
|------|------|
|
|
464
|
+
| `10000001` | 參數錯誤 |
|
|
465
|
+
| `10000002` | 發票號碼重複 |
|
|
466
|
+
| `10000003` | 特店編號錯誤 |
|
|
467
|
+
| `10000004` | 加密驗證失敗 |
|
|
468
|
+
| `10000005` | 時間戳記逾時(超過 10 分鐘) |
|
|
469
|
+
| `10000006` | RelateNumber 重複 |
|
|
470
|
+
| `10000007` | 發票不存在 |
|
|
471
|
+
| `10000008` | 發票已作廢 |
|
|
472
|
+
| `10000009` | 發票已折讓 |
|
|
473
|
+
| `10000010` | 折讓金額超過發票金額 |
|
|
474
|
+
|
|
475
|
+
### 開立發票錯誤
|
|
476
|
+
|
|
477
|
+
| 代碼 | 說明 |
|
|
478
|
+
|------|------|
|
|
479
|
+
| `10000011` | 買方統編格式錯誤 |
|
|
480
|
+
| `10000012` | 愛心碼格式錯誤 |
|
|
481
|
+
| `10000013` | 手機條碼格式錯誤 |
|
|
482
|
+
| `10000014` | 自然人憑證條碼格式錯誤 |
|
|
483
|
+
| `10000015` | 商品明細錯誤 |
|
|
484
|
+
| `10000016` | 金額計算錯誤 |
|
|
485
|
+
| `10000017` | 發票日期超過限制(6 天) |
|
|
486
|
+
| `10000018` | 載具與捐贈不可同時存在 |
|
|
487
|
+
| `10000019` | 打統編不可使用載具 |
|
|
488
|
+
| `10000020` | 打統編不可捐贈 |
|
|
489
|
+
|
|
490
|
+
### 作廢發票錯誤
|
|
491
|
+
|
|
492
|
+
| 代碼 | 說明 |
|
|
493
|
+
|------|------|
|
|
494
|
+
| `10000021` | 發票不可作廢(已超過期限) |
|
|
495
|
+
| `10000022` | 發票已有折讓不可作廢 |
|
|
496
|
+
|
|
497
|
+
### 折讓錯誤
|
|
498
|
+
|
|
499
|
+
| 代碼 | 說明 |
|
|
500
|
+
|------|------|
|
|
501
|
+
| `10000031` | 折讓單不存在 |
|
|
502
|
+
| `10000032` | 折讓單已作廢 |
|
|
503
|
+
| `10000033` | 折讓金額錯誤 |
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## 補充說明
|
|
508
|
+
|
|
509
|
+
### 載具類型說明
|
|
510
|
+
|
|
511
|
+
| 代碼 | 名稱 | 格式 | 說明 |
|
|
512
|
+
|------|------|------|------|
|
|
513
|
+
| `''` | 無載具 | - | 一般發票 |
|
|
514
|
+
| `1` | 綠界電子發票載具 | Email | 綠界會員載具 |
|
|
515
|
+
| `2` | 自然人憑證 | 2 碼英文 + 14 碼數字 | 總長度 16 碼 |
|
|
516
|
+
| `3` | 手機條碼 | `/` 開頭共 8 碼 | 需先驗證 |
|
|
517
|
+
|
|
518
|
+
### 課稅別說明
|
|
519
|
+
|
|
520
|
+
| 代碼 | 名稱 | 說明 |
|
|
521
|
+
|------|------|------|
|
|
522
|
+
| `1` | 應稅 | 一般商品(5% 稅率) |
|
|
523
|
+
| `2` | 零稅率 | 外銷、國際運輸等(需填 ClearanceMark) |
|
|
524
|
+
| `3` | 免稅 | 土地、未經加工農產品等 |
|
|
525
|
+
| `9` | 混合 | 混合應稅與免稅商品 |
|
|
526
|
+
|
|
527
|
+
### 零稅率原因代碼(自 115 年起必填)
|
|
528
|
+
|
|
529
|
+
| 代碼 | 說明 |
|
|
530
|
+
|------|------|
|
|
531
|
+
| `71` | 外銷貨物 |
|
|
532
|
+
| `72` | 與外銷有關之勞務,或在國內提供而在國外使用之勞務 |
|
|
533
|
+
| `73` | 依法設立之免稅商店銷售與過境或出境旅客之貨物 |
|
|
534
|
+
| `74` | 銷售與保稅區營業人供營運之貨物或勞務 |
|
|
535
|
+
| `75` | 國際間之運輸 |
|
|
536
|
+
| `76` | 國際運輸用之船舶、航空器及遠洋漁船 |
|
|
537
|
+
| `77` | 銷售與國際運輸用之船舶、航空器及遠洋漁船所使用之貨物或修繕勞務 |
|
|
538
|
+
| `78` | 保稅區營業人銷售與課稅區營業人未輸往課稅區而直接出口之貨物 |
|
|
539
|
+
| `79` | 保稅區營業人銷售與課稅區營業人存入自由港區事業或海關管理之保稅倉庫、物流中心以供外銷之貨物 |
|
|
540
|
+
|
|
541
|
+
### 金額計算邏輯
|
|
542
|
+
|
|
543
|
+
**B2C 發票(含稅):**
|
|
544
|
+
```
|
|
545
|
+
SalesAmount = 含稅總金額
|
|
546
|
+
TaxAmount = 0 (系統自動計算)
|
|
547
|
+
TotalAmount = SalesAmount
|
|
548
|
+
|
|
549
|
+
ItemPrice = 含稅單價
|
|
550
|
+
ItemAmount = 含稅小計
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**B2B 發票(未稅):**
|
|
554
|
+
```
|
|
555
|
+
SalesAmount = 未稅銷售額
|
|
556
|
+
TaxAmount = 稅額 (需自行計算,通常為 SalesAmount × 0.05)
|
|
557
|
+
TotalAmount = SalesAmount + TaxAmount
|
|
558
|
+
|
|
559
|
+
ItemPrice = 未稅單價
|
|
560
|
+
ItemAmount = 未稅小計
|
|
561
|
+
ItemTax = 商品稅額
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
**計算範例(B2B):**
|
|
565
|
+
```
|
|
566
|
+
商品單價:9524 元(未稅)
|
|
567
|
+
稅額:9524 × 0.05 = 476 元
|
|
568
|
+
總計:9524 + 476 = 10000 元
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## 開發筆記 (踩坑紀錄)
|
|
574
|
+
|
|
575
|
+
> 以下是實際整合過程中遇到的問題與解決方案
|
|
576
|
+
|
|
577
|
+
### 1. B2B 發票需使用不同 Endpoint
|
|
578
|
+
|
|
579
|
+
**問題**:B2B 發票使用 `/B2CInvoice/Issue` 會失敗
|
|
580
|
+
|
|
581
|
+
**解決**:
|
|
582
|
+
- B2C 發票:`/B2CInvoice/Issue`
|
|
583
|
+
- B2B 發票:`/B2BInvoice/Issue`
|
|
584
|
+
|
|
585
|
+
```typescript
|
|
586
|
+
const endpoint = isB2B ? '/B2BInvoice/Issue' : '/B2CInvoice/Issue'
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### 2. 測試環境 B2B 限制
|
|
590
|
+
|
|
591
|
+
**問題**:測試環境開 B2B 發票顯示「買方識別碼(統編)資料不存在」(RtnCode 6000015)
|
|
592
|
+
|
|
593
|
+
**原因**:ECPay 測試環境的 B2B 需要預先註冊買方統編,一般測試無法使用
|
|
594
|
+
|
|
595
|
+
**解決**:B2B 功能需在正式環境測試,或使用 B2C API 加上統編(ECPay 文件有提到這種方式)
|
|
596
|
+
|
|
597
|
+
### 3. 列印發票
|
|
598
|
+
|
|
599
|
+
**方法**:使用 `printInvoice` 方法呼叫 `/B2CInvoice/Print`
|
|
600
|
+
|
|
601
|
+
**回傳**:ECPay 會回傳 HTML 內容,前端開新視窗顯示並觸發列印
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
// 回傳格式
|
|
605
|
+
{
|
|
606
|
+
success: true,
|
|
607
|
+
htmlContent: '<html>...</html>' // 直接顯示在新視窗
|
|
608
|
+
}
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### 4. 金額計算
|
|
612
|
+
|
|
613
|
+
**B2C (二聯式)**:
|
|
614
|
+
- `SalesAmount` = 含稅總額
|
|
615
|
+
- `TaxAmount` = 0(不需計算)
|
|
616
|
+
|
|
617
|
+
**B2B (三聯式)**:
|
|
618
|
+
- `SalesAmount` = 未稅金額
|
|
619
|
+
- `TaxAmount` = 稅額
|
|
620
|
+
- `TotalAmount` = 含稅金額
|
|
621
|
+
|
|
622
|
+
### 5. 實作檔案
|
|
623
|
+
|
|
624
|
+
- **服務實作**:`lib/services/ecpay-invoice-service.ts`
|
|
625
|
+
- **API 路由**:`app/api/v1/financials/[id]/issue-invoice/route.ts`
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
629
|
+
## 相關文件
|
|
630
|
+
|
|
631
|
+
- [速買配 API 規格](./SMILEPAY_API_REFERENCE.md)
|
|
632
|
+
- [光貿 Amego API 規格](./AMEGO_API_REFERENCE.md)
|
|
633
|
+
- [發票開立流程](./INVOICE_FLOW.md)
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## 聯絡客服
|
|
638
|
+
|
|
639
|
+
如有任何問題,請聯絡綠界客服:
|
|
640
|
+
- **官方網站**:https://www.ecpay.com.tw
|
|
641
|
+
- **開發者文件**:https://developers.ecpay.com.tw/
|
|
642
|
+
- **技術支援**:請至官網查詢
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
最後更新:2026/01/28
|
|
647
|
+
文件版本:基於綠界官方文件整理 + 實作筆記
|