Complyance Logo

Complyance PHP SDK

Production-ready PHP SDK with intelligent document type support, automatic compliance validations, and multi-country e-invoicing capabilities for UAE, KSA, and Malaysia. Designed with enterprise-grade features and modern PHP architecture for real-world e-invoice applications.

Feature Summary

  • Multi-Country Support - UAE,KSA,Malaysia
  • PSR-7 Compatible - Modern HTTP message interfaces
  • PHP 8.0+ - Modern PHP features and type hints
  • Composer - Easy dependency management

Installation

Composer

composer require io.complyance/unify-sdk

Quick Start

SDK Setup & Configuration

You must configure the SDK once at the start of your application.

use ComplyanceSDK\GETSUnifySDK;
use ComplyanceSDK\Models\SDKConfig;
use ComplyanceSDK\Models\Source;
use ComplyanceSDK\Enums\SourceType;
use ComplyanceSDK\Enums\Environment;

// 1. Define your source info (Your App Name and Version)
$sources = [new Source('App name', 'Version', SourceType::fromString(SourceType::FIRST_PARTY))];

// 2. Set up configuration
// Change Environment::SANDBOX to Environment::PRODUCTION when going live
$config = new SDKConfig(
    'YOUR_API_KEY_HERE', 
    Environment::from(Environment::SANDBOX), 
    $sources
);

// 3. Initialize the SDK
GETSUnifySDK::configure($config);

The "Purpose" Workflow

The integration requires a specific two-stage process to ensure your document data correctly translates to regulatory standards.

Step 1: MAPPING (Setup & Template Creation)

Set the Purpose to "MAPPING" to push your raw data to the Complyance platform. This stage is used for initial field discovery and visualization.

  • In Code: Submit your payload with Purpose::from('MAPPING').
  • In Portal: Locate the uploaded payload, complete the field mapping, and save it as a successful Template.
  • Final Step: Register and bind your unique sourceName and sourceVersion to this template on the portal.

Step 2: INVOICING (Production Submission)

After your template is successfully bound to your source identifiers, change the Purpose to "INVOICING".

  • Action: The system now recognizes your sourceName/sourceVersion and applies the saved template logic to transform, validate, and officially submit the document to the tax authority.
  • Requirement: You must use the exact same Source identifiers registered during the Mapping phase.

How to change the Purpose in code:

use ComplyanceSDK\Enums\Purpose;

// 1. Initial Phase: Field Analysis & Template Binding
$currentPurpose = Purpose::from('MAPPING'); 

// 2. Final Phase: Official Submission using the bound template
// $currentPurpose = Purpose::from('INVOICING');

Why this structure is important:

  1. MAPPING is the "Discovery" phase where you build the blueprint.
  2. The Portal is where you finalize the logic and connect it to your sourceName.
  3. INVOICING is the "Execution" phase where the SDK performs the actual heavy lifting using that blueprint.

Field Mapping Reference

For a comprehensive understanding of all available fields, validation rules, and country-specific requirements, refer to our detailed Field Mapping Payload Reference.

This reference provides:

  • Complete field documentation for all supported countries (SA, MY, BE, DE, AE)
  • Country-specific requirements and compliance rules
  • Field descriptions with examples and validation rules
  • Required vs Optional field indicators

Review this reference to ensure your payload structure meets all regulatory requirements for your target country.

Building the UAE Payload

