diff --git a/tests/Feature/EInvoice/Verifactu/Models/WSTest.php b/tests/Feature/EInvoice/Verifactu/Models/WSTest.php index 013e80fe41..686b5d9663 100644 --- a/tests/Feature/EInvoice/Verifactu/Models/WSTest.php +++ b/tests/Feature/EInvoice/Verifactu/Models/WSTest.php @@ -5,10 +5,18 @@ namespace Tests\Feature\EInvoice\Verifactu\Models; use Illuminate\Support\Facades\Http; use Tests\TestCase; + class WSTest extends TestCase { + + + public function test_send_aeat_example_to_verifactu() { + + + + $soapXml = << sign(); + // Try direct HTTP approach instead of SOAP client $response = Http::withHeaders([ 'Content-Type' => 'text/xml; charset=utf-8', - 'SOAPAction' => 'RegFactuSistemaFacturacion', + 'SOAPAction' => '', ]) ->withOptions([ - 'cert' => $certPath, - 'ssl_key' => $keyPath, - 'verify' => false, // Optional: disable CA verification for testing - 'timeout' => 30, // Increase timeout + 'cert' => storage_path('aeat-cert2.pem'), + 'ssl_key' => storage_path('aeat-key2.pem'), + 'verify' => false, + 'timeout' => 30, ]) - ->post($endpoint, $soapXml); + ->post('https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP', $soapXml); \Log::info('Request with AEAT official test data:'); \Log::info($soapXml); @@ -109,7 +115,6 @@ XML; \Log::info('Response Headers: ' . json_encode($response->headers())); \Log::info('Response Body: ' . $response->body()); - // Don't assert success yet, let's see what the actual response is if (!$response->successful()) { \Log::error('Request failed with status: ' . $response->status()); \Log::error('Response body: ' . $response->body()); @@ -399,4 +404,507 @@ XML; $this->assertTrue($response->successful()); } + + public function test_send_new_invoice_without_chaining() + { + // Create a completely new invoice without any chaining + $soapXml = << + + + + + + + + 99999910G + Empresa Ejemplo SL + + + + 99999910G + Mi Sistema + 1.0 + + + 2025 + 06 + + + + + + 99999910G + Empresa Ejemplo SL + + FAC001 + 25-06-2025 + + + F1 + 25-06-2025 + + + ES + 02 + 12345678A + + Cliente Ejemplo + 99999910G + + + Venta de productos + + RL + 100.00 + + 100.00 + 100.00 + + + + ES + 02 + 12345678A + + Cliente Ejemplo + + + + + + +XML; + + // Calculate the correct hash for this XML + $xmlForHash = str_replace('PLACEHOLDER_HUELLA', '', $soapXml); + $xmlForHash = preg_replace('/.*?<\/sum1:HuellaDigital>/s', '', $xmlForHash); + $correctHash = strtoupper(hash('sha256', $xmlForHash)); + + // Replace the placeholder with the correct hash + $soapXml = str_replace('PLACEHOLDER_HUELLA', $correctHash, $soapXml); + + \Log::info('New invoice without chaining - Calculated hash: ' . $correctHash); + + // Sign the XML before sending + $certPath = storage_path('aeat-cert2.pem'); + $keyPath = storage_path('aeat-key2.pem'); + $signingService = new \App\Services\EDocument\Standards\Verifactu\Signing\SigningService($soapXml, file_get_contents($keyPath), file_get_contents($certPath)); + $soapXml = $signingService->sign(); + + // Send the request + $response = Http::withHeaders([ + 'Content-Type' => 'text/xml; charset=utf-8', + 'SOAPAction' => '', + ]) + ->withOptions([ + 'cert' => storage_path('aeat-cert2.pem'), + 'ssl_key' => storage_path('aeat-key2.pem'), + 'verify' => false, + 'timeout' => 30, + ]) + ->post('https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP', $soapXml); + + \Log::info('New invoice without chaining response:'); + \Log::info('Response Status: ' . $response->status()); + \Log::info('Response Headers: ' . json_encode($response->headers())); + \Log::info('Response Body: ' . $response->body()); + + if (!$response->successful()) { + \Log::error('Request failed with status: ' . $response->status()); + \Log::error('Response body: ' . $response->body()); + } + + $this->assertTrue($response->successful()); + } + + public function test_send_official_structure_with_real_data() + { + // Use the exact structure from the official example but with real data + $soapXml = << + + + + + + + Empresa Test SL + 99999910G + + + + + 1.0 + + 99999910G + TEST-001 + 24-06-2025 + + Empresa Test SL + F1 + Venta de productos de prueba + + + Cliente Test SL + B12345678 + + + + Venta de productos de prueba + + RL + 100.00 + + 100.00 + 100.00 + + + + ES + 02 + B12345678 + + Cliente Test SL + + + S + + 2025-06-24T22:34:00+01:00 + 01 + PLACEHOLDER_HUELLA + + + + + +XML; + + // Calculate the correct hash for this XML + $xmlForHash = $this->getXmlForHashCalculation($soapXml); + $correctHash = strtoupper(hash('sha256', $xmlForHash)); + + // Replace the placeholder with the correct hash + $soapXml = str_replace('PLACEHOLDER_HUELLA', $correctHash, $soapXml); + + \Log::info('Official structure with real data - Calculated hash: ' . $correctHash); + + // Sign the XML before sending + $certPath = storage_path('aeat-cert2.pem'); + $keyPath = storage_path('aeat-key2.pem'); + $signingService = new \App\Services\EDocument\Standards\Verifactu\Signing\SigningService($soapXml, file_get_contents($keyPath), file_get_contents($certPath)); + $soapXml = $signingService->sign(); + + // Send the request + $response = Http::withHeaders([ + 'Content-Type' => 'text/xml; charset=utf-8', + 'SOAPAction' => '', + ]) + ->withOptions([ + 'cert' => storage_path('aeat-cert2.pem'), + 'ssl_key' => storage_path('aeat-key2.pem'), + 'verify' => false, + 'timeout' => 30, + ]) + ->post('https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP', $soapXml); + + \Log::info('Official structure with real data response:'); + \Log::info('Response Status: ' . $response->status()); + \Log::info('Response Headers: ' . json_encode($response->headers())); + \Log::info('Response Body: ' . $response->body()); + + if (!$response->successful()) { + \Log::error('Request failed with status: ' . $response->status()); + \Log::error('Response body: ' . $response->body()); + } + + $this->assertTrue($response->successful()); + } + + public function test_send_minimal_invoice_to_aeat() + { + // Create the most minimal invoice possible with only required fields + $soapXml = << + + + + + + + Test Company + 99999910G + + + + + 1.0 + + 99999910G + 001 + 01-01-2024 + + Test Company + F1 + Test + + Test + + RL + 10.00 + + 10.00 + + + S + + 2024-01-01T12:00:00+01:00 + 01 + PLACEHOLDER_HUELLA + + + + + +XML; + + // Calculate the correct hash for this XML + $xmlForHash = $this->getXmlForHashCalculation($soapXml); + $correctHash = strtoupper(hash('sha256', $xmlForHash)); + + // Replace the placeholder with the correct hash + $soapXml = str_replace('PLACEHOLDER_HUELLA', $correctHash, $soapXml); + + \Log::info('Minimal invoice - Calculated hash: ' . $correctHash); + + // Sign the XML before sending + $certPath = storage_path('aeat-cert2.pem'); + $keyPath = storage_path('aeat-key2.pem'); + $signingService = new \App\Services\EDocument\Standards\Verifactu\Signing\SigningService($soapXml, file_get_contents($keyPath), file_get_contents($certPath)); + $soapXml = $signingService->sign(); + + // Send the request + $response = Http::withHeaders([ + 'Content-Type' => 'text/xml; charset=utf-8', + 'SOAPAction' => '', + ]) + ->withOptions([ + 'cert' => storage_path('aeat-cert2.pem'), + 'ssl_key' => storage_path('aeat-key2.pem'), + 'verify' => false, + 'timeout' => 30, + ]) + ->post('https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP', $soapXml); + + \Log::info('Minimal invoice response:'); + \Log::info('Response Status: ' . $response->status()); + \Log::info('Response Headers: ' . json_encode($response->headers())); + \Log::info('Response Body: ' . $response->body()); + + // Check if we got a different response + $responseBody = $response->body(); + if (strpos($responseBody, 'Error interno en el servidor') === false) { + \Log::info('SUCCESS: No server error found in response!'); + } else { + \Log::error('Still getting server error with minimal invoice'); + } + + $this->assertTrue($response->successful()); + } + + public function test_send_ultra_minimal_invoice_to_aeat() + { + // Ultra minimal invoice with current date and no optional fields + $currentDate = date('d-m-Y'); + $currentDateTime = date('Y-m-d\TH:i:sP'); + + $soapXml = << + + + + + + + Test + 99999910G + + + + + 1.0 + + 99999910G + 1 + $currentDate + + Test + F1 + Test + + Test + + RL + 1.00 + + 1.00 + + + S + + $currentDateTime + 01 + PLACEHOLDER_HUELLA + + + + + +XML; + + // Calculate the correct hash for this XML + $xmlForHash = $this->getXmlForHashCalculation($soapXml); + $correctHash = strtoupper(hash('sha256', $xmlForHash)); + + // Replace the placeholder with the correct hash + $soapXml = str_replace('PLACEHOLDER_HUELLA', $correctHash, $soapXml); + + \Log::info('Ultra minimal invoice - Calculated hash: ' . $correctHash); + \Log::info('Using date: ' . $currentDate . ' and datetime: ' . $currentDateTime); + + // Sign the XML before sending + $certPath = storage_path('aeat-cert2.pem'); + $keyPath = storage_path('aeat-key2.pem'); + $signingService = new \App\Services\EDocument\Standards\Verifactu\Signing\SigningService($soapXml, file_get_contents($keyPath), file_get_contents($certPath)); + $soapXml = $signingService->sign(); + + // Send the request + $response = Http::withHeaders([ + 'Content-Type' => 'text/xml; charset=utf-8', + 'SOAPAction' => '', + ]) + ->withOptions([ + 'cert' => storage_path('aeat-cert2.pem'), + 'ssl_key' => storage_path('aeat-key2.pem'), + 'verify' => false, + 'timeout' => 30, + ]) + ->post('https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP', $soapXml); + + \Log::info('Ultra minimal invoice response:'); + \Log::info('Response Status: ' . $response->status()); + \Log::info('Response Headers: ' . json_encode($response->headers())); + \Log::info('Response Body: ' . $response->body()); + + // Check if we got a different response + $responseBody = $response->body(); + if (strpos($responseBody, 'Error interno en el servidor') === false) { + \Log::info('SUCCESS: No server error found in ultra minimal response!'); + } else { + \Log::error('Still getting server error with ultra minimal invoice'); + } + + $this->assertTrue($response->successful()); + } + + public function test_send_invoice_without_encadenamiento() + { + // Try without Encadenamiento section + $currentDate = date('d-m-Y'); + $currentDateTime = date('Y-m-d\TH:i:sP'); + + $soapXml = << + + + + + + + Test + 99999910G + + + + + 1.0 + + 99999910G + 1 + $currentDate + + Test + F1 + Test + + Test + + RL + 1.00 + + 1.00 + + $currentDateTime + 01 + PLACEHOLDER_HUELLA + + + + + +XML; + + // Calculate the correct hash for this XML + $xmlForHash = $this->getXmlForHashCalculation($soapXml); + $correctHash = strtoupper(hash('sha256', $xmlForHash)); + + // Replace the placeholder with the correct hash + $soapXml = str_replace('PLACEHOLDER_HUELLA', $correctHash, $soapXml); + + \Log::info('Invoice without Encadenamiento - Calculated hash: ' . $correctHash); + + // Sign the XML before sending + $certPath = storage_path('aeat-cert2.pem'); + $keyPath = storage_path('aeat-key2.pem'); + $signingService = new \App\Services\EDocument\Standards\Verifactu\Signing\SigningService($soapXml, file_get_contents($keyPath), file_get_contents($certPath)); + $soapXml = $signingService->sign(); + + // Send the request + $response = Http::withHeaders([ + 'Content-Type' => 'text/xml; charset=utf-8', + 'SOAPAction' => '', + ]) + ->withOptions([ + 'cert' => storage_path('aeat-cert2.pem'), + 'ssl_key' => storage_path('aeat-key2.pem'), + 'verify' => false, + 'timeout' => 30, + ]) + ->post('https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP', $soapXml); + + \Log::info('Invoice without Encadenamiento response:'); + \Log::info('Response Status: ' . $response->status()); + \Log::info('Response Headers: ' . json_encode($response->headers())); + \Log::info('Response Body: ' . $response->body()); + + // Check if we got a different response + $responseBody = $response->body(); + if (strpos($responseBody, 'Error interno en el servidor') === false) { + \Log::info('SUCCESS: No server error found without Encadenamiento!'); + } else { + \Log::error('Still getting server error without Encadenamiento'); + } + + $this->assertTrue($response->successful()); + } } \ No newline at end of file