rebasesoftware / edm-efatura
EDM e-invoice client package
Requires
- php: ^8.3
- ext-dom: *
- ext-soap: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.58
- phpstan/phpstan: ^1.11
- squizlabs/php_codesniffer: ^3.9
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 contentSENDER
- Sender informationRECEIVER
- Receiver informationISSUE_DATE
- Invoice issue datePAYABLE_AMOUNT
- Total payable amount with currencyCURRENCY
- Invoice currencySTATUS
- Invoice statusSTATUS_DESCRIPTION
- Status descriptionDESCRIPTION
- Human-readable status descriptionUUID
- Invoice UUIDID
- Invoice IDTRXID
- 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
- Fork the repository
- Create a feature branch
- 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
- Run code quality tools:
composer cs:fix && composer stan
- Ensure all tests pass
- 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.