PHP code example of krendil007 / verifactu-php

1. Go to this page and download the library: Download krendil007/verifactu-php library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

krendil007 / verifactu-php example snippets


use eseperio\verifactu\Verifactu;

// Configure the library (do this once before any operation)
Verifactu::config(
    '/path/to/your-certificate.pfx', // Path to certificate
    'your-certificate-password',     // Certificate password
    Verifactu::TYPE_CERTIFICATE,     // Certificate type: TYPE_CERTIFICATE or TYPE_SEAL
    Verifactu::ENVIRONMENT_PRODUCTION // Environment: ENVIRONMENT_PRODUCTION or ENVIRONMENT_SANDBOX
);

use eseperio\verifactu\Verifactu;
use eseperio\verifactu\models\InvoiceSubmission;
use eseperio\verifactu\models\InvoiceId;
use eseperio\verifactu\models\Breakdown;
use eseperio\verifactu\models\BreakdownDetail;
use eseperio\verifactu\models\Chaining;
use eseperio\verifactu\models\ComputerSystem;
use eseperio\verifactu\models\LegalPerson;
use eseperio\verifactu\models\Recipient;
use eseperio\verifactu\models\enums\InvoiceType;
use eseperio\verifactu\models\enums\TaxType;
use eseperio\verifactu\models\enums\YesNoType;
use eseperio\verifactu\models\enums\HashType;
use eseperio\verifactu\models\enums\RegimeType;
use eseperio\verifactu\models\enums\OperationQualificationType;

// After calling Verifactu::config(...)

$invoice = new InvoiceSubmission();

// Set invoice ID (using object-oriented approach)
$invoiceId = new InvoiceId();
$invoiceId->issuerNif = 'B12345678';
$invoiceId->seriesNumber = 'FA2024/001';
$invoiceId->issueDate = '01-07-2024';
$invoice->setInvoiceId($invoiceId);

// Set basic invoice data
$invoice->issuerName = 'Empresa Ejemplo SL';
$invoice->invoiceType = InvoiceType::STANDARD; // Using corrected enum value
$invoice->operationDescription = 'Venta de productos';
$invoice->taxAmount = 21.00; // Total tax amount
$invoice->totalAmount = 121.00; // Total invoice amount
$invoice->simplifiedInvoice = YesNoType::NO;
$invoice->invoiceWithoutRecipient = YesNoType::NO; 

// Add tax breakdown (using object-oriented approach)
$breakdown = new Breakdown();
$detail = new BreakdownDetail();
$detail->taxType = TaxType::IVA;
$detail->regimeKey = RegimeType::C01;
$detail->taxRate = 21.00;
$detail->taxableBase = 100.00; 
$detail->taxAmount = 21.00;
$detail->operationQualification = OperationQualificationType::SUBJECT_NO_EXEMPT_NO_REVERSE;
$breakdown->addDetail($detail);
$invoice->setBreakdown($breakdown);

// Set chaining data (using object-oriented approach)
$chaining = new Chaining();
$chaining->firstRecord = YesNoType::YES; // For the first invoice in a chain
// Or for subsequent invoices:
// $chaining->setPreviousInvoice([
//     'seriesNumber' => 'FA2024/000',
//     'issuerNif' => 'B12345678',
//     'issueDate' => '2024-06-30',
//     'hash' => '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
// ]);
$invoice->setChaining($chaining);

// Set system information (using object-oriented approach)
$computerSystem = new ComputerSystem();
$computerSystem->systemName = 'ERP Company';
$computerSystem->version = '1.0';
$computerSystem->providerName = 'Software Provider';
$computerSystem->systemId = '01';
$computerSystem->installationNumber = '1';
$computerSystem->onlyVerifactu = YesNoType::YES;
$computerSystem->multipleObligations = YesNoType::NO;

// Set provider information
$provider = new LegalPerson();
$provider->name = 'Software Provider SL';
$provider->nif = 'B87654321';
$computerSystem->setProviderId($provider);

$invoice->setSystemInfo($computerSystem);

// Set other 

use eseperio\verifactu\Verifactu;
use eseperio\verifactu\models\InvoiceCancellation;
use eseperio\verifactu\models\InvoiceId;
use eseperio\verifactu\models\Chaining;
use eseperio\verifactu\models\ComputerSystem;
use eseperio\verifactu\models\LegalPerson;
use eseperio\verifactu\models\enums\YesNoType;
use eseperio\verifactu\models\enums\HashType;
use eseperio\verifactu\models\enums\GeneratorType;

// After calling Verifactu::config(...)

$cancellation = new InvoiceCancellation();

