logistics-adapters
Taiwan Logistics Adapters (台灣物流適配器)
Overview
@rytass/logistics 系列套件提供統一的台灣物流服務整合介面,支援包裹追蹤、訂單建立和狀態管理。
套件清單
| 套件 | 說明 | 功能 |
|---|---|---|
@rytass/logistics |
基礎介面 | 定義統一的物流服務介面 |
@rytass/logistics-adapter-tcat |
黑貓宅急便 | 包裹追蹤(HTML 爬蟲) |
@rytass/logistics-adapter-ctc |
中華宅配 | 包裹追蹤 + 訂單管理(REST API) |
Quick Start
安裝
# 黑貓宅急便
npm install @rytass/logistics-adapter-tcat
# 中華宅配
npm install @rytass/logistics-adapter-ctc
黑貓宅急便追蹤
import { TCatLogisticsService, TCatLogistics } from '@rytass/logistics-adapter-tcat';
const logistics = new TCatLogisticsService(TCatLogistics);
// 追蹤單一包裹
const [result] = await logistics.trace('800978442950');
console.log(result.statusHistory);
// [{ date: '2024-01-15 14:30', status: 'DELIVERED', businessPremise: '台北營業所' }]
// 批量追蹤
const results = await logistics.trace(['800978442950', '903404283301']);
中華宅配追蹤與建單
⚠️ 安全警告:預設的
CtcLogistics配置包含測試用的 API Token,請勿用於生產環境。務必使用您自己的 API Token。
import { CtcLogisticsService, CtcLogistics } from '@rytass/logistics-adapter-ctc';
// 使用預設設定(必須替換 apiToken)
const logistics = new CtcLogisticsService({
...CtcLogistics,
apiToken: process.env.CTC_API_TOKEN!, // ⚠️ 必須替換為您的 API Token
});
// 追蹤包裹
const [result] = await logistics.trace('TRACKING-001');
// 建立託運單
const order = await logistics.create({
senderCompany: '寄件公司',
senderAddress: '台北市中正區重慶南路一段122號',
senderMobile: '0912345678',
receiverCompany: '收件公司',
receiverContactName: '收件人',
receiverAddress: '台北市信義區信義路五段7號',
receiverMobile: '0987654321',
paidCode: '客戶宅配',
});
console.log(order.shippingNumber); // 託運單號
console.log(order.trackingNumber); // 查件單號
// 更新託運單(需指定 trackingNumber)
const updatedOrder = await logistics.update({
trackingNumber: 'TRACKING-001', // 必填:查件單號
senderCompany: '新寄件公司',
senderAddress: '台北市中正區重慶南路一段122號',
senderMobile: '0912345678',
receiverCompany: '新收件公司',
receiverContactName: '新收件人',
receiverAddress: '台北市信義區信義路五段7號',
receiverMobile: '0987654321',
paidCode: '客戶宅配',
});
CTC 建單/更新選項
interface CreateOrUpdateCtcLogisticsOptions {
// 基本資訊
trackingNumber?: string; // 查件單號(create 時可選,update 時必填)
customerDepartmentId?: number; // 客戶部門 ID
customerDepartmentUnitId?: number; // 客戶部門單位 ID
// 寄件人資訊
senderCompany: string; // 寄件人公司名稱(必填)
senderContactName?: string; // 寄件人聯絡人(預設同 senderCompany)
senderAddress: string; // 寄件人地址(必填)
senderTel?: string; // 寄件人市話(與 senderMobile 二擇一)
senderMobile?: string; // 寄件人手機(與 senderTel 二擇一)
senderRemark?: string; // 寄件人備註
// 收件人資訊
receiverCompany: string; // 收件人公司名稱(必填)
receiverContactName: string; // 收件人聯絡人(必填)
receiverAddress: string; // 收件人地址(必填)
receiverTel?: string; // 收件人市話(與 receiverMobile 二擇一)
receiverMobile?: string; // 收件人手機(與 receiverTel 二擇一)
receiverRemark?: string; // 收件人備註
// 運送資訊
paidCode: string; // 付款代碼(必填)
shipmentContent?: string; // 貨物內容(預設 '貨件')
transportation?: string; // 運輸工具(預設 'truck')
shippingMethod?: string; // 運送方式(預設 'land')
payer?: string; // 費用支付方(預設 'receiver')
shippingTime?: string; // 送件時效(預設 'regular')
paymentMethod?: string; // 結算方式(預設 'monthly')
quantity?: number; // 件數(預設 1)
weight?: number; // 重量(預設 1)
volume?: number; // 材積(預設 1)
}
// 回傳結果
interface CtcLogisticsDto {
trackingNumber?: string; // 查件單號
shippingNumber: string; // 託運單號
}
Core Concepts
統一介面 LogisticsService
所有適配器都實現 LogisticsService 介面:
// 基礎物流介面
interface LogisticsInterface<T = LogisticsBaseStatus> {
reference?: T;
url: string;
}
// LogisticsService 介面(泛型約束較複雜)
interface LogisticsService<LogisticsType extends LogisticsInterface<LogisticsStatus<LogisticsType>>> {
trace(request: string): Promise<LogisticsTraceResponse<LogisticsType>[]>;
trace(request: string[]): Promise<LogisticsTraceResponse<LogisticsType>[]>;
}
追蹤結果結構
// 泛型約束較複雜,簡化理解:K 代表物流介面類型
interface LogisticsTraceResponse<K extends LogisticsInterface<LogisticsStatus<K>>> {
logisticsId: string; // 追蹤號碼
statusHistory: LogisticsStatusHistory<K['reference']>[]; // 狀態歷史
}
interface LogisticsStatusHistory<T> {
date: string; // 時間
status: T; // 狀態代碼(字串)
}
// T-CAT 擴展(包含營業所資訊)
interface TCatLogisticsStatusHistory<T> extends LogisticsStatusHistory<T> {
businessPremise: string; // 營業所名稱
}
// CTC 擴展(包含狀態碼)
interface CtcLogisticsStatusHistory<T> extends LogisticsStatusHistory<T> {
statusCode: CtcLogisticsStatusEnum; // 狀態碼(數字)
}
// CTC 狀態碼枚舉
enum CtcLogisticsStatusEnum {
CREATED = 10, // 新單
PICKUP_EXCEPTION = 29, // 取件異常
PICKED_UP = 30, // 已取件
PICKUP_ARRIVED_AT_HUB = 40, // 取件到站
IN_TRANSIT = 50, // 轉運中
TRANSIT_ARRIVED_AT_HUB = 60, // 轉運到站
SHELVED = 65, // 回站保管
DELIVERING = 70, // 配送中
DELIVERY_EXCEPTION = 75, // 配送異常
DELIVERED = 80, // 配送完成
EMPTY_TRIP = 87, // 空趟
COMPLETED = 88, // 正常結案
NOTIFICATION_SENT = 91, // 通知完成
CANCELLED = 99, // 取消
}
基本狀態類型
type LogisticsBaseStatus = 'DELIVERED' | 'DELIVERING' | 'SHELVED';
// 完整的 T-CAT 狀態類型(Union Type)
type TCatLogisticsStatus =
| 'DELIVERED'
| 'TRANSPORTING'
| 'DELIVERING'
| 'COLLECTING'
| 'CONSOLIDATED'
| 'PICKUP_CANCELED'
| 'SHELVED'
| 'INVESTIGATING'
| 'DELIVERING_TODAY'
| 'FAIL_PICKUP'
| 'AWAY_HOME'
| LogisticsBaseStatus;
// 完整的 CTC 狀態類型(Union Type)
type CtcLogisticsStatus =
| 'CREATED'
| 'PICKUP_EXCEPTION'
| 'PICKED_UP'
| 'PICKUP_ARRIVED_AT_HUB'
| 'IN_TRANSIT'
| 'TRANSIT_ARRIVED_AT_HUB'
| 'SHELVED'
| 'DELIVERING'
| 'DELIVERY_EXCEPTION'
| 'DELIVERED'
| 'EMPTY_TRIP'
| 'COMPLETED'
| 'NOTIFICATION_SENT'
| 'CANCELLED';
額外導出類型
// 錯誤介面
interface LogisticsErrorInterface {
readonly code: string;
readonly message?: string;
}
// T-CAT 物流介面(可自訂 statusMap)
interface TCatLogisticsInterface<T> extends LogisticsInterface<T> {
ignoreNotFound: boolean;
statusMap: (html: string, id: string) => LogisticsStatusHistory<T>[];
}
// CTC 物流介面
interface CtcLogisticsInterface<T> extends LogisticsInterface<T> {
apiToken: string;
ignoreNotFound?: boolean;
}
// CTC 狀態對照表常數(可用於自訂映射)
const CtcLogisticsStatusMap: { [key: string]: CtcLogisticsStatus };
// CTC API 回應(內部使用,但有導出)
interface CreateOrUpdateCtcLogisticsResponse {
success: boolean;
error: string;
shipping_number: string;
tracking_number?: string;
}
Common Patterns
T-CAT 狀態對照表
| 狀態 | 中文原文 | 說明 |
|---|---|---|
DELIVERED |
順利送達 | 包裹已成功送達 |
TRANSPORTING |
轉運中 | 包裹在轉運途中 |
DELIVERING |
配送中 | 配送員正在派送 |
COLLECTING |
取件中 | 正在取件 |
CONSOLIDATED |
已集貨 | 已完成集貨 |
PICKUP_CANCELED |
取消取件 | 取件已取消 |
SHELVED |
暫置營業所 | 暫存於營業所 |
INVESTIGATING |
調查處理中 | 正在調查處理 |
DELIVERING_TODAY |
配送中(當配下車) (當配上車) | 當日配送中 |
FAIL_PICKUP |
未順利取件,請洽客服中心 | 取件失敗 |
AWAY_HOME |
不在家.公司行號休息 | 收件人不在 |
CTC 狀態對照表
| 狀態 | 狀態碼 | 說明 |
|---|---|---|
CREATED |
10 | 新單 |
PICKUP_EXCEPTION |
29 | 取件異常 |
PICKED_UP |
30 | 已取件 |
PICKUP_ARRIVED_AT_HUB |
40 | 取件到站 |
IN_TRANSIT |
50 | 轉運中 |
TRANSIT_ARRIVED_AT_HUB |
60 | 轉運到站 |
SHELVED |
65 | 回站保管 |
DELIVERING |
70 | 配送中 |
DELIVERY_EXCEPTION |
75 | 配送異常 |
DELIVERED |
80 | 配送完成 |
EMPTY_TRIP |
87 | 空趟 |
COMPLETED |
88 | 正常結案 |
NOTIFICATION_SENT |
91 | 通知完成 |
CANCELLED |
99 | 取消 |
錯誤處理
import { LogisticsError, ErrorCode } from '@rytass/logistics';
// ErrorCode 枚舉
enum ErrorCode {
NOT_IMPLEMENTED = '999', // 未實作
NOT_FOUND_ERROR = '101', // 找不到包裹
PERMISSION_DENIED = '102', // 無權查詢
INVALID_PARAMETER = '103', // 無效參數
}
try {
const result = await logistics.trace('INVALID');
} catch (error) {
if (error instanceof LogisticsError) {
switch (error.code) {
case ErrorCode.NOT_FOUND_ERROR:
console.error('找不到此包裹');
break;
case ErrorCode.PERMISSION_DENIED:
console.error('無權查詢');
break;
case ErrorCode.INVALID_PARAMETER:
console.error('無效的追蹤號碼');
break;
case ErrorCode.NOT_IMPLEMENTED:
console.error('功能未實作');
break;
}
}
}
忽略找不到錯誤
// T-CAT 預設 ignoreNotFound: false
const tcatLogistics = new TCatLogisticsService({
...TCatLogistics, // 預設 ignoreNotFound: false
ignoreNotFound: true, // 找不到時返回空歷史而非拋出錯誤
});
// CTC 預設 ignoreNotFound: true
const ctcLogistics = new CtcLogisticsService({
...CtcLogistics, // 預設 ignoreNotFound: true
apiToken: 'your-token',
ignoreNotFound: false, // 改為找不到時拋出錯誤
});
API Reference
詳細 API 文件請參閱 reference.md。
Troubleshooting
T-CAT 追蹤失敗
T-CAT 使用 HTML 爬蟲,可能因網站改版而失效。檢查:
- 網站是否可正常訪問
- HTML 結構是否變更
- 考慮使用自訂
statusMap函數
CTC API 認證失敗
- 確認
apiToken正確 - 檢查 API 端點 URL
- 確認帳戶有對應權限
批量追蹤效能
批量追蹤使用 Promise.all,注意:
- 避免一次追蹤過多包裹
- 考慮分批處理大量請求
- 設置適當的超時時間
More from rytass/utils
wms-module
|
24logistics-development
|
13invoice-adapters
Taiwan e-invoice integration (台灣電子發票整合). Use when working with ECPay (綠界), EZPay (藍新), BankPro (金財通), or Amego (光貿) invoice services. Covers issuing invoices (開立發票), voiding (作廢), allowances (折讓), and querying invoice data.
8payment-adapters
Taiwan payment integration (台灣支付整合). Use when working with ECPay (綠界), NewebPay (藍新), HwaNan Bank (華南銀行), CTBC (中信), iCash Pay, or Happy Card payment services. Covers credit card (信用卡), virtual account (虛擬帳號), ATM, CVS payment (超商代碼/條碼), card binding (卡片綁定), installments (分期付款), recurring payments (訂閱付款), and NestJS integration.
7member-module
|
7quadrats-module
|
7