Releases: paid-tw/einvoice
v0.1.6 — debug logger, branded isInvoiceError, MockProvider fidelity
Minor release across all packages — observability, error-guard robustness, and a higher-fidelity test double. No breaking changes.
Highlights
- Opt-in request tracing. Set
debugon any provider config to receive metadata-only trace events (provider/method/url/status/durationMs/error) for each HTTP call. Every adapter routes its fetch through the new coretracedFetch— a zero-overhead passthrough whendebugis unset. Request/response bodies are never logged (encrypted on the wire for ezPay/ECPay, potentially PII for the others; wrap thefetchoverride to capture those). isInvoiceErroris now brand-based. It checks a globally-registeredSymbol.forbrand instead ofinstanceof, so it still narrows correctly when two copies of the package are loaded (dual ESM/CJS, transitive version skew).- Higher-fidelity
MockProvider. Configurablecapabilities(a non-TWDcurrencyis rejected withUNSUPPORTEDwhenFOREIGN_CURRENCYis omitted, matching a real domestic adapter), a tighter state machine (allowanceon a voided invoice →CONFLICT;voidAllowancechecks the allowance exists →NOT_FOUND), validation through the sharedparseInput, andfailNext(error)to inject a one-shot failure for exercising error paths.
New exports (@paid-tw/einvoice)
tracedFetch, InvoiceDebugEvent, InvoiceDebugLogger; MockProviderOptions.capabilities and MockProvider#failNext; debug on BaseProviderConfig.
Versions
| Package | Version |
|---|---|
@paid-tw/einvoice |
0.4.0 |
@paid-tw/einvoice-amego |
0.4.0 |
@paid-tw/einvoice-ecpay |
0.4.0 |
@paid-tw/einvoice-ezpay |
0.4.0 |
@paid-tw/einvoice-ezpay-crossborder |
0.2.0 |
@paid-tw/einvoice-ezreceipt |
0.2.0 |
v0.1.5 — ezReceipt + cross-border adopt shared input schemas
Patch release for two adapters — validation-error consistency (no breaking changes).
What changed
ezReceipt and ezPay cross-border previously skipped the shared Zod input schemas. They now adopt them where the schema is a clean fit, so their validation errors are normalized to InvoiceError (code VALIDATION) — consistent with the Amego / ECPay / ezPay adapters.
@paid-tw/einvoice-ezreceipt—void/allowance/voidAllowance/queryuse the shared schemas.@paid-tw/einvoice-ezpay-crossborder—void/voidAllowance/queryuse the shared schemas.
Intentional exceptions (documented at the call sites)
- ezReceipt
issuekeeps its own validator — it accepts a member id viabuyer.email(carrier-info fallback), which the shared schema's email check would reject. - cross-border
issue/allowancekeep their own validator — foreign-currency sales carry 2-decimal amounts, which the integer-only amount schema would reject.
Verified against the live sandboxes: ezReceipt 15/15, ezPay cross-border 27/27.
Versions
| Package | Version |
|---|---|
@paid-tw/einvoice-ezreceipt |
0.1.4 |
@paid-tw/einvoice-ezpay-crossborder |
0.1.4 |
v0.1.4 — validation normalization, allowance amount guard, crypto guards
Patch release across all packages — correctness and error-model improvements (no breaking changes).
Highlights
- Allowance amount validation (fix).
amountSummarySchemanow enforcessalesAmount + taxAmount === totalAmounton allowances, not just invoices —allowance()rejects an inconsistent amount locally instead of sending it to the provider. - Normalized validation errors. Adapter input validation now rejects with an
InvoiceError(codeVALIDATION, with the provider name and offending field) instead of leaking a rawZodError, so every operation honors the SDK contract. (amego / ECPay / ezPay) - Clear crypto key/IV errors. A wrong-length
HashKey/HashIVnow throws a message naming the field and actual byte count, instead of an opaque NodecreateCipheriverror (ECPay 16/16, ezPay 32/16). InvoiceError.toJSON(). Structured logging keeps the normalized fields (code/rawCode/rawMessage) that a plainJSON.stringify(error)dropped.- New shared exports from
@paid-tw/einvoice:parseInput,parseTaipeiDate,taipeiDateTime,taxTypeToCode.
Under the hood (no API change)
- Build migrated from tsup → tsdown (rolldown); published outputs unchanged, verified with
attw+publint. - De-duplicated Taipei date helpers and the tax-type mapping into core.
- Extracted types/wire-maps out of the large ECPay/ezReceipt providers.
- Added MSW coverage for the tax-type wire mapping and the allowance amount guard.
All changes verified against the live provider sandboxes (Amego, ECPay, ezPay, ezPay cross-border, ezReceipt).
Versions
| Package | Version |
|---|---|
@paid-tw/einvoice |
0.3.2 |
@paid-tw/einvoice-amego |
0.3.2 |
@paid-tw/einvoice-ecpay |
0.3.2 |
@paid-tw/einvoice-ezpay |
0.3.2 |
@paid-tw/einvoice-ezpay-crossborder |
0.1.3 |
@paid-tw/einvoice-ezreceipt |
0.1.3 |
@paid-tw/einvoice@0.3.0
Adds a FOREIGN_CURRENCY capability for the currency + exchangeRate annotation. Amego declares and maps it; ECPay/ezPay now reject a non-TWD currency with an UNSUPPORTED error instead of silently dropping it. Statutory amounts stay integer TWD. The root README gains a provider capability matrix, and all package READMEs are now zh-tw by default (English in README.en.md).
@paid-tw/einvoice-ezpay@0.3.0
Adds a FOREIGN_CURRENCY capability for the currency + exchangeRate annotation. Amego declares and maps it; ECPay/ezPay now reject a non-TWD currency with an UNSUPPORTED error instead of silently dropping it. Statutory amounts stay integer TWD. The root README gains a provider capability matrix, and all package READMEs are now zh-tw by default (English in README.en.md).
@paid-tw/einvoice-ezpay-crossborder@0.1.1
Patch — verify the response CheckCode (附件二) on issued invoices.
issue and triggerIssue now recompute the SHA-256 CheckCode over MerchantID / MerchantOrderNo / InvoiceTransNo / TotalAmt / RandomNum (reusing @paid-tw/einvoice-ezpay's makeCheckCode) and throw a PROVIDER error on a mismatch — detecting a tampered or mis-routed reply. Controlled by verifyCheckCode (default on); TotalAmt uses the raw returned string so foreign-currency replies verify too.
Verified live: the CheckCode matches real responses for TWD and all 20 currencies. First package published via the repo's OIDC trusted-publishing workflow (tokenless + provenance).
📦 https://www.npmjs.com/package/@paid-tw/einvoice-ezpay-crossborder
@paid-tw/einvoice-ezpay-crossborder@0.1.0
First release 🎉 — a separate ezPay service adapter for 境外電商 (cross-border e-commerce supplier): foreign-currency-native B2C e-invoices for foreign sellers issuing to Taiwan consumers.
- Set
currency+exchangeRate→ amounts carry 2 decimals (the 20 currencies of 附件三 are accepted; others returnINV10002).TWDstays integer. - B2C e-mail-carrier only — 統編 / 載具 / 捐贈 / 混合稅率 are rejected as
UNSUPPORTED. - Reuses the standard ezPay wire layer (AES-256-CBC, CheckCode) via
@paid-tw/einvoice-ezpay. - Implements the unified
InvoiceProvider+ two-phase issue (Status 0/3) + allowance confirm/cancel. - Verified live end-to-end on the ezPay cross-border test environment; 100% line coverage.
📦 https://www.npmjs.com/package/@paid-tw/einvoice-ezpay-crossborder
@paid-tw/einvoice-ecpay@0.3.0
Adds a FOREIGN_CURRENCY capability for the currency + exchangeRate annotation. Amego declares and maps it; ECPay/ezPay now reject a non-TWD currency with an UNSUPPORTED error instead of silently dropping it. Statutory amounts stay integer TWD. The root README gains a provider capability matrix, and all package READMEs are now zh-tw by default (English in README.en.md).
@paid-tw/einvoice-amego@0.3.0
Adds a FOREIGN_CURRENCY capability for the currency + exchangeRate annotation. Amego declares and maps it; ECPay/ezPay now reject a non-TWD currency with an UNSUPPORTED error instead of silently dropping it. Statutory amounts stay integer TWD. The root README gains a provider capability matrix, and all package READMEs are now zh-tw by default (English in README.en.md).