* @copyright 2007-2017 Decanet SA * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) * International Registered Trademark & Property of PrestaShop SA */ /** * SEPA SSD (Sepa Direct Debit) 2.0 * This class creates a Sepa Direct Debit xml File. */ class SepaDD { private $config; private $xml; private $batch_array = array(); public function __construct($config) { //Check the config $config_validator = $this->validateConfig($config); if ($config_validator) { $this->config = $config; } else { throw new Exception('Invalid config file: '.$config_validator); } //Prepare the document $this->prepareDocument(); $this->createGroupHeader(); } /** * Build the main document node and set xml namespaces. */ private function prepareDocument() { //Create the xml Instance $this->xml = new DOMDocument('1.0', 'UTF-8'); //Create the document node $document_node = $this->xml->createElement('Document'); //set the namespace $document_attribute_xmlns = $this->xml->createAttribute('xmlns'); if (isset($this->config['version']) && $this->config['version'] == '3') { $document_attribute_xmlns->value = 'urn:iso:std:iso:20022:tech:xsd:pain.008.001.03'; } else { $document_attribute_xmlns->value = 'urn:iso:std:iso:20022:tech:xsd:pain.008.001.02'; } $document_node->appendChild($document_attribute_xmlns); //set the namespace url $document_attribute_xmlnsxsi = $this->xml->createAttribute('xmlns:xsi'); $document_attribute_xmlnsxsi->value = 'http://www.w3.org/2001/XMLSchema-instance'; $document_node->appendChild($document_attribute_xmlnsxsi); //create the Direct Debit node $cstmr_drct_dbt_initn_node = $this->xml->createElement('CstmrDrctDbtInitn'); $document_node->appendChild($cstmr_drct_dbt_initn_node); //append the document node to the xml Instance $this->xml->appendChild($document_node); } /** * Function to create the GroupHeader (GrpHdr) in the CstmrDrctDbtInit Node */ private function createGroupHeader() { //Retrieve the CstmrDrctDbtInitn node $cstmr_drct_dbt_initn_node = $this->getCstmrDrctDbtInitnNode(); //Create the required nodes $grp_hdr_node = $this->xml->createElement('GrpHdr'); $msg_id_node = $this->xml->createElement('MsgId'); $cre_dt_tm_node = $this->xml->createElement('CreDtTm'); $nb_of_txs_node = $this->xml->createElement('NbOfTxs'); $ctrl_sum_node = $this->xml->createElement('CtrlSum'); $initg_pty_node = $this->xml->createElement('InitgPty'); $nm_node = $this->xml->createElement('Nm'); //Set the values for the nodes $msg_id_node->nodeValue = $this->makeMsgId(); $cre_dt_tm_node->nodeValue = date('c'); //if using lower than PHP 5.4.0, there is no ENT_XML1 if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $nm_node->nodeValue = htmlentities($this->config['name'], ENT_XML1, 'UTF-8'); } else { $nm_node->nodeValue = htmlentities($this->config['name'], ENT_QUOTES, 'UTF-8'); } //Append the nodes $initg_pty_node->appendChild($nm_node); $grp_hdr_node->appendChild($msg_id_node); $grp_hdr_node->appendChild($cre_dt_tm_node); // $grp_hdr_node->appendChild($reqd_exctn_dt_tm_node); $grp_hdr_node->appendChild($nb_of_txs_node); $grp_hdr_node->appendChild($ctrl_sum_node); $grp_hdr_node->appendChild($initg_pty_node); //Append the header to its parent $cstmr_drct_dbt_initn_node->appendChild($grp_hdr_node); } /** * Public function to add payments * @param the payment to be added in the form of an array * @throws Exception if payment array is invalid. */ public function addPayment($payment) { //First validate the payment array $validation_result = $this->validatePayment($payment); if ($validation_result !== true) { throw new Exception('Invalid Payment, error with: '.$validation_result); } //Get the CstmrDrctDbtInitnNode $cstmr_drct_dbt_initn_node = $this->getCstmrDrctDbtInitnNode(); //if there is a batch, the batch will create this information. if ($this->config['batch'] == false) { $pmt_inf_node = $this->xml->createElement('PmtInf'); $pmt_inf_id_node = $this->xml->createElement('PmtInfId'); $pmt_mtd_node = $this->xml->createElement('PmtMtd'); $btch_bookg_node = $this->xml->createElement('BtchBookg'); $nb_of_txs_node = $this->xml->createElement('NbOfTxs'); $ctrl_sum_node = $this->xml->createElement('CtrlSum'); $pmt_tp_inf_node = $this->xml->createElement('PmtTpInf'); $svc_lvl_node = $this->xml->createElement('SvcLvl'); $cd_svc_lvl_node = $this->xml->createElement('Cd'); $lcl_instrm_node = $this->xml->createElement('LclInstrm'); $cd_lcl_instrm_node = $this->xml->createElement('Cd'); $seq_tp_node = $this->xml->createElement('SeqTp'); $reqd_colltn_dt_node = $this->xml->createElement('ReqdColltnDt'); $cdtr_node = $this->xml->createElement('Cdtr'); $nm_cdtr_node = $this->xml->createElement('Nm'); $cdtr_acct_node = $this->xml->createElement('CdtrAcct'); $id_cdtr_acct_node = $this->xml->createElement('Id'); $iban_cdtr_acct_node = $this->xml->createElement('IBAN'); if (isset($this->config['BIC'])) { $cdtr_agt_node = $this->xml->createElement('CdtrAgt'); $fin_instn_id_cdtr_agt_node = $this->xml->createElement('FinInstnId'); if (isset($this->config['version']) && $this->config['version'] == '3') { $bic_cdtr_agt_node = $this->xml->createElement('BICFI'); } else { $bic_cdtr_agt_node = $this->xml->createElement('BIC'); } } $chrg_br_node = $this->xml->createElement('ChrgBr'); $cdtr_schme_id_node = $this->xml->createElement('CdtrSchmeId'); $nm_cdtr_schme_id_node = $this->xml->createElement('Nm'); $id_cdtr_schme_id_node = $this->xml->createElement('Id'); $prvt_id_node = $this->xml->createElement('PrvtId'); $othr_node = $this->xml->createElement('Othr'); $id_othr_node = $this->xml->createElement('Id'); $schme_nm_node = $this->xml->createElement('SchmeNm'); $prtry_node = $this->xml->createElement('Prtry'); $pmt_inf_id_node->nodeValue = $this->makeId(); $pmt_mtd_node->nodeValue = 'DD';//Direct Debit $btch_bookg_node->nodeValue = 'false'; $nb_of_txs_node->nodeValue = '1'; $ctrl_sum_node->nodeValue = $this->intToDecimal($payment['amount']); $cd_svc_lvl_node->nodeValue = 'SEPA'; $cd_lcl_instrm_node->nodeValue = 'CORE'; $seq_tp_node->nodeValue = $payment['type'];//Define a check for: FRST RCUR OOFF FNAL $reqd_colltn_dt_node->nodeValue = $payment['collection_date']; if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $nm_cdtr_node->nodeValue = htmlentities($this->config['name'], ENT_XML1, 'UTF-8'); } else { $nm_cdtr_node->nodeValue = htmlentities($this->config['name'], ENT_QUOTES, 'UTF-8'); } $iban_cdtr_acct_node->nodeValue = $this->config['IBAN']; if (isset($this->config['BIC'])) { $bic_cdtr_agt_node->nodeValue = $this->config['BIC']; } $chrg_br_node->nodeValue = 'SLEV'; if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $nm_cdtr_schme_id_node->nodeValue = htmlentities($this->config['name'], ENT_XML1, 'UTF-8'); } else { $nm_cdtr_schme_id_node->nodeValue = htmlentities($this->config['name'], ENT_QUOTES, 'UTF-8'); } $id_othr_node->nodeValue = $this->config['creditor_id']; $prtry_node->nodeValue = 'SEPA'; } else {//Get the batch node for this kind of payment to add the DrctDbtTxInf node. $batch = $this->getBatch($payment['type'], $payment['collection_date']); } //Create the payment node. $drct_dbt_tx_inf_node = $this->xml->createElement('DrctDbtTxInf'); $pmt_id_node = $this->xml->createElement('PmtId'); $end_to_end_id_node = $this->xml->createElement('EndToEndId'); $instd_amt_node = $this->xml->createElement('InstdAmt'); $drct_dbt_tx_node = $this->xml->createElement('DrctDbtTx'); $mndt_rltd_inf_node = $this->xml->createElement('MndtRltdInf'); $mndt_id_node = $this->xml->createElement('MndtId'); $dt_of_sgntr_node = $this->xml->createElement('DtOfSgntr'); if (isset($payment['BIC'])) { $dbtr_agt_node = $this->xml->createElement('DbtrAgt'); $fin_instn_id_dbtr_agt_node = $this->xml->createElement('FinInstnId'); if (isset($this->config['version']) && $this->config['version'] == '3') { $bic_dbtr_agt_node = $this->xml->createElement('BICFI'); } else { $bic_dbtr_agt_node = $this->xml->createElement('BIC'); } } $dbtr_node = $this->xml->createElement('Dbtr'); $nm_dbtr_node = $this->xml->createElement('Nm'); $dbtr_acct_node = $this->xml->createElement('DbtrAcct'); $id_dbtr_acct_node = $this->xml->createElement('Id'); $iban_dbtr_acct_node = $this->xml->createElement('IBAN'); $rmt_inf_node = $this->xml->createElement('RmtInf'); $ustrd_node = $this->xml->createElement('Ustrd'); //Set the payment node information $instd_amt_node->setAttribute('Ccy', $this->config['currency']); $instd_amt_node->nodeValue = $this->intToDecimal($payment['amount']); $mndt_id_node->nodeValue = $payment['mandate_id']; $dt_of_sgntr_node->nodeValue = $payment['mandate_date']; if (isset($payment['BIC'])) { $bic_dbtr_agt_node->nodeValue = $payment['BIC']; } if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $nm_dbtr_node->nodeValue = htmlentities($payment['name'], ENT_XML1, 'UTF-8'); } else { $nm_dbtr_node->nodeValue = htmlentities($payment['name'], ENT_QUOTES, 'UTF-8'); } $iban_dbtr_acct_node->nodeValue = $payment['IBAN']; if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $ustrd_node->nodeValue = htmlentities($payment['description'], ENT_XML1, 'UTF-8'); } else { $ustrd_node->nodeValue = htmlentities($payment['description'], ENT_QUOTES, 'UTF-8'); } $end_to_end_id_node->nodeValue = $this->makeId(); //Fold the nodes, if batch is enabled, some of this will be done by the batch. if ($this->config['batch'] == false) { $pmt_inf_node->appendChild($pmt_inf_id_node); $pmt_inf_node->appendChild($pmt_mtd_node); $pmt_inf_node->appendChild($btch_bookg_node); $pmt_inf_node->appendChild($nb_of_txs_node); $pmt_inf_node->appendChild($ctrl_sum_node); $svc_lvl_node->appendChild($cd_svc_lvl_node); $pmt_tp_inf_node->appendChild($svc_lvl_node); $lcl_instrm_node->appendChild($cd_lcl_instrm_node); $pmt_tp_inf_node->appendChild($lcl_instrm_node); $pmt_tp_inf_node->appendChild($seq_tp_node); $pmt_inf_node->appendChild($pmt_tp_inf_node); $pmt_inf_node->appendChild($reqd_colltn_dt_node); $cdtr_node->appendChild($nm_cdtr_node); $pmt_inf_node->appendChild($cdtr_node); $id_cdtr_acct_node->appendChild($iban_cdtr_acct_node); $cdtr_acct_node->appendChild($id_cdtr_acct_node); $pmt_inf_node->appendChild($cdtr_acct_node); $fin_instn_id_cdtr_agt_node->appendChild($bic_cdtr_agt_node); $cdtr_agt_node->appendChild($fin_instn_id_cdtr_agt_node); $pmt_inf_node->appendChild($cdtr_agt_node); $pmt_inf_node->appendChild($chrg_br_node); $cdtr_schme_id_node->appendChild($nm_cdtr_schme_id_node); $othr_node->appendChild($id_othr_node); $schme_nm_node->appendChild($prtry_node); $othr_node->appendChild($schme_nm_node); $prvt_id_node->appendChild($othr_node); $id_cdtr_schme_id_node->appendChild($prvt_id_node); $cdtr_schme_id_node->appendChild($id_cdtr_schme_id_node); $pmt_inf_node->appendChild($cdtr_schme_id_node); } $pmt_id_node->appendChild($end_to_end_id_node); $drct_dbt_tx_inf_node->appendChild($pmt_id_node); $drct_dbt_tx_inf_node->appendChild($instd_amt_node); $mndt_rltd_inf_node->appendChild($mndt_id_node); $mndt_rltd_inf_node->appendChild($dt_of_sgntr_node); $drct_dbt_tx_node->appendChild($mndt_rltd_inf_node); $drct_dbt_tx_inf_node->appendChild($drct_dbt_tx_node); if (isset($payment['BIC'])) { $fin_instn_id_dbtr_agt_node->appendChild($bic_dbtr_agt_node); $dbtr_agt_node->appendChild($fin_instn_id_dbtr_agt_node); $drct_dbt_tx_inf_node->appendChild($dbtr_agt_node); } $dbtr_node->appendChild($nm_dbtr_node); $drct_dbt_tx_inf_node->appendChild($dbtr_node); $id_dbtr_acct_node->appendChild($iban_dbtr_acct_node); $dbtr_acct_node->appendChild($id_dbtr_acct_node); $drct_dbt_tx_inf_node->appendChild($dbtr_acct_node); $rmt_inf_node->appendChild($ustrd_node); $drct_dbt_tx_inf_node->appendChild($rmt_inf_node); $pmt_id_node->appendChild($end_to_end_id_node); if ($this->config['batch'] == false) { //Add to the document $pmt_inf_node->appendChild($drct_dbt_tx_inf_node); $cstmr_drct_dbt_initn_node->appendChild($pmt_inf_node); } else { //Update the batch metrics $batch['ctrlSum']->nodeValue += $payment['amount']; $batch['nbOfTxs']->nodeValue++; //Add to the batch $batch['node']->appendChild($drct_dbt_tx_inf_node); } } /** * Function to finalize and save the document after all payments are added. * @return The xml to be echoed or saved to file. */ public function save() { $this->finalize(); $result = $this->xml->saveXML(); return $result; } /** * Function to validate xml against the pain.008.001.02 schema definition. * @param $xml The xml, as a string, to validate agianst the schema. */ public function validate($xml) { $domdoc = new DOMDocument(); $domdoc->loadXML($xml); if (isset($this->config['version']) && $this->config['version'] == '3') { return $domdoc->schemaValidate('pain.008.001.03.xsd'); } else { return $domdoc->schemaValidate('pain.008.001.02.xsd'); } } /** * Function to add a custom node to the document. * @param $parent_xpath A valid XPATH expression defining the parent of the new node * @param $name The name of the new node * @param $value The value of the new node (Optional, default '') * @param $attr Key => Value array defining the attributes (Optional, default none) */ public function addCustomNode($parent_xpath, $name, $value = '', $attr = array()) { $xpath = new DOMXPath($this->xml); $parent = $xpath->query($parent_xpath); if ($parent == false || $parent->length == 0) { throw new Exception('Invalid XPATH expression, or no results found: '.$parent_xpath); } $newnode = $this->xml->createElement($name); if ($value != '') { $newnode->nodeValue = $value; } if (!empty($attr)) { foreach ($attr as $attr_name => $attr_value) { $newnode->setAttribute($attr_name, $attr_value); } } $parent->item(0)->appendChild($newnode); } /** * Function to finalize the document, completes the header with metadata, and processes batches. */ private function finalize() { if (!empty($this->batch_array)) { $cstmr_drct_dbt_initn_node = $this->getCstmrDrctDbtInitnNode(); foreach ($this->batch_array as $batch) { $batch['ctrlSum']->nodeValue = $this->intToDecimal($batch['ctrlSum']->nodeValue); $cstmr_drct_dbt_initn_node->appendChild($batch['node']); } } $trx_count = $this->xml->getElementsByTagName('DrctDbtTxInf'); $trx_count = $trx_count->length; $trx_amounts = $this->xml->getElementsByTagName('InstdAmt'); $trx_amount_array = array(); foreach ($trx_amounts as $amount) { $trx_amount_array[] = $amount->nodeValue; } $trx_amount = $this->calcTotalAmount($trx_amount_array); $xpath = new DOMXPath($this->xml); $nb_of_txs_xpath = '//Document/CstmrDrctDbtInitn/GrpHdr/NbOfTxs'; $ctrl_sum_xpath = '//Document/CstmrDrctDbtInitn/GrpHdr/CtrlSum'; $nb_of_txs_node = $xpath->query($nb_of_txs_xpath)->item(0); $ctrl_sum_node = $xpath->query($ctrl_sum_xpath)->item(0); $nb_of_txs_node->nodeValue = $trx_count; $ctrl_sum_node->nodeValue = $trx_amount; } /** * Check the config file for required fields and validity. * NOTE: A function entry in this field will NOT be evaluated if the field is not present in the * config array. if this is necessary, please include it in the $required array as well. * @param $config the config to check. * @return TRUE if valid, error string if invalid. */ private function validateConfig($config) { $required = array('name', 'IBAN', 'batch', 'creditor_id', 'currency'); $functions = array('IBAN' => 'validateIBAN', 'BIC' => 'validateBIC'); foreach ($required as $requirement) { if (array_key_exists($requirement, $config)) { //It exists, check if not empty if (empty($config[$requirement])) { return $requirement.' is empty.'; } } else { return $requirement.' does not exist.'; } } foreach ($functions as $target => $function) { if (array_key_exists($target, $config)) { //Perform the RegEx $function_result = call_user_func('SELF::'.$function, $config[$target]); if ($function_result) { continue; } else { return $target.' does not validate.'; } } } return true; } /** * Check a payment for validity * @param $payment The payment array * @return TRUE if valid, error string if invalid. */ private function validatePayment($payment) { $required = array('name', 'IBAN', 'amount', 'type', 'collection_date', 'mandate_id', 'mandate_date', 'description'); $functions = array('IBAN' => 'validateIBAN', 'BIC' => 'validateBIC', 'amount' => 'validateAmount', 'collection_date' => 'validateDate', 'mandate_date' => 'validateDate', 'type' => 'validateDDType'); foreach ($required as $requirement) { //Check if the config has the required parameter if (array_key_exists($requirement, $payment)) { //It exists, check if not empty if (empty($payment[$requirement])) { return $requirement.' is empty.'; } } else { return $requirement.' does not exist.'; } } foreach ($functions as $target => $function) { //Check if it is even there in the config if (array_key_exists($target, $payment)) { //Perform the RegEx $function_result = call_user_func('SELF::'.$function, $payment[$target]); if ($function_result) { continue; } else { return $target.' does not validate.'; } } } return true; } /** * Validate an IBAN Number. * @param $iban the IBAN number to check. * @return BOOLEAN TRUE if valid, FALSE if invalid. */ public static function validateIBAN($iban) { $result = preg_match('/[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}/', $iban); if ($result > 0 && $result !== false) { return true; } else { return false; } } /** * Validate a BIC number.Payment Information * @param $bic the BIC number to check. * @return TRUE if valid, FALSE if invalid. */ public static function validateBIC($bic) { $result = preg_match('([a-zA-Z]{4}[a-zA-Z]{2}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?)', $bic); if ($result > 0 && $result !== false) { return true; } else { return false; } } /** * Function to validate a ISO date. * @param $date The date to validate. * @return True if valid, error string if invalid. */ public static function validateDate($date) { $result = DateTime::createFromFormat('Y-m-d', $date); if ($result === false) { return false; } else { return $date.' is not a valid ISO Date'; } } /** * Function to validate the Direct Debit Transaction types * @param Typecode * @return True if valid, error string if invalid. */ public static function validateDDType($type) { $types = array('FRST', 'RCUR', 'FNAL', 'OOFF'); if (in_array($type, $types)) { return true; } else { return $type.' is not a valid Sepa Direct Debit Transaction Type.'; } } /** * Function to validate an amount, to check that amount is in cents. * @param $amount The amount to validate. * @return TRUE if valid, FALSE if invalid. */ public static function validateAmount($amount) { return ctype_digit((int)($amount)); } /** * Function to convert an amount in cents to a decimal (with point). * @param $int The amount as decimal string * @return The decimal */ private function intToDecimal($int) { $before = Tools::substr($int, 0, -2); $after = Tools::substr($int, -2); if (empty($before)) { $before = 0; } if (Tools::strlen($after) == 1) { $after = '0'.$after; } return $before.'.'.$after; } /** * Function to convert an amount in decimal to cents (without point). * @param $decimal The amount as decimal * @return The amount as integer string */ private function decimalToInt($decimal) { return str_replace('.', '', $decimal); } /** * Function to calculate the sum of the amounts, given as decimals in an array. * @param $array The array with decimals * @return The decimal sum of the array */ private function calcTotalAmount($array) { $ints = array(); $sum = 0; foreach ($array as $decimal) { $ints[] = $this->decimalToInt($decimal); } $sum = array_sum($ints); $sum = $this->intToDecimal($sum); return $sum; } /** * Create a random Message Id f$PmtInfNodeor the header, prefixed with a timestamp. * @return the Message Id. */ private function makeMsgId() { $random = mt_rand(); $random = md5($random); $random = Tools::substr($random, 0, 12); $timestamp = date('dmYsi'); return $timestamp.'-'.$random; } /** * Create a random id, combined with the name (truncated at 22 chars). * @return the Id. */ private function makeId() { $random = mt_rand(); $random = md5($random); $random = Tools::substr($random, 0, 12); $name = $this->config['name']; $length = Tools::strlen($name); if ($length > 22) { $name = Tools::substr($name, 0, 22); } return $name.'-'.$random; } /** * Function to get the CstmrDrctDbtInitnNode from the current document. * @return The CstmrDrctDbtInitn DOMNode. * @throws Exception when the node does noet exist or there are more then one. */ private function getCstmrDrctDbtInitnNode() { $cstmr_drct_dbt_initn_node_list = $this->xml->getElementsByTagName('CstmrDrctDbtInitn'); if ($cstmr_drct_dbt_initn_node_list->length != 1) { throw new Exception('Error retrieving node from document: No or Multiple CstmrDrctDbtInitn'); } return $cstmr_drct_dbt_initn_node_list->item(0); } /** * Function to create a batch (PmtInf with BtchBookg set true) element. * @param $type The DirectDebit type for this batch. * @param $date The required collection date. */ private function getBatch($type, $date) { //if the batch for this type and date already exists, return it. if ($this->validateDDType($type) && $this->validateDate($date) && array_key_exists($type.'::'.$date, $this->batch_array)) { return $this->batch_array[$type.'::'.$date]; } //Create the PmtInf element and its subelements // $reqd_exctn_dt_tm_node = $this->xml->createElement('ReqdExctnDt'); $pmt_inf_node = $this->xml->createElement('PmtInf'); $pmt_inf_id_node = $this->xml->createElement('PmtInfId'); $pmt_mtd_node = $this->xml->createElement('PmtMtd'); $btch_bookg_node = $this->xml->createElement('BtchBookg'); $nb_of_txs_node = $this->xml->createElement('NbOfTxs'); $ctrl_sum_node = $this->xml->createElement('CtrlSum'); $pmt_tp_inf_node = $this->xml->createElement('PmtTpInf'); $svc_lvl_node = $this->xml->createElement('SvcLvl'); $cd_svc_lvl_node = $this->xml->createElement('Cd'); $lcl_instrm_node = $this->xml->createElement('LclInstrm'); $cd_lcl_instrm_node = $this->xml->createElement('Cd'); $seq_tp_node = $this->xml->createElement('SeqTp'); $reqd_colltn_dt_node = $this->xml->createElement('ReqdColltnDt'); $cdtr_node = $this->xml->createElement('Cdtr'); $nm_cdtr_node = $this->xml->createElement('Nm'); $cdtr_acct_node = $this->xml->createElement('CdtrAcct'); $id_cdtr_acct_node = $this->xml->createElement('Id'); $iban_cdtr_acct_node = $this->xml->createElement('IBAN'); if (isset($this->config['BIC'])) { $cdtr_agt_node = $this->xml->createElement('CdtrAgt'); $fin_instn_id_cdtr_agt_node = $this->xml->createElement('FinInstnId'); if (isset($this->config['version']) && $this->config['version'] == '3') { $bic_cdtr_agt_node = $this->xml->createElement('BICFI'); } else { $bic_cdtr_agt_node = $this->xml->createElement('BIC'); } } $chrg_br_node = $this->xml->createElement('ChrgBr'); $cdtr_schme_id_node = $this->xml->createElement('CdtrSchmeId'); $nm_cdtr_schme_id_node = $this->xml->createElement('Nm'); $id_cdtr_schme_id_node = $this->xml->createElement('Id'); $prvt_id_node = $this->xml->createElement('PrvtId'); $othr_node = $this->xml->createElement('Othr'); $id_othr_node = $this->xml->createElement('Id'); $schme_nm_node = $this->xml->createElement('SchmeNm'); $prtry_node = $this->xml->createElement('Prtry'); //Fill in the blanks $pmt_inf_id_node->nodeValue = $this->makeId(); $pmt_mtd_node->nodeValue = 'DD';//Direct Debit $btch_bookg_node->nodeValue = 'true'; $ctrl_sum_node->nodeValue = '0'; $cd_svc_lvl_node->nodeValue = 'SEPA'; $cd_lcl_instrm_node->nodeValue = 'CORE'; $seq_tp_node->nodeValue = $type;//Define a check for: FRST RCUR OOFF FNAL $reqd_colltn_dt_node->nodeValue = $date; if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $nm_cdtr_node->nodeValue = htmlentities($this->config['name'], ENT_XML1, 'UTF-8'); } else { $nm_cdtr_node->nodeValue = htmlentities($this->config['name'], ENT_QUOTES, 'UTF-8'); } $iban_cdtr_acct_node->nodeValue = $this->config['IBAN']; if (isset($this->config['BIC'])) { $bic_cdtr_agt_node->nodeValue = $this->config['BIC']; } $chrg_br_node->nodeValue = 'SLEV'; if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $nm_cdtr_schme_id_node->nodeValue = htmlentities($this->config['name'], ENT_XML1, 'UTF-8'); } else { $nm_cdtr_schme_id_node->nodeValue = htmlentities($this->config['name'], ENT_QUOTES, 'UTF-8'); } $id_othr_node->nodeValue = $this->config['creditor_id']; $prtry_node->nodeValue = 'SEPA'; //Fold the batch information $pmt_inf_node->appendChild($pmt_inf_id_node); $pmt_inf_node->appendChild($pmt_mtd_node); $pmt_inf_node->appendChild($btch_bookg_node); $pmt_inf_node->appendChild($nb_of_txs_node); $pmt_inf_node->appendChild($ctrl_sum_node); $svc_lvl_node->appendChild($cd_svc_lvl_node); $pmt_tp_inf_node->appendChild($svc_lvl_node); // $pmt_inf_node->appendChild($reqd_exctn_dt_tm_node); $lcl_instrm_node->appendChild($cd_lcl_instrm_node); $pmt_tp_inf_node->appendChild($lcl_instrm_node); $pmt_tp_inf_node->appendChild($seq_tp_node); $pmt_inf_node->appendChild($pmt_tp_inf_node); $pmt_inf_node->appendChild($reqd_colltn_dt_node); $cdtr_node->appendChild($nm_cdtr_node); $pmt_inf_node->appendChild($cdtr_node); $id_cdtr_acct_node->appendChild($iban_cdtr_acct_node); $cdtr_acct_node->appendChild($id_cdtr_acct_node); $pmt_inf_node->appendChild($cdtr_acct_node); if (isset($this->config['BIC'])) { $fin_instn_id_cdtr_agt_node->appendChild($bic_cdtr_agt_node); $cdtr_agt_node->appendChild($fin_instn_id_cdtr_agt_node); $pmt_inf_node->appendChild($cdtr_agt_node); } $pmt_inf_node->appendChild($chrg_br_node); //$cdtr_schme_id_node->appendChild($nm_cdtr_schme_id_node); $othr_node->appendChild($id_othr_node); $schme_nm_node->appendChild($prtry_node); $othr_node->appendChild($schme_nm_node); $prvt_id_node->appendChild($othr_node); $id_cdtr_schme_id_node->appendChild($prvt_id_node); $cdtr_schme_id_node->appendChild($id_cdtr_schme_id_node); $pmt_inf_node->appendChild($cdtr_schme_id_node); //Add it to the batch_array. $this->batch_array[$type.'::'.$date]['node'] = $pmt_inf_node; $this->batch_array[$type.'::'.$date]['ctrlSum'] = $ctrl_sum_node; $this->batch_array[$type.'::'.$date]['nbOfTxs'] = $nb_of_txs_node; //Return the batch array for this type and date. return $this->batch_array[$type.'::'.$date]; } }