Skip to content

Releases: paid-tw/einvoice

v0.1.6 — debug logger, branded isInvoiceError, MockProvider fidelity

18 Jun 22:13

Choose a tag to compare

Minor release across all packages — observability, error-guard robustness, and a higher-fidelity test double. No breaking changes.

Highlights

  • Opt-in request tracing. Set debug on 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 core tracedFetch — a zero-overhead passthrough when debug is unset. Request/response bodies are never logged (encrypted on the wire for ezPay/ECPay, potentially PII for the others; wrap the fetch override to capture those).
  • isInvoiceError is now brand-based. It checks a globally-registered Symbol.for brand instead of instanceof, so it still narrows correctly when two copies of the package are loaded (dual ESM/CJS, transitive version skew).
  • Higher-fidelity MockProvider. Configurable capabilities (a non-TWD currency is rejected with UNSUPPORTED when FOREIGN_CURRENCY is omitted, matching a real domestic adapter), a tighter state machine (allowance on a voided invoice → CONFLICT; voidAllowance checks the allowance exists → NOT_FOUND), validation through the shared parseInput, and failNext(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

18 Jun 20:43

Choose a tag to compare

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-ezreceiptvoid / allowance / voidAllowance / query use the shared schemas.
  • @paid-tw/einvoice-ezpay-crossbordervoid / voidAllowance / query use the shared schemas.

Intentional exceptions (documented at the call sites)

  • ezReceipt issue keeps its own validator — it accepts a member id via buyer.email (carrier-info fallback), which the shared schema's email check would reject.
  • cross-border issue / allowance keep 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

18 Jun 20:19

Choose a tag to compare

Patch release across all packages — correctness and error-model improvements (no breaking changes).

Highlights

  • Allowance amount validation (fix). amountSummarySchema now enforces salesAmount + taxAmount === totalAmount on 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 (code VALIDATION, with the provider name and offending field) instead of leaking a raw ZodError, so every operation honors the SDK contract. (amego / ECPay / ezPay)
  • Clear crypto key/IV errors. A wrong-length HashKey / HashIV now throws a message naming the field and actual byte count, instead of an opaque Node createCipheriv error (ECPay 16/16, ezPay 32/16).
  • InvoiceError.toJSON(). Structured logging keeps the normalized fields (code / rawCode / rawMessage) that a plain JSON.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

17 Jun 16:18

Choose a tag to compare

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).

📦 https://www.npmjs.com/package/@paid-tw/einvoice

@paid-tw/einvoice-ezpay@0.3.0

17 Jun 16:18

Choose a tag to compare

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).

📦 https://www.npmjs.com/package/@paid-tw/einvoice-ezpay

@paid-tw/einvoice-ezpay-crossborder@0.1.1

17 Jun 16:38

Choose a tag to compare

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

17 Jun 16:18

Choose a tag to compare

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 return INV10002). TWD stays 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

17 Jun 16:18

Choose a tag to compare

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).

📦 https://www.npmjs.com/package/@paid-tw/einvoice-ecpay

@paid-tw/einvoice-amego@0.3.0

17 Jun 16:18

Choose a tag to compare

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).

📦 https://www.npmjs.com/package/@paid-tw/einvoice-amego