taiwan-logistics-skill 1.0.4 → 1.0.5
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/README.md +5 -5
- package/assets/taiwan-logistics/EXAMPLES.md +3183 -3183
- package/assets/taiwan-logistics/README.md +5 -5
- package/assets/taiwan-logistics/SKILL.md +827 -827
- package/assets/taiwan-logistics/references/NEWEBPAY_LOGISTICS_REFERENCE.md +774 -774
- package/assets/taiwan-logistics/references/ecpay-logistics-api.md +536 -536
- package/assets/taiwan-logistics/references/payuni-logistics-api.md +712 -712
- package/assets/templates/base/quick-reference.md +85 -0
- package/assets/templates/base/skill-content.md +361 -0
- package/assets/templates/platforms/agent.json +26 -0
- package/assets/templates/platforms/claude.json +26 -0
- package/assets/templates/platforms/codebuddy.json +25 -0
- package/assets/templates/platforms/codex.json +26 -0
- package/assets/templates/platforms/continue.json +25 -0
- package/assets/templates/platforms/copilot.json +25 -0
- package/assets/templates/platforms/cursor.json +26 -0
- package/assets/templates/platforms/gemini.json +25 -0
- package/assets/templates/platforms/kiro.json +25 -0
- package/assets/templates/platforms/opencode.json +25 -0
- package/assets/templates/platforms/qoder.json +25 -0
- package/assets/templates/platforms/roocode.json +25 -0
- package/assets/templates/platforms/trae.json +25 -0
- package/assets/templates/platforms/windsurf.json +25 -0
- package/dist/index.js +125 -18
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
## When to Apply
|
|
2
|
+
|
|
3
|
+
Reference these guidelines when:
|
|
4
|
+
- Developing Taiwan E-Invoice issuance functionality
|
|
5
|
+
- Integrating ECPay, SmilePay, or Amego APIs
|
|
6
|
+
- Implementing B2C or B2B invoice logic
|
|
7
|
+
- Handling invoice printing, void, and allowance
|
|
8
|
+
- Troubleshooting invoice API integration issues
|
|
9
|
+
|
|
10
|
+
## Provider Quick Reference
|
|
11
|
+
|
|
12
|
+
| Priority | Task | Impact | Provider |
|
|
13
|
+
|----------|------|--------|----------|
|
|
14
|
+
| 1 | Amount Calculation | CRITICAL | All |
|
|
15
|
+
| 2 | Encryption/Signature | CRITICAL | All |
|
|
16
|
+
| 3 | B2B vs B2C Logic | HIGH | All |
|
|
17
|
+
| 4 | Print Response Handling | HIGH | All |
|
|
18
|
+
| 5 | Provider Binding | MEDIUM | All |
|
|
19
|
+
| 6 | Error Handling | MEDIUM | All |
|
|
20
|
+
| 7 | Carrier/Donation | LOW | B2C only |
|
|
21
|
+
|
|
22
|
+
## Quick Reference
|
|
23
|
+
|
|
24
|
+
### 1. Amount Calculation (CRITICAL)
|
|
25
|
+
|
|
26
|
+
- `b2c-tax-inclusive` - B2C uses tax-inclusive total
|
|
27
|
+
- `b2b-split-tax` - B2B requires pre-tax + tax split
|
|
28
|
+
- `round-tax` - Round tax: `Math.round(total - (total / 1.05))`
|
|
29
|
+
- `salesamount` - ECPay/Amego: Use SalesAmount for pre-tax
|
|
30
|
+
|
|
31
|
+
### 2. Encryption/Signature (CRITICAL)
|
|
32
|
+
|
|
33
|
+
- `ecpay-aes` - ECPay: AES-128-CBC with HashKey/HashIV
|
|
34
|
+
- `smilepay-verify` - SmilePay: Grvc + Verify_key params
|
|
35
|
+
- `amego-md5` - Amego: MD5(data + time + appKey)
|
|
36
|
+
- `url-encode` - Always URL encode before encryption
|
|
37
|
+
|
|
38
|
+
### 3. B2B vs B2C Logic (HIGH)
|
|
39
|
+
|
|
40
|
+
- `buyer-id-b2c` - B2C: BuyerIdentifier = "0000000000"
|
|
41
|
+
- `buyer-id-b2b` - B2B: BuyerIdentifier = actual 8-digit tax ID
|
|
42
|
+
- `no-carrier-b2b` - B2B: Cannot use carrier or donation
|
|
43
|
+
- `validate-taxid` - Validate 8-digit tax ID format
|
|
44
|
+
|
|
45
|
+
### 4. Print Response Handling (HIGH)
|
|
46
|
+
|
|
47
|
+
- `ecpay-html` - ECPay: Returns HTML, use window.document.write
|
|
48
|
+
- `smilepay-redirect` - SmilePay: Returns URL, use window.open
|
|
49
|
+
- `amego-pdf` - Amego: Returns PDF URL, use window.open
|
|
50
|
+
- `form-submit` - Some APIs require form POST submission
|
|
51
|
+
|
|
52
|
+
### 5. Provider Binding (MEDIUM)
|
|
53
|
+
|
|
54
|
+
- `save-provider` - Save invoiceProvider when issuing
|
|
55
|
+
- `save-random` - Save invoiceRandomNum for printing
|
|
56
|
+
- `match-provider` - Use issuing provider for print/void
|
|
57
|
+
|
|
58
|
+
### 6. Error Handling (MEDIUM)
|
|
59
|
+
|
|
60
|
+
- `log-raw-response` - Log complete raw response for debugging
|
|
61
|
+
- `ecpay-codes` - ECPay: Check RtnCode and RtnMsg
|
|
62
|
+
- `smilepay-codes` - SmilePay: Check Status field
|
|
63
|
+
- `amego-codes` - Amego: Check Code and Message
|
|
64
|
+
|
|
65
|
+
### 7. Carrier/Donation (B2C only)
|
|
66
|
+
|
|
67
|
+
- `carrier-mobile` - Mobile barcode: /XXXXXXX format
|
|
68
|
+
- `carrier-npc` - Natural person certificate
|
|
69
|
+
- `donation-code` - Donation: 3-7 digit love code
|
|
70
|
+
- `mutual-exclusive` - Carrier and donation are mutually exclusive
|
|
71
|
+
|
|
72
|
+
## Test Credentials
|
|
73
|
+
|
|
74
|
+
| Provider | Key Info |
|
|
75
|
+
|----------|----------|
|
|
76
|
+
| ECPay | MerchantID: 2000132, Stage URL |
|
|
77
|
+
| SmilePay | Grvc: SEI1000034, Test Tax ID: 80129529 |
|
|
78
|
+
| Amego | Tax ID: 12345678, test@amego.tw |
|
|
79
|
+
|
|
80
|
+
## How to Use
|
|
81
|
+
|
|
82
|
+
See the full skill documentation for detailed API references and code examples.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# {{TITLE}}
|
|
2
|
+
|
|
3
|
+
> {{DESCRIPTION}}
|
|
4
|
+
|
|
5
|
+
## Quick Navigation
|
|
6
|
+
|
|
7
|
+
### Related Documents
|
|
8
|
+
When using this skill, refer to the API reference documents in the project:
|
|
9
|
+
- `references/ECPAY_API_REFERENCE.md` - ECPay API Specification
|
|
10
|
+
- `references/SMILEPAY_API_REFERENCE.md` - SmilePay API Specification
|
|
11
|
+
- `references/AMEGO_API_REFERENCE.md` - Amego API Specification
|
|
12
|
+
- [EXAMPLES.md](EXAMPLES.md) - Code Examples
|
|
13
|
+
|
|
14
|
+
### When to Use This Skill
|
|
15
|
+
- Developing e-invoice issuance functionality
|
|
16
|
+
- Integrating Taiwan E-Invoice provider APIs
|
|
17
|
+
- Implementing B2C or B2B invoices
|
|
18
|
+
- Handling invoice printing, void, and allowance
|
|
19
|
+
- Processing encryption/signatures (AES, MD5)
|
|
20
|
+
- Troubleshooting invoice API integration issues
|
|
21
|
+
|
|
22
|
+
## Invoice Types
|
|
23
|
+
|
|
24
|
+
### B2C Invoice (Two-Part)
|
|
25
|
+
- Buyer without tax ID
|
|
26
|
+
- `BuyerIdentifier` = `0000000000`
|
|
27
|
+
- Amount is **tax-inclusive**
|
|
28
|
+
- Can use carrier or donation
|
|
29
|
+
- Example: General consumer purchase
|
|
30
|
+
|
|
31
|
+
### B2B Invoice (Three-Part)
|
|
32
|
+
- Buyer has 8-digit tax ID
|
|
33
|
+
- `BuyerIdentifier` = actual tax ID (validate format)
|
|
34
|
+
- Amount is **pre-tax**, requires separate tax calculation
|
|
35
|
+
- **Cannot** use carrier or donation
|
|
36
|
+
- Example: Company purchase
|
|
37
|
+
|
|
38
|
+
## Provider Comparison
|
|
39
|
+
|
|
40
|
+
| Feature | ECPay | SmilePay | Amego |
|
|
41
|
+
|---------|-------|----------|-------|
|
|
42
|
+
| Test/Prod URL | Different URLs | Different URLs | **Same URL** |
|
|
43
|
+
| Authentication | AES encryption + HashKey/HashIV | Grvc + Verify_key | MD5 signature + App Key |
|
|
44
|
+
| Print Method | POST form submit | GET URL params | API returns PDF URL |
|
|
45
|
+
| B2B Amount Field | SalesAmount (pre-tax) | UnitTAX=N | DetailVat=0 |
|
|
46
|
+
| Transport Format | JSON (AES encrypted) | URL Parameters | JSON (URL Encoded) |
|
|
47
|
+
|
|
48
|
+
## Implementation Steps
|
|
49
|
+
|
|
50
|
+
### 1. Service Architecture
|
|
51
|
+
|
|
52
|
+
Create services following this structure:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// lib/services/invoice-provider.ts - Interface definition
|
|
56
|
+
export interface InvoiceService {
|
|
57
|
+
issueInvoice(userId: string, data: InvoiceIssueData): Promise<InvoiceIssueResponse>
|
|
58
|
+
voidInvoice(userId: string, invoiceNumber: string, reason: string): Promise<InvoiceVoidResponse>
|
|
59
|
+
printInvoice(userId: string, invoiceNumber: string): Promise<InvoicePrintResponse>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// lib/services/{provider}-invoice-service.ts - Provider implementation
|
|
63
|
+
export class ECPayInvoiceService implements InvoiceService {
|
|
64
|
+
private async encryptData(data: any, hashKey: string, hashIV: string): Promise<string> {
|
|
65
|
+
// AES-128-CBC encryption implementation
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async issueInvoice(userId: string, data: InvoiceIssueData) {
|
|
69
|
+
// 1. Get user settings
|
|
70
|
+
// 2. Prepare API data
|
|
71
|
+
// 3. Encrypt and sign
|
|
72
|
+
// 4. Send request
|
|
73
|
+
// 5. Decrypt response
|
|
74
|
+
// 6. Return standard format
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 2. Amount Calculation
|
|
80
|
+
|
|
81
|
+
**Tax-inclusive total -> Pre-tax amount + Tax:**
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
function calculateInvoiceAmounts(totalAmount: number, isB2B: boolean) {
|
|
85
|
+
if (isB2B) {
|
|
86
|
+
// B2B: Need to split tax
|
|
87
|
+
const taxAmount = Math.round(totalAmount - (totalAmount / 1.05))
|
|
88
|
+
const salesAmount = totalAmount - taxAmount
|
|
89
|
+
return { salesAmount, taxAmount, totalAmount }
|
|
90
|
+
} else {
|
|
91
|
+
// B2C: Tax-inclusive total
|
|
92
|
+
return { salesAmount: totalAmount, taxAmount: 0, totalAmount }
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Example
|
|
97
|
+
const amounts = calculateInvoiceAmounts(1050, true)
|
|
98
|
+
// { salesAmount: 1000, taxAmount: 50, totalAmount: 1050 }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3. Encryption Implementation
|
|
102
|
+
|
|
103
|
+
**ECPay - AES Encryption:**
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import crypto from 'crypto'
|
|
107
|
+
|
|
108
|
+
function encryptECPay(data: object, hashKey: string, hashIV: string): string {
|
|
109
|
+
// 1. Convert JSON to string and URL encode
|
|
110
|
+
const jsonString = JSON.stringify(data)
|
|
111
|
+
const urlEncoded = encodeURIComponent(jsonString)
|
|
112
|
+
|
|
113
|
+
// 2. AES-128-CBC encryption
|
|
114
|
+
const cipher = crypto.createCipheriv('aes-128-cbc', hashKey, hashIV)
|
|
115
|
+
let encrypted = cipher.update(urlEncoded, 'utf8', 'base64')
|
|
116
|
+
encrypted += cipher.final('base64')
|
|
117
|
+
|
|
118
|
+
return encrypted
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function decryptECPay(encryptedData: string, hashKey: string, hashIV: string): object {
|
|
122
|
+
const decipher = crypto.createDecipheriv('aes-128-cbc', hashKey, hashIV)
|
|
123
|
+
let decrypted = decipher.update(encryptedData, 'base64', 'utf8')
|
|
124
|
+
decrypted += decipher.final('utf8')
|
|
125
|
+
|
|
126
|
+
const urlDecoded = decodeURIComponent(decrypted)
|
|
127
|
+
return JSON.parse(urlDecoded)
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Amego - MD5 Signature:**
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
function generateAmegoSign(data: object, time: number, appKey: string): string {
|
|
135
|
+
const dataString = JSON.stringify(data)
|
|
136
|
+
const signString = dataString + time + appKey
|
|
137
|
+
return crypto.createHash('md5').update(signString).digest('hex')
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 4. Provider Binding
|
|
142
|
+
|
|
143
|
+
**Key: When issuing invoice, must record the provider used so printing can call the correct one**
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Save provider when issuing
|
|
147
|
+
await prisma.financialRecord.update({
|
|
148
|
+
where: { id: recordId },
|
|
149
|
+
data: {
|
|
150
|
+
invoiceNo: result.invoiceNumber,
|
|
151
|
+
invoiceProvider: actualProvider, // 'ECPAY' | 'SMILEPAY' | 'AMEGO'
|
|
152
|
+
invoiceRandomNum: result.randomNumber, // **Important**: needed for printing
|
|
153
|
+
invoiceDate: new Date(),
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
// Use the issuing provider when printing
|
|
158
|
+
const service = record.invoiceProvider
|
|
159
|
+
? InvoiceServiceFactory.getService(record.invoiceProvider)
|
|
160
|
+
: await InvoiceServiceFactory.getServiceForUser(userId)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 5. Print Response Handling
|
|
164
|
+
|
|
165
|
+
Frontend needs to handle based on response type:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Backend response format
|
|
169
|
+
interface InvoicePrintResponse {
|
|
170
|
+
success: boolean
|
|
171
|
+
type?: 'html' | 'redirect' | 'form'
|
|
172
|
+
htmlContent?: string // ECPay
|
|
173
|
+
printUrl?: string // SmilePay/Amego
|
|
174
|
+
formUrl?: string
|
|
175
|
+
formParams?: Record<string, string>
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Frontend handling example
|
|
179
|
+
if (result.type === 'html') {
|
|
180
|
+
const win = window.open('', '_blank')
|
|
181
|
+
win.document.write(result.htmlContent)
|
|
182
|
+
} else if (result.type === 'redirect') {
|
|
183
|
+
window.open(result.url, '_blank')
|
|
184
|
+
} else if (result.type === 'form') {
|
|
185
|
+
// Dynamically create form submission
|
|
186
|
+
const form = document.createElement('form')
|
|
187
|
+
form.method = 'POST'
|
|
188
|
+
form.action = result.formUrl
|
|
189
|
+
form.target = '_blank'
|
|
190
|
+
// ... add parameters
|
|
191
|
+
form.submit()
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Common Issues
|
|
196
|
+
|
|
197
|
+
### Issue 1: Invoice issuance failed with unclear error
|
|
198
|
+
|
|
199
|
+
**Diagnostic steps:**
|
|
200
|
+
1. Check logger output for complete error in `raw` field
|
|
201
|
+
2. Confirm environment variables (test/prod) are correct
|
|
202
|
+
3. Verify required fields are complete
|
|
203
|
+
|
|
204
|
+
**ECPay common errors:**
|
|
205
|
+
- `10000006`: RelateNumber duplicate -> Order number already used
|
|
206
|
+
- `10000016`: Amount calculation error -> Check B2C/B2B calculation
|
|
207
|
+
- `10000019`: Cannot use carrier with tax ID -> Remove CarrierType
|
|
208
|
+
|
|
209
|
+
**SmilePay common errors:**
|
|
210
|
+
- `-10066`: AllAmount validation error -> Check if TotalAmount was sent
|
|
211
|
+
- `-10084`: orderid format error -> Limit to 30 characters
|
|
212
|
+
- `-10053`: Carrier number error -> Validate mobile barcode format
|
|
213
|
+
|
|
214
|
+
**Amego common errors:**
|
|
215
|
+
- `1002`: OrderId already exists -> Use unique order number
|
|
216
|
+
- `1007`: Amount calculation error -> Check DetailVat setting
|
|
217
|
+
- `1012`: B2B invoice cannot use carrier or donation
|
|
218
|
+
|
|
219
|
+
### Issue 2: Print shows "Invoice not found"
|
|
220
|
+
|
|
221
|
+
**Solution:**
|
|
222
|
+
Confirm `invoiceProvider` field is saved correctly, use the issuing provider when printing.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// Correct: Use provider from invoice record
|
|
226
|
+
const service = record.invoiceProvider
|
|
227
|
+
? InvoiceServiceFactory.getService(record.invoiceProvider)
|
|
228
|
+
: await InvoiceServiceFactory.getServiceForUser(userId)
|
|
229
|
+
|
|
230
|
+
// Incorrect: Use user's current default provider
|
|
231
|
+
const service = await InvoiceServiceFactory.getServiceForUser(userId)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Issue 3: B2B invoice amount error
|
|
235
|
+
|
|
236
|
+
**Amount fields by provider:**
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
// ECPay
|
|
240
|
+
const b2bData = {
|
|
241
|
+
SalesAmount: 1000, // Pre-tax sales
|
|
242
|
+
TaxAmount: 50, // Tax
|
|
243
|
+
TotalAmount: 1050, // Total
|
|
244
|
+
ItemPrice: 100, // Item unit price (pre-tax)
|
|
245
|
+
ItemAmount: 1000, // Item subtotal (pre-tax)
|
|
246
|
+
ItemTax: 50 // Item tax
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// SmilePay
|
|
250
|
+
const b2bData = {
|
|
251
|
+
AllAmount: '1050', // Tax-inclusive total
|
|
252
|
+
SalesAmount: '1000', // Pre-tax sales (optional but recommended)
|
|
253
|
+
TaxAmount: '50', // Tax (optional)
|
|
254
|
+
UnitTAX: 'N', // **Important**: Unit price is pre-tax
|
|
255
|
+
UnitPrice: '100', // Item unit price (pre-tax)
|
|
256
|
+
Amount: '1000' // Item subtotal (pre-tax)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Amego
|
|
260
|
+
const b2bData = {
|
|
261
|
+
DetailVat: 0, // **Important**: 0=pre-tax
|
|
262
|
+
SalesAmount: 1000, // Pre-tax sales
|
|
263
|
+
TaxAmount: 50, // Tax
|
|
264
|
+
TotalAmount: 1050, // Total
|
|
265
|
+
ProductItem: [{
|
|
266
|
+
UnitPrice: 100, // Item unit price (pre-tax)
|
|
267
|
+
Amount: 1000 // Item subtotal (pre-tax)
|
|
268
|
+
}]
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Issue 4: SmilePay print blank
|
|
273
|
+
|
|
274
|
+
**Cause:** Using `type: 'form'` when response has `method: 'GET'`
|
|
275
|
+
|
|
276
|
+
**Solution:**
|
|
277
|
+
```typescript
|
|
278
|
+
// Correct
|
|
279
|
+
if (printData.method === 'GET' && printData.url) {
|
|
280
|
+
return { type: 'redirect', url: printData.url }
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Incorrect
|
|
284
|
+
return { type: 'form', url: printData.url, params: printData.params }
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Issue 5: Timestamp expired
|
|
288
|
+
|
|
289
|
+
**ECPay error 10000005:** Timestamp exceeds 10 minutes
|
|
290
|
+
|
|
291
|
+
**Solution:**
|
|
292
|
+
```typescript
|
|
293
|
+
// Ensure using current timestamp
|
|
294
|
+
const timestamp = Math.floor(Date.now() / 1000)
|
|
295
|
+
|
|
296
|
+
// Amego: tolerance is +/- 60 seconds
|
|
297
|
+
const time = Math.floor(Date.now() / 1000)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Test Accounts
|
|
301
|
+
|
|
302
|
+
### ECPay Test Environment
|
|
303
|
+
```
|
|
304
|
+
MerchantID: 2000132
|
|
305
|
+
HashKey: ejCk326UnaZWKisg
|
|
306
|
+
HashIV: q9jcZX8Ib9LM8wYk
|
|
307
|
+
URL: https://einvoice-stage.ecpay.com.tw
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### SmilePay Test Environment
|
|
311
|
+
```
|
|
312
|
+
Grvc: SEI1000034
|
|
313
|
+
Verify_key: 9D73935693EE0237FABA6AB744E48661
|
|
314
|
+
Test Tax ID: 80129529
|
|
315
|
+
URL: https://ssl.smse.com.tw/api_test/SPEinvoice_Storage.asp
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Amego Test Environment
|
|
319
|
+
```
|
|
320
|
+
Tax ID: 12345678
|
|
321
|
+
App Key: sHeq7t8G1wiQvhAuIM27
|
|
322
|
+
Admin: https://invoice.amego.tw/
|
|
323
|
+
Test Account: test@amego.tw
|
|
324
|
+
Test Password: 12345678
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Development Checklist
|
|
328
|
+
|
|
329
|
+
Use this checklist to ensure complete implementation:
|
|
330
|
+
|
|
331
|
+
- [ ] Implement `InvoiceService` interface
|
|
332
|
+
- [ ] Handle B2C / B2B amount calculation differences
|
|
333
|
+
- [ ] Implement encryption/signature mechanism (AES or MD5)
|
|
334
|
+
- [ ] Save `invoiceProvider` field
|
|
335
|
+
- [ ] Save `invoiceRandomNum` (needed for printing)
|
|
336
|
+
- [ ] Handle print response types (html/redirect/form)
|
|
337
|
+
- [ ] Implement error handling and logging
|
|
338
|
+
- [ ] Test environment verification
|
|
339
|
+
- [ ] Handle carrier and donation mutual exclusion
|
|
340
|
+
- [ ] Validate tax ID format (8-digit number)
|
|
341
|
+
|
|
342
|
+
## Adding New Provider
|
|
343
|
+
|
|
344
|
+
1. Create `{provider}-invoice-service.ts` in `lib/services/`
|
|
345
|
+
2. Implement all methods of `InvoiceService` interface
|
|
346
|
+
3. Register new provider in `InvoiceServiceFactory`
|
|
347
|
+
4. Add option to `InvoiceProvider` enum in `prisma/schema.prisma`
|
|
348
|
+
5. Run `prisma migrate` or `prisma db push`
|
|
349
|
+
6. Update frontend settings page (`app/settings/invoice/page.tsx`)
|
|
350
|
+
7. Write unit tests
|
|
351
|
+
|
|
352
|
+
## References
|
|
353
|
+
|
|
354
|
+
For detailed API specifications, see the `references/` directory:
|
|
355
|
+
- [ECPay API Specification](./references/ECPAY_API_REFERENCE.md)
|
|
356
|
+
- [SmilePay API Specification](./references/SMILEPAY_API_REFERENCE.md)
|
|
357
|
+
- [Amego API Specification](./references/AMEGO_API_REFERENCE.md)
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
Last updated: 2026/01/28
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "antigravity",
|
|
3
|
+
"displayName": "Antigravity / Generic Agent",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".agent",
|
|
7
|
+
"skillPath": "skills/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md",
|
|
9
|
+
"globalRoot": "~/.gemini/antigravity/global_skills"
|
|
10
|
+
},
|
|
11
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
12
|
+
"frontmatter": {
|
|
13
|
+
"name": "taiwan-invoice",
|
|
14
|
+
"description": "Taiwan E-Invoice API integration for ECPay, SmilePay, and Amego. Provides B2C/B2B invoice issuance, void, allowance, query, and print functionality.",
|
|
15
|
+
"user-invocable": "true"
|
|
16
|
+
},
|
|
17
|
+
"sections": {
|
|
18
|
+
"examples": true,
|
|
19
|
+
"references": true,
|
|
20
|
+
"scripts": true,
|
|
21
|
+
"quickReference": false
|
|
22
|
+
},
|
|
23
|
+
"title": "Taiwan E-Invoice Skill",
|
|
24
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
25
|
+
"skillOrWorkflow": "Skill"
|
|
26
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "claude",
|
|
3
|
+
"displayName": "Claude Code",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".claude",
|
|
7
|
+
"skillPath": "skills/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md",
|
|
9
|
+
"globalRoot": "~/.claude"
|
|
10
|
+
},
|
|
11
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
12
|
+
"frontmatter": {
|
|
13
|
+
"name": "taiwan-invoice",
|
|
14
|
+
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego. Provides B2C/B2B invoice issuance, void, allowance, query, and print functionality. Includes encryption implementations (AES-128-CBC, MD5), tax calculations, and complete API specifications.",
|
|
15
|
+
"user-invocable": "true"
|
|
16
|
+
},
|
|
17
|
+
"sections": {
|
|
18
|
+
"examples": true,
|
|
19
|
+
"references": true,
|
|
20
|
+
"scripts": true,
|
|
21
|
+
"quickReference": true
|
|
22
|
+
},
|
|
23
|
+
"title": "Taiwan E-Invoice Skill",
|
|
24
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
25
|
+
"skillOrWorkflow": "Skill"
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "codebuddy",
|
|
3
|
+
"displayName": "CodeBuddy",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".codebuddy",
|
|
7
|
+
"skillPath": "skills/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "taiwan-invoice",
|
|
13
|
+
"description": "Taiwan E-Invoice API integration for ECPay, SmilePay, and Amego.",
|
|
14
|
+
"user-invocable": "true"
|
|
15
|
+
},
|
|
16
|
+
"sections": {
|
|
17
|
+
"examples": true,
|
|
18
|
+
"references": true,
|
|
19
|
+
"scripts": true,
|
|
20
|
+
"quickReference": false
|
|
21
|
+
},
|
|
22
|
+
"title": "Taiwan E-Invoice Skill",
|
|
23
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
24
|
+
"skillOrWorkflow": "Skill"
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "codex",
|
|
3
|
+
"displayName": "Codex CLI",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".codex",
|
|
7
|
+
"skillPath": "skills/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md",
|
|
9
|
+
"globalRoot": "~/.codex"
|
|
10
|
+
},
|
|
11
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
12
|
+
"frontmatter": {
|
|
13
|
+
"name": "taiwan-invoice",
|
|
14
|
+
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego.",
|
|
15
|
+
"user-invocable": "true"
|
|
16
|
+
},
|
|
17
|
+
"sections": {
|
|
18
|
+
"examples": true,
|
|
19
|
+
"references": true,
|
|
20
|
+
"scripts": true,
|
|
21
|
+
"quickReference": false
|
|
22
|
+
},
|
|
23
|
+
"title": "Taiwan E-Invoice Skill",
|
|
24
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
25
|
+
"skillOrWorkflow": "Skill"
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "continue",
|
|
3
|
+
"displayName": "Continue",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".continue",
|
|
7
|
+
"skillPath": "skills/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "taiwan-invoice",
|
|
13
|
+
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego.",
|
|
14
|
+
"user-invocable": "true"
|
|
15
|
+
},
|
|
16
|
+
"sections": {
|
|
17
|
+
"examples": true,
|
|
18
|
+
"references": true,
|
|
19
|
+
"scripts": true,
|
|
20
|
+
"quickReference": false
|
|
21
|
+
},
|
|
22
|
+
"title": "Taiwan E-Invoice Skill",
|
|
23
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
24
|
+
"skillOrWorkflow": "Skill"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "copilot",
|
|
3
|
+
"displayName": "GitHub Copilot",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".github",
|
|
7
|
+
"skillPath": "prompts/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "prompts/taiwan-invoice/scripts",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "taiwan-invoice",
|
|
13
|
+
"description": "Taiwan E-Invoice API integration for ECPay, SmilePay, and Amego.",
|
|
14
|
+
"user-invocable": "true"
|
|
15
|
+
},
|
|
16
|
+
"sections": {
|
|
17
|
+
"examples": true,
|
|
18
|
+
"references": true,
|
|
19
|
+
"scripts": true,
|
|
20
|
+
"quickReference": false
|
|
21
|
+
},
|
|
22
|
+
"title": "Taiwan E-Invoice Skill",
|
|
23
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
24
|
+
"skillOrWorkflow": "Skill"
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "cursor",
|
|
3
|
+
"displayName": "Cursor",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".cursor",
|
|
7
|
+
"skillPath": "skills/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md",
|
|
9
|
+
"globalRoot": "~/.cursor"
|
|
10
|
+
},
|
|
11
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
12
|
+
"frontmatter": {
|
|
13
|
+
"name": "taiwan-invoice",
|
|
14
|
+
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego. Provides B2C/B2B invoice issuance, void, allowance, query, and print functionality. Includes encryption implementations (AES-128-CBC, MD5), tax calculations, and complete API specifications.",
|
|
15
|
+
"user-invocable": "true"
|
|
16
|
+
},
|
|
17
|
+
"sections": {
|
|
18
|
+
"examples": true,
|
|
19
|
+
"references": true,
|
|
20
|
+
"scripts": true,
|
|
21
|
+
"quickReference": false
|
|
22
|
+
},
|
|
23
|
+
"title": "Taiwan E-Invoice Skill",
|
|
24
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
25
|
+
"skillOrWorkflow": "Skill"
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "gemini",
|
|
3
|
+
"displayName": "Gemini CLI",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".gemini",
|
|
7
|
+
"skillPath": "skills/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/taiwan-invoice/scripts",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "taiwan-invoice",
|
|
13
|
+
"description": "Taiwan E-Invoice API integration specialist for ECPay, SmilePay, and Amego.",
|
|
14
|
+
"user-invocable": "true"
|
|
15
|
+
},
|
|
16
|
+
"sections": {
|
|
17
|
+
"examples": true,
|
|
18
|
+
"references": true,
|
|
19
|
+
"scripts": true,
|
|
20
|
+
"quickReference": false
|
|
21
|
+
},
|
|
22
|
+
"title": "Taiwan E-Invoice Skill",
|
|
23
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
24
|
+
"skillOrWorkflow": "Skill"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "kiro",
|
|
3
|
+
"displayName": "Kiro",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".kiro",
|
|
7
|
+
"skillPath": "steering/taiwan-invoice",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "steering/taiwan-invoice/scripts",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "taiwan-invoice",
|
|
13
|
+
"description": "Taiwan E-Invoice API integration for ECPay, SmilePay, and Amego.",
|
|
14
|
+
"user-invocable": "true"
|
|
15
|
+
},
|
|
16
|
+
"sections": {
|
|
17
|
+
"examples": true,
|
|
18
|
+
"references": true,
|
|
19
|
+
"scripts": true,
|
|
20
|
+
"quickReference": false
|
|
21
|
+
},
|
|
22
|
+
"title": "Taiwan E-Invoice Skill",
|
|
23
|
+
"description": "Comprehensive guide for Taiwan E-Invoice API integration. Supports ECPay, SmilePay, and Amego providers with B2C/B2B invoice operations.",
|
|
24
|
+
"skillOrWorkflow": "Skill"
|
|
25
|
+
}
|