Initial commit

This commit is contained in:
2019-11-20 07:44:43 +01:00
commit 5bf49c4a81
41188 changed files with 5459177 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
class DecanetApi
{
public $LOGIN = false;
public $PASS = false;
public $ROOT = 'https://api.decanet.fr';
public $timeDrift = 0;
public function __construct($_login = false, $_pass = false, $_root = false)
{
if ($_login) {
$this->LOGIN = $_login;
}
if ($_pass) {
$this->PASS = $_pass;
}
if ($_root) {
$this->ROOT = $_root;
}
// Compute time drift
$srvTime = Tools::jsonDecode(Tools::file_get_contents($this->ROOT . '/auth/time'));
if ($srvTime !== false) {
$this->timeDrift = time() - (int)$srvTime;
}
}
private function call($method, $url, $body = null)
{
$url = $this->ROOT . $url;
if ($body) {
$bodystring = '';
foreach ($body as $key => $value) {
$bodystring .= $key.'='.urlencode($value).'&';
}
$bodystring = rtrim($bodystring, '&');
}
// Compute signature
$time = time() - $this->timeDrift;
$toSign = $this->LOGIN.'+'.$this->PASS.'+'.$method.'+'.$time;
$signature = '$1$' . sha1($toSign);
// Call
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'X-Consumer:' . $this->LOGIN,
'X-Signature:' . $signature,
'X-Timestamp:' . $time,
));
if ($body) {
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $bodystring);
}
$result = curl_exec($curl);
if ($result === false) {
echo curl_error($curl);
return null;
}
return Tools::jsonDecode($result);
}
public function get($url)
{
return $this->call("GET", $url);
}
public function put($url, $body)
{
return $this->call("PUT", $url, $body);
}
public function post($url, $body)
{
return $this->call("POST", $url, $body);
}
public function delete($url, $body = false)
{
return $this->call("DELETE", $url, $body);
}
}

View File

@@ -0,0 +1,135 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
class HTMLTemplatePrelevementSepaPdf extends HTMLTemplate
{
public $custom_model;
public function __construct($custom_object, $smarty)
{
$this->custom_model = $custom_object;
$this->smarty = $smarty;
// header informations
//$id_lang = Context::getContext()->language->id;
$this->title = HTMLTemplatePrelevementSepaPdf::l('Mandat SEPA a imprimer et nous retourner');
// footer informations
$this->shop = new Shop(Context::getContext()->shop->id);
}
/**
* Returns the template's HTML content
* @return string HTML content
*/
public function getContent()
{
$this->smarty->assign(array(
'custom_model' => $this->custom_model,
'shop_name' => $this->shop->name,
));
return $this->custom_model->html;
}
/**
* Returns the template's HTML header
*
* @return string HTML header
*/
public function getHeader()
{
$prel_obj = new PrelevementSEPA();
$this->assignCommonHeaderData();
$this->smarty->assign(array(
'conf' => $prel_obj->conf_keys,
'sepa' => $this->custom_model
));
$template = $prel_obj->getLocalPath().'views/templates/front/'.$prel_obj->conf_keys['template'].'.header.tpl';
if (!file_exists($template)) {
$template = $prel_obj->getLocalPath().'views/templates/front/mandate.header.tpl';
}
if (file_exists(_PS_THEME_DIR_.'modules/'.$prel_obj->name.'/views/templates/front/'.
$prel_obj->conf_keys['template'].'.header.tpl')) {
$template = _PS_THEME_DIR_.'modules/'.$prel_obj->name.'/views/templates/front/'.
$prel_obj->conf_keys['template'].'.header.tpl';
}
return $this->smarty->fetch($template);
}
public function getFooter()
{
$prel_obj = new PrelevementSEPA();
$shop_address = $this->getShopAddress();
$id_shop = (int)$this->shop->id;
$this->smarty->assign(
array(
'conf' => $prel_obj->conf_keys,
'shop_address' => $shop_address,
'shop_fax' => Configuration::get('PS_SHOP_FAX', null, null, $id_shop),
'shop_phone' => Configuration::get('PS_SHOP_PHONE', null, null, $id_shop),
'shop_email' => Configuration::get('PS_SHOP_EMAIL', null, null, $id_shop),
'free_text' => Configuration::get(
'PS_INVOICE_FREE_TEXT',
(int)Context::getContext()->language->id,
null,
$id_shop
)
)
);
$template = $prel_obj->getLocalPath().'views/templates/front/'.$prel_obj->conf_keys['template'].'.footer.tpl';
if (!file_exists($template)) {
$template = $prel_obj->getLocalPath().'views/templates/front/mandate.footer.tpl';
}
if (file_exists(_PS_THEME_DIR_.'modules/'.$prel_obj->name.'/views/templates/front/'.
$prel_obj->conf_keys['template'].'.footer.tpl')) {
$template = _PS_THEME_DIR_.'modules/'.$prel_obj->name.'/views/templates/front/'.
$prel_obj->conf_keys['template'].'.footer.tpl';
}
return $this->smarty->fetch($template);
}
public function getPagination()
{
return null;
}
/**
* Returns the template filename
* @return string filename
*/
public function getFilename()
{
return 'sepa-'.$this->custom_model->rum.'.pdf';
}
/**
* Returns the template filename when using bulk rendering
* @return string filename
*/
public function getBulkFilename()
{
return 'sepa-'.$this->custom_model->rum.'.pdf';
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class PrevSepa extends ObjectModel
{
public $id_customer;
public $etat = 0;
public $rum = '';
public $name = '';
public $address = '';
public $iban = '';
public $bic = '';
public $sepa_type = '';
public $phone = '';
public $code = '';
public $datevalid = '';
public $html = '';
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'prelevementsepa',
'primary' => 'id_sepa',
'multilang' => false,
'fields' => array(
'id_customer' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'name' =>array('type' => self::TYPE_STRING),
'address' =>array('type' => self::TYPE_STRING),
'etat' =>array('type' => self::TYPE_BOOL),
'rum' =>array('type' => self::TYPE_STRING),
'iban' =>array('type' => self::TYPE_STRING),
'bic' =>array('type' => self::TYPE_STRING),
'sepa_type' =>array('type' => self::TYPE_STRING),
'phone' =>array('type' => self::TYPE_STRING),
'code' =>array('type' => self::TYPE_STRING),
'datevalid' =>array('type' => self::TYPE_STRING),
),
);
public static function existCustomer($id_customer)
{
$sql = 'SELECT id_sepa FROM `'._DB_PREFIX_.'prelevementsepa`
WHERE id_customer = '.(int)$id_customer.'';
$list = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($list && is_array($list) && count($list)) {
return (int)$list[0]['id_sepa'];
}
return null;
}
public static function getAll()
{
$sql = 'SELECT * FROM `'._DB_PREFIX_.'prelevementsepa`';
$list = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($list && is_array($list) && count($list)) {
return $list;
}
return array();
}
public static function updateUnTraitSepaIDByOids($sepa_id, $oid_list)
{
return Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'prelevementsepa_detail` SET id_sepa='.$sepa_id
.' WHERE id_sepa=0 AND traite=0 AND id_order IN ('.implode(', ', $oid_list).')');
}
}

View File

