diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bdda11c..8e27dee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,18 +12,19 @@ jobs: runs-on: ubuntu-latest continue-on-error: ${{ matrix.experimental || false }} strategy: + fail-fast: false matrix: - php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] include: - - php-version: '8.2' + - php-version: '8.3' test-ws: true send-coverage: true - - php-version: '8.3' + - php-version: '8.4' experimental: true steps: # Download code from repository - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Setup PHP and Composer - name: Setup PHP diff --git a/README.md b/README.md index d6bb6ca..4778656 100644 --- a/README.md +++ b/README.md @@ -65,5 +65,13 @@ file_put_contents(__DIR__ . "/factura.xsig", $signedXml); - Sellado de tiempo según el [RFC3161](https://www.ietf.org/rfc/rfc3161.txt) - Envío automatizado de facturas a **FACe y FACeB2B** 🔥 +## Usan Facturae-PHP +Estas son algunas de las organizaciones y soluciones software que usan Facturae-PHP o mantienen un fork interno basado en el código de la librería: + +Holded +hotelgest +InvoiceNinja +FacturaScripts + ## Licencia Facturae-PHP se encuentra bajo [licencia MIT](LICENSE). Eso implica que puedes utilizar este paquete en cualquier proyecto (incluso con fines comerciales), siempre y cuando hagas referencia al uso y autoría de la misma. diff --git a/doc/envio-y-recepcion/face.md b/doc/envio-y-recepcion/face.md index d4876c1..20add0e 100644 --- a/doc/envio-y-recepcion/face.md +++ b/doc/envio-y-recepcion/face.md @@ -50,6 +50,17 @@ $endpointUrl = "https://w390w.gipuzkoa.net/WAS/HACI/HFAServiciosProveedoresWEB/s $face = new CustomFaceClient($endpointUrl, "certificado.pfx", null, "passphrase"); ``` +Si al intentar conectarte al punto de recepción obtienes un error similar a "A bad canonicalization algorithm was specified", es posible que el servidor de destino no soporte canonicalización de XML exclusiva ([EXC-C14N](https://www.w3.org/TR/xml-exc-c14n/)). +Para usar C14N en vez de EXC-C14N, utiliza este método del cliente: +```php +$face->setExclusiveC14n(false); +``` + +Otro error típico es "Document element namespace mismatch expected". En ese caso, el punto de entrada necesita usar un namespace personalizado, que puedes especificar usando este método: +```php +$face->setWebNamespace('https://webservice.efact.es/sspp'); // Ejemplo para e-FACT +``` + --- ## Listado de métodos diff --git a/src/Common/FacturaeSigner.php b/src/Common/FacturaeSigner.php index 9b69cde..b279e31 100644 --- a/src/Common/FacturaeSigner.php +++ b/src/Common/FacturaeSigner.php @@ -175,14 +175,18 @@ public function sign($xml) { $signingTime = ($this->signingTime === null) ? time() : $this->signingTime; $certData = openssl_x509_parse($this->publicChain[0]); $certIssuer = []; - foreach ($certData['issuer'] as $item=>$rawValues) { - if (!array_key_exists($item, self::ALLOWED_OID_TYPES)) { - continue; - } - $item = self::ALLOWED_OID_TYPES[$item]; + foreach ($certData['issuer'] as $rawType=>$rawValues) { $values = is_array($rawValues) ? $rawValues : [$rawValues]; foreach ($values as $value) { - $certIssuer[] = "$item=$value"; + if ($rawType === "UNDEF" && preg_match('/^VAT[A-Z]{2}-/', $value) === 1) { + $type = "OID.2.5.4.97"; // Fix for OpenSSL <3.0.0 + } else { + if (!array_key_exists($rawType, self::ALLOWED_OID_TYPES)) { + continue; // Skip unknown OID types + } + $type = self::ALLOWED_OID_TYPES[$rawType]; + } + $certIssuer[] = "$type=$value"; } } $certIssuer = implode(', ', array_reverse($certIssuer)); diff --git a/src/Extensions/FacturaeExtension.php b/src/Extensions/FacturaeExtension.php index 73ab121..29f1c7b 100644 --- a/src/Extensions/FacturaeExtension.php +++ b/src/Extensions/FacturaeExtension.php @@ -4,6 +4,7 @@ use josemmo\Facturae\Facturae; abstract class FacturaeExtension { + /** @var Facturae */ private $fac; /** diff --git a/src/Extensions/Fb2bExtension.php b/src/Extensions/Fb2bExtension.php index d4331d6..864485e 100644 --- a/src/Extensions/Fb2bExtension.php +++ b/src/Extensions/Fb2bExtension.php @@ -4,9 +4,13 @@ use josemmo\Facturae\FacturaeCentre; class Fb2bExtension extends FacturaeExtension { + /** @var array */ private $publicSectorInfo = array(); + /** @var FacturaeCentre|null */ private $receiver = null; + /** @var FacturaeCentre[] */ private $sellerCentres = array(); + /** @var FacturaeCentre[] */ private $buyerCentres = array(); /** diff --git a/src/Face/CustomFaceClient.php b/src/Face/CustomFaceClient.php index 310e2af..6500c9c 100644 --- a/src/Face/CustomFaceClient.php +++ b/src/Face/CustomFaceClient.php @@ -5,6 +5,7 @@ class CustomFaceClient extends SoapClient { private $endpointUrl; + private $webNamespace = "https://webservice.face.gob.es"; use FaceTrait; @@ -22,6 +23,23 @@ public function __construct($endpointUrl, $publicPath, $privatePath=null, $passp } + /** + * Set custom web service namespace + * @param string $webNamespace Web service namespace to override the default one + */ + public function setWebNamespace($webNamespace) { + $this->webNamespace = $webNamespace; + } + + + /** + * @inheritdoc + */ + protected function getWebNamespace() { + return $this->webNamespace; + } + + /** * Get endpoint URL * @return string Endpoint URL diff --git a/src/Face/SoapClient.php b/src/Face/SoapClient.php index 368f7e2..f68ca1a 100644 --- a/src/Face/SoapClient.php +++ b/src/Face/SoapClient.php @@ -8,6 +8,7 @@ abstract class SoapClient { const REQUEST_EXPIRATION = 60; // In seconds + private $useExcC14n = true; use KeyPairReaderTrait; @@ -28,6 +29,15 @@ public function __construct($storeOrCertificate, $privateKey=null, $passphrase=' } + /** + * Set exclusive canonicalization mode + * @param boolean $enabled Whether to use EXC-C14N (`true`) or C14N (`false`) + */ + public function setExclusiveC14n($enabled) { + $this->useExcC14n = $enabled; + } + + /** * Get endpoint URL * @return string Endpoint URL @@ -91,8 +101,10 @@ protected function request($body) { ''; // Generate signed info + $c14nNamespace = $this->useExcC14n ? "http://www.w3.org/2001/10/xml-exc-c14n#" : "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; + $signedInfoNs = $this->useExcC14n ? ['xmlns:ds' => $ns['xmlns:ds']] : $ns; $signedInfo = '' . - '' . + '' . '' . '' . '' . @@ -104,7 +116,7 @@ protected function request($body) { '' . $bodyDigest . '' . '' . ''; - $signedInfoPayload = XmlTools::injectNamespaces($signedInfo, $ns); + $signedInfoPayload = XmlTools::injectNamespaces($signedInfo, $signedInfoNs); // Add signature and KeyInfo to header $reqHeader .= '' . diff --git a/src/Facturae.php b/src/Facturae.php index 10ec12d..e3401cb 100644 --- a/src/Facturae.php +++ b/src/Facturae.php @@ -10,7 +10,7 @@ * Class for creating electronic invoices that comply with the Spanish FacturaE format. */ class Facturae { - const VERSION = "1.7.9"; + const VERSION = "1.8.0"; const USER_AGENT = "FacturaePHP/" . self::VERSION; const SCHEMA_3_2 = "3.2"; diff --git a/src/FacturaeCentre.php b/src/FacturaeCentre.php index d9e7a67..a2f2ec0 100644 --- a/src/FacturaeCentre.php +++ b/src/FacturaeCentre.php @@ -25,18 +25,29 @@ class FacturaeCentre { const ROLE_B2B_COLLECTION_RECEIVER = "Collection receiver"; const ROLE_B2B_ISSUER = "Issuer"; + /** @var string|null */ public $code = null; + /** @var string|null */ public $role = null; + /** @var string|null */ public $name = null; + /** @var string|null */ public $firstSurname = null; + /** @var string|null */ public $lastSurname = null; + /** @var string|null */ public $description = null; + /** @var string|null */ public $address = null; + /** @var string|null */ public $postCode = null; + /** @var string|null */ public $town = null; + /** @var string|null */ public $province = null; + /** @var string */ public $countryCode = "ESP"; diff --git a/src/FacturaeItem.php b/src/FacturaeItem.php index 18077c1..5e8b252 100644 --- a/src/FacturaeItem.php +++ b/src/FacturaeItem.php @@ -12,32 +12,54 @@ class FacturaeItem { /** Non-subject operation */ const SPECIAL_TAXABLE_EVENT_NON_SUBJECT = "02"; + /** @var int|string|null */ private $articleCode = null; + /** @var string|null */ private $name = null; + /** @var string|null */ private $description = null; + /** @var int|float */ private $quantity = 1; + /** @var string */ private $unitOfMeasure = Facturae::UNIT_DEFAULT; + /** @var int|float|null */ private $unitPrice = null; + /** @var int|float|null */ private $unitPriceWithoutTax = null; private $discounts = array(); private $charges = array(); private $taxesOutputs = array(); private $taxesWithheld = array(); + /** @var string|null */ private $specialTaxableEventCode = null; + /** @var string|null */ private $specialTaxableEventReason = null; + /** @var string|null */ private $issuerContractReference = null; + /** @var string|null */ private $issuerContractDate = null; + /** @var string|null */ private $issuerTransactionReference = null; + /** @var string|null */ private $issuerTransactionDate = null; + /** @var string|null */ private $receiverContractReference = null; + /** @var string|null */ private $receiverContractDate = null; + /** @var string|null */ private $receiverTransactionReference = null; + /** @var string|null */ private $receiverTransactionDate = null; + /** @var string|null */ private $fileReference = null; + /** @var string|null */ private $fileDate = null; + /** @var string|null */ private $sequenceNumber = null; + /** @var string|null */ private $periodStart = null; + /** @var string|null */ private $periodEnd = null; diff --git a/src/FacturaeParty.php b/src/FacturaeParty.php index 863f12d..2f3fc16 100644 --- a/src/FacturaeParty.php +++ b/src/FacturaeParty.php @@ -16,38 +16,87 @@ class FacturaeParty { 'IRL', 'ITA', 'LTU', 'LUX', 'LVA', 'MLT', 'NLD', 'POL', 'PRT', 'ROU', 'SVK', 'SVN', 'SWE' ]; + /** @var boolean */ public $isLegalEntity = true; // By default is a company and not a person + /** @var string|null */ public $taxNumber = null; + /** @var string|null */ public $name = null; - // This block is only used for legal entities - public $book = null; // "Libro" - public $registerOfCompaniesLocation = null; // "Registro mercantil" - public $sheet = null; // "Hoja" - public $folio = null; // "Folio" - public $section = null; // "Sección" - public $volume = null; // "Tomo" + /** + * Libro (only for legal entities) + * @var string|null + */ + public $book = null; + /** + * Registro mercantil (only for legal entities) + * @var string|null + */ + public $registerOfCompaniesLocation = null; + /** + * Hoja (only for legal entities) + * @var string|null + */ + public $sheet = null; + /** + * Folio (only for legal entities) + * @var string|null + */ + public $folio = null; + /** + * Sección (only for legal entities) + * @var string|null + */ + public $section = null; + /** + * Tomo (only for legal entities) + * @var string|null + */ + public $volume = null; - // This block is only required for individuals + /** + * First surname (required for individuals) + * @var string|null + */ public $firstSurname = null; + /** + * Last surname (required for individuals) + * @var string|null + */ public $lastSurname = null; + /** @var string|null */ public $address = null; + /** @var string|null */ public $postCode = null; + /** @var string|null */ public $town = null; + /** @var string|null */ public $province = null; + /** @var string */ public $countryCode = "ESP"; - /** @var boolean|null */ - public $isEuropeanUnionResident = null; // By default is calculated based on the country code + /** + * NOTE: By default (when `null`) is calculated based on the country code + * @var boolean|null + */ + public $isEuropeanUnionResident = null; + /** @var string|null */ public $email = null; + /** @var string|null */ public $phone = null; + /** @var string|null */ public $fax = null; + /** @var string|null */ public $website = null; + /** @var string|null */ public $contactPeople = null; + /** @var string|null */ public $cnoCnae = null; + /** @var string|null */ public $ineTownCode = null; + /** @var FacturaeCentre[] */ public $centres = array(); diff --git a/src/FacturaeTraits/UtilsTrait.php b/src/FacturaeTraits/UtilsTrait.php index 02dea57..b94551d 100644 --- a/src/FacturaeTraits/UtilsTrait.php +++ b/src/FacturaeTraits/UtilsTrait.php @@ -10,6 +10,7 @@ * @var Facturae $this */ trait UtilsTrait { + /** @var FacturaeExtension[] */ protected $extensions = array(); /** diff --git a/tests/AbstractTest.php b/tests/AbstractTest.php index 570054f..6c6aa65 100644 --- a/tests/AbstractTest.php +++ b/tests/AbstractTest.php @@ -10,7 +10,6 @@ abstract class AbstractTest extends TestCase { const OUTPUT_DIR = __DIR__ . "/output"; const CERTS_DIR = __DIR__ . "/certs"; const FACTURAE_CERT_PASS = "1234"; - const WEBSERVICES_CERT_PASS = "IZProd2021"; const NOTIFICATIONS_EMAIL = "josemmo@pm.me"; const COOKIES_PATH = self::OUTPUT_DIR . "/cookies.txt"; diff --git a/tests/WebservicesTest.php b/tests/WebservicesTest.php index 8dd1396..0d9dd98 100644 --- a/tests/WebservicesTest.php +++ b/tests/WebservicesTest.php @@ -5,6 +5,7 @@ use josemmo\Facturae\FacturaeParty; use josemmo\Facturae\FacturaeCentre; use josemmo\Facturae\FacturaeFile; +use josemmo\Facturae\Face\CustomFaceClient; use josemmo\Facturae\Face\FaceClient; use josemmo\Facturae\Face\Faceb2bClient; @@ -50,7 +51,7 @@ private function getWsBaseInvoice() { public function testFace() { $this->checkEnv(); - $face = new FaceClient(self::CERTS_DIR . "/webservices.p12", null, self::WEBSERVICES_CERT_PASS); + $face = new FaceClient(self::CERTS_DIR . "/facturae.p12", null, self::FACTURAE_CERT_PASS); $face->setProduction(false); // Test misc. methods @@ -59,6 +60,11 @@ public function testFace() { $this->assertNotEmpty($face->getUnits('E04921501')->relaciones); $this->assertNotEmpty($face->getNifs('E04921501')->nifs); + // Test C14N (non-exclusive) + $face->setExclusiveC14n(false); + $this->assertNotEmpty($face->getStatus()->estados); + $face->setExclusiveC14n(true); + // Generate invoice $fac = $this->getWsBaseInvoice(); $fac->setBuyer(new FacturaeParty([ @@ -86,7 +92,7 @@ public function testFace() { ]) ] ])); - $fac->sign(self::CERTS_DIR . "/webservices.p12", null, self::WEBSERVICES_CERT_PASS); + $fac->sign(self::CERTS_DIR . "/facturae.p12", null, self::FACTURAE_CERT_PASS); // Send invoice $invoiceFile = new FacturaeFile(); @@ -107,13 +113,25 @@ public function testFace() { } + public function testCustomFace() { + $this->checkEnv(); + + $endpointUrl = "https://efact-pre.aoc.cat/bustia/services/EFactWebServiceProxyService"; + $customFace = new CustomFaceClient($endpointUrl, self::CERTS_DIR . "/facturae.p12", null, self::FACTURAE_CERT_PASS); + $customFace->setWebNamespace('https://webservice.efact.es/sspp'); + + // Test misc. methods + $this->assertNotEmpty($customFace->getStatus()->estados); + } + + /** * Test FACeB2B */ public function testFaceb2b() { $this->checkEnv(); - $faceb2b = new Faceb2bClient(self::CERTS_DIR . "/webservices.p12", null, self::WEBSERVICES_CERT_PASS); + $faceb2b = new Faceb2bClient(self::CERTS_DIR . "/facturae.p12", null, self::FACTURAE_CERT_PASS); $faceb2b->setProduction(false); // Test misc. methods @@ -121,6 +139,11 @@ public function testFaceb2b() { $this->assertEquals(intval($faceb2b->getRegisteredInvoices()->resultStatus->code), 0); $this->assertEquals(intval($faceb2b->getInvoiceCancellations()->resultStatus->code), 0); + // Test C14N (non-exclusive) + $faceb2b->setExclusiveC14n(false); + $this->assertNotEmpty($faceb2b->getCodes()->codes); + $faceb2b->setExclusiveC14n(true); + // Generate invoice $fac = $this->getWsBaseInvoice(); $fac->setBuyer(new FacturaeParty([ @@ -135,7 +158,7 @@ public function testFaceb2b() { "code" => "ESA789231250000", "name" => "Centro administrativo receptor" ])); - $fac->sign(self::CERTS_DIR . "/webservices.p12", null, self::WEBSERVICES_CERT_PASS); + $fac->sign(self::CERTS_DIR . "/facturae.p12", null, self::FACTURAE_CERT_PASS); // Send invoice $invoiceFile = new FacturaeFile(); diff --git a/tests/certs/facturae-private.pem b/tests/certs/facturae-private.pem index 2b03bdb..41e9cea 100644 --- a/tests/certs/facturae-private.pem +++ b/tests/certs/facturae-private.pem @@ -1,30 +1,30 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIG4Kky+Gm/VICAggA -MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECLtOZxo5MtoqBIIEyGblv9lcZ4gh -9UMmH4DvngSuZQ8V4hboG3Eqd0YVpLs8r+/CXXh11J7f6EJKwaGKIxb9s7YI6t2u -KdtNhfv8KzBpl9yQx2LPtuyb4QUcrPuOMQ6I6AneKLyvDXWFUCRw3XM/1oqlzxjP -9G4RxEsxiLJuPaTPxhSAbi7hdm7RREXmL/4+gs1fxjk98bvDAmZDpjnxgEiXeZE1 -qOlvWm6MHL/Qo3kpbk6DKk3uqpcX12T6/LwDX35zktzu6BzrukvS5tvmZH0gFJYv -+YXllJPE5OAaxLBGPVhVOZGMs5Fe9adcr0dcTzJGc5hC25pnHIl39/aiiLQ0sKUQ -MkV/rV8ChoRiA++rlC6Pcm0ucco1pYnejCPaTPfvEL2GPWp5O4CU+UQL+X+hdmd2 -vAprvikEIxT3XjrKe+iQTRdZkwIcRjpFo6qvxN2lHhIQjAJE4U3gfnHE1tCAvrA/ -fP/ThSRGI268zw0MFx2hGELwUSbt5WXV6ajXg+tWP3FUgSy/amcxeezUUqiq4KMe -OPzKFSvekkfEQjVi5R/HxeLkCbJrhDXmxhtrLKRE47kdfNB8MSaufuhJJrstvCJ+ -7UWRWl6tvWpVB0oJPD8NXq+eV8Hv9onsuie/Vg2c13Sj2Gu21QHkIOAElvktFTi0 -kV/gj2DCPWZEi71fejpHKdQzBykbMaibzNcDqiVb0tElEo0QjZhjxc69tYgSSAY2 -zLMHybeA9ea/8S4MTC2A655X/5cgwQWRcAz8Iks4bBQLknjoIC9va8/K6JfScfxi -BTH6qYwP2YbkcgmP9s9QeqZqEdV+YKfuNOWHafRlvDBAagH4pmdN1OSl12ivkiF/ -cjt1KYTl3QO+3ABrHVNK59Np6O6KlMGgBbkqs6rmSZQ9QfracSIqgJF91iACBiZJ -uCU8q6HJJRj6If+XjGd+8VTQ+lORLjhgNXxb9KXpPNVayNUrwNKWHshgXvepXFEJ -fegQwzugFEyf0cRXWWc6zp/BOUdHk+g11QqwXXuRd1C7jLJd9N3DSfCRcBNDF1M0 -Mzk+1WuPewBoH18LNty6O/jxoxe7zpLT87A8FMeRMi+x8jBVN1sUxSPSPp2wyAuF -iOgEPjlsSHi3/Hxd8li5a7J/I9my8Y85Qyq13O4OiVohlXZA3UKaRBJS+ETs3BYY -j1aqS207Hzu7kCLlSFjW7s8QXpjUuJDkSIKLiKgn2Akge6Ay8FRFENfnd28OwYDP -QRAGXFjkqfPyTiL/CRO1fnC2tCN6HbddX02UDekg7RQCCkGHv14dz8TphovvgICf -MU+5zULnHSc7YNBsvKo8laFEZ7HZfdw8caxCxcdKptbLIPDAQIpVTwiRxOXL/dbh -/jB7nA5+aC1b0EYFd6XWoyxw1fglMrypKqOt6qSvpfl4nqGbrx102izjQCnUxNPd -yMSSrnhemoGMyYoC5DdlSyiTFFMpKkqb3rVNT+eyMtCPQDVIni7g9RKWlXyPe9Gi -vj+cvdzwnFa+LWAKJDDcCdsF9hN7I/xrHdYMzzMsIR1W0leQKmWvGbjS1LMDch/h -R2VJniGFkbYFkqUw3FfoTgSadvYQD30sG+R2rnBMuADpfLwmUpA90bLSYDdEI4kL -CQ7aDxgZUOrFC+FxxMcuKw== +MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIBvzP/2jJehkCAggA +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBANEgcqWh4Z4q+YhIKCUaaABIIE +0MNoYmNFQCtXs4cFvGSS30slLW1to3y3emUm6Qgf7CVHWEHbWLMiXaD7Ak/XyUty +WXbAr41Ew4hM/gKYQGXh+imdzMG+kOYgcqf38JRhPvBkiwrCZnmCxJyC+RSbLU4w +wNmF+JwfDtw9269X1ewWwnKaceqhA71TDLfzJFKDydZGKXAgFeilZhhCq8K32VZo +qtZD58beHeldBvnazc1vTI6dP6gFbnDxE0S79h5lNsEeq8Qd2zCJ3OfuVviVGbpF +YF52BDG8T+clFuFIxg9zZQiVh4tUmuaFeAzuGbMM9FSlKkExn/9dx2xSS7rnFmTK +ordGD67XT51C7Z4pYFZ644niXQiK3YeFziSfITzSlyYCk0e8vcArlKu8+oUh2pU0 +o6h7Ue+I9mlXswY5bBzH+MXJyUK23EOVBftBnAGThoMFq/XCEX+We52X8zoLmeIF +gLdi9Pdk/LpsiLTsvHCKVdxWg4yCHGwACx8pdvcAwbDdXmYTbg/nUso1aFSNt1Oj +Mg2WtfQJ30SidmxfluWaxmuHbYUNLRsviizDyrvukv21DCK8FNlPzJrDrjn7ohyv ++gYqaguU0rPE+fCGkRDNfzJ3hy4Rhq8uYKW2E/CJUHexpk1nsvuNGtPUyA1qlbLm +pyZmGbhsZZOVNhFEtbxx1oHT/lrTcRnXo4Wl62Y8x+KBneBaQUTKSmD/5HChqSFU +UzL8iAWHDw1WQSeks1aEzIWzmdS8uxiKrCIWLlyJQE6gWnSwxj1MYSjrKSPCY57+ +E3yDWZFkRgRrFBaJsjo7iisuHKNMGIH1WUO5qIchBJaRlE9o3JJd16Cdst/ILgqj +AKqcOZ0hiN83f2KXsMv7rKi8IxpIHPtrEdvrMY0AUtVBRNj5hpv6w9TFH6ELfLES +Q6RLQ+3jkhzmi8Z1xeF94Kv/r5+ZhBrMuauqrbPsdT0VK/Y9eqnZCSaflP58eIN+ +i28a09xzp5N+c4pproaKHLT/iL1FOHNJb1xJ7aYIkLcXmbdNZLcAPlWPtkatfwZ7 +MfUijJCWCu0EFl9+zhmOyDmC2RCMnL4MxeOD7LtqEE2DfECWmk7rVIIQ20Orvr22 +6WH8JyMRlq/2o0TWE6/j1PPN3RmdMEJwSsLmAcQy0Px69GMC2w8HidkdDwCKRLvo +thy+gfIShXTCCwY0N2IwxUNv17XIFV+uIatR83evDEOqMypybhGA9sXHrGKJz9/e +AquF82caXsULkvdbxtd+PPn/GAP9+kY4HfWfrlWkgXk7PMQtHJT+JSfMza8qKtnV +p+cruUAvrS0DgApLWxQt2TDPPXdGxlWAJmeu2cNVUNGfbTfWx4w8sSQy0zQrG26e +X3otyVIf8fs7cvQxox9EBLcLxFwQiMeqz96QVs3ymFh1kpUthBW6894pb1RT3V66 +DtIpATu8F1Vf1Umas/TgMzJRnA0CUzPXY6xjIPGMc08kKYK8wnhEmHqT8929PGm/ +0l1D+F7vGKsbZy2vn/bdR+EdKpS7WQbysRtGuOXyWfjzfxqXvEg+dO7sNjmCBz7W +tdhZSfdBQ8knPIScdX4bkABZhSat3pGbk/HcZ4k1AbamPh63/AHT6XIRYqPxyLUU +O6kkEbFOeT76+wGstBGYPQICGUjd3EqBlJLSBEkIiWY8 -----END ENCRYPTED PRIVATE KEY----- \ No newline at end of file diff --git a/tests/certs/facturae-public.pem b/tests/certs/facturae-public.pem index 22dd397..8938204 100644 --- a/tests/certs/facturae-public.pem +++ b/tests/certs/facturae-public.pem @@ -1,43 +1,43 @@ -----BEGIN CERTIFICATE----- -MIIHhjCCBm6gAwIBAgIQSOSlyjvRFUlfo/hUFNAvqDANBgkqhkiG9w0BAQsFADBL +MIIHoDCCBoigAwIBAgIQc/g6LlAaVg9l7w+qq1iLnzANBgkqhkiG9w0BAQsFADBL MQswCQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVz -MRkwFwYDVQQDDBBBQyBGTk1UIFVzdWFyaW9zMB4XDTIwMTEwNTEzMDQyMFoXDTI0 -MTEwNTEzMDQyMFowgYUxCzAJBgNVBAYTAkVTMRgwFgYDVQQFEw9JRENFUy05OTk5 -OTk5OVIxEDAOBgNVBCoMB1BSVUVCQVMxGjAYBgNVBAQMEUVJREFTIENFUlRJRklD +MRkwFwYDVQQDDBBBQyBGTk1UIFVzdWFyaW9zMB4XDTI0MDMxMTE0MDUzMFoXDTI4 +MDMxMTE0MDUzMFowgYUxCzAJBgNVBAYTAkVTMRgwFgYDVQQFEw9JRENFUy05OTk5 +OTk3MkMxEDAOBgNVBCoMB1BSVUVCQVMxGjAYBgNVBAQMEUVJREFTIENFUlRJRklD QURPMS4wLAYDVQQDDCVFSURBUyBDRVJUSUZJQ0FETyBQUlVFQkFTIC0gOTk5OTk5 -OTlSMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAujAnB2L5X2Bm42S5 -f/axKFu1QsAcZGJAeYELZZJ04jriBu3E8V3Rus3tUxfQ+ylqBm0bNWgHfP+gekos -HaYoJNQmAVBuwpd183uHksTRUtbeOAFS2xd7v29stM7ARkec+WVV+SK8G6HECIB0 -VIAMoB2tVs0y6XRVRcjE4I7kH1h3ZbMIzvW43B4hxruYtXcvozGwvZpxQKVrjEY8 -IXH5+aXHM8WLCba4I06FyhvI+2/9WUPN2YvDoml7lQM4edgepTEZifq2ZPHGpCC5 -NhSXj2ab5FtnGTMgUaWH6tCljT0kOdfJBOHnIWOw4dBdgkik2CuxwGyMrq/P5VqQ -IC2hXQIDAQABo4IEKTCCBCUwgZIGA1UdEQSBijCBh4Edc29wb3J0ZV90ZWNuaWNv -X2NlcmVzQGZubXQuZXOkZjBkMRgwFgYJKwYBBAGsZgEEDAk5OTk5OTk5OVIxGjAY -BgkrBgEEAaxmAQMMC0NFUlRJRklDQURPMRQwEgYJKwYBBAGsZgECDAVFSURBUzEW -MBQGCSsGAQQBrGYBAQwHUFJVRUJBUzAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQE -AwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDBAYIKwYBBQUHAwIwHQYDVR0OBBYEFE5a -HiQQRwVYJzmmkfG/i5MxmMNdMB8GA1UdIwQYMBaAFLHUT8QjefpEBQnG6znP6DWw -uCBkMIGCBggrBgEFBQcBAQR2MHQwPQYIKwYBBQUHMAGGMWh0dHA6Ly9vY3NwdXN1 -LmNlcnQuZm5tdC5lcy9vY3NwdXN1L09jc3BSZXNwb25kZXIwMwYIKwYBBQUHMAKG -J2h0dHA6Ly93d3cuY2VydC5mbm10LmVzL2NlcnRzL0FDVVNVLmNydDCCARUGA1Ud -IASCAQwwggEIMIH6BgorBgEEAaxmAwoBMIHrMCkGCCsGAQUFBwIBFh1odHRwOi8v -d3d3LmNlcnQuZm5tdC5lcy9kcGNzLzCBvQYIKwYBBQUHAgIwgbAMga1DZXJ0aWZp -Y2FkbyBjdWFsaWZpY2FkbyBkZSBmaXJtYSBlbGVjdHLDs25pY2EuIFN1amV0byBh -IGxhcyBjb25kaWNpb25lcyBkZSB1c28gZXhwdWVzdGFzIGVuIGxhIERQQyBkZSBs -YSBGTk1ULVJDTSBjb24gTklGOiBRMjgyNjAwNC1KIChDL0pvcmdlIEp1YW4gMTA2 -LTI4MDA5LU1hZHJpZC1Fc3Bhw7FhKTAJBgcEAIvsQAEAMIG6BggrBgEFBQcBAwSB -rTCBqjAIBgYEAI5GAQEwCwYGBACORgEDAgEPMBMGBgQAjkYBBjAJBgcEAI5GAQYB -MHwGBgQAjkYBBTByMDcWMWh0dHBzOi8vd3d3LmNlcnQuZm5tdC5lcy9wZHMvUERT -QUNVc3Vhcmlvc19lcy5wZGYTAmVzMDcWMWh0dHBzOi8vd3d3LmNlcnQuZm5tdC5l -cy9wZHMvUERTQUNVc3Vhcmlvc19lbi5wZGYTAmVuMIG1BgNVHR8Ega0wgaowgaeg -gaSggaGGgZ5sZGFwOi8vbGRhcHVzdS5jZXJ0LmZubXQuZXMvY249Q1JMMzc0OCxj -bj1BQyUyMEZOTVQlMjBVc3VhcmlvcyxvdT1DRVJFUyxvPUZOTVQtUkNNLGM9RVM/ -Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5hcnk/YmFzZT9vYmplY3RjbGFz -cz1jUkxEaXN0cmlidXRpb25Qb2ludDANBgkqhkiG9w0BAQsFAAOCAQEAH4t5/v/S -Lsm/dXRDw4QblCmTX+5pgXJ+4G1Lb3KTSPtDJ0UbQiAMUx+iqDDOoMHU5H7po/HZ -LJXgNwvKLoiLbl5/q6Mqasif87fa6awNkuz/Y6dvXw0UOJh+Ud/Wrk0EyaP9ZtrL -VsraUOobNyS6g+lOrCxRrNxGRK2yAeotO6LEo1y3b7CB+Amd2jDq8lY3AtCYlrhu -CaTf0AD9IBYYmigHzFD/VH5a8uG95l6J85FQG7tMsG6UQHFM2EmNhpbrYH+ihetz -3UhzcC5Fd/P1X7pGBymQgbCyBjCRf/HEVzyoHL72uMp2I4JXX4v8HABZT8xtlDY4 -LE0am9keJhaNcg== +NzJDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArX6zxub5QjNrWl5a +sMPracpf+dxfRFA49u3+18Ul0EdeRVyqYyeeGfoO5dL2U4PoyEkGSCVl0pf3KXtB +FCarYimaLe1GujFBwUMM3ywsJpV04vik/LRYKSTgLIXV2iiDsyThZ9vkD/nf5CJh +kxJxRtEZ6znJjCoZOrKzcSEbHvKXVe0AtJnADuUyThw/6a0kdKKPB3RdhpjYxlKe +pe9UOWewvTVYyxmoqNeQ1zj/dsYUP4gIdOo1NbjQ+OP1rw30yZSCx9IziW7LKmJN +paehNl0zSXyFRiZEOT7F/26lBsx+lRucYi8B7p7oek58Ewno2RXvR78ZVihzlhqr +FtWNjQIDAQABo4IEQzCCBD8wcQYDVR0RBGowaKRmMGQxGDAWBgkrBgEEAaxmAQQM +CTk5OTk5OTcyQzEaMBgGCSsGAQQBrGYBAwwLQ0VSVElGSUNBRE8xFDASBgkrBgEE +AaxmAQIMBUVJREFTMRYwFAYJKwYBBAGsZgEBDAdQUlVFQkFTMAwGA1UdEwEB/wQC +MAAwDgYDVR0PAQH/BAQDAgXgMCoGA1UdJQQjMCEGCCsGAQUFBwMCBgorBgEEAYI3 +CgMMBgkqhkiG9y8BAQUwHQYDVR0OBBYEFFB7rD8U2UiFZ+YXsxDmRtmFq2O4MB8G +A1UdIwQYMBaAFLHUT8QjefpEBQnG6znP6DWwuCBkMIGCBggrBgEFBQcBAQR2MHQw +PQYIKwYBBQUHMAGGMWh0dHA6Ly9vY3NwdXN1LmNlcnQuZm5tdC5lcy9vY3NwdXN1 +L09jc3BSZXNwb25kZXIwMwYIKwYBBQUHMAKGJ2h0dHA6Ly93d3cuY2VydC5mbm10 +LmVzL2NlcnRzL0FDVVNVLmNydDCCARUGA1UdIASCAQwwggEIMIH6BgorBgEEAaxm +AwoBMIHrMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNz +LzCBvQYIKwYBBQUHAgIwgbAMga1DZXJ0aWZpY2FkbyBjdWFsaWZpY2FkbyBkZSBm +aXJtYSBlbGVjdHLDs25pY2EuIFN1amV0byBhIGxhcyBjb25kaWNpb25lcyBkZSB1 +c28gZXhwdWVzdGFzIGVuIGxhIERQQyBkZSBsYSBGTk1ULVJDTSBjb24gTklGOiBR +MjgyNjAwNC1KIChDL0pvcmdlIEp1YW4gMTA2LTI4MDA5LU1hZHJpZC1Fc3Bhw7Fh +KTAJBgcEAIvsQAEAMIG6BggrBgEFBQcBAwSBrTCBqjAIBgYEAI5GAQEwCwYGBACO +RgEDAgEPMBMGBgQAjkYBBjAJBgcEAI5GAQYBMHwGBgQAjkYBBTByMDcWMWh0dHBz +Oi8vd3d3LmNlcnQuZm5tdC5lcy9wZHMvUERTQUNVc3Vhcmlvc19lcy5wZGYTAmVz +MDcWMWh0dHBzOi8vd3d3LmNlcnQuZm5tdC5lcy9wZHMvUERTQUNVc3Vhcmlvc19l +bi5wZGYTAmVuMIHkBgNVHR8EgdwwgdkwgdaggdOggdCGgZ5sZGFwOi8vbGRhcHVz +dS5jZXJ0LmZubXQuZXMvY249Q1JMVTg2OSxjbj1BQyUyMEZOTVQlMjBVc3Vhcmlv +cyxvdT1DRVJFUyxvPUZOTVQtUkNNLGM9RVM/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdDtiaW5hcnk/YmFzZT9vYmplY3RjbGFzcz1jUkxEaXN0cmlidXRpb25Qb2lu +dIYtaHR0cDovL3d3dy5jZXJ0LmZubXQuZXMvY3Jsc2FjdXN1L0NSTFU4NjkuY3Js +MA0GCSqGSIb3DQEBCwUAA4IBAQA+YKUUF+kIW32y+vbAmSr+8aYswNC7NPV/utEq +uxX3VBGL3xLDUgkQ+5iiW7G194p93Ynnl639g070Q0SmuOPlQhgqYIMrYZbm8L1e +AlbvqLsSIeRVhPaSbHzwbmUG5hQ7hZQ4ClG2xZcOC2auPb6UOLMEpSCs2TtuYZmn +Ivh+t9YRrfFAUSLB315GHycdtrjOeEz68Dz+2UdvSmla3OO3X7XgDKqSSlul2vce +Znp+cy07trzwiwyN+lq3icNT3bgu8eXeu05kvLklADjbNq509n3KSnAWRC44i1Xg +5zXzm95KmcidynauRr6XqU0ENKHRLEWn4CltdYFkb6VtvuLC -----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/certs/facturae.p12 b/tests/certs/facturae.p12 index 5867c10..dd9b424 100644 Binary files a/tests/certs/facturae.p12 and b/tests/certs/facturae.p12 differ diff --git a/tests/certs/webservices.p12 b/tests/certs/webservices.p12 deleted file mode 100644 index 53c7051..0000000 Binary files a/tests/certs/webservices.p12 and /dev/null differ