Back to articles
BackendMar 20269 min

Integrating SOAP/XML APIs in Laravel without losing your mind

SOAP is not dead — it's just hiding in every enterprise ERP system you'll ever have to integrate with. A practical guide to building reliable, debuggable SOAP integrations in Laravel, including error handling, response parsing, and keeping the rest of your codebase clean.

Despite the prevalence of RESTful design patterns, SOAP and legacy XML APIs remain widely deployed inside banking backends and corporate ERP systems. Integrating these systems requires strict custom wrappers to prevent blocking operations and manage inconsistent schema configurations.

Extending the Native Client

PHP's default SoapClient is fragile. Under network drops or backend hangs, it blocks PHP workers indefinitely because it lacks sensible default timeouts. We must extend the client class to implement explicit cURL timeouts and capture raw XML payloads for audit logging.

app/Services/Soap/CustomSoapClient.php
namespace App\Services\Soap;

use SoapClient;

class CustomSoapClient extends SoapClient
{
    private int $timeout = 10; // Explicit timeout in seconds

    public function __doRequest($request, $location, $action, $version, $one_way = 0): string
    {
        $ch = curl_init($location);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: text/xml; charset=utf-8',
            'SOAPAction: ' . $action
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);

        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            throw new \Exception('SOAP Connection failed: ' . curl_error($ch));
        }
        
        curl_close($ch);
        return $response;
    }
}

Safe Parsing and Error Handling

XML parsing is a frequent source of security vulnerabilities (like XML External Entity attacks). Disable external entity loading explicitly in your parse logic and convert payloads to secure, iterable PHP collections or arrays.

app/Services/Soap/XmlParser.php
namespace App\Services\Soap;

use SimpleXMLElement;

class XmlParser
{
    public static function safeParse(string $rawXml): array
    {
        // Prevent XXE attacks by disabling entity loader
        $previous = libxml_disable_entity_loader(true);
        libxml_use_internal_errors(true);

        try {
            $xml = new SimpleXMLElement($rawXml);
            // Convert simpleXML to associative array
            $data = json_decode(json_encode($xml), true);
            libxml_disable_entity_loader($previous);
            return $data;
        } catch (\Exception $e) {
            libxml_clear_errors();
            libxml_disable_entity_loader($previous);
            throw new \Exception('Malformed XML response: ' . $e->getMessage());
        }
    }
}

The Integration Architecture

Avoid calling these legacy endpoints synchronously inside HTTP request cycles. Instead, run integrations inside isolated background queues with a sensible retry strategy and dead-letter queues to catch total API dropouts.

app/Jobs/SyncERPInventory.php
namespace App\Jobs;

use App\Services\Soap\CustomSoapClient;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SyncERPInventory implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3; // Allow up to 3 execution attempts
    public int $backoff = 15; // Wait 15 seconds between retries

    public function handle(): void
    {
        $client = new CustomSoapClient(config('services.erp.wsdl'), [
            'trace' => true,
            'exceptions' => true
        ]);
        
        $response = $client->GetInventory(['WarehouseID' => 101]);
        // Process data in db transactions...
    }
}
Written By
SK
Sagar Kapasi
Software Engineer

Sagar builds operational systems and developer hosting infrastructure from the ground up, specializing in Linux, PHP, and high-performance architectures.

Tags
LaravelPHPSOAPAPIs