rebasesoftware/edm-efatura

EDM e-invoice client package

v1.0.0 2025-03-14 07:42 UTC

This package is auto-updated.

Last update: 2025-08-25 19:31:30 UTC


README

A modern PHP library for Turkish E-Invoice (E-Fatura) integration provided by EDM, providing a clean and type-safe interface for SOAP-based e-invoice operations.

Features

  • ๐Ÿ” Authentication Management - Secure login/logout with session handling and automatic session management
  • ๐Ÿ“„ Invoice Operations - Send invoices with comprehensive UBL XML generation
  • ๐Ÿ” Invoice Retrieval - Get invoices by number or UUID with full metadata
  • ๐Ÿ“Š Status Tracking - Real-time invoice status monitoring with detailed status descriptions
  • ๐Ÿข Company Management - Complete issuer and recipient company information handling
  • ๐Ÿ’ฐ Tax Management - Advanced tax calculations with multiple tax rates and exemption handling
  • ๐Ÿ“ฆ Product Management - Detailed product information with brand, model, and classification support
  • ๐Ÿ’ณ Payment Integration - Payment type configuration with due dates and account information
  • ๐Ÿ“‹ Line Item Management - Individual invoice line items with quantities, prices, and tax calculations
  • ๐Ÿ›ก๏ธ Exception Handling - Comprehensive SOAP exception handling with detailed error reporting
  • ๐ŸŽฏ Type Safety - Full PHP 8.3+ type hints, return types, and nullable type support
  • ๐Ÿงน Clean Code - PSR-12 compliant code with modern PHP 8.3+ features
  • ๐Ÿ“ XML Generation - Clean, readable UBL 2.1 XML output with proper formatting and indentation
  • ๐Ÿ”ง Helper Utilities - Built-in utilities for GUID generation and status code translation
  • ๐Ÿ“š Documentation - Comprehensive API documentation with working examples

Requirements

  • PHP 8.3 or higher
  • SOAP extension enabled
  • Valid E-Fatura service credentials

Installation

composer require rebasesoftware/edm-efatura

Quick Start

<?php

require_once 'vendor/autoload.php';

use EDM\EFatura\Client;
use EDM\EFatura\Exception\EDMSoapException;
use EDM\EFatura\Invoice\Invoice;
use EDM\EFatura\Invoice\Element\Company;
use EDM\EFatura\Invoice\Element\Line;
use EDM\EFatura\Invoice\Element\Product;
use EDM\EFatura\Invoice\Element\Tax;
use EDM\EFatura\Invoice\Element\PaymentType;

// Initialize client
$client = new Client(
    'https://test.edmbilisim.com.tr/EFaturaEDM21ea/EFaturaEDM.svc?singleWsdl',
    'your_username',
    'your_password',
    'your_hostname',
    'your_reason',
    'your_channel',
    'your_application'
);

// Login
try {
    if ($client->login()) {
        echo "Login successful!";
        $sessionId = $client->getSessionId();
        echo "Session ID: " . $sessionId;
    } else {
        echo "Login failed";
    }
} catch (EDMSoapException $e) {
    echo "Login error: " . $e->getMessage();
}

API Reference

Client Constructor

__construct(string $url, string $username, string $password, string $hostname, string $reason, string $channel, string $application)

Creates a new EDM E-Fatura client instance.

$client = new Client(
    'https://test.edmbilisim.com.tr/EFaturaEDM21ea/EFaturaEDM.svc?singleWsdl',
    'your_username',
    'your_password',
    'your_hostname',
    'your_reason',
    'your_channel',
    'your_application'
);

Parameters:

  • $url - WSDL URL provided by EDM
  • $username - Username for authentication
  • $password - Password for authentication
  • $hostname - Hostname of the client system
  • $reason - Reason for using the service
  • $channel - Channel name for the application
  • $application - Application name using the service

Authentication

login(): bool