// Set invoice ID (using object-oriented approach)
$invoiceId = new InvoiceId();
$invoiceId->issuerNif = 'B12345678';
$invoiceId->seriesNumber = 'FA2024/001';
$invoiceId->issueDate = '01-07-2024';
$cancellation->setInvoiceId($invoiceId);

// Set chaining data (using object-oriented approach)
$chaining = new Chaining();
// For subsequent invoices in a chain:
$chaining->setPreviousInvoice([
    'seriesNumber' => 'FA2024/000',
    'issuerNif' => 'B12345678',
    'issueDate' => '2024-06-30',
    'hash' => '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
]);
$cancellation->setChaining($chaining);

// Set system information (using object-oriented approach)
$computerSystem = new ComputerSystem();
$computerSystem->systemName = 'ERP Company';
$computerSystem->version = '1.0';
$computerSystem->providerName = 'Software Provider';
$computerSystem->systemId = '01';
$computerSystem->installationNumber = '1';
$computerSystem->onlyVerifactu = YesNoType::YES;
$computerSystem->multipleObligations = YesNoType::NO;

// Set provider information
$provider = new LegalPerson();
$provider->name = 'Software Provider SL';
$provider->nif = 'B87654321';
$computerSystem->setProviderId($provider);

$cancellation->setSystemInfo($computerSystem);

// Set other 

use eseperio\verifactu\Verifactu;
use eseperio\verifactu\models\InvoiceQuery;
use eseperio\verifactu\models\ComputerSystem;
use eseperio\verifactu\models\LegalPerson;
use eseperio\verifactu\models\enums\YesNoType;
use eseperio\verifactu\models\enums\PeriodType;

// After calling Verifactu::config(...)

$query = new InvoiceQuery();

// Required fields
$query->year = '2024';
$query->period = PeriodType::JULY; // Using enum instead of string

// Optional filters
$query->seriesNumber = 'FA2024'; // Filter by invoice series
$query->issueDate = '2024-07-01'; // Filter by specific date

// Set counterparty (using object-oriented approach)
$counterparty = new LegalPerson();
$counterparty->name = 'Cliente Ejemplo SL';
$counterparty->nif = 'A12345678';
$query->setCounterparty($counterparty);

$name = 'Software Provider SL';
$nif = 'B87654321';
$computerSystem->setProviderId($name, $nif);

$query->setSystemInfo($computerSystem);

// Additional optional fields
$query->externalRef = 'REF-QUERY-123'; // External reference
$query->setPaginationKey(1, 50); // Page number and records per page

// Validate the query before submission
$errors = $query->validate();
if (!empty($errors)) {
    // Handle validation errors
    print_r($errors);
    exit;
}

// Submit the query
$result = Verifactu::queryInvoices($query);

// Process the results
if ($result->queryStatus === \eseperio\verifactu\models\QueryResponse::STATUS_OK) {
    echo "Total records found: " . count($result->foundRecords) . "\n";

    foreach ($result->foundRecords as $record) {
        echo "Invoice: " . $record->seriesNumber . " - Date: " . $record->issueDate . "\n";
        echo "Issuer: " . $record->issuerName . " (" . $record->issuerNif . ")\n";
        echo "Amount: " . $record->totalAmount . " EUR\n";
        echo "CSV: " . $record->csv . "\n";
        echo "Status: " . $record->status . "\n";
        echo "-------------------\n";
    }

    // Check if there are more pages
    if ($result->hasMoreRecords === YesNoType::YES) {
        echo "There are more records available. Use pagination to retrieve them.\n";
    }
} else {
    // Handle query errors
    foreach ($result->errors as $error) {
        echo "Error code: " . $error->code . " - " . $error->message . "\n";
    }
}

use eseperio\verifactu\Verifactu;
use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
use eseperio\verifactu\models\InvoiceRecord;
use eseperio\verifactu\models\InvoiceSubmission;

// Assuming you already have a valid InvoiceSubmission or InvoiceCancellation object
// that has been submitted to AEAT and has a CSV

// Basic usage (returns raw image data using GD renderer)
$qrData = VerifactuService::generateInvoiceQr($invoice);

// Save QR directly to a file
$filePath = VerifactuService::generateInvoiceQr(
    $invoice,
    QrGeneratorService::DESTINATION_FILE, // Save to file instead of returning data
    300, // Resolution (size in pixels)
    QrGeneratorService::RENDERER_GD // Use GD library (default)
);
echo "QR code saved to: $filePath";

// Generate SVG format
$svgData = VerifactuService::generateInvoiceQr(
    $invoice,
    QrGeneratorService::DESTINATION_STRING,
    300,
    QrGeneratorService::RENDERER_SVG
);
// Use SVG data directly in HTML
echo '<div>' . $svgData . '</div>';