$payload = [
    'invoice_data' => [
        'document_number' => 'INV-' . date('YmdHis'),
        'document_id' => '{UNIQUE_ID}',
        'document_type' => 'tax_invoice',
        'invoice_date' => getDynamicDate(0),
        'invoice_time' => '00:00:00Z',
        'currency_code' => '{CURRENCY_CODE}',
        'tax_currency_code' => '{CURRENCY_CODE}',
        'due_date' => getDynamicDate(30),
        'period_start_date' => getDynamicDate(-30),
        'period_end_date' => getDynamicDate(0),
        'period_frequency' => '{FREQUENCY}', // e.g., MONTHLY
        'exchange_rate' => '{EXCHANGE_RATE}',
        'line_extension_amount' => '{LINE_EXTENSION_AMOUNT}',
        'tax_exclusive_amount' => '{TAX_EXCLUSIVE_AMOUNT}',
        'total_tax_amount' => '{TOTAL_TAX_AMOUNT}',
        'total_amount' => '{TOTAL_AMOUNT}',
        'total_allowances' => '{TOTAL_ALLOWANCES}',
        'total_charges' => '{TOTAL_CHARGES}',
        'prepaid_amount' => '{PREPAID_AMOUNT}',
        'amount_due' => '{AMOUNT_DUE}',
        'rounding_amount' => '{ROUNDING_AMOUNT}',
        'original_reference_id' => '{ORIGINAL_REFERENCE_ID}',
        'credit_note_reason' => '{CREDIT_NOTE_REASON}'
    ],

    'seller_info' => [
        'seller_name' => '{SELLER_NAME}',
        'seller_trade_name' => '{SELLER_TRADE_NAME}',
        'seller_party_id' => '{SELLER_PARTY_ID}',
        'vat_number_type' => '{VAT_NUMBER_TYPE}',
        'vat_number' => '{VAT_NUMBER}',
        'tax_scheme' => '{TAX_SCHEME}',
        'registration_number' => '{REGISTRATION_NUMBER}',
        'registration_type' => '{REGISTRATION_TYPE}',
        'registration_scheme' => '{REGISTRATION_SCHEME}',
        'authority_name' => '{AUTHORITY_NAME}',
        'peppol_id' => '{PEPPOL_ID}',
        'seller_email' => '{SELLER_EMAIL}',
        'seller_phone' => '{SELLER_PHONE}',
        'seller_contact_name' => '{SELLER_CONTACT_NAME}',
        'street_name' => '{STREET_NAME}',
        'additional_address' => '{ADDITIONAL_ADDRESS}',
        'building_number' => '{BUILDING_NUMBER}',
        'city_name' => '{CITY}',
        'state_province' => '{STATE}',
        'postal_code' => '{POSTAL_CODE}',
        'country_code' => '{COUNTRY_CODE}'
    ],

    'buyer_info' => [
        'buyer_name' => '{BUYER_NAME}',
        'buyer_trade_name' => '{BUYER_TRADE_NAME}',
        'buyer_party_id' => '{BUYER_PARTY_ID}',
        'buyer_vat_type' => '{BUYER_VAT_TYPE}',
        'buyer_vat_number' => '{BUYER_VAT_NUMBER}',
        'buyer_tax_scheme' => '{BUYER_TAX_SCHEME}',
        'buyer_registration_number' => '{BUYER_REGISTRATION_NUMBER}',
        'buyer_registration_type' => '{BUYER_REGISTRATION_TYPE}',
        'buyer_registration_scheme' => '{BUYER_REGISTRATION_SCHEME}',
        'buyer_authority_name' => '{BUYER_AUTHORITY_NAME}',
        'buyer_peppol_id' => '{BUYER_PEPPOL_ID}',
        'buyer_email' => '{BUYER_EMAIL}',
        'buyer_phone' => '{BUYER_PHONE}',
        'buyer_contact_name' => '{BUYER_CONTACT_NAME}',
        'buyer_street_name' => '{BUYER_STREET_NAME}',
        'buyer_additional_address' => '{BUYER_ADDITIONAL_ADDRESS}',
        'buyer_building_number' => '{BUYER_BUILDING_NUMBER}',
        'buyer_city' => '{BUYER_CITY}',
        'buyer_state_province' => '{BUYER_STATE}',
        'buyer_postal_code' => '{BUYER_POSTAL_CODE}',
        'buyer_country' => '{BUYER_COUNTRY_CODE}'
    ],

    'line_items' => [
        [
            'line_id' => '{LINE_ID}',
            'item_name' => '{ITEM_NAME}',
            'item_description' => '{ITEM_DESCRIPTION}',
            'quantity' => '{QUANTITY}',
            'unit_code' => '{UNIT_CODE}',
            'unit_price' => '{UNIT_PRICE}',
            'net_price' => '{NET_PRICE}',
            'gross_price' => '{GROSS_PRICE}',
            'line_taxable_value' => '{LINE_TAXABLE_VALUE}',
            'tax_category' => '{TAX_CATEGORY}',
            'tax_rate' => '{TAX_RATE}',
            'tax_amount' => '{TAX_AMOUNT}',
            'line_total' => '{LINE_TOTAL}',
            'item_type' => '{ITEM_TYPE}', // e.g., GOODS or SERVICE
            'country_of_origin' => '{COUNTRY_OF_ORIGIN}',
            'classification_code' => '{CLASSIFICATION_CODE}',
            'classification_scheme' => '{CLASSIFICATION_SCHEME}',
            'seller_item_code' => '{SELLER_ITEM_CODE}',
            'buyer_item_code' => '{BUYER_ITEM_CODE}',
            'batch_number' => '{BATCH_NUMBER}'
        ]
    ],

    'extensions' => [
        'unique_identifier' => '{UNIQUE_ID}',
        'invoiced_object_id' => '{INVOICED_OBJECT_ID}',
        'taxpoint_date' => getDynamicDate(0),
        'total_amount_including_tax' => '{TOTAL_AMOUNT_INCLUDING_TAX}',
        'authority_name' => '{AUTHORITY_NAME}',
        'buyer_authority_name' => '{BUYER_AUTHORITY_NAME}',
        'business_process_type' => '{BUSINESS_PROCESS_TYPE}',
        'specification_identifier' => '{SPECIFICATION_IDENTIFIER}'
    ],

    'payment_info' => [
        'payment_id' => '{PAYMENT_ID}',
        'payment_means_code' => '{PAYMENT_MEANS_CODE}',
        'payment_means_text' => '{PAYMENT_MEANS_TEXT}',
        'remittance_info' => '{REMITTANCE_INFO}',
        'account_id' => '{ACCOUNT_ID}',
        'account_name' => '{ACCOUNT_NAME}',
        'bank_id' => '{BANK_ID}'
    ],

    'payment_terms' => [
        [
            'instructions_id' => '{TERM_ID}',
            'note' => '{PAYMENT_NOTE}',
            'amount' => '{TERM_AMOUNT}',
            'due_date' => getDynamicDate(30)
        ]
    ],

    'supporting_documents' => [
        [
            'type' => '{DOCUMENT_TYPE}',
            'id' => '{DOCUMENT_ID}'
        ]
    ],

    'additional_data' => [
        'delivery_date' => getDynamicDate(0),
        'order_reference' => '{ORDER_REFERENCE}',
        'source_system' => '{SOURCE_SYSTEM}'
    ]
];

