Malaysia (MY) Implementation Examples
Complete LHDN (Lembaga Hasil Dalam Negeri) compliant examples using the canonical GETS structure. Includes both the final GETS JSON format and Java SDK payload examples. All examples provide 100% field coverage for Malaysia requirements with MyInvois system integration.
Malaysia-Specific Features
Compliance Standards
- Government System: LHDN (Lembaga Hasil Dalam Negeri)
- Portal: MyInvois
- VAT Format: C-prefixed registration numbers (e.g., C22181204000)
- BRN Format: Business Registration Number (e.g., 198801006871)
- Tax Scheme: TIN (Tax Identification Number)
Required Fields
- VAT registration numbers (C-prefixed)
- BRN (Business Registration Number)
- Industry codes
- District and state information
- Malaysian Ringgit (MYR) currency
- LHDN compliance flags
Java SDK Examples
Complete B2B Tax Invoice Example
Complete working example from MalaysiaTaxInvoiceTest.java demonstrating Malaysia-specific TAX_INVOICE functionality with LHDN compliance.
package io.complyance.test;
import io.complyance.sdk.*;
import io.complyance.sdk.Source;
import io.complyance.sdk.SourceType;
import io.complyance.sdk.SDKConfig;
import io.complyance.sdk.Environment;
import io.complyance.sdk.GETSUnifySDK;
import io.complyance.sdk.LogicalDocType;
import io.complyance.sdk.Country;
import io.complyance.sdk.Operation;
import io.complyance.sdk.Mode;
import io.complyance.sdk.Purpose;
import io.complyance.sdk.UnifyResponse;
import io.complyance.sdk.SDKException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
/**
* Malaysia Tax Invoice Test - Demonstrates Malaysia-specific TAX_INVOICE functionality
*
* This test class demonstrates:
* - Malaysia (MY) country-specific compliance
* - TAX_INVOICE logical document type mapping
* - B2B transaction processing
* - Malaysia-specific field mappings
* - Comprehensive payload with Malaysian invoice data
*/
public class MalaysiaTaxInvoiceTest {
public static void main(String[] args) {
System.out.println("=== š²š¾ Malaysia Tax Invoice Test ===");
System.out.println("Testing Malaysia-specific TAX_INVOICE functionality");
System.out.println("Demonstrates B2B mapping, MY compliance, and comprehensive payload");
try {
// Configure SDK
configureSDK();
// Create comprehensive Malaysia test payload
Map<String, Object> payload = createMalaysiaTestPayload();
System.out.println("ā
Malaysia test payload created");
System.out.println(" š Expected GETS fields coverage: 37/37 (100%)");
System.out.println(" š²š¾ Expected MY country fields coverage: 3/3 (100%)");
System.out.println(" š° Expected MY compliance fields coverage: 3/3 (100%)");
// Test Malaysia TAX_INVOICE flow
testMalaysiaTaxInvoiceFlow(payload);
System.out.println("\nš Malaysia Tax Invoice test completed successfully!");
} catch (Exception e) {
System.err.println("ā Unexpected error: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Configure the SDK for Malaysia testing
*/
private static void configureSDK() {
Source source = new Source("Sample_source-7", "7", SourceType.FIRST_PARTY);
SDKConfig config = new SDKConfig("ak_368d073d3de1f19041612fe6cdcf",
Environment.SANDBOX, Arrays.asList(source));
GETSUnifySDK.configure(config);
System.out.println("ā
SDK Configured for Malaysia Testing");
}
/**
* Creates Malaysia test payload using exact test data provided
*/
private static Map<String, Object> createMalaysiaTestPayload() {
Map<String, Object> payload = new HashMap<>();
// Invoice Data - Exact match with provided test data
Map<String, Object> invoiceData = new HashMap<>();
invoiceData.put("currency_code", "MYR");
invoiceData.put("exchange_percentage", 1);
invoiceData.put("invoice_date", "2025-10-14");
invoiceData.put("invoice_due_date", "2025-10-14");
invoiceData.put("invoice_endDate", "2025-10-14");
invoiceData.put("invoice_number", "INVOICE-RETRY17");
invoiceData.put("invoice_startDate", "2025-10-14");
invoiceData.put("invoice_time", "14:30:00");
invoiceData.put("line_extension_amount", 20000);
invoiceData.put("tax_exclusive_amount", 20000);
invoiceData.put("total_amount", 23000);
invoiceData.put("total_discount", "0");
invoiceData.put("total_payable_amount", 23000);
invoiceData.put("total_tax_amount", 3000);
invoiceData.put("vat_currency_code", "MYR");
payload.put("invoice_data", invoiceData);
// Seller Info - Exact match with provided test data
Map<String, Object> sellerInfo = new HashMap<>();
sellerInfo.put("Additional_Type", "BRN");
sellerInfo.put("additional_address_info", "Building 123");
sellerInfo.put("building_number", "1234");
sellerInfo.put("city_name", "Kuala Lumpur");
sellerInfo.put("company_name", "Advanced Tech Solutions Malaysia Sdn Bhd");
sellerInfo.put("contact_name", "Ahmad Rahman");
sellerInfo.put("country_code", "MY");
sellerInfo.put("district_name", "Kuala Lumpur");
sellerInfo.put("email", "contact@advancedtech.my");
sellerInfo.put("phone", "+60123456789");
sellerInfo.put("postal_code", "50000");
sellerInfo.put("seller_id", "123456789012");
sellerInfo.put("state_name", "Kuala Lumpur");
sellerInfo.put("street_address", "Jalan Tun Razak");
sellerInfo.put("tax_scheme", "TIN");
sellerInfo.put("vat_registration", "C22181204000");
sellerInfo.put("seller_industryCode", "01111");
sellerInfo.put("address_info", "Bangunan Merdeka");
sellerInfo.put("BRN_number", "198801006871");
payload.put("seller_info", sellerInfo);
// Buyer Info - Exact match with provided test data
Map<String, Object> buyerInfo = new HashMap<>();
buyerInfo.put("Additional_Type", "BRN");
buyerInfo.put("buyer_additional_address_info", "Block A");
buyerInfo.put("buyer_address", "Industrial City");
buyerInfo.put("buyer_building", "4567");
buyerInfo.put("buyer_city", "Kuala Lumpur");
buyerInfo.put("buyer_country", "MY");
buyerInfo.put("buyer_district", "Industrial Area");
buyerInfo.put("buyer_id", "987654321098");
buyerInfo.put("buyer_name", "Global Manufacturing Co. Malaysia");
buyerInfo.put("buyer_postal", "50000");
buyerInfo.put("buyer_state", "Kuala Lumpur");
buyerInfo.put("buyer_tax_scheme", "TIN");
buyerInfo.put("buyer_vat", "C4855999070");
buyerInfo.put("buyer_address_info", "Persiaran Jaya");
buyerInfo.put("phone", "60123456789");
buyerInfo.put("BRN_Number", "201234567890");
payload.put("buyer_info", buyerInfo);
// Line Items - Exact match with provided test data
List<Map<String, Object>> lineItems = new ArrayList<>();
Map<String, Object> item1 = new HashMap<>();
item1.put("discount_amount", "0");
item1.put("item_id", "ITEM001");
item1.put("item_name", "Industrial Server System");
item1.put("quantity", "2");
item1.put("sub_Total", "19550");
item1.put("tax_amount", "2550.00");
item1.put("tax_category", "01");
item1.put("tax_rate", "15");
item1.put("taxable_amount", "17000");
item1.put("unit_code", "XUN");
item1.put("unit_price", "8500.00");
item1.put("classification_code", "001");
lineItems.add(item1);
payload.put("line_items", lineItems);
// Malaysia Compliance - Exact match with provided test data
Map<String, Object> malaysiaCompliance = new HashMap<>();
malaysiaCompliance.put("export_transaction", "false");
malaysiaCompliance.put("self_billed_invoice", "false");
malaysiaCompliance.put("B2B_transaction", "true");
payload.put("malaysia_compliance", malaysiaCompliance);
// Document Destinations - Exact match with provided test data
List<Map<String, Object>> destinations = new ArrayList<>();
Map<String, Object> taxAuthorityDestination = new HashMap<>();
taxAuthorityDestination.put("type", "tax_authority");
Map<String, Object> destinationDetails = new HashMap<>();
destinationDetails.put("authority", "LHDN");
destinationDetails.put("country", "MY");
destinationDetails.put("document_type", "tax_invoice");
taxAuthorityDestination.put("details", destinationDetails);
destinations.add(taxAuthorityDestination);
payload.put("destinations", destinations);
// Additional Data - Exact match with provided test data
Map<String, Object> additionalData = new HashMap<>();
additionalData.put("delivery_date", "2024-01-20");
additionalData.put("order_reference", "PO-2024-5678");
additionalData.put("source_system", "malaysia-source-system");
payload.put("additional_data", additionalData);
return payload;
}
/**
* Test Malaysia TAX_INVOICE flow
*/
private static void testMalaysiaTaxInvoiceFlow(Map<String, Object> payload) {
try {
System.out.println("\n=== š Testing Malaysia Tax Invoice Flow ===");
System.out.println(" šÆ Testing: TAX_INVOICE with Malaysia");
System.out.println(" š Logical Type: TAX_INVOICE");
System.out.println(" š²š¾ Country: MY");
System.out.println(" š Expected: B2B tax invoice processing with Malaysia compliance");
// Test with logical document type
UnifyResponse response = GETSUnifySDK.pushToUnify(
"Sample_source-7", // Source name (matches test data)
"7", // Source version
LogicalDocType.TAX_INVOICE, // Logical document type
Country.MY, // Country
Operation.SINGLE, // Operation
Mode.DOCUMENTS, // Mode
Purpose.MAPPING, // Purpose
payload // Exact test data payload
);
printUnifyResponse(response, "Malaysia Tax Invoice Flow");
System.out.println(" š Expected: B2B tax invoice processing with Malaysia compliance");
} catch (SDKException e) {
System.err.println("ā Malaysia Tax Invoice Flow failed: " + e.getMessage());
if (e.getErrorDetail() != null) {
System.err.println(" Error Code: " + e.getErrorDetail().getCode());
System.err.println(" Message: " + e.getErrorDetail().getMessage());
if (e.getErrorDetail().getSuggestion() != null) {
System.err.println(" Suggestion: " + e.getErrorDetail().getSuggestion());
}
}
}
}
/**
* Print UnifyResponse in a formatted way
*/
private static void printUnifyResponse(UnifyResponse response, String context) {
if (response == null) {
System.err.println("ā " + context + " failed: Response is null");
return;
}
if ("error".equalsIgnoreCase(response.getStatus())) {
System.err.println("ā " + context + " failed:");
if (response.getError() != null) {
System.err.println(" Error Code: " + response.getError().getCode());
System.err.println(" Message: " + response.getError().getMessage());
if (response.getError().getSuggestion() != null) {
System.err.println(" Suggestion: " + response.getError().getSuggestion());
}
} else {
System.err.println(" Message: " + response.getMessage());
}
} else {
System.out.println("ā
" + context + " Response: " + response.getStatus());
}
}
}Key Malaysia-Specific Features
VAT Registration Number Format
Malaysia VAT numbers use C-prefixed format:
sellerInfo.put("vat_registration", "C22181204000");
buyerInfo.put("buyer_vat", "C4855999070");Business Registration Number (BRN)
Malaysia requires BRN for business entities:
sellerInfo.put("BRN_number", "198801006871");
sellerInfo.put("Additional_Type", "BRN");
buyerInfo.put("BRN_Number", "201234567890");
buyerInfo.put("Additional_Type", "BRN");Industry Code
Malaysia requires industry codes:
sellerInfo.put("seller_industryCode", "01111");District and State Information
Malaysia requires detailed location information:
sellerInfo.put("district_name", "Kuala Lumpur");
sellerInfo.put("state_name", "Kuala Lumpur");
buyerInfo.put("buyer_district", "Industrial Area");
buyerInfo.put("buyer_state", "Kuala Lumpur");Tax Scheme
Malaysia uses TIN (Tax Identification Number):
sellerInfo.put("tax_scheme", "TIN");
buyerInfo.put("buyer_tax_scheme", "TIN");Currency
Malaysia uses Malaysian Ringgit (MYR):
invoiceData.put("currency_code", "MYR");
invoiceData.put("vat_currency_code", "MYR");LHDN Compliance Flags
Malaysia-specific compliance flags:
malaysiaCompliance.put("export_transaction", "false");
malaysiaCompliance.put("self_billed_invoice", "false");
malaysiaCompliance.put("B2B_transaction", "true");LHDN Destination
Malaysia requires LHDN as the tax authority destination:
destinationDetails.put("authority", "LHDN");
destinationDetails.put("country", "MY");
destinationDetails.put("document_type", "tax_invoice");Implementation Guide
1. Choose the Right LogicalDocType
// B2B Tax Invoices
LogicalDocType.TAX_INVOICE // Standard B2B invoice
LogicalDocType.TAX_INVOICE_CREDIT_NOTE // B2B credit note
LogicalDocType.TAX_INVOICE_DEBIT_NOTE // B2B debit note2. Submit via Java SDK
// Configure SDK
SDKConfig config = new SDKConfig.Builder()
.apiKey("your-api-key")
.environment(Environment.SANDBOX)
.build();
GETSUnifySDK.configure(config);
// Create payload (use examples above)
Map<String, Object> payload = createMalaysiaTestPayload();
// Submit to GETS
UnifyResponse response = GETSUnifySDK.pushToUnify(
"Sample_source-7", // Source name
"7", // Source version
LogicalDocType.TAX_INVOICE, // Document type
Country.MY, // Malaysia
Operation.SINGLE, // Single document
Mode.DOCUMENTS, // Document mode
Purpose.INVOICING, // Full invoicing flow
payload // Business data
);Malaysia Compliance Checklist
- VAT registration numbers in C-prefixed format
- BRN (Business Registration Number) included
- Industry codes specified
- District and state information provided
- Tax scheme set to TIN
- Currency set to MYR
- LHDN compliance flags set correctly
- LHDN destination configured
Next Steps
- API Reference - Detailed API endpoint documentation
- GETS Schema - Understanding the core GETS schema
- Country Extensions - Malaysia-specific extensions
- Java SDK Guide - Complete Java SDK documentation