Skip to content
Sandbox setup

Set up the LHDN MyInvois preprod sandbox before you submit a single live invoice.

LHDN runs two environments: preprod (preprod-api.myinvois.hasil.gov.my) for integration testing and production for live submissions. Everything you build should land in preprod first — same OAuth2 flow, same UBL 2.1 schema, same status responses, but no compliance consequences for malformed submissions.

Five steps

What you need to do, in order.

  1. 01

    Get LHDN preprod credentials

    Apply through the LHDN portal for preprod client credentials. They issue a client ID and client secret. These are different from your production credentials — never mix.

  2. 02

    Configure your environment

    Point your integration at `https://preprod-api.myinvois.hasil.gov.my`. In MyInvois Bridge this is the `LHDN_API_BASE_URL` env var. Verification QR codes will resolve to `preprod.myinvois.hasil.gov.my/<uuid>` — that's expected.

  3. 03

    Run a token exchange

    Hit the token endpoint with `grant_type=client_credentials` and `scope=InvoicingAPI`. If you get a bearer token back, the credentials are wired correctly. Cache the token — it's valid for 60 minutes.

  4. 04

    Submit a sample invoice

    Generate a UBL 2.1 invoice with a synthetic supplier TIN, customer TIN, and one line item. POST to the document submission endpoint. LHDN returns a UUID immediately and a Long ID once server-side validation completes.

  5. 05

    Verify the round-trip

    Poll the status endpoint until status becomes `approved` or `rejected`. Open the LHDN preprod verification URL to confirm the QR resolves. You're ready to flip the base URL to production when this works.

Common pitfalls

The four pitfalls every team hits.

  • Reusing production credentials in preprod (different environments).
  • Mismatched `onBehalfOf` TIN when issuing for a different company in a multi-company setup.
  • Treating a UUID return as confirmation — the Long ID arrives only after server-side validation.
  • Hardcoding the preprod base URL — store it as an env var so the cutover to production is one env change, not a redeploy.

Last updated · May 2026

Independent reference. MyInvois is operated by LHDN. We are not affiliated with LHDN.