Download the PHP package jiannius/myinvois without Composer

On this page you can find all versions of the php package jiannius/myinvois. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package myinvois

Jiannius MyInvois SDK

A Laravel SDK for the Malaysian LHDN MyInvois e-invoicing API. Handles authentication, UBL 2.1 document building, XAdES digital signing, submission, and lifecycle tracking against both the production and preprod (sandbox) MyInvois portals.

Requirements

Host apps still on Laravel 12 should pin the ^0.1 release line — the ^1.0 line is L13-only.

Installation

The package's service provider is auto-discovered via Laravel's package discovery — it also auto-loads the myinvois_documents migration. Just run:

The migration is idempotent (it short-circuits if myinvois_documents already exists), so it's safe even if you've already created the table by other means.

Configuration

Add a myinvois section to config/services.php:

Quick start

Submit the bundled sample document against preprod:

That builds a fully populated test invoice from Helpers/Sample::build(), signs it with your configured cert, and POSTs to MyInvois. The response includes the submission UID and per-document acceptance/rejection.

Resolving the SDK

The package binds a singleton-ish myinvois key to a fresh Myinvois instance:

You can override any of the configured settings per-instance via fluent setters:

Setter Purpose
setClientId($value) OAuth2 client ID
setClientSecret($value) OAuth2 client secret
setPreprod($bool) Force preprod (true) or production (false). Omit to auto-detect via app()->environment().
setOnBehalfOf($tin, $brn = null) For intermediaries — submit as if logged in as another taxpayer. $brn is only used when $tin matches the IG-prefix intermediary format.
setPrivateKey($pem) PEM-encoded RSA private key (only needed for submitDocuments)
setCertificate($pem) PEM-encoded X.509 certificate (only needed for submitDocuments)
setFailedCallback(fn) Closure invoked when an API call returns a non-2xx response. Receives the Illuminate\Http\Client\Response; whatever it returns replaces the original response.

Submitting documents

submitDocuments($documents) accepts an array of document arrays (see Document shape below) and runs the full pipeline:

  1. UBL 2.1 schema build (Helpers\UBL::build)
  2. XAdES enveloped signature (Helpers\Signature::build)
  3. SHA-256 hash + base64 encode
  4. POST to /api/v1.0/documentsubmissions
  5. Create one myinvois_documents row per accepted document (or one per line item for consolidated submissions, see below)
  6. Poll the submission up to 3 times (2s intervals) to flip submittedvalid / invalid immediately

Consolidated submissions

When every line item across all submitted documents has only classification code 004, the SDK treats it as a consolidated submission and creates one myinvois_documents row per line item (using description as document_number and the parent invoice number as consolidate_number), rather than one row per document.

Failure handling

A non-2xx response from MyInvois passes through failedCallback if set:

A 403 always throws (Permissions denied from MyInvois Portal). A 4xx during token acquisition aborts with a human-friendly message derived from LHDN's OAuth error — e.g. invalid_client becomes "MyInvois rejected the API credentials…" (see getTokenErrorMessage). Preprod and prod credentials never fall back to one another: requesting preprod without sandbox credentials throws Missing MyInvois sandbox (preprod) Client ID / Client Secret rather than silently using prod creds against the preprod endpoint.

Document shape

The SDK accepts a flat array shape (translated internally to UBL). Below is the canonical structure with required fields marked. See Helpers/Sample.php for a full populated example.

Validating before submission

validator() returns a Laravel Validator instance against the document shape — handy for surfacing user-friendly errors before paying for a rejected MyInvois call:

Pass 'sample' to validate (or submit) the bundled test fixture:

Retrieving documents

All retrieval methods return the raw decoded JSON response from MyInvois. getSubmission and getDocumentDetails additionally call updateMyinvoisDocuments to sync the local myinvois_documents row's status and response columns.

Cancelling and rejecting

cancelDocument updates the local row's status to cancelled and stores the reason in response. The 72-hour window is enforced client-side via MyinvoisDocument::isCancellable().

Taxpayer TIN lookup

Code helper

LHDN publishes static code tables (countries, states, currencies, MSIC industry codes, units of measure, taxes, classifications, payment modes, document types/versions). The SDK ships these as JSON in json/codes/ and exposes them via Jiannius\Myinvois\Helpers\Code:

get($needle) matches by either the code value or the human-readable label. value($needle) returns just the code, label($needle) returns just the description. The countries helper auto-uppercases input; the states helper auto-prefixes Wilayah Persekutuan for KL/Labuan/Putrajaya.

Tracking documents in your host app

The package's MyinvoisDocument Eloquent model is morph-related to whatever host model "owns" each invoice. Attach the HasMyinvoisDocument trait to that model:

The trait adds:

The trait registers an observer that auto-syncs myinvois_status / myinvois_preprod_status columns on the host model whenever a child MyinvoisDocument is saved (separated so preprod testing never overwrites prod state).

To wire up the parent relationship when submitting, just set parent_type / parent_id after submission (or extend submitDocuments in your own code to set them inline).

Swapping the document model

By default, the trait and Myinvois itself use the package's own Jiannius\Myinvois\Models\MyinvoisDocument. Host apps that want to add custom scopes/methods can extend it and register their subclass from a service provider:

Both the trait's morph relations and the SDK's internal create()/query() calls resolve through MyinvoisDocument::$useModel, so both stay consistent.

Enums

Jiannius\Myinvois\Enums\Status

Jiannius\Myinvois\Enums\TinType

Special TINs LHDN reserves for non-traditional buyers:

When a buyer's TIN matches one of these, the validator skips the BRN/NRIC/phone/address requirements. (GENERAL_PUBLIC cannot be used on standard non-consolidated invoices — only credit/debit/refund notes or consolidated invoices.)

On-behalf-of (intermediary submissions)

If you're a tax service provider submitting on behalf of clients, set the target TIN before each call:

The TIN goes into the OAuth onbehalfof header. If $clientTin matches config('services.myinvois.client_tin'), the SDK clears the header (you're submitting as yourself).

The intermediary IG-prefixed format requires both TIN and BRN, joined as IG...:BRN — handled automatically by setOnBehalfOf.

Rate limiting

The SDK enforces the per-endpoint limits LHDN publishes, using Laravel's RateLimiter. When the local counter hits the cap, the call sleeps for 60 / perMinute seconds and clears the counter rather than rejecting outright:

Endpoint family Limit (per minute)
documentsubmissions (submit), documents/*/raw, documents/*/details, taxpayer search, documentsubmissions/{uid} 60
documents/recent, documents/search, documents/state/*/state 12

Token caching

OAuth tokens are cached under myinvois_<clientId>_<onBehalfOf> for 50 minutes (MyInvois issues 60-minute tokens; the 10-minute buffer prevents edge-of-window failures). The cache is automatically invalidated on expiry.

License

MIT — see LICENSE.md.


All versions of myinvois with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
illuminate/support Version ^13.0
illuminate/database Version ^13.0
illuminate/http Version ^13.0
symfony/http-client Version ^7.0
noki/laravel-xml-converter Version ^1.0
simplesoftwareio/simple-qrcode Version ^4.2
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package jiannius/myinvois contains the following files

Loading the files please wait ...