@@ -0,0 +1,151 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class PrevSepaOrder extends ObjectModel
{
public $id_sepa_detail;
public $id_sepa;
public $id_order;
public $sepa_date;
public $traite;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'prelevementsepa_detail',
'primary' => 'id_sepa_detail',
'multilang' => false,
'fields' => array(
'id_sepa' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'id_order' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'traite' => array('type' => self::TYPE_BOOL),
'sepa_date' => array('type' => self::TYPE_DATE)
),
);
public static function existOrder($id_order)
{
$sql = 'SELECT id_sepa_detail FROM `'._DB_PREFIX_.'prelevementsepa_detail`
WHERE id_order = '.(int)$id_order;
$list = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($list && is_array($list) && count($list)) {
return (int)$list[0]['id_sepa_detail'];
}
return null;
}
public static function getAllActive()
{
$sql = 'SELECT `'._DB_PREFIX_.'prelevementsepa_detail`.* FROM `'._DB_PREFIX_.'prelevementsepa_detail`
LEFT JOIN `'._DB_PREFIX_.'prelevementsepa`
ON (`'._DB_PREFIX_.'prelevementsepa`.id_sepa=`'._DB_PREFIX_.'prelevementsepa_detail`.id_sepa)
WHERE `'._DB_PREFIX_.'prelevementsepa`.etat=1 ORDER BY id_sepa_detail DESC';
$list = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($list && is_array($list) && count($list)) {
return $list;
}
return null;
}
public static function getAllTodo()
{
$sql = 'SELECT `'._DB_PREFIX_.'prelevementsepa_detail`.* FROM `'._DB_PREFIX_.'prelevementsepa_detail`
LEFT JOIN `'._DB_PREFIX_.'prelevementsepa`
ON (`'._DB_PREFIX_.'prelevementsepa`.id_sepa=`'._DB_PREFIX_.'prelevementsepa_detail`.id_sepa)
WHERE `'._DB_PREFIX_.'prelevementsepa`.etat=1 AND'.
'`'._DB_PREFIX_.'prelevementsepa_detail`.traite=0 AND'.
'`'._DB_PREFIX_.'prelevementsepa_detail`.sepa_date<="'.date('Y-m-d').'"
GROUP BY id_sepa_detail ORDER BY id_sepa_detail DESC';
$list = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
// die(var_dump($list, $sql));
if ($list && is_array($list) && count($list)) {
return $list;
}
return null;
}
public static function getAllSepa($traite = 0, $etat = 1, $now = true)
{
$sql = 'SELECT `'._DB_PREFIX_.'prelevementsepa_detail`.* FROM `'._DB_PREFIX_.'prelevementsepa_detail`
WHERE `'._DB_PREFIX_.'prelevementsepa_detail`.traite='.(int)$traite.
($now ? ' AND `'._DB_PREFIX_.'prelevementsepa_detail`.sepa_date<="'.date('Y-m-d').'" ':' ').
'GROUP BY id_sepa_detail ORDER BY id_sepa_detail DESC';
$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
$list = array();
if ($tmp && is_array($tmp) && count($tmp)) {
foreach ($tmp as $t) {
if ($t['id_sepa']==0) {
require_once(dirname(__FILE__).'/PrevSepa.php');
$order = new Order((int)$t['id_order']);
$id_sepa = PrevSepa::existCustomer((int)$order->id_customer);
$t['id_sepa'] = $id_sepa;
$sepa_order_obj = new PrevSepaOrder((int)$t['id_sepa_detail']);
$sepa_order_obj->id_sepa = (int)$t['id_sepa'];
$sepa_order_obj->save();
}
$sql2 = 'SELECT `'._DB_PREFIX_.'prelevementsepa`.* FROM `'._DB_PREFIX_.'prelevementsepa`
WHERE `'._DB_PREFIX_.'prelevementsepa`.etat='.(int)$etat.' AND'.
'`'._DB_PREFIX_.'prelevementsepa`.id_sepa='.(int)$t['id_sepa'];
$tmp2 = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql2);
if (count($tmp2)>0) {
$tmp2 = $tmp2[0];
$list[] = array_merge($t, $tmp2);
}
}
return $list;
}
return null;
}
public static function getGeneratedSepaList($id_order)
{
$id_sepa_traited = Db::getInstance()->getValue('SELECT id_sepa_traited FROM
`'._DB_PREFIX_.'prelevementsepa_traited_order`
WHERE id_order='.(int)$id_order);
if ($id_sepa_traited) {
$orders = Db::getInstance()->executeS('SELECT id_order FROM `'._DB_PREFIX_.'prelevementsepa_traited_order`
WHERE id_sepa_traited='.(int)$id_sepa_traited);
$orders_list = array();
if ($orders) {
foreach ($orders as $order) {
$orders_list[] = $order['id_order'];
}
$sql = 'SELECT `'._DB_PREFIX_.'prelevementsepa_detail`.*, rum, iban, bic
FROM `'._DB_PREFIX_.'prelevementsepa_detail`
LEFT JOIN `'._DB_PREFIX_.'prelevementsepa`
ON (`'._DB_PREFIX_.'prelevementsepa`.id_sepa=`'._DB_PREFIX_.'prelevementsepa_detail`.id_sepa)
WHERE id_order IN ('.implode(',', $orders_list).')
GROUP BY id_sepa_detail ORDER BY id_sepa_detail DESC';
return Db::getInstance()->executeS($sql);
}
}
return null;
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class PrevSepaOrderTraited extends ObjectModel
{
public $id_sepa_traited;
public $date_add;
public $date_upd;
public $order_state;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'prelevementsepa_traited',
'primary' => 'id_sepa_traited',
'multilang' => false,
'fields' => array(
'date_add' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'),
'date_upd' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'),
'order_state' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
),
);
public function addOrder($id_order)
{
Db::getInstance()->insert('prelevementsepa_traited_order', array(
'id_sepa_traited' => (int)$this->id,
'id_order' => (int)$id_order
));
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
require_once(dirname(__FILE__).'/DecanetApi.php');
if (!class_exists('SMSDecanet')) {
class SMSDecanet
{
/**
* Récupération du crédit restant
*/
public function getCredit(array $parameter)
{
$api_obj = new DecanetApi($parameter['LOGIN'], $parameter['API_KEY']);
$result = $api_obj->get('/sms/credit');
if ($parameter['TEST']==1) {
return $result;
}
return isset($result->credit) ? (int)$result->credit : 0;
}
/**
* envoi du SMS
* @param array $parameter
*/
public function send(array $parameter)
{
$msg = $parameter['SMS'];
if (preg_match('!!u', $msg)) {
$msg = utf8_decode($msg);
}
$api_obj = new DecanetApi($parameter['LOGIN'], $parameter['API_KEY']);
$api_obj->post(
'/sms/send',
array(
'FROMNUM' => $parameter['FROMNUM'],
'TO' => $parameter['TO'],
'MSG' => $msg,
'TRANSACTIONAL' => 1
)
);
return 'ok';
}
}
}

View File

@@ -0,0 +1,750 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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];
}
}

View File

@@ -0,0 +1,752 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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 SepaDDCbi
{
private $config;
private $xml;
private $batch_array = array();
private $num=0;
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('CBISDDReqLogMsg');
$document_attribute_xml = $this->xml->createAttribute('xmlns');
$document_attribute_xml->value = 'urn:CBI:xsd:CBISDDReqLogMsg.00.01.00';
$document_node->appendChild($document_attribute_xml);
$document_attribute_xmlns = $this->xml->createAttribute('xmlns:xsi');
$document_attribute_xmlns->value = 'http://www.w3.org/2001/XMLSchema-instance';
$document_node->appendChild($document_attribute_xmlns);
$document_attribute_xmlxsi = $this->xml->createAttribute('xsi:schemaLocation');
$document_attribute_xmlxsi->value = 'urn:CBI:xsd:CBISDDReqLogMsg.00.01.00 CBISDDReqLogMsg.00.01.00.xsd';
$document_node->appendChild($document_attribute_xmlxsi);
//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 CBISDDReqLogMsg node
$cstmr_drct_dbt_initn_node = $this->getCBISDDReqLogMsgNode();
//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');
$id_node = $this->xml->createElement('Id');
$origid_node = $this->xml->createElement('OrgId');
$othr_node = $this->xml->createElement('Othr');
$id2_node = $this->xml->createElement('Id');
$issr_node = $this->xml->createElement('Issr');
//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');
}
$issr_node->nodeValue = 'CBI';
$id2_node->nodeValue = $this->config['CBI'];
//Append the nodes
$othr_node->appendChild($id2_node);
$othr_node->appendChild($issr_node);
$origid_node->appendChild($othr_node);
$id_node->appendChild($origid_node);
$initg_pty_node->appendChild($nm_node);
$initg_pty_node->appendChild($id_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 CBISDDReqLogMsgNode
$cstmr_drct_dbt_initn_node = $this->getCBISDDReqLogMsgNode();
//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');
$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';
$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');
$instrid_node = $this->xml->createElement('InstrId');
$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');
}
$this->num++;
$instrid_node->nodeValue = $this->num;
$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);
$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($instrid_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->getCBISDDReqLogMsgNode();
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 = '//CBISDDReqLogMsg/GrpHdr/NbOfTxs';
$ctrl_sum_xpath = '//CBISDDReqLogMsg/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 CBISDDReqLogMsgNode from the current document.
* @return The CBISDDReqLogMsg DOMNode.
* @throws Exception when the node does noet exist or there are more then one.
*/
private function getCBISDDReqLogMsgNode()
{
$cstmr_drct_dbt_initn_node_list = $this->xml->getElementsByTagName('CBISDDReqLogMsg');
if ($cstmr_drct_dbt_initn_node_list->length != 1) {
throw new Exception('Error retrieving node from document: No or Multiple CBISDDReqLogMsg');
}
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');
$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';
$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);
$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;
//Return the batch array for this type and date.
return $this->batch_array[$type.'::'.$date];
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>prelevementsepa</name>
<displayName><![CDATA[Pr&eacute;l&egrave;vement SEPA]]></displayName>
<version><![CDATA[2.5.0]]></version>
<description><![CDATA[Proposez les pr&eacute;l&egrave;vements SEPA comme mode de paiement]]></description>
<author><![CDATA[Decanet]]></author>
<tab><![CDATA[payments_gateways]]></tab>
<confirmUninstall><![CDATA[souhaitez vous réellement désinstaller le module]]></confirmUninstall>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,244 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
require_once(dirname(__FILE__).'/../../prelevementsepa.php');
class AdminSepaMandateController extends ModuleAdminController
{
public $module = 'prelevementsepa';
public $name = 'prelevementsepa';
private $extensions = array('.txt', '.rtf', '.doc', '.docx', '.pdf', '.zip', '.png', '.jpeg', '.gif', '.jpg');
public function __construct()
{
$this->path = _PS_MODULE_DIR_.$this->module.'/';
$this->className = 'prelevementsepa';
$this->display = 'edit';
$this->multishop_context = Shop::CONTEXT_ALL;
$this->id_lang = (int)Context::getContext()->language->id;
$this->lang = true;
$this->deleted = false;
$this->colorOnBackground = false;
$this->url = __PS_BASE_URI__.basename(_PS_MODULE_DIR_).'/'.$this->name.'/';
$this->images = $this->url.'views/img/';
$this->context = Context::getContext();
$this->bootstrap = true;
parent::__construct();
}
public function postProcess()
{
$return = parent::postProcess();
return $return;
}
public function processSave()
{
$obj = parent::processSave();
return $obj;
}
public function renderForm()
{
$id = Tools::getIsset('id_sepa')?(int)Tools::getValue('id_sepa'):0;
$customers = Customer::getCustomers(true);
foreach ($customers as &$cust) {
$cust['name'] = $cust['firstname'].' '.$cust['lastname'];
}
array_unshift($customers, array('id_customer' => 0, 'name' => ''));
$file = array(
'type' => 'file',
'label' => $this->l('Mandate'),
'name' => 'file'
);
if ($id>0) {
require_once(dirname(__FILE__).'/../../classes/PrevSepa.php');
$sepa_obj = new PrevSepa((int)$id);
foreach ($this->extensions as $e) {
if (file_exists(_PS_UPLOAD_DIR_.'sepa/'.sha1($sepa_obj->rum.$sepa_obj->id_customer).$e)) {
$file['file'] = __PS_BASE_URI__.basename(_PS_UPLOAD_DIR_)
.'/sepa/'.sha1($sepa_obj->rum.$sepa_obj->id_customer).$e;
break;
}
}
}
$fields_form = array(
'form' => array(
'legend' => array(
'title' => ($id>0)?$this->l('Edit a Sepa mandate'):$this->l('Add a Sepa mandate'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'select',
'label' => $this->l('Customer\'s account'),
'name' => 'id_customer',
'options' => array(
'query' => $customers,
'id' => 'id_customer',
'name' => 'name'
),
'col' => '4'
),
array(
'type' => 'text',
'label' => $this->l('Customer\'s name'),
'name' => 'sepa_name'
),
array(
'type' => 'text',
'label' => $this->l('Customer\'s address'),
'name' => 'sepa_address'
),
array(
'type' => 'switch',
'label' => $this->l('State'),
'name' => 'sepa_state',
'values' => array(
array(
'id' => 'state_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'state_off',
'value' => 0,
'label' => $this->l('No')
)
)
),
array(
'type' => 'text',
'label' => $this->l('RUM'),
'name' => 'sepa_rum'
),
array(
'type' => 'text',
'label' => $this->l('IBAN'),
'name' => 'sepa_iban'
),
array(
'type' => 'text',
'label' => $this->l('BIC/BNC'),
'name' => 'sepa_bic'
),
array(
'type' => 'select',
'label' => $this->l('Type'),
'name' => 'sepa_type',
'options' => array(
'query' => array(array('name'=>'FRST'),array('name'=>'RCUR')),
'id' => 'name',
'name' => 'name'
),
'col' => '4'
),
array(
'type' => 'date',
'label' => $this->l('Validate date'),
'name' => 'datevalid'
),
$file,
array(
'type' => 'hidden',
'name' => 'id_sepa'
)
),
'submit' => array(
'name' => 'send_sepamandate',
'title' => ($id==0)?$this->l('New Sepa Mandate'):$this->l('Save Sepa Mandate'),
)
),
);
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$helper->identifier = $this->identifier;
$helper->submit_action = 'sepaMandate';
$helper->show_cancel_button = true;
$helper->back_url = $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
.'&configure='.$this->name.'&update_sepa='.(int)$id
.'&module_name='.$this->name;
$helper->back_url .= '&token='.Tools::getAdminTokenLite('AdminModules').'&module_tab=mandates';
$helper->token = Tools::getAdminTokenLite('AdminModules');
if ($id == 0) {
$helper->tpl_vars = array(
'fields_value' => array(
'sepa_name' => '',
'sepa_address' => '',
'sepa_state' => 0,
'sepa_rum' => 'UI'.date('Ymd').Tools::passwdGen(12, 'NUMERIC'),
'sepa_iban' => '',
'sepa_bic' => '',
'id_customer' => 0,
'datevalid' => '',
'sepa_type' => 'RCUR',
'id_sepa' => $id
)
);
} else {
if (Tools::strlen($sepa_obj->rum) < 3) {
$sepa_obj->rum = 'UI'.date('Ymd').Tools::passwdGen(12, 'NUMERIC');
}
$helper->tpl_vars = array(
'fields_value' => array(
'sepa_name' => $sepa_obj->name,
'sepa_address' => $sepa_obj->address,
'sepa_state' => $sepa_obj->etat,
'sepa_rum' => $sepa_obj->rum,
'sepa_iban' => $sepa_obj->iban,
'sepa_bic' => $sepa_obj->bic,
'id_customer' => $sepa_obj->id_customer,
'datevalid' => $sepa_obj->datevalid,
'sepa_type' => $sepa_obj->sepa_type,
'id_sepa' => $id
)
);
}
return $helper->generateForm(array($fields_form));
}
public function ajaxProcessCheckAddress()
{
$address = new Address(Address::getFirstCustomerAddressId(Tools::getValue('cid')));
echo $address->address1.' '.$address->postcode.' - '.$address->city.', '.$address->country;
die();
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJS(__PS_BASE_URI__.$this->admin_webpath.'/themes/'
.$this->bo_theme.'/js/vendor/test.min.js');
$this->addJqueryUI('ui.autocomplete');
$this->addJqueryPlugin('validate');
$this->addJS($this->path.'views/js/sepa_bo.js');
$this->addCSS($this->path.'views/css/sepa_bo.css');
}
}

View File

@@ -0,0 +1,545 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
require_once(dirname(__FILE__).'/../../prelevementsepa.php');
class AdminSepaOrdersController extends ModuleAdminController
{
public $module = 'prelevementsepa';
public $name = 'prelevementsepa';
public function __construct()
{
$this->path = _PS_MODULE_DIR_.$this->module.'/';
$this->className = 'prelevementsepa';
$this->display = 'edit';
$this->multishop_context = Shop::CONTEXT_ALL;
$this->id_lang = (int)Context::getContext()->language->id;
$this->lang = true;
$this->deleted = false;
$this->colorOnBackground = false;
$this->url = __PS_BASE_URI__.basename(_PS_MODULE_DIR_).'/'.$this->name.'/';
$this->images = $this->url.'views/img/';
$this->context = Context::getContext();
$this->bootstrap = true;
parent::__construct();
}
public function postProcess()
{
if (Tools::isSubmit('submitGenerateXML') || Tools::isSubmit('submitRegenerateXML')) {
require_once(dirname(__FILE__).'/../../classes/PrevSepaOrder.php');
require_once(dirname(__FILE__).'/../../classes/PrevSepaOrderTraited.php');
require_once(dirname(__FILE__).'/../../classes/PrevSepa.php');
require_once(dirname(__FILE__).'/../../classes/SepaDD.php');
require_once(dirname(__FILE__).'/../../classes/SepaDDCbi.php');
$order_state = false;
if (Tools::isSubmit('submitGenerateXML')) {
if ((int)Tools::getValue('id_order_state')>0) {
$id_order_state = (int)Tools::getValue('id_order_state');
$order_state = new OrderState($id_order_state);
if (!Validate::isLoadedObject($order_state)) {
$this->errors[] = sprintf(
Tools::displayError('Order status #%d cannot be loaded'),
$id_order_state
);
}
}
}
$params = array(
'name' => $this->module->conf_keys['creancier'],
'IBAN' => $this->module->conf_keys['IBAN'],
'BIC' => $this->module->conf_keys['BIC'],
'batch' => true,
'creditor_id' => $this->module->conf_keys['ICS'],
'delay_working' => $this->module->conf_keys['delay_working'],
'currency' => 'EUR',
'CBI' => $this->module->conf_keys['CBI']
);
if ($this->module->conf_keys['format']!='cbi') {
$sepadd = new SepaDD($params);
} else {
$sepadd = new SepaDDCbi($params);
}
if (Tools::isSubmit('submitGenerateXML')) {
$sepatraited_obj = new PrevSepaOrderTraited();
$sepatraited_obj->order_state = (int)Tools::getValue('id_order_state');
$sepatraited_obj->add();
}
if (Tools::getIsset('sepaordersBox') &&
is_array(Tools::getValue('sepaordersBox')) &&
count(Tools::getValue('sepaordersBox'))>0) {
foreach (Tools::getValue('sepaordersBox') as $id_sepa) {
if (count($this->errors)==0) {
$sepa_obj = new PrevSepaOrder((int)$id_sepa);
$order = new Order((int)$sepa_obj->id_order);
$id_order = $order->id;
if (!Validate::isLoadedObject($order)) {
$this->errors[] = sprintf(
Tools::displayError('Order #%d cannot be loaded'),
$id_order
);
} else {
if (Tools::isSubmit('submitGenerateXML')) {
$sepatraited_obj->addOrder($id_order);
}
try {
$customer = new Customer((int)$order->id_customer);
$sepa_customer_obj = new PrevSepa($sepa_obj->id_sepa);
$sepa_obj->traite = 1;
$amount = (int)round($order->total_paid * 100);
$sepa_obj->save();
if ((Tools::strlen($customer->company)>0)) {
$name = $customer->company;
} elseif (Tools::strlen($customer->firstname.$customer->lastname) > 3) {
$name = $customer->firstname.' '.$customer->lastname;
} else {
$name = 'No name';
}
$mandateid = $order->invoice_number ? Configuration::get('PS_INVOICE_PREFIX', $order->id_lang).sprintf('%06d', $order->invoice_number) : $order->reference;
$payment = array(
'name' => $name,
'IBAN' => $sepa_customer_obj->iban,
'BIC' => $sepa_customer_obj->bic,
'amount' => $amount,
'type' => empty($sepa_customer_obj->sepa_type) ? 'RCUR' : $sepa_customer_obj->sepa_type,
'collection_date' => date(
'Y-m-d',
$this->getWorkingDays(
time(),
($this->module->conf_keys['delay_working']?
$this->module->conf_keys['delay_working']:2)
)
),
'mandate_id' => $mandateid,
'mandate_date' => date('Y-m-d'),
'description' => str_replace(
'[reference]',
$order->reference,
$this->module->conf_keys['label']
)
);
$sepadd->addPayment($payment);
if ($sepa_customer_obj->sepa_type=='FRST') {
$sepa_customer_obj->sepa_type='RCUR';
$sepa_customer_obj->save();
}
if (Tools::isSubmit('submitGenerateXML')) {
if ($order_state && Validate::isLoadedObject($order_state)) {
$current_order_state = $order->getCurrentOrderState();
if ($current_order_state->id == $order_state->id) {
$this->errors[] = $this->displayWarning(
sprintf('Order #%d has already been assigned this status.', $id_order)
);
} else {
$history = new OrderHistory();
$history->id_order = $order->id;
$history->id_employee = (int)$this->context->employee->id;
$use_existings_payment = !$order->hasInvoice();
$history->changeIdOrderState(
(int)$order_state->id,
$order,
$use_existings_payment
);
$carrier = new Carrier($order->id_carrier, $order->id_lang);
$templateVars = array();
if ($history->id_order_state == Configuration::get('PS_OS_SHIPPING')
&& $order->shipping_number
) {
$templateVars = array(
'{followup}' => str_replace(
'@',
$order->shipping_number,
$carrier->url
)
);
}
if ($history->addWithemail(true, $templateVars)) {
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
foreach ($order->getProducts() as $product) {
if (StockAvailable::dependsOnStock($product['product_id'])) {
StockAvailable::synchronize(
$product['product_id'],
(int)$product['id_shop']
);
}
}
}
} else {
$this->errors[] = sprintf(
Tools::displayError('Cannot change status for order #%d.'),
$id_order
);
}
}
}
}
} catch (Exception $e) {
$this->errors[] = 'Order '.$order->reference.' : '.$e->getMessage();
}
}
}
}
}
if (count($this->errors)==0) {
$filename = 'sepa_file_'.date('Y-m-d-His').'.xml';
file_put_contents(_PS_CACHE_DIR_.$filename, $sepadd->save());
Tools::redirectAdmin(self::$currentIndex.'&token='.$this->token
.'&file='.$filename);
}
}
parent::postProcess();
}
public function renderForm()
{
if (Tools::getIsset('dl')) {
if (!file_exists(_PS_CACHE_DIR_.Tools::getValue('dl'))) {
$this->errors[] = $this->module->l('A problem occurred with the file download. '
. 'Maybe you have already downloaded it?');
} else {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.Tools::getValue('dl'));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '.filesize(_PS_CACHE_DIR_.Tools::getValue('dl')));
readfile(_PS_CACHE_DIR_.Tools::getValue('dl'));
@unlink(_PS_CACHE_DIR_.Tools::getValue('dl'));
die();
}
}
require_once(dirname(__FILE__).'/../../classes/PrevSepaOrder.php');
$traited = (int)Tools::getValue('etat', 0);
if (Tools::getIsset('submitResetsepaorders')) {
$_POST['sepaordersFilter_id_sepa_detail'] = null;
$_POST['sepaordersFilter_order'] = null;
$_POST['sepaordersFilter_customer'] = null;
}
$fields_list = array(
'id_sepa_detail' => array(
'title' => $this->l('Id'),
'width' => 140,
'type' => 'text',
),
'order' => array(
'title' => $this->l('Order number'),
'width' => 140,
'type' => 'text',
'search' => 'true',
'orderby' => false
),
'customer' => array(
'title' => $this->l('Customer'),
'width' => 140,
'type' => 'text',
'search' => 'true',
'orderby' => false
),
'sepa_date' => array(
'title' => $this->l('Payment date'),
'width' => 70,
'type' => 'date',
'search' => false,
'orderby' => false
),
'jn' => array(
'title' => $this->l('J +/-N'),
'width' => 70,
'type' => 'text',
'search' => false,
'orderby' => false
),
'remarks' => array(
'title' => $this->l('Remarks'),
'width' => 140,
'type' => 'text',
'search' => false,
'orderby' => false,
)
);
$helper = new HelperList();
$helper->module = $this->module;
$helper->shopLinkType = '';
//$helper->simple_header = true;
$helper->list_id = $list_id = 'sepaorders';
if ($traited == 1) {
$helper->actions = array('view');
}
$helper->identifier = 'id_sepa_detail';
//$helper->show_toolbar = true;
$helper->title = $this->l('SEPA Direct Debits');
$helper->no_link = true;
$helper->token = $this->token;
$helper->currentIndex = self::$currentIndex;
// if (!$traited) {
$helper->bulk_actions = array(
'generateXML' => array(
'text' => $this->l('Generate the XML file'),
'icon' => 'icon-refresh'
)
);
$helper->force_show_bulk_actions = true;
// }
if (Tools::getIsset('file')) {
$helper->tpl_vars['dlFile'] = Tools::getValue('file');
}
if (Tools::isSubmit('submitBulkgenerateXMLconfiguration')) {
if (Tools::getIsset('cancel')) {
Tools::redirectAdmin(self::$currentIndex.'&token='.$this->token);
}
$helper->tpl_vars['updateOrderStatus_mode'] = 1;
$statuses = OrderState::getOrderStates((int)$this->context->language->id);
$helper->tpl_vars['order_statuses'] = array();
foreach ($statuses as $status) {
$helper->tpl_vars['order_statuses'][$status['id_order_state']] = $status['name'];
}
$helper->tpl_vars['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
}
$helper->tpl_vars['POST'] = $_POST;
if ($traited == 2) {
$sepa = PrevSepaOrder::getAllSepa(0, 0, null);
} else {
$sepa = PrevSepaOrder::getAllSepa($traited);
}
$sepa_list = array();
if ($sepa && count($sepa)>0) {
foreach ($sepa as $s) {
if (Tools::getValue('sepaordersFilter_id_sepa_detail') && Tools::getValue('sepaordersFilter_id_sepa_detail') != $s['id_sepa_detail']) {
continue;
}
$s['remarks'] = '';
$s['jn'] = '';
if (empty($s['rum'])) {
$s['remarks'] .= $this->l('RUM is empty')."; ";
}
if (empty($s['iban'])) {
$s['remarks'] .= $this->l('IBAN is empty')."; ";
}
if (empty($s['bic'])) {
$s['remarks'] .= $this->l('BIC is empty')."; ";
}
$s['order'] = new Order((int)$s['id_order']);
if ($s['order']->valid == 1) {
if (Tools::getValue('sepaordersFilter_order') && !preg_match('#'.Tools::getValue('sepaordersFilter_order').'#i', $s['order']->reference)) {
continue;
}
$nbdays = (strtotime($s['sepa_date']) - time()) / 86400;
// die(var_dump(intval($nbdays)));
if ($nbdays < 0) {
$s['jn'] = 'J -'.floor(abs($nbdays));
} else {
$s['jn'] = 'J +'.floor(abs($nbdays));
}
$customer_obj = new Customer((int)$s['order']->id_customer);
if (Tools::getValue('sepaordersFilter_customer') && !preg_match('#'.Tools::getValue('sepaordersFilter_customer').'#i', $customer_obj->firstname) && !preg_match('#'.Tools::getValue('sepaordersFilter_customer').'#i', $customer_obj->lastname)) {
continue;
}
$sepa_list[] = array(
'id_sepa_detail' => $s['id_sepa_detail'],
'order' => $s['order']->reference,
'customer' => Tools::strtoupper(Tools::substr($customer_obj->firstname, 0, 1).'. '.$customer_obj->lastname),
'sepa_date' => $s['sepa_date'],
'jn' => $s['jn'],
'remarks' => $s['remarks']
);
}
}
}
return $helper->generateList($sepa_list, $fields_list);
}
public function ajaxProcessGetUnvalidOrdersSEPA()
{
$sepa = PrevSepaOrder::getAllUnActive();
if (is_array($sepa) && count($sepa)) {
foreach ($sepa as &$s) {
$s['order'] = new Order((int)$s['id_order']);
$s['customer'] = new Customer((int)$s['order']->id_customer);
}
}
$this->context->smarty->assign('path', $this->url);
$this->context->smarty->assign('modimgdir', $this->images);
$this->context->smarty->assign('sepaList', $sepa);
echo $this->context->smarty->fetch($this->path.'views/templates/admin/sepa_list.tpl');
die();
}
public function getWorkingDays($date_start, $nb_days)
{
$wd = 1;
$i = 1;
while ($wd <= $nb_days) {
$date_mk = $date_start + (86400 * $i);
if ((date("N", $date_mk) != 6) && (date("N", $date_mk) != 7)) {
$wd++;
}
$i++;
}
return $date_start +(86400 * ($i-1));
}
public function getWorkingDay($date_start, $nb_days)
{
$date_start = $date_start + (86400 * $nb_days);
if ((date("N", $date_start) != 6) && (date("N", $date_start) != 7)) {
return $date_start;
} else {
$date_start = $date_start + 86400;
if ((date("N", $date_start) != 6) && (date("N", $date_start) != 7)) {
return $date_start;
} else {
return $date_start + 86400;
}
}
}
public function renderView()
{
require_once(dirname(__FILE__).'/../../classes/PrevSepaOrder.php');
$sepa_obj = new PrevSepaOrder((int) Tools::getValue('id_sepa_detail'));
$sepa = PrevSepaOrder::getGeneratedSepaList($sepa_obj->id_order);
$fields_list = array(
'id_sepa_detail' => array(
'title' => $this->l('Id'),
'width' => 140,
'type' => 'text',
),
'order' => array(
'title' => $this->l('Order number'),
'width' => 140,
'type' => 'text',
),
'sepa_date' => array(
'title' => $this->l('Payment date'),
'width' => 140,
'type' => 'date',
),
'jn' => array(
'title' => $this->l('J +/-N'),
'width' => 140,
'type' => 'text',
'search' => false,
'orderby' => false,
),
'remarks' => array(
'title' => $this->l('Remarks'),
'width' => 140,
'type' => 'text',
'search' => false,
'orderby' => false,
)
);
$helper = new HelperList();
// $helper->module = $this->module;
$helper->shopLinkType = '';
$helper->simple_header = false;
$helper->actions = array('');
$helper->identifier = 'id_sepa_detail';
$helper->title = $this->l('SEPA Direct Debits');
$helper->no_link = true;
$helper->token = $this->token;
$helper->currentIndex = self::$currentIndex;
$sepa_list = array();
if (count($sepa)>0) {
foreach ($sepa as $s) {
$s['remarks'] = '';
$s['jn'] = '';
if (empty($s['rum'])) {
$s['remarks'] .= $this->l('RUM is empty')."; ";
}
if (empty($s['iban'])) {
$s['remarks'] .= $this->l('IBAN is empty')."; ";
}
if (empty($s['bic'])) {
$s['remarks'] .= $this->l('BIC is empty')."; ";
}
$s['order'] = new Order((int)$s['id_order']);
if ($s['order']->valid == 1) {
$nbdays = (strtotime($s['sepa_date']) - time()) / 86400;
if ($nbdays < 0) {
$s['jn'] = 'J -'.floor(abs($nbdays));
} else {
$s['jn'] = 'J +'.floor(abs($nbdays));
}
$sepa_list[] = array(
'id_sepa_detail' => $s['id_sepa_detail'],
'order' => $s['order']->reference,
'sepa_date' => $s['sepa_date'],
'jn' => $s['jn'],
'remarks' => $s['remarks']
);
}
}
}
$this->tpl_view_vars = array(
'sepas' => $sepa_list,
'sepalist' => $helper->generateList($sepa_list, $fields_list)
);
if (Tools::getIsset('file')) {
$this->tpl_view_vars['dlFile'] = Tools::getValue('file');
}
return parent::renderView();
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,226 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
require_once(dirname(__FILE__).'/../../classes/PrevSepa.php');
class PrelevementSepaMandatSepaModuleFrontController extends ModuleFrontController
{
public $ssl = true;
public $display_column_left = false;
public function __construct()
{
parent::__construct();
$this->context = Context::getContext();
include_once($this->module->getLocalPath().'prelevementsepa.php');
}
/**
* @see FrontController::initContent()
*/
public function initContent()
{
if (Tools::getIsset('downloadMandate')) {
require_once(dirname(__FILE__).'/../../classes/HTMLTemplatePrelevementSepaPdf.php');
$prev_obj = new PrevSepa();
$id_sepa = $prev_obj->existCustomer((int)$this->context->customer->id);
$prev_obj = new PrevSepa((int)$id_sepa);
$prel_obj = new PrelevementSEPA();
$this->context->smarty->assign(array(
'sepa' => $prev_obj,
'conf' => $prel_obj->conf_keys,
'this_path_sepa' => $this->module->getPathUri(),
'shop_name' => $this->context->shop->name,
));
$template = $this->module->getLocalPath().'views/templates/front/pdf/'.$this->module->conf_keys['template'].'.tpl';
if (file_exists(_PS_THEME_DIR_.'modules/'.$this->module->name.'/views/templates/front/pdf/'.$this->module->conf_keys['template'].'.tpl')) {
$template = _PS_THEME_DIR_.'modules/'.$this->module->name.'/views/templates/front/pdf/'.$this->module->conf_keys['template'].'.tpl';
}
$prev_obj->html = $this->context->smarty->fetch($template);
$pdf = new PDF($prev_obj, 'PrelevementSepaPdf', Context::getContext()->smarty, 'P');
$pdf->render();
die();
}
$this->customProcess();
parent::initContent();
$this->assign();
}
/**
* Assign wishlist template
*/
public function assign()
{
if (!$this->context->customer->isLogged()) {
Tools::redirect('index.php?controller=authentication&back='
.urlencode($this->context->link->getModuleLink('prelevementsepa', 'mandatsepa')));
}
$prev_obj = new PrevSepa();
$id_sepa = $prev_obj->existCustomer((int)$this->context->customer->id);
if (!is_null($id_sepa)) {
//$prev_obj->id_customer = (int)$this->context->customer->id;
// $prev_obj->etat = 0;
// $prev_obj->save();
// $id_sepa = $prev_obj->id;
// } else {
$prel_obj = new PrelevementSEPA();
if ($prel_obj->isConnected() && $prel_obj->sms_solde>0) {
$this->context->controller->addCSS($this->module->getLocalPath().'views/css/intlTelInput.css');
$this->context->controller->addCSS($this->module->getLocalPath().'views/css/sepamandate.css');
$this->context->controller->addJS($this->module->getLocalPath().'views/js/intlTelInput.js');
$this->context->controller->addJS($this->module->getLocalPath().'views/js/sepamandate.js');
$this->context->smarty->assign('smsvalidation', 1);
}
}
$sepa = new PrevSepa((int)$id_sepa);
$this->context->smarty->assign(array(
'id_customer' => (int)$this->context->customer->id,
'customer_country' => $this->context->country->iso_code,
'errors' => $this->errors,
'sepa' => $sepa,
));
if (version_compare(_PS_VERSION_, '1.7', '<')) {
$this->setTemplate('1.6/mandatsepa.tpl');
} else {
$this->setTemplate('module:prelevementsepa/views/templates/front/1.7/mandatsepa.tpl');
}
}
public function customProcess()
{
if (Tools::getIsset('submitSepa')) {
$prev_obj = new PrevSepa();
$id_sepa = $prev_obj->existCustomer((int)$this->context->customer->id);
if (!is_null($id_sepa)) {
$prev_obj = new PrevSepa($id_sepa);
} else {
$prev_obj->etat = 0;
}
if (Tools::strlen($prev_obj->rum) < 3) {
$prev_obj->rum = 'UI'.date('Ymd').Tools::passwdGen(12, 'NUMERIC');
}
if (empty(Tools::getValue('sepa_name'))) {
$this->errors[] = $this->module->l("You must fill the account holder's name", 'mandatsepa');
} else {
$prev_obj->name = Tools::getValue('sepa_name');
}
if (empty(Tools::getValue('sepa_address'))) {
$this->errors[] = $this->module->l("You must fill the account holder's address", 'mandatsepa');
} else {
$prev_obj->address = Tools::getValue('sepa_address');
}
require($this->module->getLocalPath().'libs/oophp-iban.php');
$iban = str_replace(' ', '', Tools::strtoupper(Tools::getValue('sepa_iban')));
$bicbnc = str_replace(' ', '', Tools::strtoupper(Tools::getValue('sepa_bic')));
if (Tools::strlen($iban) > 3) {
$ibanObj = new IBAN($iban);
if ($ibanObj->Verify()) {
$prev_obj->iban = $iban;
} else {
$this->errors[] = $this->module->l("Your IBAN is incorrect");
}
} else {
$this->errors[] = $this->module->l("Your IBAN is incorrect");
}
if (preg_match('#^([a-zA-Z]){4}([a-zA-Z]){2}([0-9a-zA-Z]){2}([0-9a-zA-Z]{3})?$#', $bicbnc)) {
$prev_obj->bic = $bicbnc;
} else {
$this->errors[] = $this->module->l("Your BIC/BNC is incorrect", 'mandatsepa');
}
if (!$this->errors) {
$prev_obj->id_customer = (int)$this->context->customer->id;
$prev_obj->save();
}
// die(var_dump($this->errors));
}
if (Tools::getIsset('internationalphonenumber') && !Tools::getIsset('sepa_smscode')) {
$prel_obj = new PrelevementSEPA();
$code = rand(100000, 999999);
$prev_obj = new PrevSepa();
$id_sepa = $prev_obj->existCustomer((int)$this->context->customer->id);
$prev_obj = new PrevSepa((int)$id_sepa);
$prev_obj->code = $code;
$prev_obj->phone = Tools::getValue('internationalphonenumber');
$prev_obj->save();
require_once($this->module->getLocalPath().'classes/SMSDecanet.php');
$sms_obj = new SMSDecanet();
$sms_obj->send(array(
'LOGIN' => $prel_obj->conf_keys['decanetlogin'],
'API_KEY' => $prel_obj->conf_keys['decanetapikey'],
'TO' => Tools::getValue('internationalphonenumber'),
'COUNTRY' => $this->context->country->iso_code,
'FROMNUM' => 'SEPA',
'SMS' => $this->module->l('Hello, your SEPA validation code is', 'mandatsepa').' : '.$code
));
$this->context->smarty->assign(array('smsvalidation' => 1, 'smscode' => 1));
} elseif (Tools::getIsset('sepa_smscode')) {
$prel_obj = new PrelevementSEPA();
$prev_obj = new PrevSepa();
$id_sepa = $prev_obj->existCustomer((int)$this->context->customer->id);
$prev_obj = new PrevSepa((int)$id_sepa);
if ($prev_obj->code == Tools::getValue('sepa_smscode')) {
$prev_obj->datevalid = date('Y-m-d H:i:s');
$prev_obj->etat = 1;
$prev_obj->save();
$cust_orders = Order::getCustomerOrders($prev_obj->id_customer);
$listods = array();
if ($cust_orders) {
foreach ($cust_orders as $o) {
$listods[] = $o['id_order'];
}
PrevSepa::updateUnTraitSepaIDByOids($prev_obj->id, $listods);
}
require_once(dirname(__FILE__).'/../../classes/HTMLTemplatePrelevementSepaPdf.php');
$prev_obj = new PrevSepa();
$id_sepa = $prev_obj->existCustomer((int)$this->context->customer->id);
$prev_obj = new PrevSepa((int)$id_sepa);
$prel_obj = new PrelevementSEPA();
$this->context->smarty->assign(array(
'sepa' => $prev_obj,
'conf' => $prel_obj->conf_keys
));
$prev_obj->html = $this->context->smarty->fetch(
$this->module->getLocalPath().'views/templates/front/mandate.tpl'
);
$pdf = new PDFCore($prev_obj, 'PrelevementSepaPdf', Context::getContext()->smarty, 'P');
$pdf->filename = _PS_UPLOAD_DIR_.'sepa/'.sha1($prev_obj->rum.$prev_obj->id_customer).'.pdf';
$pdf->render('F');
} else {
$this->errors[] = $this->module->l(
'Your validation code is incorrect. Please try again.',
'mandatsepa'
);
}
}
}
}

View File

@@ -0,0 +1,61 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
/**
* @since 1.5.0
*/
class PrelevementSepaPaymentModuleFrontController extends ModuleFrontController
{
public $ssl = true;
public $display_column_left = false;
/**
* @see FrontController::initContent()
*/
public function initContent()
{
parent::initContent();
$cart = $this->context->cart;
$this->context->smarty->assign(array(
'nbProducts' => $cart->nbProducts(),
'cust_currency' => $cart->id_currency,
'currencies' => $this->module->getCurrency((int)$cart->id_currency),
'total' => $cart->getOrderTotal(true, Cart::BOTH),
'isoCode' => $this->context->language->iso_code,
'this_path' => $this->module->getPathUri(),
'this_path_sepa' => $this->module->getPathUri(),
'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->module->name.'/'
));
if (version_compare(_PS_VERSION_, '1.7', '<')) {
$this->setTemplate('payment_sepa.tpl');
} else {
$this->setTemplate('payment_execution.tpl');
}
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* 2007-2017 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author Decanet SA <contact@decanet.fr>
* @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
*/
/**
* @since 1.5.0
*/
class PrelevementSepaValidationModuleFrontController extends ModuleFrontController
{
public function postProcess()
{
$cart = $this->context->cart;
if ($cart->id_customer == 0
|| $cart->id_address_delivery == 0
|| $cart->id_address_invoice == 0
|| !$this->module->active
) {
Tools::redirect('index.php?controller=order&step=1');
}
// Check that this payment option is still available in case the customer
// changed his address just before the end of the checkout process
$authorized = false;
foreach (Module::getPaymentModules() as $module) {
if ($module['name'] == 'prelevementsepa') {
$authorized = true;
break;
}
}
if (!$authorized) {
die($this->module->l('This payment method is not available.', 'validation'));
}
$customer = new Customer($cart->id_customer);
if (!Validate::isLoadedObject($customer)) {
Tools::redirect('index.php?controller=order&step=1');
}
$currency = $this->context->currency;
$total = (float)$cart->getOrderTotal(true, Cart::BOTH);
$this->module->validateOrder(
(int)$cart->id,
(int)$this->module->conf_keys['state'],
$total,
$this->module->displayName,
null,
array(),
(int)$currency->id,
false,
$customer->secure_key
);
$this->module->generateSEPA($this->module->currentOrder);
Tools::redirect('index.php?controller=order-confirmation&id_cart='
.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder
.'&key='.$customer->secure_key);
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,234 @@
<?php
/**
* 2007-2016 Decanet
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@shoppinity.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Shoppinity to newer
* versions in the future. If you wish to customize Shoppinity for your
* needs please refer to http://www.shoppinity.com for more information.
*
* @author DECANET SARL <decanet.fr>
* @copyright 2007-2016 DECANET SARL
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Shoppinity
*/
require_once dirname(__FILE__) . '/../../config/config.inc.php';
require_once(dirname(__FILE__).'/classes/PrevSepaOrder.php');
require_once(dirname(__FILE__).'/classes/PrevSepaOrderTraited.php');
require_once(dirname(__FILE__).'/classes/PrevSepa.php');
require_once(dirname(__FILE__).'/classes/SepaDD.php');
require_once(dirname(__FILE__).'/prelevementsepa.php');
$sepatodo = PrevSepaOrder::getAllTodo();
$mod_obj = new PrelevementSEPA();
$errors = array();
$order_state = false;
$token = Tools::getValue('token');
if ($token != $mod_obj->conf_keys['token']) {
Tools::displayError('Invalid token given!');
die();
}
if ((int)$mod_obj->conf_keys['state_sepa']) {
$id_order_state = (int)$mod_obj->conf_keys['state_sepa'];
$order_state = new OrderState($id_order_state);
if (!Validate::isLoadedObject($order_state)) {
$order_state = false;
}
}
if (count($sepatodo)>0) {
$sepatraited_obj = new PrevSepaOrderTraited();
$sepatraited_obj->order_state = (int)Tools::getValue('id_order_state');
$sepatraited_obj->add();
foreach ($sepatodo as $s) {
$s['order'] = new Order((int)$s['id_order']);
if ($s['order']->valid == 1) {
$sepatraited_obj->addOrder((int)$s['id_order']);
$sepadd = new SepaDD(array(
'name' => $mod_obj->conf_keys['creancier'],
'IBAN' => $mod_obj->conf_keys['IBAN'],
'BIC' => $mod_obj->conf_keys['BIC'],
'batch' => true,
'creditor_id' => $mod_obj->conf_keys['ICS'],
'delay_working' => $mod_obj->conf_keys['delay_working'],
'currency' => 'EUR'
));
$id_sepa = $s['id_sepa_detail'];
if (count($errors) == 0) {
$sepa_obj = new PrevSepaOrder((int)$id_sepa);
$order = new Order((int)$sepa_obj->id_order);
$id_order = $order->id;
if (!Validate::isLoadedObject($order)) {
$errors[] = sprintf(
Tools::displayError('Order #%d cannot be loaded'),
$id_order
);
} else {
try {
$customer = new Customer((int)$order->id_customer);
$sepa_customer_obj = new PrevSepa($sepa_obj->id_sepa);
$sepa_obj->traite = 1;
$amount = (int)($order->total_paid * 100);
$sepa_obj->save();
if ((Tools::strlen($customer->company)>0)) {
$name = $customer->company;
} elseif (Tools::strlen($customer->firstname.$customer->lastname) > 3) {
$name = $customer->firstname.' '.$customer->lastname;
} else {
$name = 'No name';
}
$payment = array(
'name' => $name,
'IBAN' => $sepa_customer_obj->iban,
'BIC' => $sepa_customer_obj->bic,
'amount' => $amount,
'type' => 'RCUR',
'collection_date' => date(
'Y-m-d',
$mod_obj->getWorkingDays(
time(),
($mod_obj->conf_keys['delay_working']?$mod_obj->conf_keys['delay_working']:2)
)
),
'mandate_id' => $order->reference,
'mandate_date' => date('Y-m-d'),
'description' => str_replace(
'[reference]',
$order->reference,
$mod_obj->conf_keys['label']
)
);
// var_dump($payment);
$sepadd->addPayment($payment);
if ($order_state && Validate::isLoadedObject($order_state)) {
$current_order_state = $order->getCurrentOrderState();
if ($current_order_state->id == $order_state->id) {
$errors[] = $mod_obj->displayWarning(
sprintf('Order #%d has already been assigned this status.', $id_order)
);
} else {
$history = new OrderHistory();
$history->id_order = $order->id;
$history->id_employee = (int)ContextCore::getContext()->employee->id;
$use_existings_payment = !$order->hasInvoice();
$history->changeIdOrderState((int)$order_state->id, $order, $use_existings_payment);
$carrier = new Carrier($order->id_carrier, $order->id_lang);
$templateVars = array();
if ($history->id_order_state == Configuration::get('PS_OS_SHIPPING')
&& $order->shipping_number
) {
$templateVars = array(
'{followup}' => str_replace('@', $order->shipping_number, $carrier->url)
);
}
if ($history->addWithemail(true, $templateVars)) {
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
foreach ($order->getProducts() as $product) {
if (StockAvailable::dependsOnStock($product['product_id'])) {
StockAvailable::synchronize(
$product['product_id'],
(int)$product['id_shop']
);
}
}
}
} else {
$errors[] = sprintf(
Tools::displayError('Cannot change status for order #%d.'),
$id_order
);
}
}
}
} catch (Exception $e) {
$errors[] = 'Order '.$order->reference.' : '.$e->getMessage();
}
}
}
if (count($errors) == 0) {
$filename = 'sepa_file_'.date('Y-m-d-His').'.xml';
$result_sepa = $sepadd->save();
if (!file_exists(_PS_IMG_DIR_.'sepa/')) {
mkdir(_PS_IMG_DIR_.'sepa', 0777, true);
}
file_put_contents(_PS_IMG_DIR_.'sepa/'.$filename, $result_sepa);
$attach = array('content' => $result_sepa, 'mime' => 'application/xml', 'name' => $filename);
// envoie par mail et FTP si définie.
if ((int)$mod_obj->conf_keys['sendsepaemail'] && !empty($mod_obj->conf_keys['sepaemail'])) {
MailCore::Send(
(int)ContextCore::getContext()->language->id,
'send_sepa_file',
MailCore::l('New sepa file'),
array(),
$mod_obj->conf_keys['sepaemail'],
null,
null,
$attach,
null,
null,
dirname(__FILE__).'/mails/'
);
}
// envoie du fichier SEPA sur le FTP
if ((int)$mod_obj->conf_keys['sendsepaftp']) {
$server = $mod_obj->conf_keys['ftp_host'];
$user = $mod_obj->conf_keys['ftp_login'];
$pwd = $mod_obj->conf_keys['ftp_password'];
$port = $mod_obj->conf_keys['ftp_port'];
$sslcon = $mod_obj->conf_keys['ftp_sslcon'];
$path = $mod_obj->conf_keys['ftp_dirpath'];
if (!function_exists('ftp_ssl_connect')) {
$sslcon = 0;
}
if ($sslcon) {
if (!$conn_id = @ftp_ssl_connect($server, $port)) {
die($mod_obj->l('Failed to connect to FTP '));
}
} elseif (!$conn_id = ftp_connect($server, $port)) {
die($mod_obj->l('Failed to connect to FTP '));
}
// Identification avec un nom d'utilisateur et un mot de passe
if (!ftp_login($conn_id, $user, $pwd)) {
die($mod_obj->l('Failed to log in to FTP '));
}
ftp_pasv($conn_id, true);
if (!ftp_put($conn_id, $path.$filename, _PS_IMG_DIR_.'sepa/'.$filename, FTP_ASCII)) {
die($mod_obj->l("An error occured while loading file $filename\n"));
}
// Fermeture de la connexion
ftp_close($conn_id);
// die(var_dump($result_sepa));
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,22 @@
matrix:
include:
- php: 5.2
dist: precise
- php: 5.3
dist: precise
language: php
dist: trusty
php:
- '5.4'
- '5.5'
- '5.6'
- '7.0'
- nightly
- hhvm-3.3
- hhvm-3.6
- hhvm-3.9
- hhvm-3.12
- hhvm-3.15
- hhvm-3.18
- hhvm-nightly
script: php utils/test.php && php utils/ootest.php && php utils/other-tests.php

View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
{
"name": "globalcitizen/php-iban",
"description": "php-iban is a library for parsing and validating IBAN (and IIBAN) bank account information.",
"license": "LGPL-3.0",
"autoload": {
"files": ["oophp-iban.php","php-iban.php"]
}
}

View File

@@ -0,0 +1,70 @@
This file lists specific errors observed in the official IBAN specification.
In addition to the specific errors, there persist basic outstanding
matters that cause issue for implementers:
- Non 1:1 mapping of records to countries (eg: French territories, etc.)
- Mixing of free text and hard data in specification fields
- Missing clear definition of fields ("Domestic account number example" is
in many cases pre-IBAN era, in others it's an IBAN-era BBAN)
- Lack of validation of information in fields prior to publishing
- Lack of synchronisation between TXT and PDF versions of the registry
2016-01-31
----------
- SWIFT released a v63 registry PDF document supposedly
including a fix for the BBAN example for Israel with reason "typo", however
it still does not match with the specified BBAN format.
2016-01-21
----------
- Correction for broken example IBANs for multiple countries (checksum
failed, length incorrect, etc.)
- Correction for broken IBAN length field for Khazakstan (no specified
length whatsoever)
2011-07-16
----------
- No information for Kuwait past sixth column
- Total absence of information regarding Kazakhstan
- '1.00001E+15' instead of a valid BBAN example for Lithuania
- Repeated IBAN example in human format instead of IBAN format-
specification for UAE
- Incorrect domestic example for Bulgaria, Kazakhstan, Latvia,
Lithuania, Luxembourg, Macedonia, Mauritius, Romania, San Marino
(complete, human-format IBAN instead of domestic example)
Early 2012
----------
- Inconsistent record ordering (KW, KZ)
- Inconsistent capitalization (DK)
- Continued presence of incorrect domestic examples
February 2013
-------------
- Deployment of unparseable special values such as "Not in use" (FI).
- Still(!) missing a registry entry for 2010's 'new' entry of Khazakstan
September 2013
--------------
- Azerbaijan, Brazil, Costa Rica, Palestine, Virgin Islands 'SEPA
Country' field in PDF (yes/no) is completely blank
March 2014
----------
- In multiple cases, territories of a major country have a SEPA status
that differs from the parent jurisdiction. The IBAN specification as
previously released does not include individual records for these
territories, and thus cannot convey this important information.
- The IBAN registry's old URL is no longer publicly available! Its now
ends in a 404, and the apparent new home, located over at
http://www.swift.com/products_services/by_type/reference_data/iban_registry_iso13616
does not have any content. The parent portion of this part of the
SWIFT website suggests the information may have been moved to a new
'SWIFTRef' site, however that site appears to only peddle paid for
directories of BICs and similar. The new location after much
searching was found to be http://www.swift.com/products_services/bic_and_iban_format_registration_iban_format_r
June 2014
---------
- The TXT registry records of QA and JO do not match those within the
PDF and are essentially spurious while looking roughly correct. Dang.

View File

@@ -0,0 +1,27 @@
# Falsehoods Programmers Believe About IBANs
In the spirit of [Falsehoods Programmers Believe About Phone Numbers](https://github.com/googlei18n/libphonenumber/blob/master/FALSEHOODS.md), here is a list of mistaken perspectives on International Bank Account Numbers (IBAN)...
1. **IBANs are global.**
While the IBAN system has been deployed in some states on most continents, it is a long way from achieving universal adoption. Certain states, such as Australia, when their High Value Clearing Payments Association were queried regarding their decision not to adopt IBAN, first refused to respond for upwards of 12 months then finally refused to release any reasoning. There are a lot of established interests that are against reduced barriers to financial systems integration.
2. **IBAN country codes are the same as ISO3166-1 alpha-2 country codes.**
Quite dangerously this is mostly, but not always the case. Both unofficial codes such as `AA` and various dependent territories which may use the parent jurisdiction's code instead of their own do not equate to the ISO3166-1 alpha-2 country code as expected.
3. **IBAN country codes are the same as IANA country codes.**
Quite dangerously this is mostly, but not always the case. Take for example `XK`, unofficial codes such as `AA`, or various dependent territories which may use the parent jurisdiction's code instead of their own.
4. **IBAN represents a 'free' and 'neutral' namespace for global financial cooperation.**
In fact, under the IBAN standard, which is managed by defacto global monopoly SWIFT, which has significant political significance to and affinity for US interests despite being a nominally Belgium-registered international cooperative, the only people who can create endpoints are existing financial institutions within countries holding an ISO3166-1 alpha-2 country code, a list which excludes many legitimate actors, virtually all innovators, plus the various states of the world with limited recognition. For a potentially mutually interoperable system adopted by some actors (eg. Bitcoin exchange Kraken) see the Internet IBAN (IIBAN) proposal at http://ifex-project.org/
5. **Pre-IBAN national checksums are still in operation.**
There is no way to reliably determine whether or not a given country had a national, pre-IBAN checksum system, whether that system was actually applied to all banks (certain central banks are known exceptions), or whether that system is still in operation after IBAN adoption. The `php-iban` library represents a best-effort approach to gathering this knowledge as appropriate.
6. **IBAN is clearly published standard.**
There are significant problems with the current dual-format publishing process used by SWIFT, which are documented [over here](https://raw.githubusercontent.com/globalcitizen/php-iban/master/docs/COMEDY-OF-ERRORS).
7. **IBANs are always written the same way.**
Some countries tend to continue to use methods of spacing/delineation amongst legacy components present within the IBAN. Others tend to concatenate the entire IBAN to a machine-readable single word. Still others use the human-style formatting with four characters per block, `XXXX YYYY ZZZZ 0000`. It is difficult to know how to best present an IBAN to a customer. In general, reasonable practice is that if the user is likely to manually transcribe (eg. via pen and paper) then a human format (four characters per block) is recommended. If the output is likely to be copy-pasted, however, then a single word (machine format) is preferred... in which case care should be taken to exclude neighbouring punctuation.
8. **IBAN solves input errors.**
IBAN has a strong checksum system built in, however this does not really help you to help the user find the source of an input problem. The `php-iban` library includes a flexible and robust mistranscription error detection system which can assist you in presenting possible errors to the user for manual evaluation.

View File

@@ -0,0 +1,63 @@
By unix tradition, this file outlines information that may be useful to
people who wish to modify the php-iban project. It outlines some basic
information around design decisions and other considerations.
Procedural style
----------------
The code is written in PHP's original procedural style, and does
not require or assume any OO model. This is unix tradition and
should ease any integration pains due to objectspace mismatches.
In addition, it should make it easy for users both within an OO
or a procedural codebase to make use of the library. An OO wrapper
has been supplied to make things more familiar for those who are
only exposed to OO PHP: please try to keep it in synch with the
procedural (main) library where possible.
Registry maintenance
--------------------
The 'convert-registry.php' tool found in the 'utils/' subdirectory
is intended to assist with the automatic conversion of the SWIFT-
provided 'IBAN Registry' text files to the format required to
support php-iban execution. Why is there a new format, and why is it
distributed with php-iban instead of being generated on the fly
from SWIFT-provided data files? There are a few reasons:
- Error correction
If errors are discovered in the official specification then they
can be resolved by us. There are (or have been) known errors
with the official IBAN Registry. (See COMEDY-OF-ERRORS)
- Exclusion correction
If exclusions are discovered in the official specification then
they can be resolved by us. There are (or have been) known
exclusions from the official IBAN Registry. (See COMEDY-OF-ERRORS)
- Efficiency
Because pattern matching is a core part of the functionality of
php-iban, and the pattern algorithms distributed by SWIFT are
(rather strangely) not in regular expression format, using their
files directly would result in a fairly significant startup
penalty as pattern conversion would be required (at each
invocation!) unless a caching strategy were deployed, which would
create additional complexity and sources of bugs (in addition,
due to the previous two points automatic conversion is not
presently possible ... and may never be!)
- Maintainability
Distribution of a modified registry along with php-iban places
the burden of registry maintenance on with the package
maintainer(s) rather than with the user. This is better for
users who, if they really want, can still hack their local copy.
Note that due to points one and two, the 'convert-registry.php' tool
is insufficient to produce a correct 'registry.txt' file. (You may
wish to review the differences between your newly generated file
and the original with the 'diff' tool in order to ascertain what
has changed.)
A closing point on the registry: obviously, if any new fields are
added, then it is best to append them to the end of the registry
(rightmost, new field) in order to preserve backwards compatibility
instead of re-ordering the fields which would break older installs.
(The internal '_iban_load_registry()' function re-orders these fields
at load time in order to simplify runtime debugging, anyway.)

Binary file not shown.

View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -0,0 +1,207 @@
php-iban README
---------------
php-iban is a library for parsing and validating International Bank
Account Number (IBAN) information in PHP.
It also validates Internet International Bank Account Number
(IIBAN) as specified at http://tools.ietf.org/html/draft-iiban-01
(see also http://www.ifex-project.org/our-proposals/iiban)
php-iban lives at http://code.google.com/p/php-iban
What is an IBAN?
----------------
An IBAN is basically a standardised way of explaining a bank
account number that works across borders. Its structure is:
<Two Letter ISO Country Code> + <Two Digit Checksum] + <BBAN>
BBAN is the term used to describe the national-level format
for a bank account number, which varies between countries
(and was sometimes created just to get IBAN connectivity!).
Note that a BBAN may have its own checksum algorithm.
IBAN provides basic protection, using the checksum, against
transcription (ie: human copying) errors. It also provides
a registry of valid destination countries and their BBAN
formats. Thus, when you ask php-iban to 'validate' an IBAN
it ensures that these checks are passed. However, it cannot
ensure that a bank account actually exists - the only party
who can do that is the receiving bank or country.
IBAN was invented in Europe, however its usage is growing
rapidly to other parts of the world. Thus, the future of
this library looks pretty good.
For further information, please see 'docs/ISO13616.pdf' or
visit Wikipedia at http://en.wikipedia.org/wiki/IBAN
What is an IIBAN?
-----------------
An Internet IBAN (IIBAN) identifies an internet-based financial
endpoint in a manner that is superset-compatible with the existing
European Committee for Banking Standards (ECBS) International Bank
Account Number (IBAN) standard [ISO13616].
For more information see http://tools.ietf.org/html/draft-iiban-00
and http://www.ifex-project.org/our-proposals/iiban
To disable IIBAN support from your installation, simply remove
the second ('AA|...') line from the top of the registry.txt file.
Execution environment
---------------------
At present the library merely requires a PHP engine to be present
and has no external dependencies. It is recommended that your
PHP engine is configured to disable verbose warnings for events
such as access of unknown array indexes, though this should be
standard on almost any PHP deployment today. Any PHP engine
in use today should be compatible, though PHP3 or PHP4 execution
environments may require minor modifications (specifically,
some string functions may have changed).
Installation
------------
Simply copy 'php-iban.php' and 'registry.txt' to an appropriate
location for your project. The location of the files will affect
the 'require_once()' line used to load the library from your
codebase, and may have relevance security (see 'Security' below).
Note that 'php-iban.php' expects to find 'registry.txt' in the
same directory as itself.
Security
--------
Following best practice for library files, the location chosen
for the php-iban.php and registry.txt files should ideally be
outside of any web-accessible directories. Thus, if your
web project lives in /var/www/myproject/htdocs/ then it would
be preferably to place php-iban in /var/www/myproject or some
other directory that is not visible to regular web users.
Secondly, neither file should be writable by the web server
itself in order to prevent compromise of the execution path
(ie: getting hacked). So, for example if your web server runs
as user 'www', group 'www', you can ensure that the web server
has minimal required privileges against the files as follows
(note that you will need to be root to execute these commands):
# chown <myuser> php-iban registry.txt # where <myuser> is a
# non-root user that
# is not 'www'.
# chgrp www php-iban registry.txt # set group to 'www'
# chmod ugo-rwx php-iban registry.txt # remove privileges
# chmod g+r php-iban registry.txt # allow 'www' group
# to read the files
Obviously the above do not apply if you are using PHP in a
non web-oriented project (eg: a cronjob or daemon), a usage
of the language that is apparently growing - but limited.
Using the library
-----------------
Basic invocation is as follows:
# include the library
require_once('/path/to/php-iban.php'); # /path/to/ is optional
# use some library function or other...
if(!verify_iban($iban_to_verify)) {
# blame the user...
}
Note that because the library is designed in a procedural manner
rather than an object-oriented manner it should be easy to
integrate with a wide variety of established codebases and
PHP interpreter versions.
Using the library's OO wrapper
------------------------------
Because many new PHP programmers seems to learn the language via
books that only teach OO based programming and are thus unfamiliar
with procedural PHP (and often relatively inexperienced as
programmers, too) an OO wrapper-library has been provided.
======================= READ THIS =================================
However *you should avoid excessive use of OO*. For some thought
provoking discussions of the negative aspects of overusing OO,
please refer to 'Coders at Work' and 'The Art of UNIX Programming'.
(OO is great for some problems, but simply pointless for most.)
===================================================================
Anyway, to use the OO wrapper supplied, invocation is as follows:
# include the OO wrapper to the library
require_once('/path/to/oophp-iban.php'); # /path/to is optional
# instantiate an IBAN object
$myIban = new IBAN('AZ12345678901234');
if(!$myIban->Verify()) {
# blame the user...
}
Documentation
-------------
There are three types of functions provided by the library:
- IBAN-level functions
These are functions that operate on an IBAN. All of these
functions accept either machine format or human format
IBANs as input. Typically they return facts about an IBAN
as their output (for example whether it is valid or not,
or the BBAN (national-level) portion of the IBAN), though
some of them may perform other functions (eg: fixing a
broken IBAN checksum). These functions are named 'iban_*'
with the exception of the most commonly used function,
'verify_iban()', and excepting the country-level functions.
(Regarding the object oriented wrapper - all of these
functions are implemented as methods on IBAN objects)
- IBAN country-level functions
These functions return information about countries that are
part of the IBAN standard. They each take the two letter
ISO country code at the beginning of an IBAN as their
argument. They are named 'iban_country_*', with the
exception of 'iban_countries()' which returns a list of
the known IBAN countries. (For example, functions that
return an example IBAN or BBAN for the country, or the
name of the country.)
(Regarding the object oriented wrapper - all of these
functions are implemented as methods on IBANCountry
objects, except for 'iban_countries()' which is
implemented as the Countries() method on the IBAN class)
- Internal functions
These functions begin with '_iban_*' and can be ignored.
(Regarding the object oriented wrapper - these functions
are not present)
Please refer to either http://code.google.com/p/php-iban or the
commented source code of php-iban itself for the complete list of
which functions are available. Of course, in unix style one could
achieve the same in a pinch as follows (instant documentation!):
$ grep function php-iban.php
$ egrep '(Class|function)' oophp-iban.php
Community
---------
You are encouraged to contribute bugs, feedback and suggestions
through the project's website.
Particularly if you deploy php-iban in a commercial setting, you are
STRONGLY encouraged to join the project's mailing list, which can
be found via the website. Joining the mailing list ensures that you
can be made aware of important updates. Important updates include:
- Updates to new registry editions (support new countries that have
been added to the IBAN system)
- Bug fixes
- Security updates
The email list receives almost no traffic and as a 'Google Group' is
well protected from spam, so don't worry about junk in your inbox.
Thanks for choosing php-iban! You have excellent taste in software ;)

View File

@@ -0,0 +1,17 @@
To get the latest ISO13616 IBAN registry, go to:
https://www.swift.com/standards/data-standards/iban#topic-tabs-menu
TXT format:
https://www.swift.com/node/11971
PDF format:
https://www.swift.com/file/5996/download?token=lf3shUpn
Unfortunately, it has been noticed in 2011 that the official .txt file is
not an accurate representation of the PDF format specification, and lacks
some information. It is hoped that in future SWIFT will be more careful to
publish only correct standards information.
It has been noted in 2014 that this is still the case.
(For more information on this subject, see the HACKING file)

View File

@@ -0,0 +1,9 @@
Interpreting the SEPA Field
===========================
Note that some IIBAN providers may in fact provide SEPA connectivity.
Thus, implementers are reminded to consider the reported SEPA status
of a country within the registry as confirming rather than negating
the potential SEPA status of a potential financial institution who
may be party to a proposed transaction.

View File

@@ -0,0 +1,27 @@
Testing
-------
This document describes the project's approach to testing. Essentially we do not require tests
for all code but do strive to maintain reasonable test coverage.
Local testing
-------------
To run local tests, simply execute the appropriate group of tests in the `utils` subdirectory.
For example:
```sh
$ php utils/test.php # Run main tests
$ php utils/ootest.php # Run object-oriented wrapper tests
$ php utils/other-test.php # Run additional tests
```
Automated testing
-----------------
The project uses the free Travis Continuous Integration (CI) service to test new code.
The service runs automatically every time code is committed, and the results will be emailed
and displayed publicly on the project's github page.

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1,49 @@
; formalities
input-roman = number / letter
number = c-0 / c-1 / c-2 / c-3 / c-4 / c-5 / c-6 / c-7 / c-8 / c-9
letter = c-a / c-b / c-c / c-d / c-e / c-f / c-g / c-h / c-i / c-j
/ c-k / c-l / c-m / c-n / c-o / c-p / c-q / c-r / c-s
/ c-t / c-u / c-v / c-w / c-x / c-y / c-z
; possible sources of mistranscribed numbers
c-0 = "O" / "6" / "D" / "G"
c-1 = "I" / "L" / "7" / "2" / "Z"
c-2 = "Z" / "7" / "P" / "E" / "1"
c-3 = "8" / "B"
c-4 = "G" / "U"
c-5 = "S" / "7"
c-6 = "0" / "O" / "8" / "G" / "C" / "B" / "D"
c-7 = "J" / "I" / "1" / "L"
c-8 = "B" / "3" / "6"
c-9 = "G" / "Y" / "O" / "0" / "D"
; possible sources of mistranscribed letters
c-a = "G" / "Q" / "O" / "0"
c-b = "6" / "3" / "8" / "P" / "0" / "O"
c-c = "R" / "6" / "I" / "L" / "O" / "0"
c-d = "0" / "O" / "9" / "Q" / "G" / "6" / "A"
c-e = "F" / "G" / "0" / "2" / "K" / "Z" / "S" / "O"
c-f = "E" / "K" / "T" / "P" / "Y" / "4" / "B" / "7" / "1"
c-g = "9" / "Q" / "8" / "6" / "0" / "C" / "4" / "O"
c-h = "B" / "N" / "A" / "4" / "6" / "M" / "W" / "F" / "R" / "T" / "X"
c-i = "1" / "L" / "7" / "J" / "2" / "T" / "Z"
c-j = "I" / "7" / "2" / "9" / "1" / "U" / "T" / "Q" / "P" / "Y" / "Z"
/ "L" / "S"
c-k = "F" / "X" / "H" / "R"
c-l = "1" / "2" / "7" / "C" / "I" / "J" / "R" / "T" / "Y" / "Z"
c-m = "H" / "8" / "E" / "3" / "N" / "V" / "W"
c-n = "H" / "R" / "C" / "2" / "4" / "M" / "O" / "P" / "K" / "T" / "Z"
c-o = "0" / "6" / "9" / "A" / "D" / "G" / "C" / "E" / "B" / "N" / "P"
/ "Q" / "R"
c-p = "F" / "4" / "8" / "2" / "B" / "J" / "R" / "N" / "O" / "T" / "Y"
c-q = "O" / "G" / "9" / "Y" / "1" / "7" / "L"
c-r = "K" / "B" / "V" / "C" / "1" / "L" / "2"
c-s = "5" / "6" / "9" / "B" / "G" / "Q" / "A" / "Y"
c-t = "1" / "4" / "7" / "F" / "I" / "J" / "L" / "P" / "X" / "Y"
c-u = "V" / "N" / "A" / "4" / "9" / "W" / "Y"
c-v = "U" / "R" / "N"
c-w = "M" / "N" / "U" / "V"
c-x = "K" / "F" / "4" / "T" / "V" / "Y"
c-y = "G" / "V" / "J" / "I" / "4" / "9" / "T" / "F" / "Q" / "1"
c-z = "2" / "1" / "L" / "R" / "I" / "7" / "V" / "3" / "4"

View File

@@ -0,0 +1,218 @@
<?php
# OO wrapper for 'php-iban.php'
Class IBAN {
function __construct($iban = '') {
require_once('php-iban.php'); # load the procedural codebase
$this->iban = $iban;
}
public function Verify($iban='',$machine_format_only=false) {
if($iban!='') { return verify_iban($iban,$machine_format_only); }
return verify_iban($this->iban,$machine_format_only);
# we could throw exceptions of various types, but why - does it really
# add anything? possibly some slightly better user feedback potential.
# however, this can be written by hand by performing individual checks
# ala the code in verify_iban() itself where required, which is likely
# almost never. for the increased complexity and
# maintenance/documentation cost, i say, therefore: no. no exceptions.
}
public function VerifyMachineFormatOnly($iban='') {
if($iban!='') { return verify_iban($iban,true); }
return verify_iban($this->iban,true);
}
public function MistranscriptionSuggestions() {
return iban_mistranscription_suggestions($this->iban);
}
public function MachineFormat() {
return iban_to_machine_format($this->iban);
}
public function HumanFormat() {
return iban_to_human_format($this->iban);
}
public function Country($iban='') {
return iban_get_country_part($this->iban);
}
public function Checksum($iban='') {
return iban_get_checksum_part($this->iban);
}
public function NationalChecksum($iban='') {
return iban_get_nationalchecksum_part($this->iban);
}
public function BBAN() {
return iban_get_bban_part($this->iban);
}
public function VerifyChecksum() {
return iban_verify_checksum($this->iban);
}
public function FindChecksum() {
return iban_find_checksum($this->iban);
}
public function SetChecksum() {
$this->iban = iban_set_checksum($this->iban);
}
public function ChecksumStringReplace() {
return iban_checksum_string_replace($this->iban);
}
public function FindNationalChecksum() {
return iban_find_nationalchecksum($this->iban);
}
public function SetNationalChecksum() {
$this->iban = iban_set_nationalchecksum($this->iban);
}
public function VerifyNationalChecksum() {
return iban_verify_nationalchecksum($this->iban);
}
public function Parts() {
return iban_get_parts($this->iban);
}
public function Bank() {
return iban_get_bank_part($this->iban);
}
public function Branch() {
return iban_get_branch_part($this->iban);
}
public function Account() {
return iban_get_account_part($this->iban);
}
public function Countries() {
return iban_countries();
}
}
# IBANCountry
Class IBANCountry {
# constructor with code
function __construct($code = '') {
$this->code = $code;
}
public function Code() {
return $this->code;
}
public function Name() {
return iban_country_get_country_name($this->code);
}
public function DomesticExample() {
return iban_country_get_domestic_example($this->code);
}
public function BBANExample() {
return iban_country_get_bban_example($this->code);
}
public function BBANFormatSWIFT() {
return iban_country_get_bban_format_swift($this->code);
}
public function BBANFormatRegex() {
return iban_country_get_bban_format_regex($this->code);
}
public function BBANLength() {
return iban_country_get_bban_length($this->code);
}
public function IBANExample() {
return iban_country_get_iban_example($this->code);
}
public function IBANFormatSWIFT() {
return iban_country_get_iban_format_swift($this->code);
}
public function IBANFormatRegex() {
return iban_country_get_iban_format_regex($this->code);
}
public function IBANLength() {
return iban_country_get_iban_length($this->code);
}
public function BankIDStartOffset() {
return iban_country_get_bankid_start_offset($this->code);
}
public function BankIDStopOffset() {
return iban_country_get_bankid_stop_offset($this->code);
}
public function BranchIDStartOffset() {
return iban_country_get_branchid_start_offset($this->code);
}
public function BranchIDStopOffset() {
return iban_country_get_branchid_stop_offset($this->code);
}
public function NationalChecksumStartOffset() {
return iban_country_get_nationalchecksum_start_offset($this->code);
}
public function NationalChecksumStopOffset() {
return iban_country_get_nationalchecksum_stop_offset($this->code);
}
public function RegistryEdition() {
return iban_country_get_registry_edition($this->code);
}
public function SWIFTOfficial() {
return iban_country_get_country_swift_official($this->code);
}
public function IsSEPA() {
return iban_country_is_sepa($this->code);
}
public function IANA() {
return iban_country_get_iana($this->code);
}
public function ISO3166() {
return iban_country_get_iso3166($this->code);
}
public function ParentRegistrar() {
return iban_country_get_parent_registrar($this->code);
}
public function CurrencyISO4217() {
return iban_country_get_currency_iso4217($this->code);
}
public function CentralBankURL() {
return iban_country_get_central_bank_url($this->code);
}
public function CentralBankName() {
return iban_country_get_central_bank_name($this->code);
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,117 @@
country_code|country_name|domestic_example|bban_example|bban_format_swift|bban_format_regex|bban_length|iban_example|iban_format_swift|iban_format_regex|iban_length|bban_bankid_start_offset|bban_bankid_stop_offset|bban_branchid_start_offset|bban_branchid_stop_offset|registry_edition|country_sepa|swift_official|bban_checksum_start_offset|bban_checksum_stop_offset|country_code_iana|country_code_iso3166_1_alpha2|parent_registrar|currency_iso4217|central_bank_url|central_bank_name
AL|Albania|0000000235698741|212110090000000235698741|8!n16!c|^(\d{8})([A-Za-z0-9]{16})$|24|AL47212110090000000235698741|AL2!n8!n16!c|^AL(\d{2})(\d{8})([A-Za-z0-9]{16})$|28|0|2|3|6|2011-06-20|0|1|7|7|al|AL||ALL|www.bankofalbania.org|Bank of Albania
DZ|Algeria|12341234123412341234|12341234123412341234|20!n|^[0-9]{20}$|20|DZ3512341234123412341234|DZ2!n20!n|^DZ(\d{2})(\d{20})$|24|||||2016-01-22|0|0|||dz|DZ||DZD|www.bank-of-algeria.dz|Bank of Algeria
AD|Andorra|2030200359100100|00012030200359100100|4!n4!n12!c|^(\d{4})(\d{4})([A-Za-z0-9]{12})$|20|AD1200012030200359100100|AD2!n4!n4!n12!c|^AD(\d{2})(\d{4})(\d{4})([A-Za-z0-9]{12})$|24|0|3|4|7|2011-06-20|1|1|||ad|AD||EUR|www.inaf.ad|Institut Nacional Andorrà de Finances
AO|Angola|123412341234123412341|123412341234123412341|21!n|^[0-9]{21}$|21|AO44123412341234123412341|AO2!n21!n|^AO(\d{2})(\d{21})$|25|||||2016-01-22|0|0|||ao|AO||AOA|www.bna.ao|National Bank of Angola
AT|Austria|19043-234573201|1904300234573201|5!n11!n|^(\d{5})(\d{11})$|16|AT611904300234573201|AT2!n5!n11!n|^AT(\d{2})(\d{5})(\d{11})$|20|0|4|||2011-06-20|1|1|||at|AT||EUR|www.oenb.at|Austrian National Bank
AZ|Azerbaijan|NABZ00000000137010001944|NABZ00000000137010001944|4!a20!c|^([A-Z]{4})([A-Za-z0-9]{20})$|24|AZ21NABZ00000000137010001944|AZ2!n4!a20!c|^AZ(\d{2})([A-Z]{4})([A-Za-z0-9]{20})$|28|0|3|||2012-05-29|0|1|||az|AZ||AZN|www.cbar.az|The Central Bank of the Republic of Azerbaijan
BH|Bahrain|00001299123456|BMAG00001299123456|4!a14!c|^([A-Z]{4})([A-Za-z0-9]{14})$|22|BH67BMAG00001299123456|BH2!n4!a14!c|^BH(\d{2})([A-Z]{4})([A-Za-z0-9]{14})$|22|0|3|||2012-05-29|0|1|||bh|BH||BHD|www.cbb.gov.bh|Central Bank of Bahrain
BE|Belgium|539-0075470-34|539007547034|3!n7!n2!n|^(\d{3})(\d{7})(\d{2})$|12|BE68539007547034|BE2!n3!n7!n2!n|^BE(\d{2})(\d{3})(\d{7})(\d{2})$|16|0|2|||2011-06-20|1|1|10|11|be|BE||EUR|www.nbb.be|National Bank of Belgium
BJ|Benin|A12312341234123412341234|A12312341234123412341234|1!a23!n|^[A-Z]{1}[0-9]{23}$|24|BJ83A12312341234123412341234|BJ2!n1!a23!n|^BJ(\d{2})([A-Z]{1}[0-9]{23})$|28|||||2016-01-22|0|0|||bj|BJ||XOF|www.bceao.int|Central Bank of West African States (BCEAO)
BA|Bosnia and Herzegovina|199-044-00012002-79|1990440001200279|3!n3!n8!n2!n|^(\d{3})(\d{3})(\d{8})(\d{2})$|16|BA391290079401028494|BA2!n3!n3!n8!n2!n|^BA(\d{2})(\d{3})(\d{3})(\d{8})(\d{2})$|20|0|2|3|5|2011-06-20|0|1|14|15|ba|BA||BAM|www.cbbh.ba|Central Bank of Bosnia and Herzegovina
BR|Brazil|0009795493C1|00360305000010009795493P1|8!n5!n10!n1!a1!c|^(\d{8})(\d{5})(\d{10})([A-Z]{1})([A-Za-z0-9]{1})$|25|BR9700360305000010009795493P1|BR2!n8!n5!n10!n1!a1!c|^BR(\d{2})(\d{8})(\d{5})(\d{10})([A-Z]{1})([A-Za-z0-9]{1})$|29|0|7|8|12|2013-06-20|0|1|||br|BR||BRL|www.bcb.gov.br|Central Bank of Brazil
VG|British Virgin Islands|00000 12 345 678 901|VPVG0000012345678901|4!a16!n|^([A-Z]{4})(\d{16})$|20|VG96VPVG0000012345678901|VG2!n4!a16!n|^VG(\d{2})([A-Z]{4})(\d{16})$|24|0|3|||2012-05-29|0|1|||vg|VG||USD|www.bvifsc.vg|The British Virgin Islands Financial Services Commission
BG|Bulgaria|BNBG 9661 1020 3456 78|BNBG96611020345678|4!a4!n2!n8!c|^([A-Z]{4})(\d{4})(\d{2})([A-Za-z0-9]{8})$|18|BG80BNBG96611020345678|BG2!n4!a4!n2!n8!c|^BG(\d{2})([A-Z]{4})(\d{4})(\d{2})([A-Za-z0-9]{8})$|22|0|3|4|7|2011-06-20|1|1|||bg|BG||BGN|www.bnb.bg|Bulgarian National Bank
BF|Burkina Faso|12341234123412341234123|12341234123412341234123|23!n|^[0-9]{23}$|23|BF4512341234123412341234123|BF2!n23!n|^BF(\d{2})(\d{23})$|27|||||2016-01-22|0|0|||bf|BF||XOF|www.bceao.int|Central Bank of West African States (BCEAO)
BI|Burundi|123412341234|123412341234|12!n|^[0-9]{12}$|12|BI33123412341234|BI2!n12!n|^BI(\d{2})(\d{12})$|16|||||2016-01-22|0|0|||bi|BI||BIF|www.brb.bi|Bank of the Republic of Burundi
BY|Belarus|3600 0000 0000 0Z00 AB00|NBRB 3600 0000 0000 0Z00 AB00|4!c4!n16!c|^([A-Za-z0-9]{4})(\d{4})([A-Za-z0-9]{16})$|24|BY13NBRB3600900000002Z00AB00|BY2!n4!c4!n16!c|^BY(\d{2})([A-Za-z0-9]{4})(\d{4})([A-Za-z0-9]{16})$|28|0|3|||2017-08-03|0|1|||by|BY||BYN|www.nbrb.by|National Bank of the Republic of Belarus
CM|Cameroon|12341234123412341234123|12341234123412341234123|23!n|^[0-9]{23}$|23|CM1512341234123412341234123|CM2!n23!n|^CM(\d{2})(\d{23})$|27|||||2016-01-22|0|0|||cm|CM||XAF|www.beac.int|Bank of Central African States
CV|Cape Verde|12341234123412341|12341234123412341|21!n|^[0-9]{21}$|21|CV05123412341234123412341|CV2!n21!n|^CV(\d{2})(\d{21})$|25|||||2016-01-22|0|0|||cv|CV||CVE|www.bcv.cv|Bank of Cape Verde
CF|Central African Republic|0140183240140|20001000010140183240140|5!n5!n11!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|CF4220001000010120069700160|CF2!n5!n5!n11!n2!n|^CF(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-03|0|0|21|23|cf|CF||XAF|www.beac.int|Bank of Central African States
TD|Chad|37102538601 74|60003000203710253860174|5!n5!n11!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|TD8960003000203710253860174|TD2!n5!n5!n11!n2!n|^TD(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-03|0|0|21|23|cf|CF||XAF|www.beac.int|Bank of Central African States
KM|Comoros|00109044001 37|00005000010010904400137|5!n5!n13!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|KM4600005000010010904400137|KM2!n5!n5!n13!n2!n|^KM(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-03|0|0|21|23|km|KM||LMF|www.banque-comores.km|Banque Centrale des Comores
CG|Congo|10134513000|30011000101013451300019|5!n5!n11!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|CG3930013020003710721836132|CG2!n5!n5!n11!n2!n|^CG(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-01|0|1|21|23|cg|CG||CDF|www.bcc.cd|Central Bank of the Congo
CR|Costa Rica|02001026284066|015202001026284066|4!n14!n|^(\d{4})(\d{14})$|18|CR05015202001026284066|CR2!n4!n14!n|^CR(\d{2})(\d{4})(\d{14})$|22|0|2|||2012-05-29|0|1|||cr|CR||CRC|www.bccr.fi.cr|Central Bank of Costa Rica
CI|Côte d'Ivoire|A12312341234123412341234|A12312341234123412341234|1!a23!n|^[A-Z]{1}[0-9]{23}$|24|CI77A12312341234123412341234|CI2!n1!a23!n|^CI(\d{2})([A-Z]{1})(\d{23})$|28|||||2016-01-22|0|0|||ci|CI||XOF|www.bceao.int|Central Bank of West African States (BCEAO)
HR|Croatia|1001005-1863000160|10010051863000160|7!n10!n|^(\d{7})(\d{10})$|17|HR1210010051863000160|HR2!n7!n10!n|^HR(\d{2})(\d{7})(\d{10})$|21|0|6|||2011-06-20|1|1|||hr|HR||HRK|www.hnb.hr|Croatian National Bank
CY|Cyprus|1200527600|002001280000001200527600|3!n5!n16!c|^(\d{3})(\d{5})([A-Za-z0-9]{16})$|24|CY17002001280000001200527600|CY2!n3!n5!n16!c|^CY(\d{2})(\d{3})(\d{5})([A-Za-z0-9]{16})$|28|0|2|3|7|2011-06-20|1|1|||cy|CY||EUR|www.centralbank.gov.cy|Central Bank of Cyprus
CZ|Czech Republic|19-2000145399/0800|08000000192000145399|4!n6!n10!n|^(\d{4})(\d{6})(\d{10})$|20|CZ6508000000192000145399|CZ2!n4!n6!n10!n|^CZ(\d{2})(\d{4})(\d{6})(\d{10})$|24|0|3|4|9|2011-06-20|1|1|||cz|CZ||CZK|www.cnb.cz|Czech National Bank
DK|Denmark|0040 0440116243, 6460 0001631634, 6471 0001000206|00400440116243, 64600001631634, 64710001000206|4!n9!n1!n|^(\d{4})(\d{9})(\d{1})$|14|DK5000400440116243|DK2!n4!n9!n1!n|^DK(\d{2})(\d{4})(\d{9})(\d{1})$|18|0|3|||2011-06-20|1|1|||dk|DK||DKK|www.nationalbanken.dk|National Bank of Denmark (Danmarks Nationalbank)
FO|Faroe Islands|0040 0440116243, 6460 0001631634, 6471 0001000206|00400440116243, 64600001631634, 64710001000206|4!n9!n1!n|^(\d{4})(\d{9})(\d{1})$|14|FO2000400440116243|FO2!n4!n9!n1!n|^FO(\d{2})(\d{4})(\d{9})(\d{1})$|18|0|3|||2011-06-20|0|1|13|13|fo|FO|DK|DKK|www.nationalbanken.dk|National Bank of Denmark (Danmarks Nationalbank)
GL|Greenland|0040 0440116243, 6460 0001631634, 6471 0001000206|00400440116243, 64600001631634, 64710001000206|4!n9!n1!n|^(\d{4})(\d{9})(\d{1})$|14|GL2000400440116243|GL2!n4!n9!n1!n|^GL(\d{2})(\d{4})(\d{9})(\d{1})$|18|0|3|||2011-06-20|0|1|||gl|GL|DK|DKK|www.nationalbanken.dk|National Bank of Denmark (Danmarks Nationalbank)
DJ|Djibouti|04099430200 08|10002010010409943020008|5!n5!n13!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|DJ2110002010010409943020008|DJ2!n5!n5!n13!n2!n|^DJ(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-03|0|0|21|23|dj|DJ||DJF|www.banque-centrale.dj|Central Bank of Djibouti
DO|Dominican Republic|1212453611324|AGR00000001212453611324|4!c20!n|^([A-Za-z0-9]{4})(\d{20})$|24|DO28BAGR00000001212453611324|DO2!n4!c20!n|^DO(\d{2})([A-Za-z0-9]{4})(\d{20})$|28|0|3|||2011-06-20|0|1|||do|DO||DOP|www.bancentral.gov.do|Central Bank of the Dominican Republic
EG|Egypt|10023921893 79|00037000671002392189379|5!n5!n13!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|EG2100037000671002392189379|EG2!n5!n5!n13!n2!n|^EG(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-03|0|0|21|23|eg|EG||EGP|www.cbe.org.eg|Central Bank of Egypt
SV|El Salvador|00000000000000700025|CENR00000000000000700025|4!a20!n|^([A-Za-z0-9]{4})(\d{20})$|24|SV62CENR00000000000000700025|SV2!n4!a20!n|^SV(\d{2})([A-Za-z0-9]{4})(\d{20})$|28|0|3|||2017-08-03|0|1|||sv|SV||USD|www.bcr.gob.sv|Central Reserve Bank of El Salvador
GQ|Equitorial Guinea|37152281901 96|50002001003715228190196|5!n5!n11!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|GQ7050002001003715228190196|GQ2!n5!n5!n11!n2!n|^GQ(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-03|0|0|21|23|gq|GQ||XAF|www.beac.int|Bank of Central African States
EE|Estonia|221020145685|2200221020145685|2!n2!n11!n1!n|^(\d{2})(\d{2})(\d{11})(\d{1})$|16|EE382200221020145685|EE2!n2!n2!n11!n1!n|^EE(\d{2})(\d{2})(\d{2})(\d{11})(\d{1})$|20|0|1|||2011-06-20|1|1|15|15|ee|EE||EUR|www.eestipank.ee|Bank of Estonia
FI|Finland|123456-785|12345600000785|6!n7!n1!n|^(\d{6})(\d{7})(\d{1})$|14|FI2112345600000785|FI2!n6!n7!n1!n|^FI(\d{2})(\d{6})(\d{7})(\d{1})$|18|0|2|||2013-08-05|1|1|13|13|fi|FI||EUR|www.suomenpankki.fi|Bank of Finland
AX|Åland Islands|123456-785|12345600000785|6!n7!n1!n|^(\d{6})(\d{7})(\d{1})$|14|AX2112345600000785|AX2!n6!n7!n1!n|^AX(\d{2})(\d{6})(\d{7})(\d{1})$|18|0|2|||2013-09-05|1|1|||ax|AX|FI|EUR|www.suomenpankki.fi|Bank of Finland
FR|France|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|FR1420041010050500013M02606|FR2!n5!n5!n11!c2!n|^FR(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1|1|21|22|fr|FR||EUR|www.banque-france.fr|Bank of France (Banque de France)
GF|French Guiana|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|GF4120041010050500013M02606|GF2!n5!n5!n11!c2!n|^GF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1|1|21|22|gf|GF|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
PF|French Polynesia|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|PF5720041010050500013M02606|PF2!n5!n5!n11!c2!n|^PF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0|1|21|22|pf|PF|FR|XPF|www.ieom.fr|Overseas Issuing Institute (Institut d'émission d'Outre-Mer)
TF|French Southern Territories|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|TF2120041010050500013M02606|TF2!n5!n5!n11!c2!n|^TF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0|1|21|22|tf|TF|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
GP|Guadelope|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|GP1120041010050500013M02606|GP2!n5!n5!n11!c2!n|^GP(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1|1|21|22|gp|GP|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
MQ|Martinique|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|MQ5120041010050500013M02606|MQ2!n5!n5!n11!c2!n|^MQ(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1|1|21|22|mq|MQ|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
YT|Mayotte|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|YT3120041010050500013M02606|YT2!n5!n5!n11!c2!n|^YT(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1|1|21|22|yt|YT|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
NC|New Caledonia|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|NC8420041010050500013M02606|NC2!n5!n5!n11!c2!n|^NC(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0|1|21|22|nc|NC|FR|XPF|www.ieom.fr|Overseas Issuing Institute (Institut d'émission d'Outre-Mer)
RE|Réunion|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|RE4220041010050500013M02606|RE2!n5!n5!n11!c2!n|^RE(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1|1|21|22|re|RE|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
BL|Saint Barthélemy|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|BL6820041010050500013M02606|BL2!n5!n5!n11!c2!n|^BL(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-02-08|0|1|21|22||BL|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
MF|Saint Martin (French Part)|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|MF8420041010050500013M02606|MF2!n5!n5!n11!c2!n|^MF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-02-08|0|1|21|22||MF|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
PM|Saint-Pierre and Miquelon|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|PM3620041010050500013M02606|PM2!n5!n5!n11!c2!n|^PM(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1|1|21|22|pm|PM|FR|EUR|www.banque-france.fr|Bank of France (Banque de France)
WF|Wallis and Futuna|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|WF9120041010050500013M02606|WF2!n5!n5!n11!c2!n|^WF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0|1|21|22|wf|WF|FR|XPF|www.ieom.fr|Overseas Issuing Institute (Institut d'émission d'Outre-Mer)
GA|Gabon|15200001069 63|42001007341520000106963|5!n5!n11!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|GA2142001007341520000106963|GA2!n5!n5!n11!n2!n|^GA(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2017-08-03|0|0|21|23|ga|GA||XAF|www.beac.int|Bank of Central African States
GE|Georgia|0000000101904917|NB0000000101904917|2!a16!n|^([A-Z]{2})(\d{16})$|18|GE29NB0000000101904917|GE2!n2!a16!n|^GE(\d{2})([A-Z]{2})(\d{16})$|22|0|1|||2011-06-20|0|1|||ge|GE||GEL|www.nbg.gov.ge|National Bank of Georgia
DE|Germany|37040044-532013000|370400440532013000|8!n10!n|^(\d{8})(\d{10})$|18|DE89370400440532013000|DE2!n8!n10!n|^DE(\d{2})(\d{8})(\d{10})$|22|0|7|||2011-06-20|1|1|||de|DE||EUR|www.bundesbank.de|Deutsche Bundesbank
GI|Gibraltar|0000 00007099 453|NWBK000000007099453|4!a15!c|^([A-Z]{4})([A-Za-z0-9]{15})$|19|GI75NWBK000000007099453|GI2!n4!a15!c|^GI(\d{2})([A-Z]{4})([A-Za-z0-9]{15})$|23|0|3|||2011-06-20|1|1|||gi|GI||GIP|www.gibraltar.gov.gi|Government of Gibraltar
GR|Greece|01250000000012300695|01101250000000012300695|3!n4!n16!c|^(\d{3})(\d{4})([A-Za-z0-9]{16})$|23|GR1601101250000000012300695|GR2!n3!n4!n16!c|^GR(\d{2})(\d{3})(\d{4})([A-Za-z0-9]{16})$|27|0|2|3|6|2011-06-20|1|1|||gr|GR||EUR|www.bankofgreece.gr|Bank of Greece
GT|Guatemala|01020000001210029690|TRAJ01020000001210029690|4!c20!c|^([A-Za-z0-9]{4})([A-Za-z0-9]{20})$|24|GT82TRAJ01020000001210029690|GT2!n4!c20!c|^GT(\d{2})([A-Za-z0-9]{4})([A-Za-z0-9]{20})$|28|0|3|||2012-05-29|0|1|||gt|GT||GTQ|www.banguat.gob.gt|Bank of Guatemala
GW|Guinea-Bissau|0181800637601|GW1430010181800637601|2!c2!n4!n11!n2!n|^([A-Za-z0-9]{2}\d{2})(\d{4})(\d{11})(\d{2})$|21|GW04GW1430010181800637601|GW2!n2!c2!n4!n11!n2!n|^GW(\d{2})([A-Za-z0-9]{2}\d{2})(\d{4})(\d{11})(\d{2})$|25|0|3|4|7|2017-08-03|0|0|||gw|GW||XOF|www.bceao.int|Central Bank of West African States
HN|Honduras|123124|PISA00000000000000123124|4!a20!n|^([A-Za-z]{4})(\d{20})$|24|HN54PISA00000000000000123124|HN2!n4!a20!n|^HN(\d{2})([A-Za-z]{4})(\d{20})$|28|0|3|||2017-08-03|0|0|||hn|HN||HNL|www.bch.hn|Central Bank of Honduras
HU|Hungary|11773016-11111018-00000000|117730161111101800000000|3!n4!n1!n15!n1!n|^(\d{3})(\d{4})(\d{1})(\d{15})(\d{1})$|24|HU42117730161111101800000000|HU2!n3!n4!n1!n15!n1!n|^HU(\d{2})(\d{3})(\d{4})(\d{1})(\d{15})(\d{1})$|28|0|2|3|6|2011-06-20|1|1|23|23|hu|HU||HUF|english.mnb.hu|Magyar Nemzeti Bank (Central Bank of Hungary)
IS|Iceland|0159-26-007654-551073-0339|0159260076545510730339|4!n2!n6!n10!n|^(\d{4})(\d{2})(\d{6})(\d{10})$|22|IS140159260076545510730339|IS2!n4!n2!n6!n10!n|^IS(\d{2})(\d{4})(\d{2})(\d{6})(\d{10})$|26|0|3|6|11|2011-06-20|1|1|||is|IS||ISK|www.sedlabanki.is|Central Bank of Iceland
AA|IIBAN (Internet)|0011123Z5678|0011123Z5678|12!a|^[A-Z0-9]{12}$|12|AA110011123Z5678|AA2!n12!a|^AA(\d{2})([A-Z0-9]{12})$|16|0|3||||0|0||||||||
IR|Iran|1234123412341234123412|123412341234123412|22!n|^[0-9]{22}$|22|IR081234123412341234123412|IR2!n22!n|^IR(\d{2})(\d{22})$|26|||||2016-01-22|0|0|||ir|IR||IRR|www.cbi.ir|The Central Bank of the Islamic Republic of Iran
IQ|Iraq|123456789012|NBIQ850123456789012|4!a3!n12!n|^([A-Za-z]{4})(\d{3})(\d{12})$|19|IQ98NBIQ850123456789012|IQ2!n4!a3!n12!n|^IQ(\d{2})([A-Za-z]{4})(\d{3})(\d{12})$|23|0|3|4|6|2017-08-03|0|1|||iq|IQ||IQD|www.cbi.iq|Central Bank of Iraq
IE|Ireland|93-11-52 12345678|AIBK93115212345678|4!a6!n8!n|^([A-Z]{4})(\d{6})(\d{8})$|18|IE29AIBK93115212345678|IE2!n4!a6!n8!n|^IE(\d{2})([A-Z]{4})(\d{6})(\d{8})$|22|0|3|4|9|2011-06-20|1|1|||ie|IE||EUR|www.centralbank.ie|Central Bank and Financial Services Authority of Ireland
IL|Israel|10-800-99999999|010800000099999999|3!n3!n13!n|^(\d{3})(\d{3})(\d{13})$|19|IL620108000000099999999|IL2!n3!n3!n13!n|^IL(\d{2})(\d{3})(\d{3})(\d{13})$|23|0|2|3|5|2011-06-20|0|1|||il|IL||ILS|www.bankisrael.org.il|Bank of Israel
IT|Italy|X 05428 11101 000000123456|X0542811101000000123456|1!a5!n5!n12!c|^([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|23|IT60X0542811101000000123456|IT2!n1!a5!n5!n12!c|^IT(\d{2})([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|27|1|5|6|10|2011-06-20|1|1|0|0|it|IT||EUR|www.bancaditalia.it|Bank of Italy
JO|Jordan|1310000302|CBJO0010000000000131000302|4!a4!n18!c|^([A-Z]{4})(\d{4})([A-Za-z0-9]{18})$|26|JO94CBJO0010000000000131000302|JO2!n4!a4!n18!c|^JO(\d{2})([A-Z]{4})(\d{4})([A-Za-z0-9]{18})$|30|0|3|4|7|2014-06-05|0|1|||jo|JO||JOD|www.cbj.gov.jo|Central Bank of Jordan
KZ|Kazakhstan|KZ86125KZT5004100100|125KZT5004100100|3!n13!c|^(\d{3})([A-Za-z0-9]{13})$|16|KZ86125KZT5004100100|KZ2!n3!n13!c|^KZ(\d{2})(\d{3})([A-Za-z0-9]{13})$|20|0|2|||2014-06-05|0|1|||kz|KZ||KZT|www.nationalbank.kz|National Bank of Kazakhstan
XK|Kosovo|1212 0123456789 06|1212012345678906|4!n10!n2!n|^(\d{4})(\d{10})(\d{2})$|16|XK051212012345678906|XK2!n4!n10!n2!n|^XK(\d{2})(\d{4})(\d{10})(\d{2})$|20|0|1|2|3|2016-01-21|0|1||||||EUR|www.bqk-kos.org|Central Bank of the Republic of Kosovo (Banka Qendrore e Kosovës)
KW|Kuwait|CBKU0000000000001234560101|CBKU0000000000001234560101|4!a22!c|^([A-Z]{4})([A-Za-z0-9]{22})$|26|KW81CBKU0000000000001234560101|KW2!n4!a22!c|^KW(\d{2})([A-Z]{4})([A-Za-z0-9]{22})$|30|0|3|||2016-01-21|0|1|||kw|KW||KWD|www.cbk.gov.kw|Central Bank of Kuwait
LV|Latvia|BANK 0000 4351 9500 1|BANK0000435195001|4!a13!c|^([A-Z]{4})([A-Za-z0-9]{13})$|17|LV80BANK0000435195001|LV2!n4!a13!c|^LV(\d{2})([A-Z]{4})([A-Za-z0-9]{13})$|21|0|3|||2011-06-20|1|1|||lv|LV||EUR|www.bank.lv/lat/main/all|Bank of Latvia
LB|Lebanon|01 001 901229114|0999 0000 0001 0019 0122 9114|4!n20!c|^(\d{4})([A-Za-z0-9]{20})$|24|LB62099900000001001901229114|LB2!n4!n20!c|^LB(\d{2})(\d{4})([A-Za-z0-9]{20})$|28|0|3|||2011-06-20|0|1|||lb|LB||LBP|www.bdl.gov.lb|Central Bank of Lebanon
LI|Liechtenstein|8810 2324013AA|088100002324013AA|5!n12!c|^(\d{5})([A-Za-z0-9]{12})$|19|LI21088100002324013AA|LI2!n5!n12!c|^LI(\d{2})(\d{5})([A-Za-z0-9]{12})$|21|0|4|||2012-05-29|1|1|||li|LI||CHF|www.llb.li|National Bank of Liechtenstein (Liechtensteinische Landesbank)
LT|Lithuania|1000 0111 0100 1000|10000011101001000|5!n11!n|^(\d{5})(\d{11})$|16|LT121000011101001000|LT2!n5!n11!n|^LT(\d{2})(\d{5})(\d{11})$|20|0|4|||2011-06-20|1|1|||lt|LT||EUR|www.lb.lt|Bank of Lithuania
LU|Luxembourg|0019 4006 4475 0000|0019400644750000|3!n13!c|^(\d{3})([A-Za-z0-9]{13})$|16|LU280019400644750000|LU2!n3!n13!c|^LU(\d{2})(\d{3})([A-Za-z0-9]{13})$|20|0|2|||2011-06-20|1|1|14|15|lu|LU||EUR|www.bcl.lu|Central Bank of Luxembourg
MK|Macedonia|300 0000000424 25|250120000058984|3!n10!c2!n|^(\d{3})([A-Za-z0-9]{10})(\d{2})$|15|MK07250120000058984|MK2!n3!n10!c2!n|^MK(\d{2})(\d{3})([A-Za-z0-9]{10})(\d{2})$|19|0|2|||2012-05-29|0|1|13|14|mk|MK||MKD|www.nbrm.mk|National Bank of the Republic of Macedonia
MG|Madagascar|12341234123412341234123|12341234123412341234123|23!n|^[0-9]{23}$|23|MG4012341234123412341234123|MG2!n23!n|^MG(\d{2})(\d{23})$|27|||||2016-01-22|0|0|||mg|MG||MGA|www.banque-centrale.mg|Central Bank of Madagascar
ML|Mali|A12312341234123412341234|A12312341234123412341234|1!a23!n|^[A-Z]{1}[0-9]{23}$|24|ML75A12312341234123412341234|ML2!n1!a23!n|^ML(\d{2})([A-Z]{1})(\d{23})$|28|||||2016-01-22|0|0|||ml|ML||XOF|www.bceao.int|Central Bank of West African States (BCEAO)
MT|Malta|12345MTLCAST001S|MALT011000012345MTLCAST001S|4!a5!n18!c|^([A-Z]{4})(\d{5})([A-Za-z0-9]{18})$|27|MT84MALT011000012345MTLCAST001S|MT2!n4!a5!n18!c|^MT(\d{2})([A-Z]{4})(\d{5})([A-Za-z0-9]{18})$|31|0|3|4|8|2011-06-20|1|1|||mt|MT||EUR|www.centralbankmalta.org|Central Bank of Malta
MR|Mauritania|00020 00101 00001234567 53|00020001010000123456753|5!n5!n11!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|MR1300020001010000123456753|MR2!n5!n5!n11!n2!n|^MR(\d{2})(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2016-06-11|0|1|21|22|mr|MR||MRO|www.bcm.mr|Central Bank of Mauritania
MU|Mauritius|BOMM 0101 1010 3030 0200 000M UR|BOMM0101101030300200000MUR|4!a2!n2!n12!n3!n3!a|^([A-Z]{4})(\d{2})(\d{2})(\d{12})(\d{3})([A-Z]{3})$|26|MU17BOMM0101101030300200000MUR|MU2!n4!a2!n2!n12!n3!n3!a|^MU(\d{2})([A-Z]{4})(\d{2})(\d{2})(\d{12})(\d{3})([A-Z]{3})$|30|0|5|6|7|2011-06-20|0|1|||mu|MU||MUR|www.bom.mu|Bank of Mauritius
MD|Moldova|00225100013104168|AG000225100013104168|2!c18!c|^([A-Za-z0-9]{2})([A-Za-z0-9]{18})$|20|MD24AG000225100013104168|MD2!n2!c18!c|^MD(\d{2})([A-Za-z0-9]{20})$|24|0|1|||2012-09-09|0|1|||md|MD||MDL|www.bnm.org|National Bank of Moldova
MC|Monaco|0011111000h|11222 00001 01234567890 30|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|MC5811222000010123456789030|MC2!n5!n5!n11!c2!n|^MC(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|1|1|21|22|mc|MC||EUR||
ME|Montenegro|505 0000123456789 51|505000012345678951|3!n13!n2!n|^(\d{3})(\d{13})(\d{2})$|18|ME25505000012345678951|ME2!n3!n13!n2!n|^ME(\d{2})(\d{3})(\d{13})(\d{2})$|22|0|2|||2011-06-20|0|1|16|17|me|ME||EUR|www.cb-mn.org|Central Bank of Montenegro
MA|Morocco|00012050005349 21|011519000001205000534921|3!n5!n14!n2!n|^(\d{3})(\d{5})(\d{14})(\d{2})$|26|MA64011519000001205000534921|MA2!n3!n5!n14!n2!n|^MA(\d{2})(\d{3})(\d{5})(\d{14})(\d{2})$|28|0|2|3|7|2017-08-03|0|0|22|24|ma|MA||MAD|www.bkam.ma|Bank Al-Maghrib
MZ|Mozambique|12341234123412341|12341234123412341|21!n|^[0-9]{21}$|21|MZ97123412341234123412341|MZ2!n21!n|^MZ(\d{2})(\d{21})$|25|||||2016-01-22|0|0|||mz|MZ||MZN|www.bancomoc.mz|Bank of Mozambique
NL|Netherlands|041 71 64 300|ABNA0417164300|4!a10!n|^([A-Z]{4})(\d{10})$|14|NL91ABNA0417164300|NL2!n4!a10!n|^NL(\d{2})([A-Z]{4})(\d{10})$|18|0|3|4|3|2013-06-20|1|1|||nl|NL||EUR|www.dnb.nl|Netherlands Bank
NI|Nicaragua|3123123|BAMC000000000000000003123123|28!n|^([A-Za-z]{4})(\d{24})$|28|NI92BAMC000000000000000003123123|NI2!n4!a24!n|^NI(\d{2})([A-Za-z]{4})(\d{24})$|32|0|3|||2017-08-03|0|0|||ni|NI||NIO|www.bcn.gob.ni|Central Bank of Nicaragua
NE|Niger|01303050002 68|NE0380100100130305000268|2!a3!n5!n12!n2!n|^([A-Za-z]{2}\d{3})(\d{5})(\d{12})(\d{2})$|23|NE58NE0380100100130305000268|NE2!n2!a3!n5!n12!n2!n|^NE(\d{2})([A-Za-z]{2}\d{3})(\d{5})(\d{12})(\d{2})$|28|0|4|5|9|2017-08-03|0|0|22|23|ne|NE||XOF|www.bceao.int|Central Bank of West African States (BCEAO)
NO|Norway|8601 11 17947|86011117947|4!n6!n1!n|^(\d{4})(\d{6})(\d{1})$|11|NO9386011117947|NO2!n4!n6!n1!n|^NO(\d{2})(\d{4})(\d{6})(\d{1})$|15|0|3|||2011-06-20|1|1|10|10|no|NO||NOK|www.norges-bank.no|Central Bank of Norway (Norges Bank)
PK|Pakistan|00260101036360|SCBL0000001123456702|4!a16!c|^([A-Z]{4})([A-Za-z0-9]{16})$|20|PK36SCBL0000001123456702|PK2!n4!a16!c|^PK(\d{2})([A-Z]{4})([A-Za-z0-9]{16})$|24|0|3|||2012-05-29|0|1|||pk|PK||PKR|www.sbp.org.pk|State Bank of Pakistan
PS|Palestine|400123456702|PALS000000000400123456702|4!a21!c|^([A-Z]{4})([A-Za-z0-9]{21})$|25|PS92PALS000000000400123456702|PS2!n4!a21!c|^PS(\d{2})([A-Z]{4})([A-Za-z0-9]{21})$|29|0|3|||2013-09-05|0|1|||ps|PS||ILS|www.pma.ps|Palestine Monetary Authority
PL|Poland|61 1090 1014 0000 0712 1981 2874|109010140000071219812874|8!n16!n|^(\d{8})(\d{16})$|24|PL61109010140000071219812874|PL2!n8!n16n|^PL(\d{2})(\d{8})(\d{1,16})$|28|0|7|||2011-06-20|1|1|7|7|pl|PL||PLN|www.nbp.pl|National Bank of Poland
PT|Portugal|0002.0123.12345678901.54|000201231234567890154|4!n4!n11!n2!n|^(\d{4})(\d{4})(\d{11})(\d{2})$|21|PT50000201231234567890154|PT2!n4!n4!n11!n2!n|^PT(\d{2})(\d{4})(\d{4})(\d{11})(\d{2})$|25|0|3|4|7|2013-09-05|1|1|19|20|pt|PT||EUR|www.bportugal.pt|Bank of Portugal
QA|Qatar|QA58DOHB00001234567890ABCDEFG|DOHB00001234567890ABCDEFG|4!a4!n17!c|^([A-Z]{4})(\d{4})([A-Za-z0-9]{17})$|29|QA58DOHB00001234567890ABCDEFG|QA2!n4!a4!n17!c|^QA(\d{2})([A-Z]{4})(\d{4})([A-Za-z0-9]{17})$|29|0|3|4|7|2014-06-05|0|1|||qa|QA||QAR|www.qcb.gov.qa|Qatar Central Bank
RO|Romania|AAAA 1B31 0075 9384 0000|AAAA1B31007593840000|4!a16!c|^([A-Z]{4})([A-Za-z0-9]{16})$|20|RO49AAAA1B31007593840000|RO2!n4!a16!c|^RO(\d{2})([A-Z]{4})([A-Za-z0-9]{16})$|24|0|3|||2011-06-20|1|1|||ro|RO||RON|www.bnro.ro|National Bank of Romania
LC|Saint Lucia|0001 0001 0012 0012 0002 3015|HEMM000100010012001200023015|4!a24!c|^([A-Z]{4})([A-Za-z0-9]{24})$|28|LC55HEMM000100010012001200023015|LC2!n4!a24!c|^LC(\d{2})([A-Z]{4})([A-Za-z0-9]{24})$|32|0|3|||2016-04-15|0|1|||lc|LC||XCD|www.eccb-centralbank.org|Eastern Caribbean Central Bank
SM|San Marino|U032 2509 8000 0000 0270 100|U0322509800000000270100|1!a5!n5!n12!c|^([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|23|SM86U0322509800000000270100|SM2!n1!a5!n5!n12!c|^SM(\d{2})([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|27|1|5|6|10|2011-06-20|1|1|0|0|sm|SM||EUR|www.bcsm.sm|Central Bank of the Republic of San Marino
ST|São Tomé and Príncipe|518453101|0001000100518453101|8!n11!n2!n|^(\d{8})(\d{11})(\d{2})$|21|ST68000100010051845310112|ST2!n8!n11!n2!n|^ST(\d{2})(\d{8})(\d{11})(\d{2})$|25|0|3|4|7|2016-01-21|0|1|||st|ST||STD|www.bcstp.st|Central Bank of São Tomé and Príncipe
SA|Saudi Arabia|608010167519|80000000608010167519|2!n18!c|^(\d{2})([A-Za-z0-9]{18})$|20|SA0380000000608010167519|SA2!n2!n18!c|^SA(\d{2})(\d{2})([A-Za-z0-9]{18})$|24|0|1|||2012-05-29|0|1|||sa|SA||SAR|www.sama.gov.sa|Saudi Arabian Monetary Agency
SN|Senegal|A12312341234123412341234|A12312341234123412341234|1!a23!n|^[A-Z]{1}[0-9]{23}$|24|SN15A12312341234123412341234|SN2!n1!a23!n|^SN(\d{2})([A-Z]{1})(\d{23})$|28|||||2016-01-22|0|0|||sn|SN||XOF|www.bceao.int|Central Bank of West African States (BCEAO)
RS|Serbia|260-0056010016113-79|260005601001611379|3!n13!n2!n|^(\d{3})(\d{13})(\d{2})$|18|RS35260005601001611379|RS2!n3!n13!n2!n|^RS(\d{2})(\d{3})(\d{13})(\d{2})$|22|0|2|||2011-06-20|0|1|16|17|rs|RS||RSD|www.nbs.rs|National Bank of Serbia
SC|Seychelles|0000000000001497|SSCB11010000000000001497USD|4a!2n!2n!16n!3a!|^([A-Z]{4})!(\d{2})!(\d{2})!(\d{16})!([A-Z]{3})!$|27|SC18SSCB11010000000000001497USD|SC2!n4a!2n!2n!16n!3a!|^SC(\d{2})([A-Z]{4})(\d{2})(\d{2})(\d{16})([A-Z]{3})$|31|0|3|4|7|2016-06-11|0|1|||sc|SC||SCR|www.cbs.sc|Central Bank of Seychelles
SK|Slovakia|19-8742637541/1200|12000000198742637541|4!n6!n10!n|^(\d{4})(\d{6})(\d{10})$|20|SK3112000000198742637541|SK2!n4!n6!n10!n|^SK(\d{2})(\d{4})(\d{6})(\d{10})$|24|0|3|4|9|2011-06-20|1|1|||sk|SK||EUR|www.nbs.sk|National Bank of Slovakia
SI|Slovenia|2633 0001 2039 086|263300012039086|5!n8!n2!n|^(\d{5})(\d{8})(\d{2})$|15|SI56191000000123438|SI2!n5!n8!n2!n|^SI(\d{2})(\d{5})(\d{8})(\d{2})$|19|0|1|2|4|2012-09-09|1|1|13|14|si|SI||EUR|www.bsi.si|Bank of Slovenia
ES|Spain|2100 0418 45 0200051332|21000418450200051332|4!n4!n1!n1!n10!n|^(\d{4})(\d{4})(\d{1})(\d{1})(\d{10})$|20|ES9121000418450200051332|ES2!n4!n4!n1!n1!n10!n|^ES(\d{2})(\d{4})(\d{4})(\d{1})(\d{1})(\d{10})$|24|0|3|4|7|2013-09-05|1|1|8|9|es|ES||EUR|www.bde.es|Bank of Spain
SE|Sweden|1234 12 3456 1|5000 0000 0583 9825 7466|3!n16!n1!n|^(\d{3})(\d{16})(\d{1})$|20|SE4550000000058398257466|SE2!n3!n16!n1!n|^SE(\d{2})(\d{3})(\d{16})(\d{1})$|24|0|2|||2011-06-20|1|1|19|19|se|SE||SEK|www.riksbank.com|Bank of Sweden (Sveriges Riksbank)
CH|Switzerland|762 1162-3852.957|00762011623852957|5!n12!c|^(\d{5})([A-Za-z0-9]{12})$|17|CH9300762011623852957|CH2!n5!n12!c|^CH(\d{2})(\d{5})([A-Za-z0-9]{12})$|21|0|4|||2011-06-20|1|1|||ch|CH||CHF|www.snb.ch|Swiss National Bank
TL|Timor-Leste|008 00123456789101 57|0080012345678910157|3!n 14!n 2!n|^(\d{3}) (\d{14}) (\d{2})$|19|TL380080012345678910157|TL2!n3!n14!n2!n|^TL(\d{2})(\d{3})(\d{14})(\d{2})$|23|0|3|4|6|2016-01-21|0|1|17|18|tl|TL||USD|www.bancocentral.tl|Central Bank of Timor-Leste (Banco Central de Timor-Leste)
TG|Togo|43103465004000 70|TG0090604310346500400070|2!a3!n5!n12!n2!n|^([A-Za-z]{2}\d{3})(\d{5})(\d{12})(\d{2})$|26|TG53TG0090604310346500400070|TG2!n2!a3!n5!n12!n2!n|^TG(\d{2})([A-Za-z]{2}\d{3})(\d{5})(\d{12})(\d{2})$|28|0|4|5|9|2017-08-03|0|0|22|24|tg|TG||XOF|www.bceao.int|Central Bank of West African States (BCEAO)
TN|Tunisia|10 006 0351835984788 31|10006035183598478831|2!n3!n13!n2!n|^(\d{2})(\d{3})(\d{13})(\d{2})$|20|TN5910006035183598478831|TN2!n2!n3!n13!n2!n|^TN(\d{2})(\d{2})(\d{3})(\d{13})(\d{2})$|24|0|1|2|4|2011-06-20|0|1|18|19|tn|TN||TND|www.bct.gov.tn|Central Bank of Tunisia
TR|Turkey|TR33 0006 1005 1978 6457 8413 26|0006100519786457841326|5!n1!n16!c|^(\d{5})(\d{1})([A-Za-z0-9]{16})$|22|TR330006100519786457841326|TR2!n5!n1!n16!c|^TR(\d{2})(\d{5})(\d{1})([A-Za-z0-9]{16})$|26|0|4|||2016-01-21|0|1|||tr|TR||TRY|www.tcmb.gov.tr|Central Bank of the Republic of Turkey
UA|Ukraine|3996220000026007233566001|3996220000026007233566001|6!n19!c|^[0-9]{6}[A-Za-z0-9]{19}$|25|UA213996220000026007233566001|UA2!n6!n19!c|^UA(\d{2})(\d{6})([A-Za-z0-9]{19})$|29|0|5|||2016-01-22|0|0|||ua|UA||UAH|www.bank.gov.ua|National Bank of Ukraine
AE|United Arab Emirates|1234567890123456|0331234567890123456|3!n16!n|^(\d{3})(\d{16})$|19|AE070331234567890123456|AE2!n3!n16!n|^AE(\d{2})(\d{3})(\d{16})$|23|0|2|||2011-06-20|0|1|||ae|AE||AED|www.centralbank.ae|Central Bank of the United Arab Emirates
GB|United Kingdom|60-16-13 31926819|NWBK60161331926819|4!a6!n8!n|^([A-Z]{4})(\d{6})(\d{8})$|18|GB29NWBK60161331926819|GB2!n4!a6!n8!n|^GB(\d{2})([A-Z]{4})(\d{6})(\d{8})$|22|0|3|4|9|2011-06-20|1|1|||uk|GB||GBP|www.bankofengland.co.uk|Bank of England

View File

@@ -0,0 +1,24 @@
#!/usr/bin/php
<?php
$url = 'http://www.bis.org/cbanks.htm';
$data = file_get_contents($url);
# cut data before table
$data = preg_replace('/^.*<div class="country_institutions">/ms','',$data);
# cut data after table
$data = preg_replace('/<\/tbody>.*$/ms','',$data);
# split in to rows
preg_match_all('/<tr>.*?<td valign="top"><a id="country_([A-Z]{2})" name="country_.." href="[^"]+">([^<>]+)<\/a><\/td>.*?<td valign="top"><a class="external" target="_blank" href="\/dcms\/goto.jsp\?([^"]+)">([^<>]+)<\/a><\/td>.*?<\/tr>/s',$data,$matches);
# remove whole-row capture
array_shift($matches);
# display results
for($i=0;$i<count($matches[0]);$i++) {
print $matches[0][$i] . "|" . $matches[1][$i] . "|" . $matches[2][$i] . "|" . $matches[3][$i] . "\n";
}
?>

View File

@@ -0,0 +1,319 @@
<?php
# this script converts the IBAN_registry.txt file's entries to registry.txt format (php-iban's required internal format).
# init
require_once(dirname(dirname(__FILE__)) . '/php-iban.php');
date_default_timezone_set('UTC'); # mutes a warning
# read registry
$data = `iconv -f utf8 -t ascii --byte-subst="<0x%x>" --unicode-subst="<U+%04X>" 'IBAN_Registry.txt'`;
if($data == '') { die("Couldn't read IBAN_Registry.txt - try downloading from the location described in the REGISTRY-URL file."); }
# print header line
print "country_code|country_name|domestic_example|bban_example|bban_format_swift|bban_format_regex|bban_length|iban_example|iban_format_swift|iban_format_regex|iban_length|bban_bankid_start_offset|bban_bankid_stop_offset|bban_branchid_start_offset|bban_branchid_stop_offset|registry_edition|country_sepa\n";
# break in to lines
$lines = preg_split('/[\r\n]+/',$data);
# display
foreach($lines as $line) {
# if it's not a blank line, and it's not the header row
if($line != '' && !preg_match('/SEPA Country/',$line)) {
# extract individual tab-separated fields
$bits = explode("\t",$line);
# remove quotes and superfluous whitespace on fields that have them.
for($i=0;$i<count($bits);$i++) {
$bits[$i] = preg_replace('/^"(.*)"$/','$1',$bits[$i]);
$bits[$i] = preg_replace('/^ */','',$bits[$i]);
$bits[$i] = preg_replace('/ *$/','',$bits[$i]);
}
# assigned fields to named variables
# print "-------\n";
# print $line;
# print "-------\n";
list($country_name,$country_code,$domestic_example,$bban,$bban_structure,$bban_length,$bban_bi_position,$bban_bi_length,$bban_bi_example,$bban_example,$iban,$iban_structure,$iban_length,$iban_electronic_example,$iban_print_example,$country_sepa,$contact_details) = $bits;
# sanitise
$country_code = strtoupper(substr($country_code,0,2)); # sanitise comments away
$bban_structure = preg_replace('/[:;]/','',$bban_structure); # errors seen in Germany, Hungary entries
$iban_structure = preg_replace('/, .*$/','',$iban_structure); # duplicates for FO, GL seen in DK
$iban_electronic_example = preg_replace('/, .*$/','',$iban_electronic_example); # duplicates for FO, GL seen in DK
if($country_code=='MU') {
$iban_electronic_example = str_replace(' ','',$iban_electronic_example); # MU example has a spurious space
}
if($country_code=='CZ') {
$iban_electronic_example = preg_replace('/ \w{10,}+$/','',$iban_electronic_example); # extra example for CZ
$iban_print_example = preg_replace('/^(CZ.. .... .... .... .... ....).*$/','$1',$iban_print_example); # extra example
}
if($country_code=='FI') {
# remove additional example
$iban_electronic_example = preg_replace('/ or .*$/','',$iban_electronic_example);
# fix bban example to remove verbosity and match domestic example
$bban = '12345600000785';
}
if($country_code=='KZ') {
# fix presence of multiline free-text in KZ IBAN structure field
$iban_structure = '2!a2!n3!n13!c';
}
if($country_code=='QA') {
# fix the lack BBAN structure provision in the TXT format registry
$bban_structure = '4!a4!n17!c';
# fix broken IBAN structure provision
$iban_structure = 'QA2!n4!a4!n17!c';
}
if($country_code=='JO') {
$bban_bi_length=4; # not '4!a' as suggested
}
$iban_print_example = preg_replace('/, .*$/','',$iban_print_example); # DK includes FO and GL examples in one record
# drop leading 2!a in iban structure.
# .. should actually be the country code in question
if(substr($iban_structure,0,3) == '2!a') {
$iban_structure = $country_code . substr($iban_structure,3);
}
# calculate $bban_regex from $bban_structure
$bban_regex = swift_to_regex($bban_structure);
# calculate $iban_regex from $iban_structure
$iban_regex = swift_to_regex($iban_structure);
print "[DEBUG] got $iban_regex from $iban_structure\n";
# debugging
if(true) {
print "[$country_name ($country_code)]\n";
print "Domestic account number example: $domestic_example\n";
print "BBAN structure: $bban_structure\n";
print "BBAN length: $bban_length\n";
print "BBAN bank identifier position: $bban_bi_position\n";
print "BBAN bank identifier length: $bban_bi_length\n";
print "BBAN bank identifier example: $bban_bi_example\n";
print "BBAN example: $bban_example\n";
print "BBAN regex (calculated): $bban_regex\n";
print "IBAN structure: $iban_structure\n";
print "IBAN length: $iban_length\n";
print "IBAN electronic format example: $iban_electronic_example\n";
print "IBAN print format example: $iban_print_example\n";
print "IBAN Regex (calculated): $iban_regex\n";
print "SEPA country: $country_sepa\n";
print "Contact details: $contact_details\n\n";
}
# calculate numeric $bban_length
$bban_length = preg_replace('/[^\d]/','',$bban_length);
# calculate numeric $iban_length
$iban_length = preg_replace('/[^\d]/','',$iban_length);
# calculate bban_bankid_<start|stop>_offset
# .... First we have to parse the freetext $bban_bi_position, eg:
# Bank Identifier 1-3, Branch Identifier
# Position 1-2
# Positions 1-2
# Positions 1-3
# Positions 1-3 ;Branch is not available
# Positions 1-3, Branch identifier
# Positions 1-3, Branch identifier positions
# Positions 1-4
# Positions 1-4, Branch identifier
# Positions 1-4, Branch identifier positions
# Positions 1-5
# Positions 1-5 (positions 1-2 bank identifier; positions 3-5 branch identifier). In case of payment institutions Positions 1-5, Branch identifier positions
# Positions 1-6, Branch identifier positions
# Positions 1-6. First two digits of bank identifier indicate the bank or banking group (For example, 1 or 2 for Nordea, 31 for Handelsbanken, 5 for cooperative banks etc)
# Positions 1-7
# Positions 1-8
# Positions 2-6, Branch identifier positions
# positions 1-3, Branch identifier positions
#
# ... our algorithm is as follows:
# - find all <digit>-<digit> tokens
preg_match_all('/(\d)-(\d\d?)/',$bban_bi_position,$matches);
# - discard overlaps ({1-5,1-2,3-5} becomes {1-2,3-5})
$tmptokens = array();
for($j=0;$j<count($matches[0]);$j++) {
#print "tmptokens was... " . print_r($tmptokens,1) . "\n";
$from = $matches[1][$j];
$to = $matches[2][$j];
# (if we don't yet have a match starting here, or it goes further,
# overwrite the match-from-this-position record)
if(!isset($tmptokens[$from]) || $to < $tmptokens[$from]) {
$tmptokens[$from] = $to;
}
}
unset($matches); # done
# - assume the token starting from position 1 is the bank identifier
# (or, if it does not exist, the token starting from position 2)
$bban_bankid_start_offset = 0; # decrement 1 on assignment
if(isset($tmptokens[1])) {
$bban_bankid_stop_offset = $tmptokens[1]-1; # decrement 1 on assignment
unset($tmptokens[1]);
}
else {
$bban_bankid_stop_offset = $tmptokens[2]-1; # decrement 1 on assignment
unset($tmptokens[2]);
}
# - assume any subsequent token, if present, is the branch identifier.
$tmpkeys = array_keys($tmptokens);
$start = array_shift($tmpkeys);
unset($tmpkeys); # done
$bban_branchid_start_offset='';
$bban_branchid_stop_offset='';
if($start!= '') {
# we have a branch identifier!
$bban_branchid_start_offset=$start-1;
$bban_branchid_stop_offset=$tmptokens[$start]-1;
}
else {
# (note: this codepath occurs for around two thirds of all records)
# we have not yet found a branch identifier. HOWEVER, we can analyse the
# structure of the BBAN to determine whether there is more than one
# remaining non-tiny field (tiny fields on the end of a BBAN typically
# being checksums) and, if so, assume that the first/shorter one is the
# branch identifier.
$reduced_bban_structure = preg_replace('/^\d+![nac]/','',$bban_structure);
# print "[DEBUG] reduced BBAN structure = $reduced_bban_structure\n";
$tokens = swift_tokenize($reduced_bban_structure,1);
# print "[DEBUG] tokens = " + json_encode($tokens,1);
# discard any tokens of length 1 or 2
for($t=0;$t<count($tokens[0]);$t++) {
if($tokens[1][$t] < 3) {
$tokens['discarded'][$t] = 1;
}
}
# interesting fields are those that are not discarded...
if(!isset($tokens['discarded'])) {
$interesting_field_count = count($tokens[0]); }
else {
$interesting_field_count = (count($tokens[0])-count($tokens['discarded']));
}
# print "[DEBUG] interesting field count = $interesting_field_count\n";
# ...if we have at least two of them, there's a branchid-type field
if($interesting_field_count >= 2) {
# now loop through until we assign the branchid start offset
# (this occurs just after the first non-discarded field)
$found=0;
for($f=0; (($found==0) && ($f<count($tokens[0]))); $f++) {
# if this is a non-discarded token, of >2 length...
if((!isset($tokens['discarded'][$f]) || $tokens['discarded'][$f] != 1) && $tokens[1][$f]>2) {
# ... then assign.
$pre_offset = $bban_bankid_stop_offset+1; # this is the offset before we reduced the structure to remove the bankid field
$bban_branchid_start_offset = $pre_offset + $tokens['offset'][$f];
$bban_branchid_stop_offset = $pre_offset + $tokens['offset'][$f] + $tokens[1][$f] - 1; # decrement by one on assignment
$found=1;
}
}
}
}
# fix for Jordan
if($country_code == 'JO') {
$bban_bankid_start_offset = 0;
$bban_bankid_stop_offset = 3;
$bban_branchid_start_offset = 4;
$bban_branchid_stop_offset = 7;
}
# calculate 1=Yes, 0=No for $country_sepa
# NOTE: This is buggy due to the free inclusion of random text by the registry publishers.
# Notably it requires modification for places like Finland and Portugal where these
# comments are known to exist.
if(strtolower($country_sepa)=='yes') { $country_sepa=1; } else { $country_sepa = 0; }
# set registry edition
$registry_edition = date('Y-m-d');
# now prepare generate our registry lines...
$to_generate = array($country_code=>$country_name);
if($country_code == 'DK') {
$to_generate = array('DK'=>$country_name,'FO'=>'Faroe Islands','GL'=>'Greenland');
}
elseif($country_code == 'FR') {
$to_generate = array('FR'=>$country_name,'BL'=>'Saint Barthelemy','GF'=>'French Guyana','GP'=>'Guadelope','MF'=>'Saint Martin (French Part)','MQ'=>'Martinique','RE'=>'Reunion','PF'=>'French Polynesia','TF'=>'French Southern Territories','YT'=>'Mayotte','NC'=>'New Caledonia','PM'=>'Saint Pierre et Miquelon','WF'=>'Wallis and Futuna Islands');
}
# output loop
foreach($to_generate as $country_code=>$country_name) {
# fixes for fields duplicating country code
#print "CHECKSUM-BEFORE[$country_code] = $iban_electronic_example\n";
$iban_electronic_example = iban_set_checksum($country_code . substr($iban_electronic_example,2));
#print "CHECKSUM-AFTER[$country_code] = $iban_electronic_example\n";
$iban_structure = $country_code . substr($iban_structure,2);
# step 1
$iban_regex_fixed = '^' . $country_code;
$tmp_country_code = substr($iban_regex,1,2);
#print "[DEBUG] $tmp_country_code\n";
# route #1 ... here we are dealing with a country code in the string already
if(preg_match('/^[A-Z][A-Z]$/',$tmp_country_code)) {
#print "[DEBUG] route #1\n";
$iban_regex_fixed = $iban_regex_fixed . substr($iban_regex,3);
}
# route #2 ... here there is no country code yet present
else {
#print "[DEBUG] route #2\n";
$iban_regex_fixed = $iban_regex_fixed . substr($iban_regex,1);
}
#print "[DEBUG] substited '$iban_regex_fixed' for '$iban_regex'\n";
# output
print "$country_code|$country_name|$domestic_example|$bban_example|$bban_structure|$bban_regex|$bban_length|$iban_electronic_example|$iban_structure|$iban_regex_fixed|$iban_length|$bban_bankid_start_offset|$bban_bankid_stop_offset|$bban_branchid_start_offset|$bban_branchid_stop_offset|$registry_edition|$country_sepa\n";
}
}
}
# swift_to_regex()
# converts the SWIFT IBAN format specifications to regular expressions
# eg: 4!n6!n1!n -> ^(\d{4})(\d{6})(\d{1})$
function swift_to_regex($swift) {
# first find tokens
$matches = swift_tokenize($swift);
# now replace bits
$tr = '^' . $swift . '$';
# loop through each matched token
for($i=0;$i<count($matches[0]);$i++) {
# calculate replacement
$replacement = '(TOKEN)';
# type 'n'
if($matches[3][$i] == 'n') {
$replacement = '(\d{length})';
}
# type 'c'
elseif($matches[3][$i] == 'c') {
$replacement = '([A-Za-z0-9]{length})';
}
# type 'a'
elseif($matches[3][$i] == 'a') {
$replacement = '([A-Z]{length})';
#' . $matches[1][$i] . '})';
}
else {
print "unknown type: $matches[3][$i]\n";
exit(1);
}
# now add length indicator to the token
$length = '(LENGTH)';
if($matches[2][$i] == '!') {
$length = $matches[1][$i];
}
else {
$length = '1,' . $matches[1][$i];
}
$replacement = preg_replace('/length/',$length,$replacement,1);
# finally, replace the entire token with the replacement
$tr = preg_replace('/' . $matches[0][$i] . '/',$replacement,$tr,1);
}
return $tr;
}
# swift_tokenize()
# fetch individual tokens in a swift structural string
function swift_tokenize($string,$calculate_offsets=0) {
preg_match_all('/((?:\d*?[1-2])?\d)(!)?([anc])/',$string,$matches);
if($calculate_offsets) {
$current_offset=0;
for($i=0;$i<count($matches[0]);$i++) {
$matches['offset'][$i] = $current_offset;
$current_offset+=$matches[1][$i];
}
#print "ANALYSE[raw]: " . join(',',$matches['offset']);
}
return $matches;
}
?>

View File

@@ -0,0 +1,15 @@
<?php
# Engine configuration
# - first we enable error display
ini_set('display_errors',1);
# - next we ensure that all errors are displayed
ini_set('error_reporting',E_ALL);
# include the library itself
require_once(dirname(dirname(__FILE__)) . '/php-iban.php');
# display registry contents
print_r($_iban_registry);
?>

View File

@@ -0,0 +1,10 @@
AE020200000030124176201
AE07 0331 2345 6789 0123 456
AE14 0340 0000 1401 1019 050
AE260211000000230064016
AE320030000100228001001
AE320030010274073001001
AE320330000010195510887
AE730030000789456123456
AE940350000000250008661
AE950260001261025056501

View File

@@ -0,0 +1,78 @@
AL 79208110080000001043631801
AL 45209516090000600388970102
AL 56209516090000600388970001
AL 25208110080000001043631803
AL 79208110080000001043631801
AL77202110130000000000584625
AL27202110130000000001584625
AL4920511021633875CLTJCLALLD
AL41212110160000000000424721
AL84901111230031371010000013
AL85 2021 1037 0000 0000 0620 5792
AL05 2141 1144 0111 2930 4302 0418
AL80 2081 1008 0000 0203 8723 5304
AL94 2061 1042 0000 1403 1194 6102
AL47 2091 1108 0000 1087 4155 0001
AL22 2101 1050 0005 0002 0000 2150
AL85 9021 1209 0201 2300 1425 5899
AL50 9011 1051 0025 3380 1000 0012
AL05 2121 1016 0000 0000 0025 2224
AL19 2071 1018 0000 0103 0013 5605
AL76 2131 1044 0000 0000 0089 6731
AL88 2031 1027 2010 1520 1101 1264
AL94 2151 1031 ALL1 0000 0373 9100
AL44 2041 1017 0000 0000 0001 4315
AL29 2121 1016 0000 0000 0030 0001
AL72 2121 1016 0000 0000 0030 0003
AL02 2121 1016 0000 0000 0030 0002
AL38202110130000000000157945
AL85202110130000000001157945
AL35202110130000000002157945
AL4420511014328886CLTJCLALLA
AL11 2051 1014 3288 86CL TJCF EURA
AL55 2051 1014 3288 86CL TJCF USDA
AL47 2061 1183 0000 0108 2000 0011
AL20 2061 1183 0000 0108 2000 0012
AL74 2061 1183 0000 0108 2000 0010
AL37208110080000002024530701
AL10208110080000002024530702
AL80208110080000002024530703
AL50 2141 1209 0111 1009 2516 0413
AL40 2141 1209 0111 1009 2525 0221
AL66 2141 1209 0111 1009 2525 0141
AL86213110130000000000841534
AL32213110130000000000841536
AL05213110130000000000841537
AL38210110120000000000038968
AL21210110120000000000071963
AL38210110120000000000048280
AL43901110130022099710000018
AL76901110130022099710016011
AL20901110130022099710001014
AL84 2041 1017 0000 0000 0001 1655
AL60203110032010152011010928
AL71203110032010149011010929
AL88203110032010140011010929
AL 05 2121 1016 0000 0000 0028 8405
AL48212110160000000000288407
AL21212110160000000000288408
AL50212110160000000000691794
AL51202110130000000100011257
AL35202110130000008000011257
AL 05 2121 1016 0000 0000 0028 8405
AL 4920 5110 1427 3430 CLTJCLALLA
AL14202110130000000001002859
AL81202110130000000021002859
AL96202110130000000011002859
AL14202110130000000001002859
AL96202110130000000011002859
AL81202110130000000021002859
AL14202110130000000001002859
AL96202110130000000011002859
AL81202110130000000021002859
AL70207110320000030300030901
AL23207110320000030300020301
AL39207110320000030300020207
AL84202110130000008020003045
AL69202110130000008030003045
AL80202110130000000101003045

View File

@@ -0,0 +1,39 @@
AO 0600 5100 0014 3278 4710 124
AO 06 0006 0000 1119838830143
AO.0600520000036650 3410149
AO (060) 006 000 000 114 658 31 132
AO 06000600000173927530298
AO 0600 5100 0062 4581 8010 124
AO 0600 5300 0000 1579 3010 113
AO 0600 5300 0000 1579 3010 210
AO 0600 5300 0000 1579 3010 307
AO06005100009261796010121
AO 06004000002918140610185
AO 06 0006 0000 11198388311 13
AO 06 005500000037920810184
AO 060 006 00000 94 06 43 93 01 52
AO 06 0051 0000 9892 4734 10123
AO 06004000005632752810136
AO 06000600000. 940643930152
AO 06000100000000000100067
AO.0600.0600.0035.5695.8730.174
AO.0600.0600.0035.5695.8731.144
AO.06005200000366503415193
AO. 06000500000.402782915144
AO 0600 5100 0020 5763 4910 107
AO 06003400000500344180389
AO 0600 5100 00000 358 56 35170
AO 0600 5100 00000 358 56 15188
AO 0600 5100 00000 358 56 35267
AO 0600 4000 000 939 6859 15150
AO 0600 4000 000 939 6859 10106
AO 0600 3400 000 5000 047 47804
AO 0600 3400 000 5000 414 08954
AO 0600 0400 0000 233 362 15132
AO 0600 0400 0000 233 362 10282
AO 0600 10000 1000 17439 00526
AO 0600 10000 1000 17439 01108
AO 0600 0500 00 131 099 39 15144
AO 0600 0500 00 131 099 39 10197
AO 06000 6000 000 114 658 30259
AO 06000 6000 000 11 4 658 31617

View File

@@ -0,0 +1,25 @@
IBAN AT 73 11000 04443 171600
AT 02 6000 0000 9202 5567
AT 64 5400 0003 0026 2623
AT06 2040 4012 0012 3331
AT575400000000777771
AT632031700200200665
AT 922 011 100 002 551 063
AT 92 3501 2000 0101 2343
AT 19 20404 00600 265009
AT97 3200 0000 0051 8548
AT 15 1200 0106 1008 31 00
AT 30 36218 00000120170
AT 87 3200 0000 1207 7830
AT 56 3313 5003 0104 9196
AT 602011100002305453
AT 60 2011 1283 1261 7201
AT 60 3219 5000 0050 9315
AT 661636000136143263
AT 08 20604 009 000 01579
AT 781816041470031000
AT 17 2040 4006 0026 2717
AT 06 3400 0000 0262 1100
AT 93 12000 500 9484 0004
AT 563 225 000 000 705 343
AT 34 20111 30000011821

View File

@@ -0,0 +1,4 @@
AZ 27 CTRE 00000000000002577701
AZ 95 CTRE 00000000000002077703
AZ 16JBBK00003801000000449914
AZ 72 AZER 0002 4000 8924 AZN4 1010

View File

@@ -0,0 +1,57 @@
BA 393060203790043809
BA 39 338 690 223 178 6494
BA 391611200000517058
BA 39 1611350000455698
BA 391401011200071132
BA 39 1606100000025329
BA 39 338 690 481 206 3318
BA 391010000000001687
BA 391010000000001687
BA 393380604811081508
BA 395 6200 7812388 9056
BA 391010000000001687
BA 391862411200026334
BA 391862411200026431
BA 391340100000001672
BA; 393384304822703378
BA 393060123788314594
BA 393383204890751455
BA 39 3381 8048 5564 8389
BA 391 322 61 01 867 06 449
BA 391994520075608096
BA 393381304846769616
BA 391010000000001687
BA 393389002205504530
BA 393380604893778179
BA 39 3381 3028 3846 7066
BA 393383004890302258
BA 3914 0102 1200 2892 36
BA 39 3384 4028 1685 4244
BA 39 1990496065531685
Ba 393386902853445817
BA 39 3383207700006576
BA 393383204892682434
BA 39-16 11 20 00 00 71 14 46
BA 393380002210019263
BA 391321010086184459
BA 39 1541602002096623
BA 39 3381 3028 3846 7066
BA 39 1401010022091880
BA 39 3386 9048 3604 6471
BA 393 060 092 511 198 288
BA 393 060 092 511 057 929
BA 391549212001479953
BA 391941111768001243
BA 39 1540012000051021
BA393060203740529674
BA 391321610228083110
BA 390000030000000145
BA 391610000094000092
Ba 393386902853445817
BA 39 33858028 4202 4316
BA 395550000021321006
BA 391602000023791504
BA 393386302809360414
BA 3913200-10578360472
BA 393389002208310352
BA 3913210100 867 24943

View File

@@ -0,0 +1,12 @@
BE37 3101 1557 9428
BE57800228915735
BE72 0682 2835 6316
BE09 3631 0770 0857
BE15 3631 5154 2130
BE66 2300 3095 5043
BE79 7330 3511 4333
BE 05 0013 6299 3375
BE 12 7340 2513 1392
BE59 65283724 9926
BE37301017561428
BE28 3100 1476 6520

View File

@@ -0,0 +1,13 @@
BG09STSA93000021741508
BG44UNCR70001520862375
BG91UNCR70001506849491
BG28BPBI79401048258601
bg24stsa93003100040700
bg67uncr70001520986509
BG32RZBB91551060533767
BG64UNCR96601010526904
BG25RZBB91551000646190
BG64UNCR96601010526904
bg94iort80948400294000
BG88TTBB94001526783652
BG28BNPA94401421040710

View File

@@ -0,0 +1,3 @@
BH39SBIN02630111120001
BH82SBIN02630111120003
BH12SBIN02630111120002

View File

@@ -0,0 +1,37 @@
BY51BELB30120118150790226000
BY 07 ABLT 3012 0192793350010001
BY 21 MTBK 3012 0001093300062 646
BY46OLMP30126000005480000933
BY07BPSB30120117400149330000
BY89AKBB36025020003480000000
BY 25 PJCB 30120509311000000933
BY 58 PJCB 3012 0377151000000 933
BY14 AKBB 3632 5180 0034 2420 0000
BY 89BPSB30121062180159330000
BY28 BELB 3012 1064 5100 3022 6000
BY 29 AKBB 3013 4281 6000 1540 0000
BY38AKBB30135943430471000000
BY 93 BPSB 3 012 104 977 042 933 0000
BY44 AKBB 3632 0000 0003 0560 0000
BY 65 AKBB 3015 7665 9001 9200 0000
BY89SOMA30120008230101000933
BY 76MTBK30120001093300077564
BY72AKBB30121002800115500000
BY19AKBB30120000023964000000
BY53AKBB36006191211090000000
BY 43BAPB30153255300100000000
BY 58 UNBS 3013 0006 0200 8001 3933
BY 65 ALFA 3013 2124090080270 000
BY14BPSB30125555550009330000
BY70AKBB 3013 0000000 1742 00000
BY24AKBB 3013 0000000 3342 00000
BY11BPSB30131725050129330000
BY66BLBB30120700008710001001
BY84ALFA30122305700080270000
BY73AKBB31320416100673200000
BY59BPSB30131031290189330000
BY50BAPB30122907300100000000
BY03 AKBB 3642 9030 0155 8230 0000
BY65SLAN30123407350100200000
BY08BLBB30120100027309001001
BY96MMBN66300010000000000000

View File

@@ -0,0 +1,3 @@
CF4220001000010120069700160
CF4220002002003712551080145
CF4220001004113717538890110

View File

@@ -0,0 +1,4 @@
CG3930013020003710721836132
CG3930011000101013451300019
CG 39 30013 02000 37107049649/22
CG 39 30014 00001 0120368360135

View File

@@ -0,0 +1,15 @@
CH070023023009416905E
CH18 0838 7000 0010 80 206
CH75 0483 5041 2027 1100 0
CH57 0483 5041 2027 1200 3
CH15 0023 5235 5161 9601 X
CH86 0023 5235 5161 9602 D
CH66 0076 7000 U520 5842 3
CH44 00767 000T 5341 2535
CH60 0070 0110 0023 2850 1
CH91 0070 0130 0073 0598 2
CH69 0070 0130 0073 0599 0
CH57 0024 0240 8219 7329V
CH77 0900 0000 4034 5852 3
CH 30 0070 0070 0000 3576 9
CH8600763000115724145

View File

@@ -0,0 +1,9 @@
CZ06 3500 0000 0010 0047 2301
CZ12 3500 0000 0013 3047 2304
CZ10 3500 0000 0012 2047 2303
CZ3855000000005041018525
CZ35 0300 0000 0002 2514 9068
CZ8427000000002112049123
CZ56 0600 0000 0002 1193 3046
CZ12 0600 0000 0002 1193 3062
CZ9101000000000021645051

View File

@@ -0,0 +1,21 @@
DE50512305000018102010
DE26501108006231602308
DE 30 50021000 0010116606
DE 63 690 400 45 0272181900
DE58 7102 0072 0009 3041 50
DE83100708480513128903
DE45100708480513128908
DE72100708480513128907
DE67100708480513128900
DE35100708480512158700
DE51100708480512158703
DE52 3244 00230580202000
DE90 5241 0900 1007 0690 06
DE08600700700051438000
DE92 7601 0085 0314 1538 56
DE 65203205004989143859
DE17100400000518335500
DE40 5007 0010 0953 4496 10
DE85503300000710110026
DE13503300000021011100
DE97 5123 0500 0018 0156 10

View File

@@ -0,0 +1,2 @@
DJ2110002010010409943020008
DJ21 1000 2010 0110 7609 3000 007

View File

@@ -0,0 +1,13 @@
DK1820005000015611
DK7752950010016924
DK8352950013002088
DK7752950015002239
DK5102164069061125
DK02 3000 0011 2810 52
DK02 3000 0011 2810 52
DK8176210003001134
DK2576810000607861
DK8520000747431973
DK 2330000002630699
DK8730002138818740
DK2430003007515596

View File

@@ -0,0 +1,26 @@
EE752200221001121961
EE063300332019340005
EE481700017000107462
EE251700017000107488
EE531700017000137539
EE201700017000305264
EE381700017000380988
EE821700017000411624
EE461700017000463779
EE571700017000539629
EE841700017000540016
EE331700017000548597
EE341700017000602996
EE481700017000631844
EE251700017000659127
EE781700017000659143
EE621700017001136380
EE791700017002848318
EE351700017003391534
EE654204207004188303
EE191010220028966019
EE302200221026463536
EE441010220117273011
EE512200221056408707
EE25 1010 0020 0642 8001
EE362200221046082939

View File

@@ -0,0 +1 @@
EG2100037000671002392189379

View File

@@ -0,0 +1,37 @@
ES1201820061770080107287
ES09 2038-0626-0160-0002-5280
ES 58 0075 0204 9406 0081 1004
ES17 2100 2050 61 0200003745
ES94 2095 5381 1910 6117 3539
ES39 2095 0292 9132 3900 0567
ES65 0081 1763 11 0001002404
ES53 0030 4290 7700 0171 1271
ES-94 2100 0424 34 0200114567
ES59 0081 0264 4600 01350839
ES49-2100-0927-5602-0001-7660
ES1320133074610211236492
ES40-0049-2584-9022-14002210
ES31-2080-5155-9730-4000-0250
ES97 0182 3999 3702 0066 4662
ES37 0049-1500-03-2810355229
ES97 0182 3999 3702 0066 4662
ES92 0128 0033 7805 0000 0751
ES85 0049 6015 13 2710068066
ES6720310000010118272402
ES9521000549410200294293
ES2800810312250001194826
ES29 0182 0903 59 0200081438
ES50 0487 0045 37 2080000078
ES74 0075 0078 0006 0146 8903
ES22 0049 4306 6221 9008 4227
ES30.2096.0187.1331.7730.2704
ES10 3058 0357 3627 2090 2337
ES38 2100 2225 4702 0020 1137
ES98 3190 0974 34 - 4255071823
ES71 1465 0100 9819 0030 4942
ES06 0182 3344 2602 0160 0719
ES42-0081-0093-40-0001532358
ES62 2100 0196 2302 0046 4351
ES81-0049-1810-9627-1040-6241
ES7300496742512716208582
ES21 2038 9659 2760 0004 0359

View File

@@ -0,0 +1,22 @@
FI 24 8000 1670 5221 10
IBAN FI 2316603000077720
FI 54 800015 000 69290
FI32 157230 000 30072
FI 38 5072 0540 0320 69
FI 60 1443 3000 1131 98
FI 98 5381 1720 0190 05
FI 91 8000 2430 6462 72
FI 1410973000115945
FI 88 4055 1020 1701 83
FI 738 000 15 711 55 010
FI98 4055 00100133 61
FI 11 51050610 001888
FI 73 1528 3000 135280
FI 76 4006 2220 0144 94
FI 2140 5524 2002 9508
FI 8781 3007 1015 9704
FI 39 5670 0820 1352 57
FI 5222051800005099
FI73 5700 8120 2291 12
FI 83 519407 2011 1892
FI 42 1366 3000 1266 07

View File

@@ -0,0 +1,89 @@
FR1420041010050500013M02606
FR76 3043 8000 0837 6490 3000 526
FR76 30003 00119 00020212266 43
FR7630027175330002005370159
FR76 1832 9000 0110 1111 2000 191
FR.98.20041.01016.0994845V037.34
FR 23 2004 1000 0127 4847 3B02 035
FR 7630 0040 2569 0000 0294 37103
FR 76 1007 1750 0000 0010 0035 291
FR 76 3006 6109 4000 0100 3080 193
FR 76 1189 9001 0000 0200 3124 583
FR 76 1670 5090 1708 7710 2614 840
FR 10 2004 1000 0102 8489 4Y02 027
FR 76 3000 4015 8700 0260 1178 980
FR 76 30003 02360 00150017186 72
FR76 3006 6108 7300 01024260 178
FR 23 2004 1000 0125 7091 0Y02 053
FR 76 1213 5003 0008 8018 5921 644
FR 76 3000 4004 7800 0013 1404 410
FR 57 2004 1000 0123 2068 7S02 079
FR 76 10071760 00 00 0010 00 38 624
FR 76 1751 5006 0008 2751 2334 879
FR 76 3007 6023 5210 7618 0020 033
FR 76 3000 3032 8000 0500 6152 856
FR 75 3004 1000 0104 4244 5Z02 067
FR76 1009 6185 6500 0257 2210 186
FR 76 1680 6001 0039 3268 9620 081
FR 12 3000 2085 7100 0006 0353 S04
FR 76 3000 4015 8700 0260 1178 980
FR 76 1054 8000 6000 0476 0051 673
FR 76 1009 6185 0600 0640 9780 167
FR 40 3000 2056 5600 0046 6276 T57
FR 45 2004 1000 0115 37 359Y02097
FR 76 1548 9003 8000 0357 5450 136
FR 76 3000 4008 0400 0102 1901 036
FR 76 1910 6006 8000 9631 2601 895
FR 17 3000 1004 9700 00Q0 5050 089
FR 76 1007 1250 0000 0010 0257 708
FR 89 3000 2083 4300 0007 1547 D17
FR 76 3000 3002 7800 0270 0475 779
FR 76 3000 3039 4100 0372 6061 586
FR 76 / 1213 / 5003 / 0008 / 0013 / 0194 / 760
FR 76 3006 6109 4000 0100 3080 193
FR 40 3000 2056 5600 0046 6276 T57
FR 6820041010090469926K03088
FR 40 3000 2056 5600 0046 6276 T57
FR 76 1450 6000 0407 8843 0306 021
FR 76 1460 7000 5166 0210 9766 627
FR 76 30003 03300 00037260771 18
FR 12 3000 2006 8400 0000 5616 A66
FR 76 1870 6000 0017 6105 0800 016
FR 76 1450 6005 4472. 8200 4676 641
FR 76 1009 6181 0200 0242. 0040 136
IBAN: FR 26 4097 8000 4801 2567 0B00 101
FR 76 30003 00990 00037268733 15
FR 76 1910 6000 0143 6478 0491 968
FR 76 3006 6109 4000 0100 3080 193
FR 76 1007 1780 0000 0010 0395 848
FR 05 20041 01007 0006761X038 53
FR 76-1007-1490-0000-0010-0020-607
FR 76 1213 5003 0008 8018 5921 644
FR 45 2004 1000 0115 37 359Y02097
FR 23 2004 1000 0114 69184V02 032
FR 76 1350 7001 6130 1074 6211 303
FR 76 3000 3018 4100 0372 6064 956
FR 76 4255 9000 1521 0297 8460 138
FR 76 3000 4008 9200 0104 4351 821
FR 76 3000 4008 4900 0100 1185 914
FR 76 1007 1590 0000 0010 1131 413
FR 30 3000 1008 39C3 7800 0000 051
FR 96 20041 01010 0044826B031 51
FR 76 3000 3034 5000 0506 2190 310
FR 76 1007 19 10 0000 0010 0177471
FR 02 20041 00001 5192606T020 73
FR-76-1007-1490-0000-0010-0020-607
FR 7630003021900002015008627
FR.98.20041.01016.0994845V037.34
FR 76 1007 1740 0000 0020 0024 505
FR 75 3000 1008 33C3 1800 0000 047
FR 76 1007 1750 0000 0010 0035 776
FR 76 30003 01100 00020884475 75
FR 75 3000 1008 33C3 1400 0000 086
FR 76 3005 6000 6600 6626 3664 091
FR 76 3000 4001 7800 0101 0481 692
Fr 76 30004 01692 000202 4109 661
FR 76 1440 6001 8019 1329 1016 563
FR 76 3000 1000 6400 0000. 9018 227
FR 76 1007 1750 0000 0010 0001 244
FR 76 3000 4008 5900. 0100 2278663

View File

@@ -0,0 +1,3 @@
GA2142001007341520000106963
GA2140021010032001890020126
GA2140002000055602673300064

View File

@@ -0,0 +1,31 @@
GB76 BARC 2032 5333 6065 46
GB28BARC20325364442255
GB60 BARC 20371680886513
GB84 BARC 20371666485655
GB07 BARC 20371649487888
GB97CITI 0832 0012 0010 47
GB63MIDL40052011741942
GB78CITI18500812000717
GB25CITI08320011963155
GB06CITI18500812000849
GB43NDEA40487845673101
gb37 midl 4002 5041 2614 95
GB15BKEN10000023031123
GB37BKEN10000023031018
GB03BKEN10000052055000
GB62 LOYD 3015 9900567301
GB84 LOYD 3096 3486 3952 56
GB24 LOYD 3096 3411 6621 04
GB05NWBK56000313270222
GB55NWBK60730101286498
GB58NWBK60721106570631
GB24NWBK60730123785624
GB90 BARC 2005 0600 9813 03
GB76NWBK55502306703844
GB21 CITI 1850 0813 359549
GB72NWBK55502359606843
GB23NWBK55502359694831
GB81NWBK55502359655666
GB33SCBL60910412697823
GB98 LOYD 3096 3401 0175 44
GB32 LOYD 3096 3486 1615 49

View File

@@ -0,0 +1 @@
GQ7050002001003715228190196

View File

@@ -0,0 +1,2 @@
GR91 0172 5240 0055 2405 2435 991
GR68 0172 5240 0055 2405 2436 017

View File

@@ -0,0 +1 @@
GW04GW1430010181800637601

View File

@@ -0,0 +1 @@
HN54PISA00000000000000123124

View File

@@ -0,0 +1,9 @@
HR9423400091110140839
HR39 2503 0071 1000 2063 6
HR72 2481 0001 1200 1687 7
HR46 2360 0001 1013 8681 8
HR3525000091101256823
HR4124020061100054853
HR8223600001101301489
HR6824840081105429943
HR 5223600001101690029

View File

@@ -0,0 +1,6 @@
HU69 1070 0024 6667 6548 5110 0005
HU07 1310 0007 0210 3880 0003 3484
HU07 1310 0007 0210 3880 0003 9789
HU17 1091 8001 0000 0068 7383 0003
HU22 1091 8001 0000 0068 7383 0010
HU48 1091 8001 0000 0068 7383 0027

View File

@@ -0,0 +1 @@
IE64 ULSB 9850 3024 0620 99

View File

@@ -0,0 +1,35 @@
<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@decanet.fr so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.decanet.fr for more information.
*
* @author SARL DECANET <contact@decanet.fr>
* @copyright 2007-2017 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@@ -0,0 +1 @@
IQ98 NBIQ 8501 2345 6789 012

View File

@@ -0,0 +1,12 @@
IR800180000000000829264358
IR19 0540 2011 8002 0043 8310 08
IR21 0690 1016 0100 0192 8730 01
IR170120000000001469577435
IR410550310200103088402001
IR290150000000695301364302
IR760120010000000223421288
IR150550310180000210044001
IR290120000000000096271783
IR470120000000001186587834
IR 150120 0000 0000 5637 7655 38
IR 390 5700 228 80000 979726 001

View File

@@ -0,0 +1,6 @@
IT18T0538703601000000198036
IT57V0538703601000000198060
IT40Z0538703601000000198072
IT29P0538742530000000802006
IT94I0306940101100100003599
IT63 M033 5901 6001 0000 0131 525

View File

@@ -0,0 +1 @@
KM4600005000010010904400137

View File

@@ -0,0 +1,14 @@
LT16 7300 0100 0000 0447
LT31 7044 0600 0614 9728
LT36 7300 0101 0370 4242
LT217300010082139763
LT957044060005610711
LT187300010072788629
LT 82 7400 0342 4122 3810
LT78 7300 0101 3111 5298
LT 57 7400 0342 4172 3810
LT85 7300 0101 3111 5366
LT537300010141453717
LT55 7300 0100 0000 0036
LT16 7300 0100 0000 0447
LT987044060007701395

View File

@@ -0,0 +1,11 @@
LU300030186828400000
LU060019100068283000
LU110029156516469200
LU110080408107001003
LU040090000002358000
LU980141510010000000
LU280019400644750000
LU510019415598974000
LU311111007733700000
LU400141239257000000
LU68 0019 2955 7684 8000

View File

@@ -0,0 +1,7 @@
LV59HABA0551018547392
LV42RIKO0002930061762
LV03RIKO0002030086376
LV63 NDEA 0000 0818 2900 6
LV90 NDEA 0000 0822 2010 9
LV29 NDEA 0000 0818 1904 5
LV89 NDEA 0000 0818 1903 2

View File

@@ -0,0 +1 @@
MA64011519000001205000534921

View File

@@ -0,0 +1,13 @@
MC 78 1273 9000 7001 2417 2000 L37
MC 58 1009 6185 7900 0458 7420 187
MC 23 1450 8000 0151 0479 3001 D18
MC 581756 900001 701251 0000297
MC 58 30003 01504 00027002272 08
MC 31 1273 9000 7001 0428 7000 c37
MC 58 1756 9000 0159 2780 0000 160
MC 62 1273 9000 7001 1223 5000K08
MC 83 1273 9000 7301 0499 5000 U79
MC 31 1273 9000 7001 2377 9000 Y60
MC 49 1273 9000 7000 1337 5000 L76
MC 12 1273 9000 7001 1224 1000 Y22
MC 79 1273 9000 7201 1612 7000 M36

View File

@@ -0,0 +1,5 @@
ME25530005010000786772
ME 2555 5200 2021 2006 7050
ME 25550005080000004970
ME 25525007010044076639
ME 25520036000001482278

View File

@@ -0,0 +1,45 @@
M.K 07300701000819229
MK 07 1007 0100 0084 754
MK 07 1007 0100 00 73114
MK 07 1007 0100 0067 876
MK 07 1007 0100 0078 449
MK 07 210 3 00000 2849 48
MK 07 210 3000003122 05
MK 07 210-3000003939-76
MK 07 300701001678455
MK 07 320 1400215737 69
MK 07 380-2-730 408-012-50
MK 07-210-7220000021-04
MK 07100701000066130
MK 072 000 020184 742 53
MK 07200 0024150665 13
MK 07200000785619094
MK 07200000785622683
MK 07200001256629463
MK 07200001568795057
MK 07200001740190468
MK 07200001877047186
MK 07200001959628815
MK 07200002458017143
MK 07200002555574214
MK 07210300000190567
MK 07210300000393588
MK 07210360000269619
MK 07210701000479670
MK 07210701000626140
MK 07210701000650972
MK 07210722000008506
MK 0725 000 0000 130 576
MK 07270722000009871
MK 07300307062190557
MK 07300701000001616
MK 07300701000170493
MK 07300701001273965
MK 07300701001804846
MK 07300701002687740
MK 07530501011838094
MK 07530901000383053
MK-07-210-7010010785-48
MK. 07200001256629463
MK.07290001031382039
MK07500701000133139

View File

@@ -0,0 +1 @@
MR1300020001010000123456753

View File

@@ -0,0 +1 @@
NE58NE0380100100130305000268

View File

@@ -0,0 +1 @@
NI92BAMC000000000000000003123123

View File

@@ -0,0 +1,26 @@
NL91ABNA0417164300
NL97INGB0678631808
NL32 INGB 0655 6507 68
NL37ABNA0618139087
NL54ABNA0244747563
NL59 INGB 0657714151
NL68ABNA0484748203
NL08RABO0331753588
NL05INGB0004459505
NL47 TRIO 0254 7330 26
IBAN NL81INGB0671210432
NL78INGB0004044777
NL78 RABO 0155 4047 76
NL81INGB0671210432
NL05 ABNA 0444 0460 03
NL75 RABO 0172 9454 37
NL15 FTSB 0240 4939 31
NL41 KRED 0633 0946 68
NL58RABO0314143017
NL97 INGB 0660064650
NL10 INGB 0006 321427
NL66ABNA0518133214
NL03 RABO 0138 5613 97
NL79 RABO 0369 2244 77
NL70ABNA0590229265
NL55 RBOS 0530 1890 11

View File

@@ -0,0 +1,44 @@
NO 1797500633224
NO 5897500449156
NO23 7001 0204 168
NO33 6345 06 23123
NO4697500641723
NO 89 42004151326
NO 62 650 204 441 20
NO 43 651 204 471 94
NO87 51020519030
NO 29 1594 44 22533
NO2565500636496
NO 39 6318 05 01489
NO. 26 8101 12 42901
NO. 73 8101 12 42928
NO 35 9650 05 73667
NO9832271000153
NO 5997310504029
NO 26 7032 0516 038
NO 15 1503 42 48505
NO 15 1503 42 48505
NO 03 90012463560
NO 39 6074 06 03550
NO 6947780786090
NO 64 9001 16 65704
NO 6649101413984
NO 89 7220.20.45244
NO 39 4750 07 95936
NO 0970140500931
NO5881012749414
NO 7615030839797
NO2962420447596
NO78 1310 2590 729
NO57 5201 0511 755
NO 76 29011139688
NO. 8815944736139
NO1924800490800
NO2362720447849
NO9162760528965
NO 5370140534380
NO 081503 1046855
NO 4230001510300
NO 69 2711 13 42143
NO 6865040505746
NO 1160030689960

View File

@@ -0,0 +1,33 @@
PK77FAYS0001311490008983
PK53ALFH5508005000381358
PK68JSBL9009000000112945
PK39ALFH0056195000701779
PK27 MUCB 0001 4010 1005 4916
PK37 SCBL 0000 0013 2595 0101
PK30 DUIB 0000 0001 8154 6001
PK20MUCB 0760723941005354
PK27SCBL0000105794096390
PK27SCBL0000105794096390
PK50UNIL0000199391701354
PK67 SCBL 0000 00 124 128 0201
PK61 HABB 0001 2800 3830 6201
PK63ABPA0010000062574726
PK 04 NBPA 0003 0022 00025618
PK58 HABB 0006020095934203
PK74HABB0002967900456001
PK31 UNIL 0000 0002 0441 8243
PK87SUMB0317027140109349
PK36ABPA0010028512620019
PK35HABB0001827901121210
PK12MUCB0030445261000455
PK44 HABB 0000 5679 0058 2955
PK59UNIL0109000220096898
PK39 SCBL 0000 0087 7596 1442
PK25 SCBL 0000 1057 7727 7790
PK43ALFH0510002002766801
PK34NBPA1694003010067650
PK15NBPA1694003010124543
PK35FAYS0332100316207403
PK41FAYS0331000210175001
PK90FAYS0331100050977423
PK19ALFH 5501 00 5000 450 414

View File

@@ -0,0 +1,121 @@
PL.46 1010 1010 0030 1422 3100 0000
PL 21 1240 1545 1111 0000 1166 6233
PL71 1240 1545 1787 0000 1166 6259
PL 34124065241787001040784695
PL 77124065241978001040784653
PL 25 1910 1048 2120 9918 1929 0002
PL 59 1600 1462 1844 1457 0000 0001
PL 10 1160 2202 0000 0000 3550 6213
PL 05 1600 1462 1844 1457 0000 0003
PL 75 1600 1462 1844 1457 0000 0004
PL 80 1160 2202 0000 0000 4054 5461
PL 30 1160 2202 0000 0001 6077 7279
PL 58 1750 1064 0000 0000 3038 7082
PL 24 1050 1575 1000 0090 6523 5872
PL 20 1240 6292 1111 0010 5759 7156
PL 60 1030 1508 0000 0005 5001 0038
PL 07 1090 2398 0000 0001 1007 4280
PL 75 1020 1156 0000 7802 0059 7252
PL 73 1140 2017 0000 4502 1050 9042
PL 24 1020 4753 0000 0102 0097 7322
PL 93 1130 1017 0020 1226 4720 0001
PL 64 1130 1017 0020 1467 1520 0005
PL 37 1130 1017 0020 1467 1520 0006
PL 75 1130 1017 0020 1467 1520 0001
PL 06 1160 2202 0000 0000 4696 3052
PL 20 1140 1010 0000 2926 6700 1020
PL 85 1140 1010 0000 2926 6700 1014
PL 64 1030 1508 0000 0008 1656 1019
PL 42 1030 1508 0000 0008 1656 1027
PL 54 1240 1444 1111 0000 0936 5629
PL 59 1240 1444 1978 0000 0936 5645
PL 23 1140 1137 0000 2108 3300 1001
PL 93 1140 1137 0000 2108 3300 1002
PL 66 1140 1137 0000 2108 3300 1003
PL 22 1910 1048 2510 0026 8383 0005
PL 13 1910 1048 2781 0026 8383 0003
PL 60 1750 1237 0000 0000 1220 4922
PL 12 1750 1237 0000 0000 1218 4058
PL 24 1020 4753 0000 0102 0097 7322
PL 60 1140 2004 0000 3412 0188 0400
PL 93 1130 1017 0020 1226 4720 0001
PL 20 1140 1010 0000 2926 6700 1020
PL26 1910 1048 2122 0170 9526 0001
PL96 1910 1048 2122 0170 9526 0002
PL 45 1160 2202 0000 0000 3174 8579
PL 77 1240 3464 1111 0010 6320 9674
PL 22 1240 3464 1978 0010 6321 0188
PL 64 1030 1508 0000 0008 1656 1019
PL 42 1030 1508 0000 0008 1656 1027
PL 49 8787 0000 0024 6482 20000001
PL 42 1030 1508 0000 0008 1656 1027
PL 08 1910 1048 2669 5941 2459 0001
PL 98 1020 5226 0000 6602 0416 7565
PL 61 2490 0005 0000 4510 1650 5736
PL83 1240 3796 1978 0010 4632 3601
PL 31 1240 1037 1978 0010 1651 3186
PL 86 1240 1037 1787 0010 1740 2700
PL62 1600 1286 0003 0031 8642 6001
PL 71 1030 0019 0109 7806 0103 0205
PL 60 1030 0019 0108 4006 0111 2631
PL 89 8944 0003 0000 2088 2000 0010
PL 39 1240 4142 1978 0000 4823 0559
PL 24 1240 4142 1787 0010 3844 4994
PL 70 1240 4748 1111 0000 4879 7603
PL 74 1050 1214 1000 0007 0000 7909
PL78191010482518467065890001
PL51191010482518467065890002
PL 29 1050 1142 1000 0023 5194 3747
PL 12 1050 1142 1000 0023 5194 3762
PL 20 1050 1142 1000 0023 5336 5832
PL 11 1030 0019 0109 8530 0046 1839
PL 64 1020 1127 0000 1102 0198 5654
PL 52 84350004 0000 0002 6185 0001
PL 65 1020 5011 0000 9602 0105 7298
PL 06 1750 0009 0000 0000 0561 3183
PL 28 1140 2017 0000 4612 0074 4391
PL 95 1020 4027 0000 1002 0052 7176
PL 63 1240 5282 1111 0000 4889 8384
PL 16 1090 1883 0000 0001 0194 5244
PL 48 2490 0005 0000 4600 6936 3486
PL 07 1090 2398 0000 0001 1007 4280
PL 44 1140 2004 0000 3002 7409 3926
pl63203000451110000003803020
PL 16 1240 6609 1111 0000 4933 2414
PL 90 1020 2267 0000 4302 0004 2002
PL 29124026141111000039586445
PL 77 2490 0005 0000 4600 4362 0619
PL 10 2490 0005 0000 4000 9745 4112
PL 40 2490 0005 0000 4000 9817 2730
PL 02 1030 1276 0000 0000 5528 5211
PL 29 1030 1276 0000 0000 5528 5210
PL 46 1050 1025 1000 0023 1010 9745
PL 16 1240 6609 1111 0000 4933 2414
PL 23 1240 6609 1978 0000 4933 5789
PL 90 1020 2267 0000 4302 0004 2002
PL 71 1030 1263. 0000 0000 8949 9003
PL 29124026141111000039586445
PL 09 2490 1057 0000 9900 4941 5247
PL 97 2490 1057 0000 9902 4941 5247
PL 77 2490 0005 0000 4600 4362 0619
PL 78 1240 6612 1111 0010 3433 8273
PL 40 2490 0005 0000 4000 9817 2730
PL 02 1030 1276 0000 0000 5528 5211
PL 29 1030 1276 0000 0000 5528 5210
PL 46 1050 1025 1000 0023 1010 9745
PL 36 1240 2294 1111 0010 1209 3336
PL 81 1240 2294 1978 0010 1209 3408
PL 29 1950 0001 2006 0692 5295 0003
PL 90 1010 1599 0523 6022 3100 0000
PL 06 1050 1070 1000 0090 3057 3225
PL 59 1050 1070 1000 0022 3285 0392
PL 14 1160 2202 0000 0000 3342 4618
PL 58 1500 1083 1210 8005 7637 0000
PL 42 1050 1953 1000 0023 6908 4153
PL 35 1500 1793 1217 9006 7421 0000
PL 66103012470000000055861358
PL 44 1240 6609 1978 0010 4746 2792
PL 18 1130 1017 0020 1466 5620 0001
PL 35102032190000900200102624
PL 35102032190000950200555078
PL 72 1090 2529 0000 0001 3016 5716

View File

@@ -0,0 +1,37 @@
PT 50 0007 0000 00072023471 23
PT 50 0007 0691 0001 1420 0082 8
PT 50 000700110050014000111
PT 50 0010 0000 3801 1080 0016 7
PT 50 0010 0000 3968 6380 0016 1
PT 50 0010 0000 51177110001 55
PT 50 0018 0365 002000 10582 22
PT 50 0033 0000 0000 5717 13255
PT 50 0033 0000 5003 2983 2480 5
PT 50 0035 0001 00013018330 37
PT 50 0035 0001 00020285030 08
PT 50 0035 0205 00011528730 91
PT 50 0035 0391 00013831630 45
PT 50 0035 0542 0000 9975 730 73
PT 50 0035.0671.00000311330.75
PT 50 00360175 9910 07575091 2
PT 50 0038 0248 055245177714 0
PT 50 0781 0112 0000000 2991 22
PT 50 0781 0112 0000000 784316
PT 50.0033.0000.00192237511.05
PT 50.0035.0697.00632073.300.73
PT 500 018 000 050 924 642 020 49
PT 500 035 017 100 167 322 630 15
PT 5000 0705 2200 0138 0000 332
PT 5000 18 0269 00200010529 69
PT 5000 3800 2300 694 308 77 141
PT 50000700210013513000259
PT 50003501270004098893077
PT 50003502340000669213002
PT 50003506510052468183052
PT 500035068800000304530 44
PT 50078101120112001332826
PT-50003500970000817053048
PT50 0010 0000 1573 7690 1063 9
PT50 0038 0000 3933 1181 7719 0
PT: 50 0018 0003 24403537020 84
PT: 50003300004520006048605

View File

@@ -0,0 +1,2 @@
RO57PORL0000250010000101
RO20RZBR0000060002651722

View File

@@ -0,0 +1,57 @@
RS 35908504619019323080
RS 35105580120000358150
RS 35265100000012550493
RS 35340000001101007936
RS 35160005030000152939
RS 35908500103019323073
RS 35160005010011515520
RS 35908500100015031992
RS 35160005400001497777
RS 35908500103019323073
RS 35170003000420400289
RS 35908500100014635165
RS 35275001611660638749
RS 35908504100000769397
RS 35355000271766111755
RS 35160005400000314280
RS 35 2651 0000 0009 7229 43
RS 35908500100012897798
RS 35 2050 070 100 3046 0987
RS 35275000022001979646
RS35170003002267232080
RS 35150000206290076678
RS 35275001611660638749
RS 35265050000027565780
RS 35908500103019323073
RS35170003002267232080
RS 35275000022001979646
RS 35160005010022965788
RS 35150000206290076678
RS 35 125-1200000000051-57
RS 35908500103019323073
RS 35275001611660638749
RS 35275001611660638749
RS 35160513020147929010
RS 35 2750 0175 1220 9095 15
RS35160553020042237362
RS35908500100014807825
RS 35 2203 5304 0000 0514 07
RS 35285207541000574867
RS 35160005010022977040
RS 35190007010004595642
RS 35 2050 0701 0039 0947 63
RS 35170003000335132051
rs 35160533020031915816
RS 35205903102060995316
RS 35275001055091551475
RS 35340000001101248981
RS 35180330100021300361
RS 35205903101860366239
RS 35355000320011554170
RS 35275001611660638749
RS 35340000001101007936
RS 35160005400000584619
RS 35205903102060995316
RS 35160005010012969550
RS 35 205 0017712365000 79
RS35125120000000351932

View File

@@ -0,0 +1,4 @@
SA4150000000031002605275
SA1410000088344223000104
SA6010000055535311000107
SA7983000001500484920001

View File

@@ -0,0 +1,5 @@
SE1830000000039527909511
SE0250000000052461022488
SE3050000000059378211100
SE2450000000059378202284
SE44 5000 0000 0520 1852 7908

View File

@@ -0,0 +1,88 @@
SI56 051008011098926
SI56 0100 0000 0300 007
SI56 0451 5000 0570 577
SI56 2900 0010 1901 946
SI56 0510 0800 0022 205
SI56101000051042074
SI56 2900 0005 1352 336
SI 56 1010 0004 5900 492
SI56011008450021464
SI56047500000115384
SI56031301000271360
SI56011008881000030
SI56 0310 0100 6235 420
SI56 0292 2001 1058 965
SI56 0510 0801 2087 356
SI56 0700 0000 0843 602
SI56 3300 0000 0582 088
SI56 1010 0003 8034 471
SI56 0100 0000 3800 058
SI56 6100 0000 3565 970
SI56 0110 0845 0084 126
SI56 0292 3001 4224 317
SI56 2900 0000 1812 884
SI56 0510 0801 0612 277
SI56 3300 0000 2914 938
SI56 3000 0010 3169 721
SI56 0430 2000 1492 620
SI56 3300 0000 4432 988
SI56 0292 4025 4879 425
SI56 0292 4001 4270 634
SI56 3300 0000 1348 388
SI56 0249 8001 7625 689
SI 56 0430 2000 0284 291
SI56 0292 4001 3384 248
SI56 2900 0005 5016 220
SI56 0700 0000 1531 914
SI56 0430 2000 1472 541
SI56 1010 0000 0008 240
SI56 0223 6001 7050 416
SI56 2460 0900 2857 625
SI56 0510 0801 2802 537
SI56 0317 9100 0237 822
SI 56 3000 0001 0074 262
SI56 0100 0000 0300 007
SI56 0100 0000 0100 090
SI56 0100 0000 2900 092
SI56 0100 0000 0600 028
SI56 0100 0000 1000 153
SI56 0100 0000 1910 013
SI56 0100 0000 2700 078
SI56 0100 0000 0700 035
SI56 0100 0000 3300 023
SI56 0100 0000 3400 030
SI56 0100 0000 0400 014
SI56 0100 0000 0200 097
SI56 0100 0000 9000 034
SI56 0100 0000 2510 055
SI56 0100 0000 2400 057
SI56 0100 0000 0300 007
SI56 0100 0000 3029 005
SI56 0100 0000 3500 134
SI56 0100 0000 3700 051
SI56 0100 0000 3800 058
SI56 0100 0000 0500 021
SI56 0100 0000 4100 079
SI56 0100 0000 6100 025
SI56 0100 0000 6000 018
SI56 0100 0000 6400 046
SI56 0100 0000 7900 054
SI56 0475 2000 0502 025
SI56 0292 4025 7767 891
SI56 0510 0801 3106 632
SI56 3300 0000 3059 468
SI56 6100 0000 2218 737
SI56024260015046980
SI56060000103551776
SI56101000038263682
SI56300000002234334
SI56031761000289864
SI56 6100-0000-1966-246
SI56 6100-0000-1966-246
SI56 6100-0000-1966-537
SI56 6100-0000-2274-609
SI56 0312 5100 7981 553
SI56 0234 0001 1994 045
SI56 2490 0900 3387 483
SI56 0294 0025 9931 856
SI56 3300 0000 5944 151

Some files were not shown because too many files have changed in this diff Show More