Complyance Logo

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 note

2. 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