Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Myinvois Laravel Package

jiannius/myinvois

A Laravel package for integrating with Malaysia's MyInvois e-Invoicing platform, offering helpers to submit, validate, and manage electronic invoices through the LHDN MyInvois API from PHP applications.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for e-invoicing compliance: v1.5.0 shifts the calculus toward buy. The package now covers the operational surface a team would otherwise hand-roll — queued submission, idempotency/locking, reconciliation sweeps, per-tenant credentials, and typed lifecycle events — not just request signing and POSTing. That is the difference between a thin API wrapper and a production integration.
  • Request-path performance and SLA commitments: Myinvois::queueSubmission() moves LHDN latency out of the web request. The web request only dispatches; SubmitDocuments/PollSubmission jobs do the waiting. This unlocks product decisions like "invoice issuance never blocks checkout," and makes p95 checkout latency independent of LHDN availability. Plain submitDocuments() still works, so the migration is a per-flow decision rather than a platform rewrite.
  • Double-submission risk as a product guarantee: the per-document in-flight lock plus refusal of parents whose latest submission is SUBMITTED or VALID means the team can state, credibly, that redelivered or superseded jobs won't POST twice. That is a correctness guarantee worth putting in front of finance and audit stakeholders, not just engineering.
  • Multi-tenant / multi-entity roadmap: Contracts\ResolvesMyinvoisClient and Myinvois::clientFor() enable per-org credentials resolved on the worker, with one client enforced per submission. If the roadmap includes serving multiple legal entities, subsidiaries, or intermediary/on-behalf-of flows, this release removes a blocker that would otherwise force a fork or a separate deployment.
  • Reconciliation and drift as a scheduled job, not a manual fire drill: myinvois:sync with --limit, --dry-run, --include-valid, forParents(), withoutPolling(), and an opt-in schedule (services.myinvois.sync_schedule) turns "did every invoice actually land in LHDN?" into a background sweep. This directly informs support-cost and headcount assumptions in the business case.
  • Observability and customer-facing status: SubmissionAccepted, SubmissionSucceeded, SubmissionFailed (carrying LHDN's INVALID reasons), and DocumentStatusChanged give the product a clean seam for status timelines, notifications, dunning, or a customer invoice-status page — without scraping the database.
  • Delivery-risk management: the release notes are unusually candid about coverage — sandbox-tested end to end on LHDN preprod, but rejectDocument(), payable_rounding, and INVALID-reason handling are not live-verified. That is a planning input, not just a footnote: those paths need a UAT line item before GA.

When to Consider This Package

Adopt when:

  • The product issues invoices, credit/debit notes, or refund notes to Malaysian counterparties and must comply with LHDN MyInvois, and the team is on Laravel/PHP with no separate e-invoicing service.
  • Request-path latency matters — checkout, order confirmation, or a user-facing submission flow currently waits on LHDN.
  • Volume, retries, or queue redelivery create a real double-submission risk that finance or audit will ask about.
  • You serve multiple legal entities, brands, or intermediary/on-behalf-of arrangements and need per-org credentials on workers.
  • You want compliance events to feed product features (status pages, notifications, reconciliation dashboards) rather than being read out of a log table.

Look elsewhere, or defer, when:

  • You need rejectDocument() or payable_rounding now — neither is live-verified; treat both as UAT-gated. Same caution for relying on structured INVALID reasons in an automated decision path (unit-tested only).
  • You already run a dedicated e-invoicing or middleware vendor, or are not on Laravel — the value here is Laravel-native ergonomics (Myinvois::fake(), contracts, artisan, config), which you'd be paying for and not using.
  • Your queue infrastructure can't satisfy the stated constraint that retry_after must exceed 120s. That single config incompatibility will silently cause duplicate processing; if you can't change it, don't adopt the queued path.
  • You're on a platform without a real queue worker, or you can't operate a scheduler — the sync sweep is opt-in but is the main defence against silent drift.
  • You need a supported SLA and vendor accountability for LHDN conformance. This is a package, not a vendor; the sandbox-only validation is a risk you absorb.

How to Pitch It (Stakeholders)

To executives: this release closes the gap between "we can call LHDN's API" and "we can run e-invoicing in production." Three things change. One, invoices stop waiting on a government API inside the customer's request — submissions go to a queue, so checkout stays fast even when LHDN is slow or down. Two, the double-submission risk that finance and audit will inevitably raise is now handled in the library, not in bespoke code we'd have to write, test, and defend. Three, we can serve multiple legal entities with per-entity credentials, which removes a blocker for the next phase of the roadmap. All of it is opt-in, so there is no forced migration and no rework of existing flows.

To engineering: it's additive and non-breaking. submitDocuments() is unchanged; the queue path is a separate call. What you get: encrypted queued payloads with no secrets in the job, a per-document in-flight lock (MyinvoisInFlightException) so redelivered or superseded jobs never POST twice, ResolvesMyinvoisClient/clientFor() for per-org credentials on workers, an artisan sync sweep with dry-run and scoping, and lifecycle events carrying LHDN's reasons. There are also unconditional fixes worth taking regardless: status saves no longer bump the parent's updated_at, rate limiting is now correctly keyed per endpoint and client id (it was per submission uid), a null-returning failedCallback no longer crashes submission, a missing status field no longer blanks a row, plus a PHP 8.4 deprecation fix and a clearer unauthorized_client message.

Adoption steps and caveats to state plainly: wire the services.myinvois.* config — queue_connection, queue, lock_store, lock_seconds, sync_schedule, sync_limit — and verify queue retry_after exceeds 120s before enabling the queued path. Use Myinvois::fake() plus pollResolvesTo() in tests. Then set expectations: the release was validated end to end against the LHDN preprod sandbox, but INVALID-reason handling is unit-tested only, and rejectDocument() and payable_rounding are not live-verified — those need UAT coverage before we depend on them in a customer-facing flow.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo