以優質 DX 為目標,提供台灣金流的統一操作介面。底層金流邏輯由
@paid-tw/payment* SDK 提供;CLI 負責設定、輸出與指令。
# 全域
npm i -g @paid-tw/cli
paid --help
# 或免安裝
npx @paid-tw/cli --help- 單一指令介面操作多家金流(PAYUNi、ECPay AIO、ECPay 站內付 2.0;NewebPay 開發中)
- 統一欄位模型與錯誤正規化(
PaymentError穩定錯誤碼) - 同時支援 env、config 檔、CLI flags
- 完整 help 便於 AI 呼叫
- 選用:paid.tw OAuth 加值服務
Provider (--provider) |
create | get | refund | 備註 |
|---|---|---|---|---|
payuni |
開發中 | ✅ | 開發中 | 統一金流 trade query |
ecpay |
✅ AioCheckOut redirect | ✅ QueryTradeInfo | ✅ DoAction(信用卡) | 導轉綠界收銀台;raw.mode === "redirect" |
ecpay-ecpg |
✅ GetToken token | 開發中 | 開發中 | 站內付 2.0;raw.mode === "token"(給前端 JS) |
newebpay |
開發中 | 開發中 | 開發中 | 藍新 scaffold |
各 provider 以 capabilities 宣告能力;未支援的操作回傳 UNSUPPORTED。
金流協定細節(簽章、notify 驗簽、DoAction C/E/N 等)見 SDK:
- GitHub:https://github.com/paid-tw/payment
- npm:
@paid-tw/payment·@paid-tw/payment-ecpay·@paid-tw/payment-payuni
export PAYUNI_MERCHANT_ID=your_merchant_id
export PAYUNI_HASH_KEY=your_hash_key
export PAYUNI_HASH_IV=your_hash_iv
export PAYUNI_SANDBOX=true # 預設正式環境;測試請 true
npx @paid-tw/cli doctor --provider=payuni
npx @paid-tw/cli payments get --provider=payuni --id=ORDER-123公開 stage 特店(綠界文件明碼,AIO / 站內付可共用):
export ECPAY_MERCHANT_ID=3002607
export ECPAY_HASH_KEY=pwFHCqoQZGmho4w6
export ECPAY_HASH_IV=EkRm7iFT261dpevs
export ECPAY_SANDBOX=true
# create → raw.mode=redirect(導轉表單,非已付款)
npx @paid-tw/cli payments create --provider=ecpay --amount=1000 --method=card \
--order-id=ORDER123 --item-desc="T-shirt" --notify-url=https://example.com/ecpay/notify
npx @paid-tw/cli payments get --provider=ecpay --id=ORDER123
npx @paid-tw/cli payments refund --provider=ecpay --id=ORDER123 --amount=1000
create回傳已簽章的 AioCheckOut 表單(mode: "redirect"+action+params),商店 POST 即可導向收銀台。
--order-id(MerchantTradeNo)須為 1–20 碼英數字;--notify-url= ECPayReturnURL(必填)。
同一組 ECPAY_* 即可(可選 ECPAY_ECPG_* 覆寫):
export ECPAY_MERCHANT_ID=3002607
export ECPAY_HASH_KEY=pwFHCqoQZGmho4w6
export ECPAY_HASH_IV=EkRm7iFT261dpevs
export ECPAY_SANDBOX=true
# create → raw.mode=token(給前端 ECPay JS SDK,非已付款)
# --email 與 --phone 擇一必填
npx @paid-tw/cli payments create --provider=ecpay-ecpg --amount=100 --method=card \
--order-id=ORDER123 --notify-url=https://example.com/ecpay/notify \
--email=buyer@example.com --sandbox前端需載入綠界站內付 2.0 JS:
createPayment(token)→getPayToken(),再由伺服器呼叫 SDK 的createPaymentWithPayToken。CLI 只負責 server 端 GetToken。
# 即將推出paid doctor --provider=payuni|ecpay|ecpay-ecpg|newebpay
paid providers list
paid providers ping --provider=payuni --id=...
paid payments create --provider=ecpay|ecpay-ecpg ...
paid payments get --provider=payuni|ecpay --id=...
paid payments refund --provider=ecpay --id=... --amount=...
paid config set --provider=ecpay --merchant-id=... --hash-key=... --hash-iv=...
paid config get --provider=ecpay
paid tw auth login|status # 選用,僅 paid.tw 功能需要- CLI flags(含
--sandbox/--production) - 環境變數(含
.env,會覆蓋系統 env) ~/.config/paid/config.toml
--providerPAID_DEFAULT_PROVIDERconfig.toml的defaultProvider- 若只設定一個
providers.*,自動使用該 provider
--provider=payuni|newebpay|ecpay|ecpay-ecpg--format=json|pretty(payments get、doctor;--json等同 json)--sandbox/--production:單次切換環境--email/--phone:ecpay-ecpgcreate 用--id/--trade-no:查詢識別
PAID_DEFAULT_PROVIDER=ecpay
PAID_ENV=sandbox
# PAYUNi
PAYUNI_MERCHANT_ID=...
PAYUNI_HASH_KEY=...
PAYUNI_HASH_IV=...
PAYUNI_SANDBOX=true
# ECPay(AIO + 站內付共用;站內付也可改用 ECPAY_ECPG_*)
ECPAY_MERCHANT_ID=3002607
ECPAY_HASH_KEY=...
ECPAY_HASH_IV=...
ECPAY_SANDBOX=true
# ECPAY_ECPG_MERCHANT_ID=... # 可選覆寫前綴:PAYUNI_*、ECPAY_*、ECPAY_ECPG_*、NEWEBPAY_*;欄位 _MERCHANT_ID / _HASH_KEY / _HASH_IV / _SANDBOX。
defaultProvider = "ecpay"
outputFormat = "json"
[providers.ecpay]
merchantId = "3002607"
hashKey = "pwFHCqoQZGmho4w6"
hashIv = "EkRm7iFT261dpevs"
sandbox = true
# 站內付可省略;未設定時沿用 [providers.ecpay] / ECPAY_*
# [providers.ecpay-ecpg]
# ...完整範例見 config.example.toml。
成功時為統一 success 信封(--json)。錯誤為統一結構;底層 PaymentError 的碼在 error.details.code(如 NOT_FOUND / AUTH / VALIDATION)。
{
"provider": "ecpay",
"id": "ORDER123",
"status": "fetched",
"data": {
"status": "paid",
"method": "card",
"amount": 1234,
"paidAt": "2026/07/02 21:27:45",
"tradeNo": "2607022124117236",
"merTradeNo": "ORDER123"
}
}{
"provider": "ecpay",
"status": "created",
"raw": {
"mode": "redirect",
"action": "https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5",
"method": "POST",
"params": { "MerchantID": "3002607", "MerchantTradeNo": "ORDER123", "CheckMacValue": "..." }
}
}{
"provider": "ecpay-ecpg",
"status": "created",
"raw": {
"mode": "token",
"token": "...",
"merchantTradeNo": "ORDER123",
"frontend": { "environment": "stage" }
}
}{
"success": false,
"error": {
"code": "PAYMENT_GET_FAILED",
"message": "ECPay 查無交易資料",
"details": { "code": "NOT_FOUND", "provider": "ecpay", "rawCode": "10200047" }
},
"metadata": { "command": "payments get" }
}paid doctor --provider=ecpay
paid doctor --provider=ecpay-ecpg僅在使用 paid.tw 平台功能時需要:
paid tw auth login
paid tw auth status本地金流 CLI 可忽略此段。
paid --help
paid payments create --help
paid doctor --help
paid providers listnpm i
npm run dev -- --help
npm test # vitest(CLI 層 + 部分 provider MSW)
npm run typecheck
npm run lint
npm run format
npm run build # tsdown → dist/index.js (bin)Gateway 實作與較完整的 MSW / live 測試在 payment monorepo(paid-tw/payment)。
CLI 內 live 測試:PAYUNI_LIVE=1 / ECPAY_LIVE=1 時才會跑。
cli/
src/
commands/ # commander 指令
core/ # config、輸出、provider registry(compose SDK factories)
providers/ # 薄 re-export → @paid-tw/payment*
- CI:
.github/workflows/ci.yml(pushmain與 PR;Node 20/22/24) - npm 發布:推送 git tag
vX.Y.Z→.github/workflows/publish.yml(OIDC,不用本機npm publish)
步驟見docs/release.md
- 本 CLI:本 README、
CHANGELOG.md、docs/payuni/trade-query.md - 金流 SDK:https://github.com/paid-tw/payment