end2end = "NOTPROVIDED"; } function setEnd2End($end2end) { $this->end2end = $this->normalizeString($end2end); } function setIban($iban) { $this->iban = str_replace(' ','',$iban); } function setBic($bic) { $this->bic = $bic; } function setName($name) { $this->kontoinhaber = $this->normalizeString($name); } function setVerwendungszweck($verwendungszweck) { $this->verwendungszweck = $this->normalizeString($verwendungszweck); } function setBetrag($betrag) { $this->amount = $betrag; } /* * Methode zum Setzen des Mandates - notwendig beim Generieren von Lastschriften. Wenn gewünscht kann * nur die Mandats-ID gesetzt werden, hierbei wird das aktuelle Tagesdatum als Datum der Mandatserteilung * genommen. Das Datum ist im Format (YYYY-mm-dd - bsp. 2013-11-02 zu übergeben) * * @param String $id * @param String $mandatDatum * @param boolean $mandatAenderung - true wenn das Mandat seit letzer Erteilung geändert wurde */ function setMandat($id, $mandatDatum = null, $mandatAenderung = true) { $this->mandatId = $id; $this->mandatAenderung = $mandatAenderung; if (!isset($mandatDatum)) { $this->mandatDatum = date('Y-m-d', time()); } else { $this->mandatDatum = $mandatDatum; } } function normalizeString($input) { // Only below characters can be used within the XML tags according the guideline. // a b c d e f g h i j k l m n o p q r s t u v w x y z // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z // 0 1 2 3 4 5 6 7 8 9 // / - ? : ( ) . , ‘ + // Space // // Create a normalized array and cleanup the string $XMLText for unexpected characters in names $normalizeChars = array( 'Á'=>'A', 'À'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Å'=>'A', 'Ä'=>'Ae', 'Æ'=>'AE', 'Ç'=>'C', 'É'=>'E', 'È'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Í'=>'I', 'Ì'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ð'=>'Eth', 'Ñ'=>'N', 'Ó'=>'O', 'Ò'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ú'=>'U', 'Ù'=>'U', 'Û'=>'U', 'Ü'=>'Ue', 'Ý'=>'Y', 'á'=>'a', 'à'=>'a', 'â'=>'a', 'ã'=>'a', 'å'=>'a', 'ä'=>'ae', 'æ'=>'ae', 'ç'=>'c', 'é'=>'e', 'è'=>'e', 'ê'=>'e', 'ë'=>'e', 'í'=>'i', 'ì'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'eth', 'ñ'=>'n', 'ó'=>'o', 'ò'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'oe', 'ø'=>'o', 'ú'=>'u', 'ù'=>'u', 'û'=>'u', 'ü'=>'ue', 'ý'=>'y', 'ß'=>'ss', 'þ'=>'thorn', 'ÿ'=>'y', '&'=>'u.', '@'=>'at', '#'=>'h', '$'=>'s', '%'=>'perc', '^'=>'-','*'=>'-' ); $output = strtr($input, $normalizeChars); return $output; } } class SepaXmlCreator { var $buchungssaetze = array(); var $accountName, $accountIban, $accountBic; var $offset = 0, $fixedDate; var $waehrung = "EUR"; // Mode = 1 -> Überweisung / Mode = 2 -> Basislastschrift var $mode = 1; var $isFirst = true; // Gläubiger-ID var $glaeubigerId; // XML-Errors private $xmlerrors; function setDebitorValues($name, $iban, $bic) { trigger_error('Use setAccountValues($name, $iban, $bic) instead', E_USER_DEPRECATED); $this->setAccountValues($name, $iban, $bic); } function setAccountValues($name, $iban, $bic) { $this->accountName = $name; $this->accountIban = $iban; $this->accountBic = $bic; } function setGlaeubigerId($glaeubigerId) { $this->glaeubigerId = $glaeubigerId; } function setCurrency($currency) { $this->waehrung = $currency; } function addBuchung($buchungssatz) { array_push($this->buchungssaetze, $buchungssatz); } function setAusfuehrungOffset($offset) { $this->offset = $offset; } function setAusfuehrungDatum($datum) { $this->fixedDate = $datum; } function generateSammelueberweisungXml() { // Set Mode = 1 -> Sammelüberweisung $this->mode = 1; return $this->getGeneratedXml(); } function generateBasislastschriftXml() { // Set Mode = 2 -> Basislastschrift $this->mode = 2; return $this->getGeneratedXml(); } function setIsFolgelastschrift() { $this->isFirst = false; } function getGeneratedXml() { $dom = new DOMDocument('1.0', 'utf-8'); // Build Document-Root $document = $dom->createElement('Document'); if ($this->mode == 2) { $document->setAttribute('xmlns', 'urn:iso:std:iso:20022:tech:xsd:pain.008.002.02'); $document->setAttribute('xsi:schemaLocation', 'urn:iso:std:iso:20022:tech:xsd:pain.008.002.02 pain.008.002.02.xsd'); } else { $document->setAttribute('xmlns', 'urn:iso:std:iso:20022:tech:xsd:pain.001.002.03'); $document->setAttribute('xsi:schemaLocation', 'urn:iso:std:iso:20022:tech:xsd:pain.001.002.03 pain.001.002.03.xsd'); } $document->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $dom->appendChild($document); // Build Content-Root if ($this->mode == 2) { $content = $dom->createElement('CstmrDrctDbtInitn'); } else { $content = $dom->createElement('CstmrCdtTrfInitn'); } $document->appendChild($content); // Build Header $header = $dom->createElement('GrpHdr'); $content->appendChild($header); $creationTime = time(); // Msg-ID $header->appendChild($dom->createElement('MsgId', $this->accountBic . '00' . date('YmdHis', $creationTime))); $header->appendChild($dom->createElement('CreDtTm', date('Y-m-d', $creationTime) . 'T' . date('H:i:s', $creationTime) . '.000Z')); $header->appendChild($dom->createElement('NbOfTxs', count($this->buchungssaetze))); $header->appendChild($initatorName = $dom->createElement('InitgPty')); $initatorName->appendChild($dom->createElement('Nm', $this->accountName)); // PaymentInfo $paymentInfo = $dom->createElement('PmtInf'); $content->appendChild($paymentInfo); $paymentInfo->appendChild($dom->createElement('PmtInfId', 'PMT-ID0-' . date('YmdHis', $creationTime))); switch ($this->mode) { case 2: // 2 = Basislastschrift $paymentInfo->appendChild($dom->createElement('PmtMtd', 'DD')); break; default: // Default / 1 = Überweisung $paymentInfo->appendChild($dom->createElement('PmtMtd', 'TRF')); break; } $paymentInfo->appendChild($dom->createElement('BtchBookg', 'false')); $paymentInfo->appendChild($dom->createElement('NbOfTxs', count($this->buchungssaetze))); $paymentInfo->appendChild($dom->createElement('CtrlSum', number_format($this->getUmsatzsumme(), 2, '.', ''))); $paymentInfo->appendChild($tmp1 = $dom->createElement('PmtTpInf')); $tmp1->appendChild($tmp2 = $dom->createElement('SvcLvl')); $tmp2->appendChild($dom->createElement('Cd', 'SEPA')); if ($this->mode == 2) { // zusätzliche Attribute für Lastschriften $tmp1->appendChild($tmp2 = $dom->createElement('LclInstrm')); $tmp2->appendChild($dom->createElement('Cd', 'CORE')); if ($this->isFirst) { $tmp1->appendChild($dom->createElement('SeqTp', 'FRST')); } else { $tmp1->appendChild($dom->createElement('SeqTp', 'RCUR')); } } // Ausführungsdatum berechnen if (isset($this->fixedDate)) { $ausfuehrungsdatum = $this->fixedDate; } else { $ausfuehrungszeit = $creationTime; if ($this->offset > 0) { $ausfuehrungszeit = $ausfuehrungszeit + (24 * 3600 * $this->offset); } $ausfuehrungsdatum = date('Y-m-d', $ausfuehrungszeit); } if ($this->mode == 2) { $paymentInfo->appendChild($dom->createElement('ReqdColltnDt', $ausfuehrungsdatum)); } else { $paymentInfo->appendChild($dom->createElement('ReqdExctnDt', $ausfuehrungsdatum)); } // eigene Account-Daten Daten if ($this->mode == 2) { $paymentInfo->appendChild($tmp1 = $dom->createElement('Cdtr')); } else { $paymentInfo->appendChild($tmp1 = $dom->createElement('Dbtr')); } $tmp1->appendChild($dom->createElement('Nm', $this->accountName)); if ($this->mode == 2) { $paymentInfo->appendChild($tmp1 = $dom->createElement('CdtrAcct')); } else { $paymentInfo->appendChild($tmp1 = $dom->createElement('DbtrAcct')); } $tmp1->appendChild($tmp2 = $dom->createElement('Id')); $tmp2->appendChild($dom->createElement('IBAN', $this->accountIban)); if ($this->mode == 2) { $paymentInfo->appendChild($tmp1 = $dom->createElement('CdtrAgt')); } else { $paymentInfo->appendChild($tmp1 = $dom->createElement('DbtrAgt')); } $tmp1->appendChild($tmp2 = $dom->createElement('FinInstnId')); $tmp2->appendChild($dom->createElement('BIC', $this->accountBic)); $paymentInfo->appendChild($dom->createElement('ChrgBr', 'SLEV')); if ($this->mode == 2) { $paymentInfo->appendChild($tmp1 = $dom->createElement('CdtrSchmeId')); $tmp1->appendChild($tmp2 = $dom->createElement('Id')); $tmp2->appendChild($tmp3 = $dom->createElement('PrvtId')); $tmp3->appendChild($tmp4 = $dom->createElement('Othr')); $tmp4->appendChild($dom->createElement('Id', $this->glaeubigerId)); $tmp4->appendChild($tmp5 = $dom->createElement('SchmeNm')); $tmp5->appendChild($dom->createElement('Prtry', 'SEPA')); } // Buchungssätze hinzufügen foreach ($this->buchungssaetze as $buchungssatz) { if ($this->mode == 2) { $paymentInfo->appendChild($buchung = $dom->createElement('DrctDbtTxInf')); } else { $paymentInfo->appendChild($buchung = $dom->createElement('CdtTrfTxInf')); } // End2End setzen if (isset($buchungssatz->end2end)) { $buchung->appendChild($tmp1 = $dom->createElement('PmtId')); $tmp1->appendChild($dom->createElement('EndToEndId', $buchungssatz->end2end)); } // Betrag if ($this->mode == 2) { $buchung->appendChild($tmp2 = $dom->createElement('InstdAmt', number_format($buchungssatz->amount, 2, '.', ''))); $tmp2->setAttribute('Ccy', $this->waehrung); } else { $buchung->appendChild($tmp1 = $dom->createElement('Amt')); $tmp1->appendChild($tmp2 = $dom->createElement('InstdAmt', number_format($buchungssatz->amount, 2, '.', ''))); $tmp2->setAttribute('Ccy', $this->waehrung); } if ($this->mode == 2) { // Lastschrift -> Mandatsinformationen $buchung->appendChild($tmp1 = $dom->createElement('DrctDbtTx')); $tmp1->appendChild($tmp2 = $dom->createElement('MndtRltdInf')); $tmp2->appendChild($dom->createElement('MndtId', $buchungssatz->mandatId)); $tmp2->appendChild($dom->createElement('DtOfSgntr', $buchungssatz->mandatDatum)); if ($buchungssatz->mandatAenderung) { $tmp2->appendChild($dom->createElement('AmdmntInd', 'true')); } else { $tmp2->appendChild($dom->createElement('AmdmntInd', 'false')); } } // Institut if ($this->mode == 2) { $buchung->appendChild($tmp1 = $dom->createElement('DbtrAgt')); } else { $buchung->appendChild($tmp1 = $dom->createElement('CdtrAgt')); } $tmp1->appendChild($tmp2 = $dom->createElement('FinInstnId')); $tmp2->appendChild($dom->createElement('BIC', $buchungssatz->bic)); // Inhaber if ($this->mode == 2) { $buchung->appendChild($tmp1 = $dom->createElement('Dbtr')); } else { $buchung->appendChild($tmp1 = $dom->createElement('Cdtr')); } $tmp1->appendChild($dom->createElement('Nm', $buchungssatz->kontoinhaber)); // IBAN if ($this->mode == 2) { $buchung->appendChild($tmp1 = $dom->createElement('DbtrAcct')); } else { $buchung->appendChild($tmp1 = $dom->createElement('CdtrAcct')); } $tmp1->appendChild($tmp2 = $dom->createElement('Id')); $tmp2->appendChild($dom->createElement('IBAN', $buchungssatz->iban)); if ($this->mode == 2) { $buchung->appendChild($tmp1 = $dom->createElement('UltmtDbtr')); $tmp1->appendChild($dom->createElement('Nm', $buchungssatz->kontoinhaber)); } // Verwendungszweck if (strlen($buchungssatz->verwendungszweck) > 0) { $buchung->appendChild($tmp1 = $dom->createElement('RmtInf')); $tmp1->appendChild($dom->createElement('Ustrd', $buchungssatz->verwendungszweck)); } } // XML exportieren return $dom->saveXML(); } function getUmsatzsumme() { $betrag = 0; foreach ($this->buchungssaetze as $buchungssatz) { $betrag = $betrag + $buchungssatz->amount; } return $betrag; } public function validateBasislastschriftXml($xmlfile) { return $this->validateXML($xmlfile, 'pain.008.002.02.xsd'); } public function validateUeberweisungXml($xmlfile) { return $this->validateXML($xmlfile, 'pain.001.002.03.xsd'); } protected function validateXML($xmlfile, $xsdfile) { libxml_use_internal_errors(true); $feed = new DOMDocument(); $result = $feed->load($xmlfile); if ($result === false) { $this->xmlerrors[] = "Document is not well formed\n"; } if (@($feed->schemaValidate(dirname(__FILE__) . '/' . $xsdfile))) { return true; } else { $this->xmlerrors[] = "! Document is not valid:\n"; $errors = libxml_get_errors(); foreach ($errors as $error) { $this->xmlerrors[] = "---\n" . sprintf("file: %s, line: %s, column: %s, level: %s, code: %s\nError: %s", basename($error->file), $error->line, $error->column, $error->level, $error->code, $error->message ); } } return false; } public function printXmlErrors() { if (!is_array($this->xmlerrors)) return; foreach ($this->xmlerrors as $error) { echo $error; } } } ?>