// Generate using Imagick (if available on your server)
$pngData = VerifactuService::generateInvoiceQr(
    $invoice,
    QrGeneratorService::DESTINATION_STRING,
    300,
    QrGeneratorService::RENDERER_IMAGICK
);

// Convert to base64 for embedding in HTML or PDF
$base64Data = base64_encode($pngData);
echo '<img src="data:image/png;base64,' . $base64Data . '" alt="QR Code" />';

// Higher resolution QR code
$highResQr = VerifactuService::generateInvoiceQr(
    $invoice,
    QrGeneratorService::DESTINATION_STRING,
    600 // Higher resolution
);

// Complete example with a new invoice
$invoice = new InvoiceSubmission();
// ... set all 

Verifactu::config(
    string $certPath,           // Path to your digital certificate (PFX or P12 format)
    string $certPassword,       // Password for the certificate file
    string $certType,           // Type of certificate: Verifactu::TYPE_CERTIFICATE or Verifactu::TYPE_SEAL
    string $environment = Verifactu::ENVIRONMENT_PRODUCTION // Environment: Verifactu::ENVIRONMENT_PRODUCTION or Verifactu::ENVIRONMENT_SANDBOX
);

use eseperio\verifactu\services\VerifactuService;

VerifactuService::config([
    VerifactuService::CERT_PATH_KEY => '/path/to/your/certificate.p12',
    VerifactuService::CERT_PASSWORD_KEY => 'your-certificate-password',
    VerifactuService::WSDL_ENDPOINT => 'https://custom-endpoint.example.com',
    VerifactuService::QR_VERIFICATION_URL => 'https://custom-qr-verification.example.com',
    // Add any other custom configuration options here
]);

$model = new InvoiceSubmission();
// ... set properties ...
$validationResult = $model->validate();

if ($validationResult !== true) {
    // Handle validation errors
    foreach ($validationResult as $property => $errors) {
        echo "Errors in $property: " . implode(', ', $errors) . "\n";
    }
}

$invoice = new InvoiceSubmission();
// ... set properties ...
$dom = $invoice->toXml();
$xmlString = $dom->saveXML();

  use eseperio\verifactu\services\HashGeneratorService;

  // Calculate hash for an invoice
  $hash = HashGeneratorService::generateHash($invoice);
  $invoice->hash = $hash;
  

  use eseperio\verifactu\services\XmlSignerService;

  // Sign an XML document
  $signedXml = XmlSignerService::signXml($xmlString, $certPath, $certPassword);
  

  use eseperio\verifactu\services\SoapClientFactoryService;

  // Create a SOAP client with certificate authentication
  $client = SoapClientFactoryService::createClient($wsdlUrl, $certPath, $certPassword);
  

  use eseperio\verifactu\services\QrGeneratorService;

  // Generate a QR code for an invoice
  $qrCode = QrGeneratorService::generateQr(
      $invoice,
      QrGeneratorService::DESTINATION_STRING,
      300,
      QrGeneratorService::RENDERER_GD
  );
  

  use eseperio\verifactu\services\ResponseParserService;

  // Parse a SOAP response into an InvoiceResponse object
  $response = ResponseParserService::parseInvoiceResponse($soapResponse);
  

  use eseperio\verifactu\services\EventDispatcherService;

  // Submit an event to AEAT
  $response = EventDispatcherService::submitEvent($eventRecord);
  

  use eseperio\verifactu\services\CertificateManagerService;

  // Load a certificate and check its validity
  $certInfo = CertificateManagerService::loadCertificate($certPath, $certPassword);
  

$invoice = new InvoiceSubmission();
// ... set some properties but not all  {
    // $validationResult is an array of errors by property
    foreach ($validationResult as $property => $errors) {
        echo "Property '$property' has errors: " . implode(', ', $errors) . "\n";
    }
}

$response = Verifactu::registerInvoice($invoice);

if ($response->submissionStatus !== \eseperio\verifactu\models\InvoiceResponse::STATUS_OK) {
    foreach ($response->lineResponses as $lineResponse) {
        echo "Error code: " . $lineResponse->errorCode . "\n";
        echo "Error message: " . $lineResponse->errorMessage . "\n";
        echo "Error location: " . $lineResponse->errorLocation . "\n";
    }
}

try {
    $response = Verifactu::registerInvoice($invoice);
} catch (\InvalidArgumentException $e) {
    // Handle invalid input parameters
    echo "Invalid argument: " . $e->getMessage();
} catch (\RuntimeException $e) {
    // Handle runtime errors (file access, etc.)
    echo "Runtime error: " . $e->getMessage();
} catch (\SoapFault $e) {
    // Handle SOAP communication errors
    echo "SOAP error: " . $e->getMessage();
} catch (\Exception $e) {
    // Handle any other unexpected errors
    echo "Unexpected error: " . $e->getMessage();
}
bash
composer