Complyance Java SDK v3.0
Production ready Java SDK with Log on DocType support, automatic 320/32C classification, multi country compliance for KSA, Malaysia, and Belgium, and enterprise grade features. Built for real world e-invoice applications.
Feature Summary
- 34 Types - Registered DocType support
- 3 Countries - KSA, Malaysia, Belgium supported
- 5 Overloads - Good Comply methods
- v3.0 - Production ready
Installation
Automated Setup (Recommended)
The automated setup will detect your operating system and provide the correct instructions.
macOS & Linux
-
Install Java (JDK 11 or higher)
brew install openjdk@11 -
Set JAVA_HOME environment variable
export JAVA_HOME=$(/usr/libexec/java_home -v 11) -
Verify installation
java -version
Windows
- Download and install OpenJDK 11+
- Set JAVA_HOME environment variable
- Add Java to PATH
Manual Installation
Maven
Add the dependency to your pom.xml:
<dependency>
<groupId>io.complyance</groupId>
<artifactId>unify-sdk</artifactId>
<version>3.0.0-beta</version>
</dependency>Gradle
Add the dependency to your build.gradle:
implementation 'io.complyance:unify-sdk:3.0.0-beta'Windows Installation
Using Chocolatey (Recommended)
# Install Chocolatey (run as Administrator)
Set-ExecutionPolicy Bypass -Scope Process -Force
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
# Install OpenJDK 8 and Maven
choco install openjdk8 maven -y
# Verify installation
java -version
mvn -versionPowerShell Profile Configuration
# Edit PowerShell profile
notepad $PROFILE
# Add these lines to your PowerShell profile:
$env:JAVA_8_HOME = "C:\Program Files\OpenJDK\openjdk-8u402-b06"
$env:JAVA_HOME = $env:JAVA_8_HOME
$env:M2_HOME = "C:\Program Files\Apache\maven"
$env:PATH = "$env:JAVA_8_HOME\bin;$env:M2_HOME\bin;$env:PATH"
# Complyance SDK Environment Variables
$env:COMPLYANCE_API_BASE_URL = "http://127.0.0.1:4000"
$env:COMPLYANCE_JWT_TOKEN = "your-jwt-token-here"
# Convenient functions
function java8 { $env:JAVA_HOME = $env:JAVA_8_HOME; java -version }
function mvn8 { $env:JAVA_HOME = $env:JAVA_8_HOME; mvn @args }Linux Installation
Ubuntu/Debian
sudo apt update && sudo apt install -y openjdk-8-jdk maven
export JAVA_8_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
export JAVA_HOME="$JAVA_8_HOME"CentOS/RHEL
sudo yum install java-1.8.0-openjdk-devel mavenArch Linux
sudo pacman -S jre8-openjdk mavenAutomated Setup (Recommended)
One-command setup that automatically detects your OS and installs Java 8, Maven, and configures environment variables
macOS & Linux
# Download and run as Administrator:
setup-java8.shWindows
# Download and run as Administrator:
setup-java8.batThe automated script detects your operating system and handles all dependencies, environment variables, and verification automatically.
Interactive Code Examples
Copy-paste ready examples demonstrating key SDK functionality
SDK Setup
// Maven Dependency
<dependency>
<groupId>io.complyance</groupId>
<artifactId>unify-sdk</artifactId>
<version>3.0.0-beta</version>
</dependency>
// Gradle Dependency
implementation 'io.complyance:unify-sdk:3.0.0-beta'
// Basic SDK Configuration
public class BasicSetupExample {
public static void main(String[] args) {
SDKConfig config = new SDKConfig.Builder()
.apiKey("your-api-key")
.environment(Environment.SANDBOX)
.appId("your-app-id")
.defaultCountry("SA")
.build();
GETSUnifySDK.configure(config);
System.out.println("SDK configured successfully!");
}
}Production Invoice
/**
* ProductionInvoiceExample - Real-world invoice processing with LogicalDocType
*
* This example demonstrates:
* - Using LogicalDocType.TAX_INVOICE for B2B invoicing
* - Proper SDK configuration and error handling
* - Complete invoice payload structure
* - Production-ready implementation patterns
*/
public class ProductionInvoiceExample {
public static void main(String[] args) {
System.out.println("=== š¢ Production Invoice Processing ===");
try {
// Configure SDK for production use
Source source = new Source("my-company", "1.0");
SDKConfig config = new SDKConfig(
"your-production-api-key",
Environment.SANDBOX, // Use SANDBOX for testing, PRODUCTION for live
Arrays.asList(source)
);
GETSUnifySDK.configure(config);
// Create invoice payload
Map<String, Object> payload = createInvoicePayload();
// Submit invoice using LogicalDocType
UnifyResponse response = GETSUnifySDK.pushToUnify(
"my-company", // Source name
"1.0", // Source version
LogicalDocType.TAX_INVOICE, // Logical document type
Country.SA, // Country
Operation.SINGLE, // Operation
Mode.DOCUMENTS, // Mode
Purpose.INVOICING, // Purpose
payload // Invoice data
);
handleResponse(response);
} catch (SDKException e) {
System.err.println("ā SDK Error: " + e.getMessage());
if (e.getError() != null) {
System.err.println(" Error Code: " + e.getError().getCode());
}
} catch (Exception e) {
System.err.println("ā Unexpected error: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Create production invoice payload
*/
private static Map<String, Object> createInvoicePayload() {
Map<String, Object> payload = new HashMap<>();
// Invoice Data
Map<String, Object> invoiceData = new HashMap<>();
invoiceData.put("invoice_number", "INV-2024-001");
invoiceData.put("invoice_date", "2024-01-15");
invoiceData.put("invoice_time", "14:30:00");
invoiceData.put("currency_code", "SAR");
invoiceData.put("total_amount", 1150.00);
invoiceData.put("total_payable_amount", 1150.00);
invoiceData.put("tax_exclusive_amount", 1000.00);
invoiceData.put("line_extension_amount", 1000.00);
invoiceData.put("total_tax_amount", 150.00);
payload.put("invoice_data", invoiceData);
// Seller Info
Map<String, Object> sellerInfo = new HashMap<>();
sellerInfo.put("company_name", "Tech Solutions LLC");
sellerInfo.put("vat_registration", "310123456700003");
sellerInfo.put("tax_scheme", "VAT");
sellerInfo.put("street_address", "King Fahd Road");
sellerInfo.put("building_number", "1234");
sellerInfo.put("district_name", "Al Olaya");
sellerInfo.put("city_name", "Riyadh");
sellerInfo.put("postal_code", "11564");
sellerInfo.put("country_code", "SA");
sellerInfo.put("phone", "+966501234567");
sellerInfo.put("email", "contact@techsolutions.sa");
payload.put("seller_info", sellerInfo);
// Buyer Info
Map<String, Object> buyerInfo = new HashMap<>();
buyerInfo.put("buyer_name", "Customer Corp");
buyerInfo.put("buyer_vat", "310987654300003");
buyerInfo.put("buyer_address", "Business District");
buyerInfo.put("buyer_building", "4567");
buyerInfo.put("buyer_district", "Al Malaz");
buyerInfo.put("buyer_city", "Riyadh");
buyerInfo.put("buyer_postal", "11564");
buyerInfo.put("buyer_country", "SA");
payload.put("buyer_info", buyerInfo);
// Line Items
List<Map<String, Object>> lineItems = new ArrayList<>();
Map<String, Object> item1 = new HashMap<>();
item1.put("item_id", "ITEM001");
item1.put("item_name", "Consulting Services");
item1.put("quantity", "1");
item1.put("unit_code", "PCE");
item1.put("unit_price", "1000.00");
item1.put("tax_amount", "150.00");
item1.put("tax_category", "S");
item1.put("tax_rate", "15");
lineItems.add(item1);
payload.put("line_items", lineItems);
return payload;
}
/**
* Handle SDK response with complete structure
*/
private static void handleResponse(UnifyResponse response) {
if (response == null) {
System.err.println("ā No response received");
return;
}
if (response.isSuccess()) {
System.out.println("Invoice submitted successfully!");
System.out.println(" š Status: " + response.getStatus());
if (response.getData() != null) {
// Show submission details
if (response.getData().getSubmission() != null) {
System.out.println(" š Submission ID: " + response.getData().getSubmission().getSubmissionId());
System.out.println(" š Submission Status: " + response.getData().getSubmission().getStatus());
if (response.getData().getSubmission().getResponse() != null) {
System.out.println(" š UUID: " + response.getData().getSubmission().getResponse().getUuid());
System.out.println(" š Hash: " + response.getData().getSubmission().getResponse().getHash());
}
}
// Show logical document type info
if (response.getData().getLogicalDocumentType() != null) {
System.out.println(" šÆ Document Type: " + response.getData().getLogicalDocumentType().getOriginalType());
if (response.getData().getLogicalDocumentType().getMetaConfig() != null) {
System.out.println(" š Meta Config: " + response.getData().getLogicalDocumentType().getMetaConfig().toString());
}
}
// Show processing info
if (response.getData().getProcessing() != null) {
System.out.println(" ā±ļø Processing Time: " + response.getData().getProcessing().getTotalProcessingTime() + "ms");
}
}
} else {
System.err.println("ā Invoice submission 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());
}
if (response.getError().isRetryable()) {
System.err.println(" š Retryable: Yes");
}
} else {
System.err.println(" Message: " + response.getMessage());
}
}
}
}Document Types
/**
* DocumentTypesExample - Demonstrates different LogicalDocType options
*
* This example shows how to use various LogicalDocType enum values:
* - B2B Types: TAX_INVOICE, TAX_INVOICE_CREDIT_NOTE, TAX_INVOICE_DEBIT_NOTE
* - B2C Types: SIMPLIFIED_TAX_INVOICE, SIMPLIFIED_TAX_INVOICE_CREDIT_NOTE
* - Special Types: Export, Prepayment, Third Party, Self-Billed, Nominal Supply
*/
public class DocumentTypesExample {
public static void main(String[] args) {
System.out.println("=== š Document Types Example ===");
try {
// Configure SDK
Source source = new Source("my-app", "1.0");
SDKConfig config = new SDKConfig(
"your-api-key",
Environment.SANDBOX,
Arrays.asList(source)
);
GETSUnifySDK.configure(config);
// Create sample payload
Map<String, Object> payload = createSamplePayload();
// Example 1: B2B Tax Invoice
System.out.println("\n=== š¢ B2B Tax Invoice ===");
submitDocument(payload, LogicalDocType.TAX_INVOICE, "B2B Tax Invoice");
// Example 2: B2C Simplified Tax Invoice
System.out.println("\n=== š B2C Simplified Tax Invoice ===");
submitDocument(payload, LogicalDocType.SIMPLIFIED_TAX_INVOICE, "B2C Simplified Tax Invoice");
// Example 3: Credit Note
System.out.println("\n=== š Credit Note ===");
submitDocument(payload, LogicalDocType.TAX_INVOICE_CREDIT_NOTE, "B2B Credit Note");
// Example 4: Export Invoice
System.out.println("\n=== š Export Invoice ===");
submitDocument(payload, LogicalDocType.TAX_INVOICE_EXPORT_INVOICE, "B2B Export Invoice");
System.out.println("\nš All document type examples completed!");
} catch (SDKException e) {
System.err.println("ā SDK Error: " + e.getMessage());
} catch (Exception e) {
System.err.println("ā Unexpected error: " + e.getMessage());
e.printStackTrace();
}
}
private static Map<String, Object> createSamplePayload() {
Map<String, Object> payload = new HashMap<>();
// Invoice Data
Map<String, Object> invoiceData = new HashMap<>();
invoiceData.put("invoice_number", "INV-2024-001");
invoiceData.put("invoice_date", "2024-01-15");
invoiceData.put("currency_code", "SAR");
invoiceData.put("total_amount", 1150.00);
invoiceData.put("tax_exclusive_amount", 1000.00);
invoiceData.put("total_tax_amount", 150.00);
payload.put("invoice_data", invoiceData);
// Seller Info
Map<String, Object> sellerInfo = new HashMap<>();
sellerInfo.put("company_name", "Tech Solutions LLC");
sellerInfo.put("vat_registration", "310123456700003");
sellerInfo.put("street_address", "King Fahd Road");
sellerInfo.put("city_name", "Riyadh");
sellerInfo.put("country_code", "SA");
payload.put("seller_info", sellerInfo);
// Buyer Info
Map<String, Object> buyerInfo = new HashMap<>();
buyerInfo.put("buyer_name", "Customer Corp");
buyerInfo.put("buyer_vat", "310987654300003");
buyerInfo.put("buyer_city", "Riyadh");
buyerInfo.put("buyer_country", "SA");
payload.put("buyer_info", buyerInfo);
// Line Items
List<Map<String, Object>> lineItems = new ArrayList<>();
Map<String, Object> item1 = new HashMap<>();
item1.put("item_id", "ITEM001");
item1.put("item_name", "Consulting Services");
item1.put("quantity", "1");
item1.put("unit_price", "1000.00");
item1.put("tax_amount", "150.00");
item1.put("tax_rate", "15");
lineItems.add(item1);
payload.put("line_items", lineItems);
return payload;
}
private static void submitDocument(Map<String, Object> payload, LogicalDocType logicalType, String description) {
try {
System.out.println(" š Document Type: " + logicalType.name());
System.out.println(" šÆ Description: " + description);
UnifyResponse response = GETSUnifySDK.pushToUnify(
"my-app", // Source name
"1.0", // Source version
logicalType, // Logical document type
Country.SA, // Country
Operation.SINGLE, // Operation
Mode.DOCUMENTS, // Mode
Purpose.INVOICING, // Purpose
payload // Payload
);
if (response.isSuccess()) {
System.out.println(" " + description + " submitted successfully!");
System.out.println(" š Status: " + response.getStatus());
if (response.getData() != null) {
if (response.getData().getSubmission() != null) {
System.out.println(" š Submission ID: " + response.getData().getSubmission().getSubmissionId());
System.out.println(" š Status: " + response.getData().getSubmission().getStatus());
}
if (response.getData().getLogicalDocumentType() != null) {
System.out.println(" šÆ Original Type: " + response.getData().getLogicalDocumentType().getOriginalType());
}
if (response.getData().getProcessing() != null) {
System.out.println(" ā±ļø Processing Time: " + response.getData().getProcessing().getTotalProcessingTime() + "ms");
}
}
} else {
System.out.println(" ā " + description + " failed:");
if (response.getError() != null) {
System.out.println(" Error Code: " + response.getError().getCode());
System.out.println(" Message: " + response.getError().getMessage());
} else {
System.out.println(" Message: " + response.getMessage());
}
}
} catch (SDKException e) {
System.err.println(" ā " + description + " SDK Error: " + e.getMessage());
} catch (Exception e) {
System.err.println(" ā " + description + " failed: " + e.getMessage());
}
}
}Primary Method: pushToUnify()
// Full control with LogicalDocType
UnifyResponse response = GETSUnifySDK.pushToUnify(
String sourceName, // Source identifier
String sourceVersion, // Source version
LogicalDocType logicalType, // Document type (TAX_INVOICE, etc.)
Country country, // Target country (SA, MY, BE)
Operation operation, // SINGLE
Mode mode, // DOCUMENTS
Purpose purpose, // INVOICING or MAPPING
Map<String, Object> payload, // Business data
List<Destination> destinations // Optional: auto-generated if null
);API Usage Types
Basic SDK Usage
// Configure SDK
SDKConfig config = new SDKConfig.Builder()
.apiKey("your-api-key")
.environment(Environment.SANDBOX)
.appId("your-app-id")
.defaultCountry("SA")
.build();
GETSUnifySDK.configure(config);
// Create invoice payload
Map<String, Object> payload = createInvoicePayload();
// Submit invoice
UnifyResponse response = GETSUnifySDK.pushToUnify(
"your-app-id",
LogicalDocType.TAX_INVOICE,
Country.SA,
Operation.SINGLE,
Mode.DOCUMENTS,
Purpose.INVOICING,
payload
);
// Handle response
if (response.isSuccess()) {
System.out.println("Invoice submitted successfully!");
} else {
System.err.println("Error: " + response.getErrorMessage());
}Response Structures
Success Response Structure
{
"status": "success",
"message": "Document processed successfully",
"data": {
"submission": {
"submissionId": "sub_123456789",
"status": "processed",
"response": {
"uuid": "uuid-123456789",
"hash": "hash-123456789"
}
},
"logicalDocumentType": {
"originalType": "TAX_INVOICE",
"metaConfig": {
"isB2B": true,
"country": "SA"
}
},
"processing": {
"totalProcessingTime": 150
}
}
}Error Response Structure
{
"status": "error",
"message": "Document processing failed",
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid document structure",
"suggestion": "Check required fields",
"retryable": true
}
}Key Features and Payload Structure
Key Features
- 34 LogicalDocTypes - Complete document type support
- Automatic B2B/B2C Classification - Smart document type detection
- Multi-country compliance - SA, MY, BE, and more
- Enterprise-grade features - Production ready
Payload Structure
invoice_data- Core invoice informationseller_info- Seller/supplier detailsbuyer_info- Buyer/customer detailsline_items- Invoice line itemstax_summary- Tax calculationsadditional_data- Extra fields
LogicalDocTypes (34 Types)
B2B Document Types (22)
TAX_INVOICE- Standard B2B tax invoiceTAX_INVOICE_CREDIT_NOTE- B2B credit noteTAX_INVOICE_DEBIT_NOTE- B2B debit noteTAX_INVOICE_EXPORT_INVOICE- Export invoiceTAX_INVOICE_PREPAYMENT- Prepayment invoiceTAX_INVOICE_PREPAYMENT_ADJUSTED- Adjusted prepaymentTAX_INVOICE_EXPORT_CREDIT_NOTE- Export credit noteTAX_INVOICE_EXPORT_DEBIT_NOTE- Export debit noteTAX_INVOICE_THIRD_PARTY_INVOICE- Third-party invoiceTAX_INVOICE_SELF_BILLED_INVOICE- Self-billed invoiceTAX_INVOICE_NOMINAL_SUPPLY_INVOICE- Nominal supply invoiceTAX_INVOICE_SUMMARY_INVOICE- Summary invoiceINVOICE- Standard business invoiceCREDIT_NOTE- Credit note for adjustmentsDEBIT_NOTE- Debit note for chargesRECEIPT- Payment confirmationEXPORT_INVOICE- Export invoiceEXPORT_CREDIT_NOTE- Export credit noteEXPORT_THIRD_PARTY_INVOICE- Export third-party invoiceTHIRD_PARTY_INVOICE- Third-party invoiceSELF_BILLED_INVOICE- Self-billed invoiceNOMINAL_SUPPLY_INVOICE- Nominal supply invoice
B2C Document Types (12)
SIMPLIFIED_TAX_INVOICE- Simplified tax invoiceSIMPLIFIED_TAX_INVOICE_CREDIT_NOTE- Simplified credit noteSIMPLIFIED_TAX_INVOICE_DEBIT_NOTE- Simplified debit noteSIMPLIFIED_TAX_INVOICE_PREPAYMENT- Simplified prepaymentSIMPLIFIED_TAX_INVOICE_PREPAYMENT_ADJUSTED- Simplified adjusted prepaymentSIMPLIFIED_TAX_INVOICE_EXPORT_INVOICE- Simplified export invoiceSIMPLIFIED_TAX_INVOICE_EXPORT_CREDIT_NOTE- Simplified export credit noteSIMPLIFIED_TAX_INVOICE_EXPORT_DEBIT_NOTE- Simplified export debit noteSIMPLIFIED_TAX_INVOICE_THIRD_PARTY_INVOICE- Simplified third-party invoiceSIMPLIFIED_TAX_INVOICE_SELF_BILLED_INVOICE- Simplified self-billed invoiceSIMPLIFIED_TAX_INVOICE_NOMINAL_SUPPLY_INVOICE- Simplified nominal supply invoiceSIMPLIFIED_TAX_INVOICE_SUMMARY_INVOICE- Simplified summary invoice
Automatic Configuration
The SDK automatically configures itself based on LogicalDocType and country:
- Validation Rules - Country-specific validation
- Country-specific compliance - ZATCA, LHDN requirements
- B2B/B2C Classification - Automatic detection
- Required Payload Fields - Dynamic field requirements
- Tax Calculation - Country-specific tax rules
- Error Handling - Comprehensive error management
Common SDK Capabilities
Core Features
- Automatic document type classification - Smart detection
- Multi-country compliance - Global support
- Pre-submission validation - Catch errors early
- Dynamic payload transformation - Flexible data handling
- Real-time processing and feedback - Immediate results
Integration Features
- Easy to use Java SDK with REST API - Simple integration
- Comprehensive error handling and logging - Production ready
- Enterprise-grade security and scalability - Business grade
- Flexible deployment options - Cloud, on-premise
- Extensible for custom requirements - Customizable
Next Steps
- API Reference - Detailed API endpoint documentation
- GETS Schema - Understanding the core GETS schema
- Examples - Real-world implementation examples