Complete Implementation Example

<?php
require 'vendor/autoload.php';

use ComplyanceSDK\GETSUnifySDK;
use ComplyanceSDK\Models\SDKConfig;
use ComplyanceSDK\Models\Source;
use ComplyanceSDK\Enums\SourceType;
use ComplyanceSDK\Enums\Environment;
use ComplyanceSDK\Enums\LogicalDocType;
use ComplyanceSDK\Enums\Country;
use ComplyanceSDK\Enums\Operation;
use ComplyanceSDK\Enums\Mode;
use ComplyanceSDK\Enums\Purpose;

// -------------------
// STEP 1: CONFIGURE SDK
// -------------------

$sourceName = 'your-source-name';
$sourceVersion = 'your_source_version';

$sources = [
    new Source($sourceName, $sourceVersion, SourceType::fromString(SourceType::FIRST_PARTY))
];

$config = new SDKConfig(
    'YOUR_API_KEY_HERE', // Replace with your API key
    Environment::from(Environment::SANDBOX), // Change to PRODUCTION when going live
    $sources
);

GETSUnifySDK::configure($config);
echo "✅ SDK Configured Successfully\n\n";

// -------------------
// STEP 2: BUILD PAYLOAD
// -------------------

$documentId = bin2hex(random_bytes(16));