Authenticates with the E-Fatura service and establishes a session using the credentials provided in the constructor.

$success = $client->login();
if ($success) {
    $sessionId = $client->getSessionId();
    echo "Session established: " . $sessionId;
}

logout(): bool

Terminates the current session.

$success = $client->logout();
if ($success) {
    echo "Successfully logged out";
}

getSessionId(): ?string

Retrieves the current session ID.

$sessionId = $client->getSessionId();

Invoice Management

sendInvoice(Invoice $invoice): array

Sends an e-invoice to the service.

// Create and configure invoice
$invoice = new Invoice();
$invoice->setProfileId('TICARIFATURA');
$invoice->setId('INV-001');
// ... configure other invoice properties

$result = $client->sendInvoice($invoice);
// $result contains 'request' and 'response' arrays

getInvoice(?string $invoiceNumber = null, ?string $invoiceUUID = null, bool $incoming = false, string $contentType = 'XML'): ?array

Retrieves a single invoice by number or UUID.

// Get by invoice number
$invoice = $client->getInvoice('INV-001');

// Get by UUID
$invoice = $client->getInvoice(null, 'uuid-12345');

// Get incoming invoice
$incomingInvoice = $client->getInvoice('INV-001', null, true);

Returns an array with invoice details:

  • CONTENT - Invoice XML content
  • SENDER - Sender information
  • RECEIVER - Receiver information
  • ISSUE_DATE - Invoice issue date
  • PAYABLE_AMOUNT - Total payable amount with currency
  • CURRENCY - Invoice currency
  • STATUS - Invoice status
  • STATUS_DESCRIPTION - Status description
  • DESCRIPTION - Human-readable status description
  • UUID - Invoice UUID
  • ID - Invoice ID
  • TRXID - Transaction ID

getInvoiceStatus(string $invoiceNumber = '', ?string $invoiceUUID = null): array

Retrieves the current status of an invoice.

$status = $client->getInvoiceStatus('INV-001');
echo "Status: " . $status['response']->STATUS;
echo "Description: " . $status['response']->ACIKLAMA;

Error Handling

The library uses exceptions for error handling. All SOAP operations can throw EDMSoapException when communication fails.

try {
    $result = $client->sendInvoice($invoice);
} catch (EDMSoapException $e) {
    echo "SOAP Error: " . $e->getMessage();
}

Invoice Structure

Creating an Invoice

use EDM\EFatura\Invoice\Invoice;
use EDM\EFatura\Invoice\Element\Company;
use EDM\EFatura\Invoice\Element\Line;
use EDM\EFatura\Invoice\Element\Product;
use EDM\EFatura\Invoice\Element\Tax;
use EDM\EFatura\Invoice\Element\PaymentType;

// Create issuer company
$issuer = new Company();
$issuer->setTitle('Sample Company Ltd.');
$issuer->setTaxNumber('1234567890');
$issuer->setTaxOffice('Sample Tax Office');
$issuer->setAddress('Sample Address 123');
$issuer->setCity('Istanbul');
$issuer->setDistrict('Kadikoy');
$issuer->setCountryCode('TR');
$issuer->setCountryName('Turkey');
$issuer->setPhone('+90 212 123 45 67');
$issuer->setEmail('info@samplecompany.com');
$issuer->setWebsite('www.samplecompany.com');
$issuer->setGibUrn('urn:mail:defaultpk@sirket.com');

// Create recipient company
$recipient = new Company();
$recipient->setTitle('Customer Company Ltd.');
$recipient->setTaxNumber('0987654321');
$recipient->setTaxOffice('Customer Tax Office');
$recipient->setAddress('Customer Address 456');
$recipient->setCity('Ankara');
$recipient->setDistrict('Cankaya');
$recipient->setCountryCode('TR');
$recipient->setCountryName('Turkey');
$recipient->setPhone('+90 312 987 65 43');
$recipient->setEmail('info@customercompany.com');
$recipient->setWebsite('www.customercompany.com');
$recipient->setGibUrn('urn:mail:defaultpk@musteri.com');

