LHDN MyInvois API Integration for WooCommerce & Custom Web Platforms in Malaysia
Complete technical guide to integrate LHDN MyInvois API v1.0 with WooCommerce and custom web apps. Includes OAuth 2.0, UBL 2.1 JSON, and QR validation.
Malaysia's mandatory Inland Revenue Board (Lembaga Hasil Dalam Negeri - LHDN) e-Invoicing initiative is now a binding compliance requirement. Whether you run a high-volume WooCommerce store, a SaaS platform, or a custom web app, manually keying invoices into the MyInvois Portal is unsustainable.
To automate compliance, your web platform must interface directly with the LHDN MyInvois System Integration API (v1.0).
Here is the complete engineering architecture for integrating LHDN MyInvois with WooCommerce and custom PHP/Node.js web applications.
1. LHDN MyInvois API Architecture & Authentication
All communications with LHDN require OAuth 2.0 Client Credentials Grant using credentials generated from the MyInvois Taxpayer Portal (Sandbox & Production).
+----------------------------------------------------------------------+
| LHDN MYINVOIS INTEGRATION FLOW |
| |
| 1. WooCommerce Order ---> 2. OAuth 2.0 Auth ---> 3. UBL 2.1 JSON |
| (Status: Completed) (Identity Server) (Base64 SHA256 Doc)|
| | |
| 5. Store QR & UUID <--- 4. LHDN Validation <---------+ |
| (PDF & Cust Email) (UUID & Status Valid) |
+----------------------------------------------------------------------+
Step 1: Generating the Access Token
Submit an authenticated request to the LHDN Identity Server:
# Request OAuth 2.0 Token (Sandbox Environment)
curl -X POST "https://preprod-api.myinvois.hasil.gov.my/connect/token" -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=YOUR_LHDN_CLIENT_ID" -d "client_secret=YOUR_LHDN_CLIENT_SECRET" -d "grant_type=client_credentials" -d "scope=InvoicingAPI"
The response returns a bearer token valid for 3,600 seconds:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "InvoicingAPI"
}
2. UBL 2.1 Document Structure & Mandatory Malaysian Data Fields
LHDN mandates that every e-Invoice document adheres strictly to the Universal Business Language (UBL 2.1) standard formatted as JSON or XML.
Mandatory Malaysian Business Identifiers:
- Buyer TIN (Tax Identification Number e.g.,
C12345678090orEI00000000010for general public consolidated e-invoices). - Buyer Registration Number: SSM Registration Number (New 12-digit format), MyKad (NRIC), or Passport.
- SST Registration Number: If applicable.
- MSIC Code: 5-digit Malaysian Standard Industrial Classification (e.g.,
47912for Retail sale via e-commerce). - Classification Code: LHDN item classification code (e.g.,
001for Goods,002for Services).
UBL 2.1 JSON Payload Snippet:
{
"_D": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
"_A": "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
"_B": "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
"Invoice": [
{
"ID": [{ "_": "INV-2026-08001" }],
"IssueDate": [{ "_": "2026-08-29" }],
"IssueTime": [{ "_": "14:30:00Z" }],
"InvoiceTypeCode": [{ "_": "01", "listVersionID": "1.0" }],
"DocumentCurrencyCode": [{ "_": "MYR" }],
"AccountingSupplierParty": [
{
"Party": [
{
"PartyIdentification": [
{ "ID": [{ "_": "C25892341020", "schemeID": "TIN" }] },
{ "ID": [{ "_": "202401009876", "schemeID": "BRN" }] }
],
"PartyLegalEntity": [
{ "RegistrationName": [{ "_": "TECHFIX MALAYSIA SDN BHD" }] }
]
}
]
}
]
}
]
}
3. WooCommerce Integration: Webhook & Custom Hook Handler
To automate invoice generation upon payment completion (e.g., via Billplz, Curlec, or FPX), hook into WooCommerce's order completion event:
<?php
/**
* Hook into WooCommerce Order Status Change
*/
add_action('woocommerce_order_status_completed', 'jagaweb_dispatch_lhdn_einvoice', 10, 1);
function jagaweb_dispatch_lhdn_einvoice($order_id) {
$order = wc_get_order($order_id);
// Check if e-Invoice has already been submitted
if ($order->get_meta('_lhdn_invoice_uuid')) {
return;
}
$buyer_tin = $order->get_meta('_billing_tin') ?: 'EI00000000010'; // Default consolidated TIN
$buyer_brn = $order->get_meta('_billing_brn') ?: $order->get_meta('_billing_mykad');
$order_total = $order->get_total();
// 1. Build Document Payload
$document_data_raw = [
'Invoice' => [
'ID' => [['_' => 'ORD-' . $order->get_order_number()]],
'IssueDate' => [['_' => gmdate('Y-m-d')]],
'IssueTime' => [['_' => gmdate('H:i:sZ')]],
'InvoiceTypeCode' => [['_' => '01']],
'LegalMonetaryTotal' => [
['PayableAmount' => [['_' => (float)$order_total, 'currencyID' => 'MYR']]]
]
]
];
$document_json = json_encode($document_data_raw);
$document_data = [
'format' => 'JSON',
'document' => base64_encode($document_json),
'documentHash' => hash('sha256', $document_json),
'codeNumber' => 'ORD-' . $order->get_order_number()
];
// 2. Submit to LHDN API
$api_token = jagaweb_get_lhdn_oauth_token();
$response = wp_remote_post('https://preprod-api.myinvois.hasil.gov.my/api/v1.0/documentsubmissions/', [
'headers' => [
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json'
],
'body' => json_encode(['documents' => [$document_data]]),
'timeout' => 30
]);
if (!is_wp_error($response)) {
$body = json_decode(wp_remote_retrieve_body($response), true);
if (!empty($body['acceptedDocuments'][0]['uuid'])) {
$uuid = $body['acceptedDocuments'][0]['uuid'];
$order->update_meta_data('_lhdn_invoice_uuid', $uuid);
$order->update_meta_data('_lhdn_validation_url', "https://myinvois.hasil.gov.my/{$uuid}/share");
$order->save();
}
}
}
4. Handling Consolidated B2C e-Invoicing
Under LHDN guidelines, e-commerce stores serving everyday retail consumers are permitted to consolidate retail transactions and submit a Consolidated e-Invoice within 7 calendar days after the end of the month:
- Buyer Name: General Public
- Buyer TIN:
EI00000000010 - Buyer ID:
NA - Implement automated cron jobs in your custom backend to aggregate all B2C transactions that did not request an individual e-invoice.
Troubleshooting Common LHDN API Errors
+----------------------------+-----------------------------------+-----------------------------------+
| HTTP Code / Error Code | Cause | Actionable Solution |
+----------------------------+-----------------------------------+-----------------------------------+
| 400 Bad Request | Schema validation failed (UBL) | Validate required fields & JSON |
| DS302 | Invalid Tax Identification Number | Check TIN against LHDN TIN API |
| DS308 | Total sum mismatch vs line items | Round item totals to 2 decimals |
| 401 Unauthorized | Expired Bearer Token | Implement token caching & refresh |
+----------------------------+-----------------------------------+-----------------------------------+
Future-Proof Your e-Commerce Compliance with JagaWeb
Integrating LHDN MyInvois directly into WooCommerce or custom web platforms requires robust schema validation, cryptographic hashing, and automated failure retries.
At JagaWeb, we engineer turnkey middleware and custom API bridges for Malaysian enterprises.
- RM5,000 Architecture & Access Review: Audit your checkout workflows, database schemas, and billing endpoints for full LHDN readiness.
- Custom Middleware Engineering: End-to-end webhook integration with auto-validation, QR code generation on PDF invoices, and automated monthly consolidated submissions.
- RM450/month Managed Care Plan: Proactive API monitoring, schema version updates, and 24/7 technical support.
Ready to verify who owns your website?
Replace uncertainty with a decision-ready ownership and access report. The fixed Ownership & Access Review is RM1,500 before SST and includes a 30-day action plan.