$payload = [
    'invoice_data' => [
        'document_number' => 'INV-' . date('YmdHis'),
        'document_id' => '{UNIQUE_ID}',
        'document_type' => 'tax_invoice',
        'invoice_date' => getDynamicDate(0),
        'invoice_time' => '00:00:00Z',
        'currency_code' => '{CURRENCY_CODE}',
        'tax_currency_code' => '{CURRENCY_CODE}',
        'due_date' => getDynamicDate(30),
        'period_start_date' => getDynamicDate(-30),
        'period_end_date' => getDynamicDate(0),
        'period_frequency' => '{FREQUENCY}', // e.g., MONTHLY
        'exchange_rate' => '{EXCHANGE_RATE}',
        'line_extension_amount' => '{LINE_EXTENSION_AMOUNT}',
        'tax_exclusive_amount' => '{TAX_EXCLUSIVE_AMOUNT}',
        'total_tax_amount' => '{TOTAL_TAX_AMOUNT}',
        'total_amount' => '{TOTAL_AMOUNT}',
        'total_allowances' => '{TOTAL_ALLOWANCES}',
        'total_charges' => '{TOTAL_CHARGES}',
        'prepaid_amount' => '{PREPAID_AMOUNT}',
        'amount_due' => '{AMOUNT_DUE}',
        'rounding_amount' => '{ROUNDING_AMOUNT}',
        'original_reference_id' => '{ORIGINAL_REFERENCE_ID}',
        'credit_note_reason' => '{CREDIT_NOTE_REASON}'
    ],

    'seller_info' => [
        'seller_name' => '{SELLER_NAME}',
        'seller_trade_name' => '{SELLER_TRADE_NAME}',
        'seller_party_id' => '{SELLER_PARTY_ID}',
        'vat_number_type' => '{VAT_NUMBER_TYPE}',
        'vat_number' => '{VAT_NUMBER}',
        'tax_scheme' => '{TAX_SCHEME}',
        'registration_number' => '{REGISTRATION_NUMBER}',
        'registration_type' => '{REGISTRATION_TYPE}',
        'registration_scheme' => '{REGISTRATION_SCHEME}',
        'authority_name' => '{AUTHORITY_NAME}',
        'peppol_id' => '{PEPPOL_ID}',
        'seller_email' => '{SELLER_EMAIL}',
        'seller_phone' => '{SELLER_PHONE}',
        'seller_contact_name' => '{SELLER_CONTACT_NAME}',
        'street_name' => '{STREET_NAME}',
        'additional_address' => '{ADDITIONAL_ADDRESS}',
        'building_number' => '{BUILDING_NUMBER}',
        'city_name' => '{CITY}',
        'state_province' => '{STATE}',
        'postal_code' => '{POSTAL_CODE}',
        'country_code' => '{COUNTRY_CODE}'
    ],

    'buyer_info' => [
        'buyer_name' => '{BUYER_NAME}',
        'buyer_trade_name' => '{BUYER_TRADE_NAME}',
        'buyer_party_id' => '{BUYER_PARTY_ID}',
        'buyer_vat_type' => '{BUYER_VAT_TYPE}',
        'buyer_vat_number' => '{BUYER_VAT_NUMBER}',
        'buyer_tax_scheme' => '{BUYER_TAX_SCHEME}',
        'buyer_registration_number' => '{BUYER_REGISTRATION_NUMBER}',
        'buyer_registration_type' => '{BUYER_REGISTRATION_TYPE}',
        'buyer_registration_scheme' => '{BUYER_REGISTRATION_SCHEME}',
        'buyer_authority_name' => '{BUYER_AUTHORITY_NAME}',
        'buyer_peppol_id' => '{BUYER_PEPPOL_ID}',
        'buyer_email' => '{BUYER_EMAIL}',
        'buyer_phone' => '{BUYER_PHONE}',
        'buyer_contact_name' => '{BUYER_CONTACT_NAME}',
        'buyer_street_name' => '{BUYER_STREET_NAME}',
        'buyer_additional_address' => '{BUYER_ADDITIONAL_ADDRESS}',
        'buyer_building_number' => '{BUYER_BUILDING_NUMBER}',
        'buyer_city' => '{BUYER_CITY}',
        'buyer_state_province' => '{BUYER_STATE}',
        'buyer_postal_code' => '{BUYER_POSTAL_CODE}',
        'buyer_country' => '{BUYER_COUNTRY_CODE}'
    ],

    'line_items' => [
        [
            'line_id' => '{LINE_ID}',
            'item_name' => '{ITEM_NAME}',
            'item_description' => '{ITEM_DESCRIPTION}',
            'quantity' => '{QUANTITY}',
            'unit_code' => '{UNIT_CODE}',
            'unit_price' => '{UNIT_PRICE}',
            'net_price' => '{NET_PRICE}',
            'gross_price' => '{GROSS_PRICE}',
            'line_taxable_value' => '{LINE_TAXABLE_VALUE}',
            'tax_category' => '{TAX_CATEGORY}',
            'tax_rate' => '{TAX_RATE}',
            'tax_amount' => '{TAX_AMOUNT}',
            'line_total' => '{LINE_TOTAL}',
            'item_type' => '{ITEM_TYPE}', // e.g., GOODS or SERVICE
            'country_of_origin' => '{COUNTRY_OF_ORIGIN}',
            'classification_code' => '{CLASSIFICATION_CODE}',
            'classification_scheme' => '{CLASSIFICATION_SCHEME}',
            'seller_item_code' => '{SELLER_ITEM_CODE}',
            'buyer_item_code' => '{BUYER_ITEM_CODE}',
            'batch_number' => '{BATCH_NUMBER}'
        ]
    ],

    'extensions' => [
        'unique_identifier' => '{UNIQUE_ID}',
        'invoiced_object_id' => '{INVOICED_OBJECT_ID}',
        'taxpoint_date' => getDynamicDate(0),
        'total_amount_including_tax' => '{TOTAL_AMOUNT_INCLUDING_TAX}',
        'authority_name' => '{AUTHORITY_NAME}',
        'buyer_authority_name' => '{BUYER_AUTHORITY_NAME}',
        'business_process_type' => '{BUSINESS_PROCESS_TYPE}',
        'specification_identifier' => '{SPECIFICATION_IDENTIFIER}'
    ],

    'payment_info' => [
        'payment_id' => '{PAYMENT_ID}',
        'payment_means_code' => '{PAYMENT_MEANS_CODE}',
        'payment_means_text' => '{PAYMENT_MEANS_TEXT}',
        'remittance_info' => '{REMITTANCE_INFO}',
        'account_id' => '{ACCOUNT_ID}',
        'account_name' => '{ACCOUNT_NAME}',
        'bank_id' => '{BANK_ID}'
    ],

    'payment_terms' => [
        [
            'instructions_id' => '{TERM_ID}',
            'note' => '{PAYMENT_NOTE}',
            'amount' => '{TERM_AMOUNT}',
            'due_date' => getDynamicDate(30)
        ]
    ],

    'supporting_documents' => [
        [
            'type' => '{DOCUMENT_TYPE}',
            'id' => '{DOCUMENT_ID}'
        ]
    ],

    'additional_data' => [
        'delivery_date' => getDynamicDate(0),
        'order_reference' => '{ORDER_REFERENCE}',
        'source_system' => '{SOURCE_SYSTEM}'
    ]
];
 