// Create payment type
$paymentType = new PaymentType();
$paymentType->setCode('1');
$paymentType->setDueDate(date('Y-m-d', strtotime('+30 days')));
$paymentType->setAccountCode('TR123456789012345678901234');
$paymentType->setCurrencyCode('TRY');
$paymentType->setPaymentNote('Payment within 30 days');

// Create invoice
$invoice = new Invoice();
$invoice->setProfileId('TICARIFATURA');
$invoice->setId('INV-' . date('Ymd-His'));
$invoice->setUuid(uniqid('uuid-', true));
$invoice->setIssueDate(date('Y-m-d'));
$invoice->setIssueTime(date('H:i:s'));
$invoice->setInvoiceTypeCode('SATIS');
$invoice->setNote('Sample invoice for testing');
$invoice->setDocumentCurrencyCode('TRY');
$invoice->setLineCountNumeric(1);
$invoice->setIssuer($issuer);
$invoice->setRecipient($recipient);
$invoice->setPaymentType($paymentType);

// Create product
$product = new Product();
$product->setName('Sample Product');
$product->setBrand('Sample Brand');
$product->setModel('Sample Model');
$product->setCustomCode('PROD001');

// Create line tax
$lineTax = new Tax();
$lineTax->setSequenceNumber(1);
$lineTax->setTaxExclusiveAmount(100.00);
$lineTax->setTaxAmount(18.00);
$lineTax->setCurrencyCode('TRY');
$lineTax->setTaxRate(18);
$lineTax->setTaxCode('0015');
$lineTax->setTaxName('KDV');

// Create line
$line = new Line();
$line->setLineNumber(1);
$line->setUnit('C62');
$line->setQuantity(1);
$line->setUnitPrice(100.00);
$line->setLineTotal(100.00);
$line->setCurrencyCode('TRY');
$line->setProduct($product);
$line->setTax($lineTax);

$invoice->addLine($line);

// Set totals
$invoice->setLineTotal(100.00);
$invoice->setTaxExclusiveTotal(100.00);
$invoice->setTaxInclusiveTotal(118.00);
$invoice->setTotalDiscount(0.00);
$invoice->setRoundingAmount(0.00);
$invoice->setPayableAmount(118.00);

Code Quality

The library includes comprehensive code quality tools with modern PHP 8.3+ standards:

Code Formatting

# Format code according to PSR-12, Symfony, and PHP-CS-Fixer standards
composer cs:fix

# Check code style without making changes
composer cs:check

Static Analysis

# Run PHPStan static analysis (level 6)
composer stan

# Run PHP linting
composer lint

Code Quality Features

  • PSR-12 Compliance - Follows PHP-FIG coding standards
  • Type Safety - Full PHP 8.3+ type hints and return types
  • Clean XML Generation - Readable, properly formatted XML output
  • Modern PHP Patterns - Uses latest PHP features and best practices
  • Excluded Documentation - Code quality tools exclude doc/ folder for faster analysis

Demo

Check out the demo application in doc/demo/index.php for practical examples of all library features.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes following the established patterns:
    • Use proper PHP 8.3+ type hints and return types
    • Follow PSR-12 coding standards
    • Use clean XML generation with heredoc syntax
    • Remove unnecessary variable assignments
  4. Run code quality tools: composer cs:fix && composer stan
  5. Ensure all tests pass
  6. Submit a pull request

Development Guidelines

  • Type Safety: Always use proper type hints and return types
  • Clean Code: Remove inline re-assignments and use direct method calls
  • XML Generation: Use heredoc syntax for clean, readable XML output
  • Consistency: Follow the patterns established in existing code
  • Documentation: Update documentation for any new features

License

This library is licensed under the MIT License.

Support

For support and questions, please open an issue on GitHub or contact the development team.