// -------------------
// STEP 3: SEND REQUEST
// -------------------

try {
    echo "🔄 Sending invoice with Purpose = MAPPING...\n";

    $response = GETSUnifySDK::pushToUnify(
        $sourceName,
        $sourceVersion,
        LogicalDocType::from(LogicalDocType::TAX_INVOICE),
        Country::from(Country::YOUR_COUNTRY_CODE), // Replace with your country enum
        Operation::from(Operation::SINGLE),
        Mode::from(Mode::DOCUMENTS),
        Purpose::from(Purpose::MAPPING),
        $payload
    );

    print_r($response);

} catch (\Exception $e) {
    echo "❌ Error: " . $e->getMessage() . "\n";
}

// -------------------
// STEP 4: CHANGE PURPOSE TO INVOICE & SUBMIT
// -------------------

try {
    echo "🚀 Submitting invoice with Purpose = INVOICING...\n";

    $invoiceResponse = GETSUnifySDK::pushToUnify(
        $sourceName,
        $sourceVersion,
        LogicalDocType::from(LogicalDocType::TAX_INVOICE),
        Country::from(Country::YOUR_COUNTRY_CODE),
        Operation::from(Operation::SINGLE),
        Mode::from(Mode::DOCUMENTS),
        Purpose::from(Purpose::INVOICING),
        $payload
    );

    print_r($invoiceResponse);
    echo "✅ Invoice submitted successfully\n";

} catch (\Exception $e) {
    echo "❌ Error during INVOICING submission: " . $e->getMessage() . "\n";
}

Running the PHP Script

After completing the SDK configuration and invoice submission steps, execute the PHP file from your terminal.

Step 1: Open Terminal

Navigate to your project directory:

cd /path/to/your/project

Step 2: Run the Script

Use the following command format to execute your PHP file:

php your_file_name.php

Replace your_file_name with the name of your PHP script.

Step 3: Verify Execution

  • After running the command, the terminal will display:

  • SDK configuration status

  • Mapping response

  • Invoice submission response

  • Or validation/error messages (if any)

Sample Reference File

If you prefer to start with a ready-to-use template, we have provided a complete reference implementation that aligns with the required compliance standards.

Download the full class file: UAETaxInvoiceTest.php

Support

  • Contact: Contact Complyance for E-Invoicing - Complyance has helped over 1000+ organizations simplify global e-invoicing. Let us help you understand how Complyance can work for you.