Version Notes
First Release
Download this release
Release Info
Developer | xrec.nl |
Extension | XREC_DIM |
Version | 1.0.1 |
Comparing to | |
See all releases |
Version 1.0.1
- app/code/community/Xrec/Dim/Block/Payment/Dim/Fail.php +11 -0
- app/code/community/Xrec/Dim/Block/Payment/Dim/Form.php +12 -0
- app/code/community/Xrec/Dim/Block/Payment/Dim/Info.php +5 -0
- app/code/community/Xrec/Dim/Helper/Data.php +87 -0
- app/code/community/Xrec/Dim/Helper/Dim.php +290 -0
- app/code/community/Xrec/Dim/Model/Dim.php +258 -0
- app/code/community/Xrec/Dim/controllers/DimController.php +284 -0
- app/code/community/Xrec/Dim/etc/config.xml +169 -0
- app/code/community/Xrec/Dim/etc/system.xml +228 -0
- app/code/community/Xrec/Dim/sql/dim_setup/mysql4-install-1.0.0.php +32 -0
- app/code/community/Xrec/Dim/sql/dim_setup/mysql4-uninstall-1.0.0.php +17 -0
- app/design/frontend/base/default/layout/dim.xml +18 -0
- app/design/frontend/base/default/template/xrec/form/dim.phtml +36 -0
- app/design/frontend/base/default/template/xrec/page/exception.phtml +10 -0
- app/design/frontend/base/default/template/xrec/page/fail.phtml +65 -0
- app/etc/modules/Xrec_Dim.xml +12 -0
- lib/Communicator/.DS_Store +0 -0
- lib/Communicator/B2BCommunicator.php +56 -0
- lib/Communicator/Configuration/Configuration.php +185 -0
- lib/Communicator/CoreCommunicator.php +292 -0
- lib/Communicator/Entities/AcquirerStatusRequest.php +160 -0
- lib/Communicator/Entities/AcquirerStatusResponse.php +333 -0
- lib/Communicator/Entities/AcquirerTrxRequest.php +206 -0
- lib/Communicator/Entities/AmendmentRequest.php +351 -0
- lib/Communicator/Entities/AmendmentResponse.php +76 -0
- lib/Communicator/Entities/CancellationRequest.php +318 -0
- lib/Communicator/Entities/CancellationResponse.php +76 -0
- lib/Communicator/Entities/DirectoryRequest.php +82 -0
- lib/Communicator/Entities/DirectoryResponse.php +111 -0
- lib/Communicator/Entities/ErrorResponse.php +52 -0
- lib/Communicator/Entities/NewMandateRequest.php +289 -0
- lib/Communicator/Entities/NewMandateResponse.php +76 -0
- lib/Communicator/Libraries/CommunicatorException.php +34 -0
- lib/Communicator/Libraries/Logger.php +74 -0
- lib/Communicator/Libraries/MessageIdGenerator.php +35 -0
- lib/Communicator/Libraries/XmlSecurity.php +198 -0
- lib/Communicator/Libraries/XmlUtility.php +15 -0
- lib/Communicator/Libraries/XmlValidator.php +56 -0
- lib/Communicator/Libraries/xmlseclibs.php +1853 -0
- lib/Communicator/schemas/idx.merchant-acquirer.1.0.xsd +369 -0
- lib/Communicator/schemas/pain.009.001.04.xsd +534 -0
- lib/Communicator/schemas/pain.010.001.04.xsd +615 -0
- lib/Communicator/schemas/pain.011.001.04.xsd +574 -0
- lib/Communicator/schemas/pain.012.001.04.xsd +573 -0
- lib/Communicator/schemas/xmldsig-core-schema.xsd +309 -0
- package.xml +18 -0
- skin/frontend/dim/.DS_Store +0 -0
- skin/frontend/dim/css/style.css +9 -0
- skin/frontend/dim/images/dim.jpg +0 -0
- var/xrec/.DS_Store +0 -0
- var/xrec/.htaccess +2 -0
- var/xrec/dim/.DS_Store +0 -0
- var/xrec/dim/cer/.DS_Store +0 -0
app/code/community/Xrec/Dim/Block/Payment/Dim/Fail.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Xrec_Dim_Block_Payment_Idl_Fail extends Mage_Core_Block_Template
|
4 |
+
{
|
5 |
+
public function _construct()
|
6 |
+
{
|
7 |
+
parent::_construct();
|
8 |
+
$this->setTemplate('xrec/page/fail.phtml');
|
9 |
+
}
|
10 |
+
|
11 |
+
}
|
app/code/community/Xrec/Dim/Block/Payment/Dim/Form.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Xrec_Dim_Block_Payment_Dim_Form extends Mage_Payment_Block_Form
|
4 |
+
{
|
5 |
+
|
6 |
+
public function _construct()
|
7 |
+
{
|
8 |
+
parent::_construct();
|
9 |
+
$this->setTemplate('xrec/form/dim.phtml');
|
10 |
+
}
|
11 |
+
|
12 |
+
}
|
app/code/community/Xrec/Dim/Block/Payment/Dim/Info.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Xrec_Dim_Block_Payment_Dim_Info extends Mage_Payment_Block_Info
|
4 |
+
{
|
5 |
+
}
|
app/code/community/Xrec/Dim/Helper/Data.php
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Xrec_Dim_Helper_Data extends Mage_Core_Helper_Abstract
|
4 |
+
{
|
5 |
+
|
6 |
+
/**
|
7 |
+
* @param string $transactionId
|
8 |
+
* @return mixed
|
9 |
+
*/
|
10 |
+
public function getStatusById($transactionId)
|
11 |
+
{
|
12 |
+
/** @var $connection Varien_Db_Adapter_Interface */
|
13 |
+
$connection = Mage::getSingleton('core/resource')->getConnection('core_read');
|
14 |
+
$status = $connection->fetchAll(
|
15 |
+
sprintf(
|
16 |
+
"SELECT `bank_status` FROM `%s` WHERE `transaction_id` = %s",
|
17 |
+
Mage::getSingleton('core/resource')->getTableName('dim_payments'),
|
18 |
+
$connection->quote($transactionId)
|
19 |
+
)
|
20 |
+
);
|
21 |
+
|
22 |
+
return $status[0];
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param string $transactionId
|
27 |
+
* @return null
|
28 |
+
*/
|
29 |
+
public function getOrderIdByTransactionId($transactionId)
|
30 |
+
{
|
31 |
+
/** @var $connection Varien_Db_Adapter_Interface */
|
32 |
+
$connection = Mage::getSingleton('core/resource')->getConnection('core_read');
|
33 |
+
$id = $connection->fetchAll(
|
34 |
+
sprintf(
|
35 |
+
"SELECT `order_id` FROM `%s` WHERE `transaction_id` = %s",
|
36 |
+
Mage::getSingleton('core/resource')->getTableName('dim_payments'),
|
37 |
+
$connection->quote($transactionId)
|
38 |
+
)
|
39 |
+
);
|
40 |
+
|
41 |
+
if (sizeof($id) > 0)
|
42 |
+
{
|
43 |
+
return $id[0]['order_id'];
|
44 |
+
}
|
45 |
+
return null;
|
46 |
+
}
|
47 |
+
|
48 |
+
public function getPaymentByTransactionId($transactionId)
|
49 |
+
{
|
50 |
+
/** @var $connection Varien_Db_Adapter_Interface */
|
51 |
+
$connection = Mage::getSingleton('core/resource')->getConnection('core_read');
|
52 |
+
$data = $connection->fetchAll(
|
53 |
+
sprintf(
|
54 |
+
"SELECT * FROM `%s` WHERE `transaction_id` = %s",
|
55 |
+
Mage::getSingleton('core/resource')->getTableName('dim_payments'),
|
56 |
+
$connection->quote($transactionId)
|
57 |
+
)
|
58 |
+
);
|
59 |
+
|
60 |
+
if (sizeof($data) > 0)
|
61 |
+
{
|
62 |
+
return $data[0];
|
63 |
+
}
|
64 |
+
return array();
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Check if testmode is enabled.
|
70 |
+
*/
|
71 |
+
public function getTestModeEnabled()
|
72 |
+
{
|
73 |
+
return $this->getConfig('testmode');
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Get store config
|
78 |
+
*
|
79 |
+
* @param string $key
|
80 |
+
* @return string
|
81 |
+
*/
|
82 |
+
public function getConfig($key = null)
|
83 |
+
{
|
84 |
+
return Mage::getStoreConfig("payment/xrec/{$key}");
|
85 |
+
}
|
86 |
+
|
87 |
+
}
|
app/code/community/Xrec/Dim/Helper/Dim.php
ADDED
@@ -0,0 +1,290 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once 'Communicator/CoreCommunicator.php';
|
4 |
+
require_once 'Communicator/B2BCommunicator.php';
|
5 |
+
|
6 |
+
class Xrec_Dim_Helper_Dim
|
7 |
+
{
|
8 |
+
/** @var CoreCommunicator */
|
9 |
+
protected $coreCommunicator;
|
10 |
+
protected $issuerAuthenticationUrl;
|
11 |
+
protected $transactionId;
|
12 |
+
protected $dimSequenceType;
|
13 |
+
protected $dimBankId = null;
|
14 |
+
protected $bankStatus = null;
|
15 |
+
|
16 |
+
protected $urlProd = 'https://machtigen.secure-ing.com/EMRoutingWS/handler/ing';
|
17 |
+
protected $urlTest = 'https://machtigen.secure-ing.com/TestRoutingWS/handler/ing';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return mixed
|
21 |
+
*/
|
22 |
+
public function getIssuerAuthenticationUrl()
|
23 |
+
{
|
24 |
+
return $this->issuerAuthenticationUrl;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param mixed $issuerAuthenticationUrl
|
29 |
+
*/
|
30 |
+
public function setIssuerAuthenticationUrl($issuerAuthenticationUrl)
|
31 |
+
{
|
32 |
+
$this->issuerAuthenticationUrl = $issuerAuthenticationUrl;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @return mixed
|
37 |
+
*/
|
38 |
+
public function getTransactionId()
|
39 |
+
{
|
40 |
+
return $this->transactionId;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param mixed $transactionId
|
45 |
+
*/
|
46 |
+
public function setTransactionId($transactionId)
|
47 |
+
{
|
48 |
+
$this->transactionId = $transactionId;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
public function getDimBankId()
|
55 |
+
{
|
56 |
+
return $this->dimBankId;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param string $dimBankId
|
61 |
+
*/
|
62 |
+
public function setDimBankId($dimBankId)
|
63 |
+
{
|
64 |
+
$this->dimBankId = $dimBankId;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @return null
|
69 |
+
*/
|
70 |
+
public function getBankStatus()
|
71 |
+
{
|
72 |
+
return $this->bankStatus;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @param null $bankStatus
|
77 |
+
*/
|
78 |
+
public function setBankStatus($bankStatus)
|
79 |
+
{
|
80 |
+
$this->bankStatus = $bankStatus;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @return mixed
|
85 |
+
*/
|
86 |
+
public function getDimSequenceType()
|
87 |
+
{
|
88 |
+
return $this->dimSequenceType;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param mixed $dimSequenceType
|
93 |
+
*/
|
94 |
+
public function setDimSequenceType($dimSequenceType)
|
95 |
+
{
|
96 |
+
$this->dimSequenceType = $dimSequenceType;
|
97 |
+
}
|
98 |
+
|
99 |
+
protected function getConfiguration()
|
100 |
+
{
|
101 |
+
$urlDirectoryReq = Mage::Helper('dim/data')->getConfig('AcquirerUrl_DirectoryReq');
|
102 |
+
$urlTransactionReq = Mage::Helper('dim/data')->getConfig('AcquirerUrl_TransactionReq');
|
103 |
+
$urlStatusReq = Mage::Helper('dim/data')->getConfig('AcquirerUrl_StatusReq');
|
104 |
+
|
105 |
+
$testMode = Mage::Helper('dim/data')->getConfig('testMode');
|
106 |
+
if ($testMode) {
|
107 |
+
$urlDirectoryReq = Mage::Helper('dim/data')->getConfig('AcquirerUrl_DirectoryReqTest');
|
108 |
+
$urlTransactionReq = Mage::Helper('dim/data')->getConfig('AcquirerUrl_TransactionReqTest');
|
109 |
+
$urlStatusReq = Mage::Helper('dim/data')->getConfig('AcquirerUrl_StatusReqTest');
|
110 |
+
}
|
111 |
+
$cerPath = Mage::getBaseDir('var') . '/xrec/dim/cer/';
|
112 |
+
|
113 |
+
$returnUrl = Mage::Helper('dim/data')->getConfig('merchantReturnURL');
|
114 |
+
if (substr($returnUrl, -1) !== '/') {
|
115 |
+
$returnUrl .= '/';
|
116 |
+
}
|
117 |
+
/*
|
118 |
+
* @param string $passphrase
|
119 |
+
* @param string $keyFile
|
120 |
+
* @param string $crtFile
|
121 |
+
* @param string $crtFileAquirer
|
122 |
+
* @param string $contractID
|
123 |
+
* @param string $contractSubID
|
124 |
+
* @param string $merchantReturnURL
|
125 |
+
* @param string $AcquirerUrl_DirectoryReq
|
126 |
+
* @param string $AcquirerUrl_TransactionReq
|
127 |
+
* @param string $AcquirerUrl_StatusReq
|
128 |
+
* @param bool $enableXMLLogs
|
129 |
+
* @param string $logPath
|
130 |
+
* @param string $folderNamePattern
|
131 |
+
* @param string $fileNamePrefix
|
132 |
+
* @param bool $enableInternalLogs
|
133 |
+
* @param string $fileName
|
134 |
+
*/
|
135 |
+
return new Configuration(
|
136 |
+
Mage::Helper('dim/data')->getConfig('passphrase'),
|
137 |
+
$cerPath . Mage::Helper('dim/data')->getConfig('keyFile'),
|
138 |
+
$cerPath . Mage::Helper('dim/data')->getConfig('crtFile'),
|
139 |
+
$cerPath . Mage::Helper('dim/data')->getConfig('crtFileAquirer'),
|
140 |
+
Mage::Helper('dim/data')->getConfig('merchantID'),
|
141 |
+
Mage::Helper('dim/data')->getConfig('merchantSubID'),
|
142 |
+
$returnUrl . 'dim/dim/return',
|
143 |
+
$urlDirectoryReq ? $urlDirectoryReq : $this->urlProd,
|
144 |
+
$urlTransactionReq ? $urlTransactionReq : $this->urlProd,
|
145 |
+
$urlStatusReq ? $urlStatusReq : ($testMode ? $this->urlTest : $this->urlProd),
|
146 |
+
true,
|
147 |
+
Mage::getBaseDir('var') . '/logs/xrec/dim/',
|
148 |
+
'Y-m-d',
|
149 |
+
'His.u',
|
150 |
+
true,
|
151 |
+
'eMandates.txt'
|
152 |
+
);
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* @param Mage_Sales_Model_Order $order
|
157 |
+
* @return bool
|
158 |
+
*/
|
159 |
+
public function doNewMandateRequest($order)
|
160 |
+
{
|
161 |
+
if (!$order->getPayment()) {
|
162 |
+
Mage::throwException('Ongeldige betaling!');
|
163 |
+
}
|
164 |
+
$dimBankId = $this->dimBankId ? $this->dimBankId : 'INGBNL2A';
|
165 |
+
/*if (Mage::Helper('dim/data')->getConfig('SequenceTypeCustomer')) {
|
166 |
+
$dimSequenceType = Mage::Helper('dim/data')->getConfig('SequenceType');
|
167 |
+
} else {
|
168 |
+
$dimSequenceType = $this->dimSequenceType ? $this->dimSequenceType : 'OOFF';
|
169 |
+
}*/
|
170 |
+
$dimSequenceType = $this->dimSequenceType ? $this->dimSequenceType : 'OOFF';
|
171 |
+
$reason = Mage::Helper('dim/data')->getConfig('eMandateReason');
|
172 |
+
|
173 |
+
// Initiate a CoreCommunicator
|
174 |
+
$coreCommunicator = new CoreCommunicator($this->getConfiguration());
|
175 |
+
/**
|
176 |
+
* @param string $entranceCode
|
177 |
+
* @param string $language
|
178 |
+
* @param string $messageId
|
179 |
+
* @param string $eMandateId
|
180 |
+
* @param string $eMandateReason
|
181 |
+
* @param string $debtorReference
|
182 |
+
* @param string $debtorBankId
|
183 |
+
* @param string $purchaseId
|
184 |
+
* @param string $sequenceType
|
185 |
+
* @param string $maxAmount - optional
|
186 |
+
* @param DateInterval $expirationPeriod - optional
|
187 |
+
*/
|
188 |
+
$newMandateRequest = new NewMandateRequest(
|
189 |
+
$order->getPayment()->getId(),
|
190 |
+
'nl',
|
191 |
+
MessageIdGenerator::NewMessageId(),
|
192 |
+
$order->getPayment()->getId(),
|
193 |
+
$reason ? $reason : 'Webshop purchase',
|
194 |
+
$order->getCustomerName(),
|
195 |
+
$dimBankId,
|
196 |
+
$order->getRealOrderId(),
|
197 |
+
$dimSequenceType,
|
198 |
+
Mage::app()->getStore()->roundPrice($order->getGrandTotal()),
|
199 |
+
self::evaluateExpirationPeriod('PT20M')
|
200 |
+
);
|
201 |
+
$newMandateResponse = $coreCommunicator->NewMandate($newMandateRequest);
|
202 |
+
if ($newMandateResponse->IsError) {
|
203 |
+
Mage::throwException($newMandateResponse->Error->ErrorCode . ': ' . $newMandateResponse->Error->ConsumerMessage);
|
204 |
+
return false;
|
205 |
+
} else {
|
206 |
+
$this->issuerAuthenticationUrl = $newMandateResponse->IssuerAuthenticationUrl;
|
207 |
+
$this->transactionId = $newMandateResponse->TransactionId;
|
208 |
+
}
|
209 |
+
|
210 |
+
return true;
|
211 |
+
}
|
212 |
+
|
213 |
+
public function doDirectoryRequest()
|
214 |
+
{
|
215 |
+
try {
|
216 |
+
// Initiate a CoreCommunicator
|
217 |
+
$coreCommunicator = new CoreCommunicator($this->getConfiguration());
|
218 |
+
$diRes = $coreCommunicator->Directory();
|
219 |
+
if ($diRes->IsError) {
|
220 |
+
Mage::throwException($diRes->Error->ErrorCode . ': ' . $diRes->Error->ConsumerMessage);
|
221 |
+
} else {
|
222 |
+
$buckets = array();
|
223 |
+
foreach ($diRes->DebtorBanks as $bank) {
|
224 |
+
$buckets[$bank->DebtorBankCountry][] = $bank;
|
225 |
+
}
|
226 |
+
return $buckets;
|
227 |
+
}
|
228 |
+
} catch (Exception $e) {
|
229 |
+
Mage::throwException($e->getMessage());
|
230 |
+
}
|
231 |
+
|
232 |
+
}
|
233 |
+
|
234 |
+
public function doGetStatus($transactionId)
|
235 |
+
{
|
236 |
+
$conf = $this->getConfiguration();
|
237 |
+
// Initiate a CoreCommunicator
|
238 |
+
$coreCommunicator = new CoreCommunicator($conf);
|
239 |
+
$statusRequest = new StatusRequest($transactionId);
|
240 |
+
try {
|
241 |
+
$sRes = $coreCommunicator->GetStatus($statusRequest);
|
242 |
+
if ($sRes->IsError) {
|
243 |
+
Mage::getModel('dim/dim')->updatePayment($transactionId, $sRes->Error->ErrorCode);
|
244 |
+
Mage::throwException($sRes->Error->ErrorCode . ': ' . $sRes->Error->ConsumerMessage);
|
245 |
+
} else {
|
246 |
+
$this->bankStatus = $sRes->Status;
|
247 |
+
Mage::getModel('dim/dim')->updatePayment($transactionId, $sRes->Status);
|
248 |
+
}
|
249 |
+
return $sRes->Status;
|
250 |
+
} catch (Exception $e) {
|
251 |
+
Mage::throwException($e->getMessage());
|
252 |
+
}
|
253 |
+
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Parse the $str and return a date interval
|
258 |
+
*
|
259 |
+
* @param string $str
|
260 |
+
* @return string
|
261 |
+
*/
|
262 |
+
public static function evaluateExpirationPeriod($str)
|
263 |
+
{
|
264 |
+
$interval = '';
|
265 |
+
|
266 |
+
if (is_numeric($str)) { // when only a number is entered
|
267 |
+
$interval = 'P' . $str . 'D';
|
268 |
+
} else if (strstr($str, ':')) { // when he have a time [hours:minutes:seconds]
|
269 |
+
$arr = explode(':', $str);
|
270 |
+
$interval = "PT";
|
271 |
+
if (!empty($arr[0])) {
|
272 |
+
$interval .= $arr[0] . 'H';
|
273 |
+
}
|
274 |
+
if (!empty($arr[1])) {
|
275 |
+
$interval .= $arr[1] . 'M';
|
276 |
+
}
|
277 |
+
if (!empty($arr[2])) {
|
278 |
+
$interval .= $arr[2] . 'S';
|
279 |
+
}
|
280 |
+
} else {
|
281 |
+
$interval = $str;
|
282 |
+
}
|
283 |
+
|
284 |
+
if (empty($interval)) {
|
285 |
+
return null;
|
286 |
+
}
|
287 |
+
|
288 |
+
return new DateInterval(strtoupper($interval));
|
289 |
+
}
|
290 |
+
}
|
app/code/community/Xrec/Dim/Model/Dim.php
ADDED
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Copyright (c) 2012-2014, xrec.nl
|
5 |
+
* All rights reserved.
|
6 |
+
**/
|
7 |
+
class Xrec_Dim_Model_Dim extends Mage_Payment_Model_Method_Abstract
|
8 |
+
{
|
9 |
+
|
10 |
+
// Payment statusses
|
11 |
+
const DIM_OPEN = 'Open';
|
12 |
+
const DIM_SUCCESS = 'Success';
|
13 |
+
const DIM_CANCELLED = 'Cancelled';
|
14 |
+
const DIM_FAILURE = 'Failure';
|
15 |
+
const DIM_PENDING = 'Pending';
|
16 |
+
const DIM_EXPIRED = 'Expired';
|
17 |
+
|
18 |
+
const SEQUENCE_TYPE_OOFF = 'Machtiging eenmalige SEPA incasso.';
|
19 |
+
const SEQUENCE_TYPE_RCUR = 'Machtiging doorlopende SEPA incasso.';
|
20 |
+
|
21 |
+
// Payment flags
|
22 |
+
const PAYMENT_FLAG_PROCESSED = 'De betaling is ontvangen en verwerkt.';
|
23 |
+
const PAYMENT_FLAG_RETRY = 'De consument probeert het bedrag nogmaals af te rekenen.';
|
24 |
+
const PAYMENT_FLAG_CANCELD = 'De consument heeft de betaling geannuleerd.';
|
25 |
+
const PAYMENT_FLAG_PENDING = 'Afwachten tot de betaling binnen is.';
|
26 |
+
const PAYMENT_FLAG_EXPIRED = 'De betaling is verlopen doordat de consument niets met de betaling heeft gedaan.';
|
27 |
+
const PAYMENT_FLAG_INPROGRESS = 'De klant is doorverwezen naar de geselecteerde bank.';
|
28 |
+
const PAYMENT_FLAG_FAILED = 'De betaling is niet gelukt (er is geen verdere informatie beschikbaar).';
|
29 |
+
const PAYMENT_FLAG_FRAUD = 'Het totale bedrag komt niet overeen met de afgerekende bedrag. (Mogelijke fraude).';
|
30 |
+
const PAYMENT_FLAG_DCHECKED = 'De betaalstatus is al een keer opgevraagd.';
|
31 |
+
const PAYMENT_FLAG_UNKOWN = 'Er is een onbekende fout opgetreden.';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* unique internal payment method identifier
|
35 |
+
*
|
36 |
+
* @var string [a-z0-9_]
|
37 |
+
*/
|
38 |
+
protected $_code = 'dim';
|
39 |
+
protected $_formBlockType = 'dim/payment_dim_form';
|
40 |
+
protected $_infoBlockType = 'dim/payment_dim_info';
|
41 |
+
protected $_paymentMethod = 'DIM';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Here are examples of flags that will determine functionality availability
|
45 |
+
* of this module to be used by frontend and backend.
|
46 |
+
*
|
47 |
+
* @see all flags and their defaults in Mage_Payment_Model_Method_Abstract
|
48 |
+
*
|
49 |
+
* It is possible to have a custom dynamic logic by overloading
|
50 |
+
* public function can* for each flag respectively
|
51 |
+
*/
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Is this payment method a gateway (online auth/charge) ?
|
55 |
+
*/
|
56 |
+
protected $_isGateway = true;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Can authorize online?
|
60 |
+
*/
|
61 |
+
protected $_canAuthorize = true;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Can capture funds online?
|
65 |
+
*/
|
66 |
+
protected $_canCapture = true;
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Can capture partial amounts online?
|
70 |
+
*/
|
71 |
+
protected $_canCapturePartial = false;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Can refund online?
|
75 |
+
*/
|
76 |
+
protected $_canRefund = false;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Can void transactions online?
|
80 |
+
*/
|
81 |
+
protected $_canVoid = true;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Can use this payment method in administration panel?
|
85 |
+
*/
|
86 |
+
protected $_canUseInternal = true;
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Can show this payment method as an option on checkout payment page?
|
90 |
+
*/
|
91 |
+
protected $_canUseCheckout = true;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Is this payment method suitable for multi-shipping checkout?
|
95 |
+
*/
|
96 |
+
protected $_canUseForMultishipping = true;
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Can save credit card information for future processing?
|
100 |
+
*/
|
101 |
+
protected $_canSaveCc = false;
|
102 |
+
|
103 |
+
public function __construct()
|
104 |
+
{
|
105 |
+
parent::__construct();
|
106 |
+
|
107 |
+
$this->_dim = Mage::Helper('dim/dim');
|
108 |
+
$this->_table = Mage::getSingleton('core/resource')->getTableName('dim_payments');
|
109 |
+
$this->_mysqlr = Mage::getSingleton('core/resource')->getConnection('core_read');
|
110 |
+
$this->_mysqlw = Mage::getSingleton('core/resource')->getConnection('core_write');
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Get checkout session namespace
|
115 |
+
*
|
116 |
+
* @return Mage_Checkout_Model_Session
|
117 |
+
*/
|
118 |
+
protected function _getCheckout()
|
119 |
+
{
|
120 |
+
return Mage::getSingleton('checkout/session');
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Get current quote
|
125 |
+
*
|
126 |
+
* @return Mage_Sales_Model_Quote
|
127 |
+
*/
|
128 |
+
public function getQuote()
|
129 |
+
{
|
130 |
+
return $this->_getCheckout()->getQuote();
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Check whether payment method can be used
|
135 |
+
*
|
136 |
+
* @param Mage_Sales_Model_Quote
|
137 |
+
* @return bool
|
138 |
+
*/
|
139 |
+
public function isAvailable($quote = NULL)
|
140 |
+
{
|
141 |
+
$enabled = (bool)Mage::Helper('dim/data')->getConfig('active');
|
142 |
+
|
143 |
+
if (!$enabled) {
|
144 |
+
return false;
|
145 |
+
}
|
146 |
+
|
147 |
+
return parent::isAvailable($quote);
|
148 |
+
}
|
149 |
+
|
150 |
+
|
151 |
+
/**
|
152 |
+
* @param string $currencyCode
|
153 |
+
* @return bool
|
154 |
+
*/
|
155 |
+
public function canUseForCurrency($currencyCode)
|
156 |
+
{
|
157 |
+
if (!parent::canUseForCurrency($currencyCode)) {
|
158 |
+
return false;
|
159 |
+
}
|
160 |
+
|
161 |
+
if ($currencyCode !== 'EUR') {
|
162 |
+
return false;
|
163 |
+
}
|
164 |
+
|
165 |
+
return true;
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* On click payment button, this function is called to assign data
|
170 |
+
*
|
171 |
+
* @param mixed $data
|
172 |
+
* @return self
|
173 |
+
*/
|
174 |
+
public function assignData($data)
|
175 |
+
{
|
176 |
+
if (!($data instanceof Varien_Object)) {
|
177 |
+
$data = new Varien_Object($data);
|
178 |
+
}
|
179 |
+
|
180 |
+
if (strlen(Mage::registry('dim_bank_id')) == 0) {
|
181 |
+
Mage::register('dim_bank_id', $data->getDimBankId());
|
182 |
+
Mage::register('dim_sequence_type', $data->getDimSequenceType());
|
183 |
+
return $this;
|
184 |
+
}
|
185 |
+
return $this;
|
186 |
+
}
|
187 |
+
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Stores the payment information in the dim_payments table.
|
191 |
+
* @param $orderId
|
192 |
+
* @param $transactionId
|
193 |
+
* @param string $status
|
194 |
+
* @param string $sequenceType
|
195 |
+
* @param string $method
|
196 |
+
* @throws Mage_Core_Exception
|
197 |
+
*/
|
198 |
+
public function setPayment($orderId, $transactionId, $status = 'Pending', $sequenceType = null, $method = 'dim')
|
199 |
+
{
|
200 |
+
if (is_null($orderId) || is_null($transactionId)) {
|
201 |
+
Mage::throwException('Ongeldige order_id of transaction_id...');
|
202 |
+
}
|
203 |
+
|
204 |
+
$data = array(
|
205 |
+
'order_id' => $orderId,
|
206 |
+
'bank_status' => $status,
|
207 |
+
'transaction_id' => $transactionId,
|
208 |
+
'method' => $method,
|
209 |
+
'sequence_type' => $sequenceType,
|
210 |
+
'created_at' => date('Y-m-d H:i:s'),
|
211 |
+
'updated_at' => date('Y-m-d H:i:s')
|
212 |
+
);
|
213 |
+
|
214 |
+
$this->_mysqlw->insert($this->_table, $data);
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* @param string $transactionId
|
219 |
+
* @param null|string $status
|
220 |
+
* @throws Mage_Core_Exception
|
221 |
+
*/
|
222 |
+
public function updatePayment($transactionId, $status = null)
|
223 |
+
{
|
224 |
+
if (is_null($transactionId) || is_null($status)) {
|
225 |
+
Mage::throwException('Geen transactionId en/of status gevonden!');
|
226 |
+
}
|
227 |
+
|
228 |
+
$data = array(
|
229 |
+
'bank_status' => $status,
|
230 |
+
'updated_at' => date('Y-m-d H:i:s')
|
231 |
+
);
|
232 |
+
|
233 |
+
|
234 |
+
$where = sprintf("transaction_id = %s", $this->_mysqlw->quote($transactionId));
|
235 |
+
|
236 |
+
$this->_mysqlw->update($this->_table, $data, $where);
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Redirects the client on click 'Place Order' to selected iDEAL bank
|
241 |
+
*
|
242 |
+
* @return string
|
243 |
+
*/
|
244 |
+
public function getOrderPlaceRedirectUrl()
|
245 |
+
{
|
246 |
+
return Mage::getUrl(
|
247 |
+
'dim/dim/payment',
|
248 |
+
array(
|
249 |
+
'_secure' => TRUE,
|
250 |
+
'_query' => array(
|
251 |
+
'dim_bank_id' => Mage::registry('dim_bank_id'),
|
252 |
+
'dim_sequence_type' => Mage::registry('dim_sequence_type')
|
253 |
+
)
|
254 |
+
)
|
255 |
+
);
|
256 |
+
}
|
257 |
+
|
258 |
+
}
|
app/code/community/Xrec/Dim/controllers/DimController.php
ADDED
@@ -0,0 +1,284 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Copyright (c) 2012-2014, xrec.nl
|
5 |
+
* All rights reserved.
|
6 |
+
**/
|
7 |
+
class Xrec_Dim_DimController extends Mage_Core_Controller_Front_Action
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var Xrec_Dim_Helper_Dim
|
12 |
+
*/
|
13 |
+
protected $dim;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var Xrec_Dim_Helper_Data
|
17 |
+
*/
|
18 |
+
protected $data;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var Xrec_Dim_Model_Dim
|
22 |
+
*/
|
23 |
+
protected $model;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Get core
|
27 |
+
*/
|
28 |
+
public function _construct()
|
29 |
+
{
|
30 |
+
$this->dim = Mage::Helper('dim/dim');
|
31 |
+
$this->data = Mage::Helper('dim/data');
|
32 |
+
$this->model = Mage::getModel('dim/dim');
|
33 |
+
parent::_construct();
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @param string $e Exceptiom message
|
39 |
+
* @param null $order_id An OrderID
|
40 |
+
*/
|
41 |
+
protected function _showException($e = '', $orderId = NULL)
|
42 |
+
{
|
43 |
+
$this->loadLayout();
|
44 |
+
$order = Mage::getModel('sales/order')->load($orderId);
|
45 |
+
$block = $this->getLayout()
|
46 |
+
->createBlock('Mage_Core_Block_Template')
|
47 |
+
->setTemplate('xrec/page/exception.phtml')
|
48 |
+
->setData('exception', $e)
|
49 |
+
->setData('order', $order);
|
50 |
+
|
51 |
+
$this->getLayout()->getBlock('content')->append($block);
|
52 |
+
$this->renderLayout();
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Gets the current checkout session with order information
|
57 |
+
*
|
58 |
+
* @return Mage_Checkout_Model_Session
|
59 |
+
*/
|
60 |
+
protected function _getCheckout()
|
61 |
+
{
|
62 |
+
return Mage::getSingleton('checkout/session');
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* After clicking 'Place Order' the method 'getOrderPlaceRedirectUrl()' gets called and redirects to here with the bank_id
|
67 |
+
* Then this action creates an payment with a transaction_id that gets inserted in the database (mollie_payments, sales_payment_transaction)
|
68 |
+
*/
|
69 |
+
public function paymentAction()
|
70 |
+
{
|
71 |
+
if ($this->getRequest()->getParam('order_id')) {
|
72 |
+
/** @var $order Mage_Sales_Model_Order */
|
73 |
+
$order = Mage::getModel('sales/order')->load($this->getRequest()->getParam('order_id'));
|
74 |
+
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, Mage_Sales_Model_Order::STATE_PENDING_PAYMENT, $this->__(Xrec_Dim_Model_Dim::PAYMENT_FLAG_RETRY), FALSE)->save();
|
75 |
+
} else {
|
76 |
+
// Load last order by IncrementId
|
77 |
+
/** @var $order Mage_Sales_Model_Order */
|
78 |
+
$orderIncrementId = $this->_getCheckout()->getLastRealOrderId();
|
79 |
+
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
|
80 |
+
}
|
81 |
+
|
82 |
+
try {
|
83 |
+
$dimBankId = $this->getRequest()->getParam('dim_bank_id');
|
84 |
+
if (!$this->data->getConfig('SequenceTypeCustomer')) {
|
85 |
+
$dimSequenceType = $this->data->getConfig('SequenceType');
|
86 |
+
} else {
|
87 |
+
$dimSequenceType = $this->getRequest()->getParam('dim_sequence_type');
|
88 |
+
}
|
89 |
+
|
90 |
+
$this->dim->setDimBankId($dimBankId);
|
91 |
+
$this->dim->setDimSequenceType($dimSequenceType);
|
92 |
+
|
93 |
+
if ($this->dim->doNewMandateRequest($order)) {
|
94 |
+
|
95 |
+
if (!$order->getId()) {
|
96 |
+
Mage::log('Geen order voor verwerking gevonden');
|
97 |
+
Mage::throwException('Geen order voor verwerking gevonden');
|
98 |
+
}
|
99 |
+
|
100 |
+
$this->model->setPayment($order->getId(), $this->dim->getTransactionId(), Xrec_Dim_Model_Dim::DIM_PENDING, $dimSequenceType);
|
101 |
+
|
102 |
+
// Creates transaction
|
103 |
+
/** @var $payment Mage_Sales_Model_Order_Payment */
|
104 |
+
$payment = Mage::getModel('sales/order_payment')
|
105 |
+
->setMethod('dim')
|
106 |
+
->setTransactionId($this->dim->getTransactionId())
|
107 |
+
->setIsTransactionClosed(false);
|
108 |
+
|
109 |
+
|
110 |
+
$order->setPayment($payment);
|
111 |
+
|
112 |
+
$payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH);
|
113 |
+
|
114 |
+
if ($dimSequenceType == 'OOFF') {
|
115 |
+
$message = Xrec_Dim_Model_Dim::PAYMENT_FLAG_INPROGRESS .' '. Xrec_Dim_Model_Dim::SEQUENCE_TYPE_OOFF;
|
116 |
+
} else {
|
117 |
+
$message = Xrec_Dim_Model_Dim::PAYMENT_FLAG_INPROGRESS .' '. Xrec_Dim_Model_Dim::SEQUENCE_TYPE_RCUR;
|
118 |
+
}
|
119 |
+
$order->setState(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT, Mage_Sales_Model_Order::STATE_PENDING_PAYMENT, $message, false)->save();
|
120 |
+
|
121 |
+
$this->_redirectUrl($this->dim->getIssuerAuthenticationUrl());
|
122 |
+
|
123 |
+
} else {
|
124 |
+
Mage::throwException($this->dim->getErrorMessage());
|
125 |
+
}
|
126 |
+
} catch (Exception $e) {
|
127 |
+
Mage::log($e);
|
128 |
+
$this->_showException($e->getMessage(), $order->getId());
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Customer returning from the bank with an transaction_id
|
134 |
+
* Depending on what the state of the payment is they get redirected to the corresponding page
|
135 |
+
*/
|
136 |
+
public function returnAction()
|
137 |
+
{
|
138 |
+
// Get transaction_id from url (Ex: http://yourmagento.com/index.php/dim/dim/return?trxid=0050000000012875&ec=834hn46 )
|
139 |
+
$transactionId = $this->getRequest()->getParam('trxid');
|
140 |
+
//$orderId = Mage::Helper('dim/data')->getOrderIdByTransactionId($transactionId);
|
141 |
+
$dimPayment = Mage::Helper('dim/data')->getPaymentByTransactionId($transactionId);
|
142 |
+
$orderId = isset($dimPayment['order_id']) ? $dimPayment['order_id'] : null;
|
143 |
+
|
144 |
+
try {
|
145 |
+
if (!empty($transactionId) && $orderId) {
|
146 |
+
$dimStatus = $this->dim->doGetStatus($transactionId);
|
147 |
+
|
148 |
+
if ($dimStatus == Xrec_Dim_Model_Dim::DIM_SUCCESS) {
|
149 |
+
if ($this->_getCheckout()->getQuote()->getItemsCount() > 0) {
|
150 |
+
foreach ($this->_getCheckout()->getQuote()->getItemsCollection() as $item) {
|
151 |
+
Mage::getSingleton('checkout/cart')->removeItem($item->getId());
|
152 |
+
}
|
153 |
+
Mage::getSingleton('checkout/cart')->save();
|
154 |
+
}
|
155 |
+
|
156 |
+
// Load order by id ($oId)
|
157 |
+
/** @var $order Mage_Sales_Model_Order */
|
158 |
+
$order = Mage::getModel('sales/order')->load($orderId);
|
159 |
+
/** @var $payment Mage_Sales_Model_Order_Payment */
|
160 |
+
$payment = $order->getPayment();
|
161 |
+
$payment->setMethod('dim')
|
162 |
+
->setTransactionId($transactionId)
|
163 |
+
->setIsTransactionClosed(TRUE);
|
164 |
+
|
165 |
+
if ($dimPayment['sequence_type'] == 'OOFF') {
|
166 |
+
$message = Xrec_Dim_Model_Dim::PAYMENT_FLAG_PROCESSED .' '. Xrec_Dim_Model_Dim::SEQUENCE_TYPE_OOFF;
|
167 |
+
} else {
|
168 |
+
$message = Xrec_Dim_Model_Dim::PAYMENT_FLAG_PROCESSED .' '. Xrec_Dim_Model_Dim::SEQUENCE_TYPE_RCUR;
|
169 |
+
}
|
170 |
+
|
171 |
+
$payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
|
172 |
+
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, Mage_Sales_Model_Order::STATE_PROCESSING, $message, TRUE)->save();;
|
173 |
+
|
174 |
+
/*
|
175 |
+
* Send an email to the customer.
|
176 |
+
*/
|
177 |
+
$order->sendNewOrderEmail()->setEmailSent(TRUE);
|
178 |
+
|
179 |
+
// Redirect to success page
|
180 |
+
$this->_redirect('checkout/onepage/success', array('_secure' => TRUE));
|
181 |
+
return;
|
182 |
+
} else {
|
183 |
+
// Create fail page
|
184 |
+
$this->loadLayout();
|
185 |
+
|
186 |
+
$block = $this->getLayout()
|
187 |
+
->createBlock('Mage_Core_Block_Template')
|
188 |
+
->setTemplate('xrec/page/fail.phtml')
|
189 |
+
->setData('form', Mage::getUrl('dim/dim/form'))
|
190 |
+
->setData('order', Mage::getModel('sales/order')->load($orderId));
|
191 |
+
|
192 |
+
$this->getLayout()->getBlock('content')->append($block);
|
193 |
+
|
194 |
+
$this->renderLayout();
|
195 |
+
return;
|
196 |
+
}
|
197 |
+
}
|
198 |
+
} catch (Exception $e) {
|
199 |
+
Mage::log($e);
|
200 |
+
$this->_showException($e->getMessage(), $orderId);
|
201 |
+
return;
|
202 |
+
}
|
203 |
+
|
204 |
+
$this->_redirectUrl(Mage::getBaseUrl());
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
/**
|
209 |
+
* This action is getting called by ing to report the payment status
|
210 |
+
*/
|
211 |
+
public function reportAction()
|
212 |
+
{
|
213 |
+
// Get transaction_id from url (Ex: http://yourmagento.com/index.php/dim/dim/report?trxid=0050000000012875&ec=834hn46 )
|
214 |
+
$transactionId = $this->getRequest()->getParam('trxid');
|
215 |
+
$orderId = $this->getRequest()->getParam('order_id');
|
216 |
+
|
217 |
+
// Get order by transaction_id
|
218 |
+
$orderId = Mage::helper('dim/data')->getOrderIdByTransactionId($transactionId);
|
219 |
+
|
220 |
+
// Load order by id ($oId)
|
221 |
+
/** @var $order Mage_Sales_Model_Order */
|
222 |
+
$order = Mage::getModel('sales/order')->load($orderId);
|
223 |
+
|
224 |
+
try {
|
225 |
+
if ($transactionId !== '' && $order->getStatus() == Mage_Sales_Model_Order::STATE_PENDING_PAYMENT) {
|
226 |
+
|
227 |
+
$this->dim->doGetStatus($transactionId);
|
228 |
+
|
229 |
+
// Maakt een Order transactie aan
|
230 |
+
/** @var $payment Mage_Sales_Model_Order_Payment */
|
231 |
+
$payment = Mage::getModel('sales/order_payment')
|
232 |
+
->setMethod('dim')
|
233 |
+
->setTransactionId($transactionId)
|
234 |
+
->setIsTransactionClosed(TRUE);
|
235 |
+
|
236 |
+
$order->setPayment($payment);
|
237 |
+
|
238 |
+
if ($this->dim->getBankStatus() == Xrec_Dim_Model_Dim::DIM_SUCCESS) {
|
239 |
+
/*
|
240 |
+
* Update the total amount paid, keep that in the order. We do not care if this is the correct
|
241 |
+
* amount or not at this moment.
|
242 |
+
*/
|
243 |
+
|
244 |
+
$payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
|
245 |
+
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, Mage_Sales_Model_Order::STATE_PROCESSING, $this->__(Xrec_Dim_Model_Dim::PAYMENT_FLAG_PROCESSED), TRUE);
|
246 |
+
|
247 |
+
/*
|
248 |
+
* Send an email to the customer.
|
249 |
+
*/
|
250 |
+
$order->sendNewOrderEmail()->setEmailSent(TRUE);
|
251 |
+
|
252 |
+
} else {
|
253 |
+
// Stomme Magento moet eerst op 'cancel' en dan pas setState, andersom dan zet hij de voorraad niet terug.
|
254 |
+
$order->cancel();
|
255 |
+
$order->setState(Mage_Sales_Model_Order::STATE_CANCELED, Mage_Sales_Model_Order::STATE_CANCELED, $this->__(Xrec_Dim_Model_Dim::PAYMENT_FLAG_CANCELD), FALSE);
|
256 |
+
}
|
257 |
+
|
258 |
+
$order->save();
|
259 |
+
}
|
260 |
+
} catch (Exception $e) {
|
261 |
+
Mage::log($e);
|
262 |
+
$this->_showException($e->getMessage());
|
263 |
+
}
|
264 |
+
}
|
265 |
+
|
266 |
+
public function formAction()
|
267 |
+
{
|
268 |
+
if ($this->getRequest()->isPost()) {
|
269 |
+
$create_new_payment = Mage::getUrl(
|
270 |
+
'dim/dim/payment',
|
271 |
+
array(
|
272 |
+
'_secure' => TRUE,
|
273 |
+
'_query' => array(
|
274 |
+
'order_id' => $this->getRequest()->getPost('order_id'),
|
275 |
+
'dim_bank_id' => $this->getRequest()->getPost('dim_bank_id'),
|
276 |
+
'dim_sequence_type' => $this->getRequest()->getPost('dim_sequence_type')
|
277 |
+
)
|
278 |
+
)
|
279 |
+
);
|
280 |
+
$this->_redirectUrl($create_new_payment);
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
}
|
app/code/community/Xrec/Dim/etc/config.xml
ADDED
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<config>
|
4 |
+
<modules>
|
5 |
+
<Xrec_Dim>
|
6 |
+
<version>1.0.0</version>
|
7 |
+
</Xrec_Dim>
|
8 |
+
</modules>
|
9 |
+
|
10 |
+
<global>
|
11 |
+
<models>
|
12 |
+
<dim>
|
13 |
+
<class>Xrec_Dim_Model</class>
|
14 |
+
</dim>
|
15 |
+
</models>
|
16 |
+
<blocks>
|
17 |
+
<dim>
|
18 |
+
<class>Xrec_Dim_Block</class>
|
19 |
+
</dim>
|
20 |
+
<payment>
|
21 |
+
<class>Xrec_Dim_Block</class>
|
22 |
+
<class>Mage_Payment_Block</class>
|
23 |
+
</payment>
|
24 |
+
</blocks>
|
25 |
+
<helpers>
|
26 |
+
<dim>
|
27 |
+
<class>Xrec_Dim_Helper</class>
|
28 |
+
</dim>
|
29 |
+
</helpers>
|
30 |
+
<payment>
|
31 |
+
<groups>
|
32 |
+
<xrec>xrec</xrec>
|
33 |
+
</groups>
|
34 |
+
</payment>
|
35 |
+
<resources>
|
36 |
+
<dim_setup>
|
37 |
+
<setup>
|
38 |
+
<module>Xrec_Dim</module>
|
39 |
+
</setup>
|
40 |
+
<connection>
|
41 |
+
<use>core_setup</use>
|
42 |
+
</connection>
|
43 |
+
</dim_setup>
|
44 |
+
<dim_write>
|
45 |
+
<connection>
|
46 |
+
<use>core_write</use>
|
47 |
+
</connection>
|
48 |
+
</dim_write>
|
49 |
+
<dim_read>
|
50 |
+
<connection>
|
51 |
+
<use>core_read</use>
|
52 |
+
</connection>
|
53 |
+
</dim_read>
|
54 |
+
</resources>
|
55 |
+
<layouts>
|
56 |
+
<xrec_exception>
|
57 |
+
<label>Xrec Exception</label>
|
58 |
+
<template>xrec/page/exception.phtml</template>
|
59 |
+
</xrec_exception>
|
60 |
+
<api_payment_fail>
|
61 |
+
<label>Payment Failed</label>
|
62 |
+
<template>xrec/page/fail.phtml</template>
|
63 |
+
</api_payment_fail>
|
64 |
+
</layouts>
|
65 |
+
</global>
|
66 |
+
|
67 |
+
<frontend>
|
68 |
+
<routers>
|
69 |
+
<dim>
|
70 |
+
<use>standard</use>
|
71 |
+
<args>
|
72 |
+
<module>Xrec_Dim</module>
|
73 |
+
<frontName>dim</frontName>
|
74 |
+
</args>
|
75 |
+
</dim>
|
76 |
+
</routers>
|
77 |
+
<translate>
|
78 |
+
<modules>
|
79 |
+
<Xrec_Dim>
|
80 |
+
<files>
|
81 |
+
<default>Xrec_Dim.csv</default>
|
82 |
+
</files>
|
83 |
+
</Xrec_Dim>
|
84 |
+
</modules>
|
85 |
+
</translate>
|
86 |
+
<layout>
|
87 |
+
<updates>
|
88 |
+
<dim>
|
89 |
+
<file>dim.xml</file>
|
90 |
+
</dim>
|
91 |
+
</updates>
|
92 |
+
</layout>
|
93 |
+
</frontend>
|
94 |
+
|
95 |
+
<adminhtml>
|
96 |
+
<translate>
|
97 |
+
<modules>
|
98 |
+
<Xrec_Dim>
|
99 |
+
<files>
|
100 |
+
<default>Xrec_Dim.csv</default>
|
101 |
+
</files>
|
102 |
+
</Xrec_Dim>
|
103 |
+
</modules>
|
104 |
+
</translate>
|
105 |
+
<acl>
|
106 |
+
<resources>
|
107 |
+
<all>
|
108 |
+
<title>Allow Everything</title>
|
109 |
+
</all>
|
110 |
+
<admin>
|
111 |
+
<children>
|
112 |
+
<system>
|
113 |
+
<children>
|
114 |
+
<config>
|
115 |
+
<children>
|
116 |
+
<xrec>
|
117 |
+
<title>Digitaal Incassomachtigen via uw bank</title>
|
118 |
+
</xrec>
|
119 |
+
</children>
|
120 |
+
</config>
|
121 |
+
</children>
|
122 |
+
</system>
|
123 |
+
</children>
|
124 |
+
</admin>
|
125 |
+
</resources>
|
126 |
+
</acl>
|
127 |
+
<layout>
|
128 |
+
<updates>
|
129 |
+
<dim>
|
130 |
+
<file>dim.xml</file>
|
131 |
+
</dim>
|
132 |
+
</updates>
|
133 |
+
</layout>
|
134 |
+
</adminhtml>
|
135 |
+
|
136 |
+
<!-- declare default configuration values for this module -->
|
137 |
+
<default>
|
138 |
+
<!-- 'payment' configuration section (tab) -->
|
139 |
+
<payment>
|
140 |
+
<dim>
|
141 |
+
<!-- by default this payment method is inactive -->
|
142 |
+
<active>1</active>
|
143 |
+
<!-- model to handle logic for this payment method -->
|
144 |
+
<model>dim/dim</model>
|
145 |
+
<!-- order status for new orders paid by this payment method -->
|
146 |
+
<!--<order_status>pending</order_status>-->
|
147 |
+
<!-- default title for payment checkout page and order view page -->
|
148 |
+
<title>Digitaal Incassomachtigen via uw bank</title>
|
149 |
+
<group>xrec</group>
|
150 |
+
|
151 |
+
</dim>
|
152 |
+
<xrec>
|
153 |
+
<!-- DEFAULT VALUES -->
|
154 |
+
<testMode>1</testMode>
|
155 |
+
<eMandateReason>webshop purchase</eMandateReason>
|
156 |
+
<AcquirerUrl_DirectoryReq>https://machtigen.secure-ing.com/EMRoutingWS/handler/ing</AcquirerUrl_DirectoryReq>
|
157 |
+
<AcquirerUrl_TransactionReq>https://machtigen.secure-ing.com/EMRoutingWS/handler/ing</AcquirerUrl_TransactionReq>
|
158 |
+
<AcquirerUrl_StatusReq>https://machtigen.secure-ing.com/EMRoutingWS/handler/ing</AcquirerUrl_StatusReq>
|
159 |
+
<AcquirerUrl_DirectoryReqTest>https://machtigen.secure-ing.com/TestRoutingWS/handler/ing</AcquirerUrl_DirectoryReqTest>
|
160 |
+
<AcquirerUrl_TransactionReqTest>https://machtigen.secure-ing.com/TestRoutingWS/handler/ing</AcquirerUrl_TransactionReqTest>
|
161 |
+
<AcquirerUrl_StatusReqTest>https://machtigen.secure-ing.com/TestRoutingWS/handler/ing</AcquirerUrl_StatusReqTest>
|
162 |
+
<merchantReturnURL>{{base_url}}</merchantReturnURL>
|
163 |
+
<SequenceType>OOFF</SequenceType>
|
164 |
+
<SequenceTypeCustomer>0</SequenceTypeCustomer>
|
165 |
+
</xrec>
|
166 |
+
</payment>
|
167 |
+
</default>
|
168 |
+
|
169 |
+
</config>
|
app/code/community/Xrec/Dim/etc/system.xml
ADDED
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<config>
|
4 |
+
<sections>
|
5 |
+
<payment>
|
6 |
+
<groups>
|
7 |
+
<xrec translate="label" module="dim">
|
8 |
+
<label>Digitaal Incassomachtigen via uw bank</label>
|
9 |
+
<expanded>1</expanded>
|
10 |
+
<sort_order>-100</sort_order>
|
11 |
+
<frontend_type>text</frontend_type>
|
12 |
+
<show_in_default>1</show_in_default>
|
13 |
+
<show_in_website>1</show_in_website>
|
14 |
+
<show_in_store>1</show_in_store>
|
15 |
+
|
16 |
+
<fields>
|
17 |
+
<active translate="label tooltip">
|
18 |
+
<label>Enabled</label>
|
19 |
+
<frontend_type>select</frontend_type>
|
20 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
21 |
+
<sort_order>1</sort_order>
|
22 |
+
<show_in_default>1</show_in_default>
|
23 |
+
<show_in_website>1</show_in_website>
|
24 |
+
<show_in_store>1</show_in_store>
|
25 |
+
<tooltip><![CDATA[<b>Status:</b> <br/>]]> Enable or disable the Digitaal Incassomachtigen plugin.</tooltip>
|
26 |
+
</active>
|
27 |
+
|
28 |
+
<testMode translate="label">
|
29 |
+
<label>Testmode</label>
|
30 |
+
<frontend_type>select</frontend_type>
|
31 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
32 |
+
<sort_order>2</sort_order>
|
33 |
+
<show_in_default>1</show_in_default>
|
34 |
+
<show_in_website>1</show_in_website>
|
35 |
+
<show_in_store>1</show_in_store>
|
36 |
+
<tooltip><![CDATA[<b>Testmode:</b> <br/>]]> Gebruik de testmode om betalingen te testen zonder een echte betaling te doen.</tooltip>
|
37 |
+
</testMode>
|
38 |
+
|
39 |
+
<merchantID translate="label tooltip">
|
40 |
+
<label>Merchant ID</label>
|
41 |
+
<frontend_type>text</frontend_type>
|
42 |
+
<sort_order>11</sort_order>
|
43 |
+
<show_in_default>1</show_in_default>
|
44 |
+
<show_in_website>1</show_in_website>
|
45 |
+
<show_in_store>1</show_in_store>
|
46 |
+
<tooltip><![CDATA[<b>Merchant ID:</b> <br/>]]> Your merchant ID. The payment is added to this account.</tooltip>
|
47 |
+
<validate>validate-number</validate>
|
48 |
+
</merchantID>
|
49 |
+
|
50 |
+
<merchantSubID translate="label tooltip">
|
51 |
+
<label>Merchant SubID</label>
|
52 |
+
<frontend_type>text</frontend_type>
|
53 |
+
<sort_order>21</sort_order>
|
54 |
+
<show_in_default>1</show_in_default>
|
55 |
+
<show_in_website>1</show_in_website>
|
56 |
+
<show_in_store>0</show_in_store>
|
57 |
+
<frontend_class>validate-number</frontend_class>
|
58 |
+
<tooltip>eMandate.ContractSubId as supplied to you by the creditor bank. If you do not have a ContractSubId, use 0 for this field.</tooltip>
|
59 |
+
</merchantSubID>
|
60 |
+
|
61 |
+
<SequenceTypeCustomer translate="label tooltip">
|
62 |
+
<label>SequenceType Choice</label>
|
63 |
+
<frontend_type>select</frontend_type>
|
64 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
65 |
+
<sort_order>22</sort_order>
|
66 |
+
<show_in_default>1</show_in_default>
|
67 |
+
<show_in_website>1</show_in_website>
|
68 |
+
<show_in_store>0</show_in_store>
|
69 |
+
<tooltip>Allow to choice SequenceType by customer.</tooltip>
|
70 |
+
</SequenceTypeCustomer>
|
71 |
+
|
72 |
+
<SequenceType translate="label tooltip">
|
73 |
+
<label>Sequence Type</label>
|
74 |
+
<frontend_type>text</frontend_type>
|
75 |
+
<sort_order>23</sort_order>
|
76 |
+
<show_in_default>1</show_in_default>
|
77 |
+
<show_in_website>1</show_in_website>
|
78 |
+
<show_in_store>0</show_in_store>
|
79 |
+
<comment>OOFF = one-off | RCUR = recurring</comment>
|
80 |
+
<tooltip>Indicates type of eMandate: one-off Direct Debit or recurring.</tooltip>
|
81 |
+
</SequenceType>
|
82 |
+
|
83 |
+
<eMandateReason translate="label tooltip">
|
84 |
+
<label>Mandate Reason</label>
|
85 |
+
<frontend_type>text</frontend_type>
|
86 |
+
<sort_order>24</sort_order>
|
87 |
+
<show_in_default>1</show_in_default>
|
88 |
+
<show_in_website>1</show_in_website>
|
89 |
+
<show_in_store>0</show_in_store>
|
90 |
+
<tooltip>webshop purchase</tooltip>
|
91 |
+
</eMandateReason>
|
92 |
+
|
93 |
+
<merchantReturnURL translate="label tooltip">
|
94 |
+
<label>Return URL</label>
|
95 |
+
<frontend_type>text</frontend_type>
|
96 |
+
<sort_order>31</sort_order>
|
97 |
+
<show_in_default>1</show_in_default>
|
98 |
+
<show_in_website>1</show_in_website>
|
99 |
+
<show_in_store>0</show_in_store>
|
100 |
+
<frontend_class>required-entry</frontend_class>
|
101 |
+
<tooltip>A valid URL to which the debtor banks redirects to, after the debtor has authorized a transaction.</tooltip>
|
102 |
+
</merchantReturnURL>
|
103 |
+
|
104 |
+
<passphrase translate="label tooltip">
|
105 |
+
<label>Passphrase</label>
|
106 |
+
<frontend_type>text</frontend_type>
|
107 |
+
<sort_order>41</sort_order>
|
108 |
+
<show_in_default>1</show_in_default>
|
109 |
+
<show_in_website>1</show_in_website>
|
110 |
+
<show_in_store>0</show_in_store>
|
111 |
+
<frontend_class>required-entry</frontend_class>
|
112 |
+
<tooltip>The password for the private key of the signing certificate.</tooltip>
|
113 |
+
</passphrase>
|
114 |
+
|
115 |
+
<AcquirerUrl_DirectoryReq translate="label tooltip">
|
116 |
+
<label>AcquirerUrl_DirectoryReq</label>
|
117 |
+
<comment>https://machtigen.secure-ing.com/EMRoutingWS/handler/ing</comment>
|
118 |
+
<frontend_type>text</frontend_type>
|
119 |
+
<sort_order>51</sort_order>
|
120 |
+
<show_in_default>1</show_in_default>
|
121 |
+
<show_in_website>1</show_in_website>
|
122 |
+
<show_in_store>0</show_in_store>
|
123 |
+
<frontend_class>required-entry</frontend_class>
|
124 |
+
<tooltip>The URL to which the library sends Directory request messages.</tooltip>
|
125 |
+
</AcquirerUrl_DirectoryReq>
|
126 |
+
|
127 |
+
<AcquirerUrl_TransactionReq translate="label tooltip">
|
128 |
+
<label>AcquirerUrl_TransactionReq</label>
|
129 |
+
<comment>https://machtigen.secure-ing.com/EMRoutingWS/handler/ing</comment>
|
130 |
+
<frontend_type>text</frontend_type>
|
131 |
+
<sort_order>61</sort_order>
|
132 |
+
<show_in_default>1</show_in_default>
|
133 |
+
<show_in_website>1</show_in_website>
|
134 |
+
<show_in_store>0</show_in_store>
|
135 |
+
<frontend_class>required-entry</frontend_class>
|
136 |
+
<tooltip>The URL to which the library sends Transaction request messages (including eMandates messages).</tooltip>
|
137 |
+
</AcquirerUrl_TransactionReq>
|
138 |
+
|
139 |
+
<AcquirerUrl_StatusReq translate="label tooltip">
|
140 |
+
<label>AcquirerUrl_StatusReq</label>
|
141 |
+
<comment>https://machtigen.secure-ing.com/EMRoutingWS/handler/ing</comment>
|
142 |
+
<frontend_type>text</frontend_type>
|
143 |
+
<sort_order>71</sort_order>
|
144 |
+
<show_in_default>1</show_in_default>
|
145 |
+
<show_in_website>1</show_in_website>
|
146 |
+
<show_in_store>0</show_in_store>
|
147 |
+
<frontend_class>required-entry</frontend_class>
|
148 |
+
<tooltip>The URL to which the library sends Status request messages</tooltip>
|
149 |
+
</AcquirerUrl_StatusReq>
|
150 |
+
|
151 |
+
<AcquirerUrl_DirectoryReqTest translate="label tooltip">
|
152 |
+
<label>TEST AcquirerUrl_DirectoryReq</label>
|
153 |
+
<comment>https://machtigen.secure-ing.com/TestRoutingWS/handler/ing</comment>
|
154 |
+
<frontend_type>text</frontend_type>
|
155 |
+
<sort_order>81</sort_order>
|
156 |
+
<show_in_default>1</show_in_default>
|
157 |
+
<show_in_website>1</show_in_website>
|
158 |
+
<show_in_store>0</show_in_store>
|
159 |
+
<frontend_class>required-entry</frontend_class>
|
160 |
+
<tooltip>The URL to which the library sends Directory request messages.</tooltip>
|
161 |
+
</AcquirerUrl_DirectoryReqTest>
|
162 |
+
|
163 |
+
<AcquirerUrl_TransactionReqTest translate="label tooltip">
|
164 |
+
<label>TEST AcquirerUrl_TransactionReq</label>
|
165 |
+
<comment>https://machtigen.secure-ing.com/TestRoutingWS/handler/ing</comment>
|
166 |
+
<frontend_type>text</frontend_type>
|
167 |
+
<sort_order>91</sort_order>
|
168 |
+
<show_in_default>1</show_in_default>
|
169 |
+
<show_in_website>1</show_in_website>
|
170 |
+
<show_in_store>0</show_in_store>
|
171 |
+
<frontend_class>required-entry</frontend_class>
|
172 |
+
<tooltip>The URL to which the library sends Transaction request messages (including eMandates messages).</tooltip>
|
173 |
+
</AcquirerUrl_TransactionReqTest>
|
174 |
+
|
175 |
+
<AcquirerUrl_StatusReqTest translate="label tooltip">
|
176 |
+
<label>TEST AcquirerUrl_StatusReq</label>
|
177 |
+
<comment>https://machtigen.secure-ing.com/TestRoutingWS/handler/ing</comment>
|
178 |
+
<frontend_type>text</frontend_type>
|
179 |
+
<sort_order>101</sort_order>
|
180 |
+
<show_in_default>1</show_in_default>
|
181 |
+
<show_in_website>1</show_in_website>
|
182 |
+
<show_in_store>0</show_in_store>
|
183 |
+
<frontend_class>required-entry</frontend_class>
|
184 |
+
<tooltip>The URL to which the library sends Status request messages.</tooltip>
|
185 |
+
</AcquirerUrl_StatusReqTest>
|
186 |
+
|
187 |
+
<keyFile translate="label">
|
188 |
+
<label>Key File (.pem)</label>
|
189 |
+
<frontend_type>file</frontend_type>
|
190 |
+
<backend_model>adminhtml/system_config_backend_file</backend_model>
|
191 |
+
<upload_dir>var/xrec/dim/cer</upload_dir>
|
192 |
+
<sort_order>50</sort_order>
|
193 |
+
<show_in_default>1</show_in_default>
|
194 |
+
<show_in_website>0</show_in_website>
|
195 |
+
<show_in_store>0</show_in_store>
|
196 |
+
<comment>The file containing the private key to use for signing messages to the creditor bank (aka the signing certificate).</comment>
|
197 |
+
</keyFile>
|
198 |
+
|
199 |
+
<crtFile translate="label">
|
200 |
+
<label>Certificate File (.cer)</label>
|
201 |
+
<frontend_type>file</frontend_type>
|
202 |
+
<backend_model>adminhtml/system_config_backend_file</backend_model>
|
203 |
+
<upload_dir>var/xrec/dim/cer</upload_dir>
|
204 |
+
<sort_order>50</sort_order>
|
205 |
+
<show_in_default>1</show_in_default>
|
206 |
+
<show_in_website>0</show_in_website>
|
207 |
+
<show_in_store>0</show_in_store>
|
208 |
+
<comment>The file containing the public key of the signing certificate.</comment>
|
209 |
+
</crtFile>
|
210 |
+
|
211 |
+
<crtFileAquirer translate="label">
|
212 |
+
<label>Certificate File Aquirer (.cer)</label>
|
213 |
+
<frontend_type>file</frontend_type>
|
214 |
+
<backend_model>adminhtml/system_config_backend_file</backend_model>
|
215 |
+
<upload_dir>var/xrec/dim/cer</upload_dir>
|
216 |
+
<sort_order>50</sort_order>
|
217 |
+
<show_in_default>1</show_in_default>
|
218 |
+
<show_in_website>0</show_in_website>
|
219 |
+
<show_in_store>0</show_in_store>
|
220 |
+
<comment>The file containing the public key of the certificate to use to validate messages from the creditor bank.</comment>
|
221 |
+
</crtFileAquirer>
|
222 |
+
|
223 |
+
</fields>
|
224 |
+
</xrec>
|
225 |
+
</groups>
|
226 |
+
</payment>
|
227 |
+
</sections>
|
228 |
+
</config>
|
app/code/community/Xrec/Dim/sql/dim_setup/mysql4-install-1.0.0.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$installer = $this;
|
3 |
+
$installer->startSetup();
|
4 |
+
|
5 |
+
$installer->run(
|
6 |
+
sprintf("CREATE TABLE IF NOT EXISTS `%s` (
|
7 |
+
`order_id` int(11) NOT NULL,
|
8 |
+
`method` varchar(3) NOT NULL,
|
9 |
+
`transaction_id` varchar(32) NOT NULL,
|
10 |
+
`sequence_type` varchar(15) NOT NULL,
|
11 |
+
`bank_status` varchar(20) NOT NULL,
|
12 |
+
`created_at` datetime NOT NULL,
|
13 |
+
`updated_at` datetime DEFAULT NULL
|
14 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
|
15 |
+
$installer->getTable('dim_payments')
|
16 |
+
)
|
17 |
+
);
|
18 |
+
|
19 |
+
if(strlen(Mage::getStoreConfig("payment/xrec/merchantID")) == 0)
|
20 |
+
{
|
21 |
+
$installer->run(
|
22 |
+
sprintf("INSERT INTO `%s` (`severity`, `date_added`, `title`, `description`, `url`, `is_read`, `is_remove`)
|
23 |
+
VALUES ('4', '%s', 'Ga naar System -> Configuration -> Betaalmethodes om uw ING digitaal Incassomachtigen gegevens in te vullen om onze betaalmethode(s) te gebruiken',
|
24 |
+
'Uw Digitaal Incassomachtigen instellingen moeten ingesteld worden. Als u dit niet doet dan kunnen uw klanten geen gebruik maken van de betaalmethode(s).',
|
25 |
+
'http://www.xrec.nl/', '0', '0');",
|
26 |
+
$installer->getTable('adminnotification_inbox'),
|
27 |
+
date("Y/m/d H:i:s", time())
|
28 |
+
)
|
29 |
+
);
|
30 |
+
}
|
31 |
+
|
32 |
+
$installer->endSetup();
|
app/code/community/Xrec/Dim/sql/dim_setup/mysql4-uninstall-1.0.0.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$installer = $this;
|
3 |
+
|
4 |
+
$installer->startSetup();
|
5 |
+
|
6 |
+
$installer->run(
|
7 |
+
sprintf("DROP TABLE IF EXISTS `%s`",
|
8 |
+
$installer->getTable('dim_payments')
|
9 |
+
)
|
10 |
+
);
|
11 |
+
|
12 |
+
$installer->run("
|
13 |
+
DELETE FROM `{$installer->getTable('core_config_data')}` where `path` LIKE 'payment/xrec%';
|
14 |
+
DELETE FROM `{$installer->getTable('core_resource')}` where `code` = 'dim_setup';"
|
15 |
+
);
|
16 |
+
|
17 |
+
$installer->endSetup();
|
app/design/frontend/base/default/layout/dim.xml
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<layout version="0.1.0">
|
3 |
+
<default>
|
4 |
+
<reference name="head">
|
5 |
+
<action method="addCss">
|
6 |
+
<stylesheet>/../../../dim/css/style.css</stylesheet>
|
7 |
+
</action>
|
8 |
+
</reference>
|
9 |
+
</default>
|
10 |
+
|
11 |
+
<dim_api_return>
|
12 |
+
<reference name="root">
|
13 |
+
<action method="setTemplate">
|
14 |
+
<template>page/1column.phtml</template>
|
15 |
+
</action>
|
16 |
+
</reference>
|
17 |
+
</dim_api_return>
|
18 |
+
</layout>
|
app/design/frontend/base/default/template/xrec/form/dim.phtml
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$_code = $this->getMethodCode();
|
3 |
+
$helper = Mage::Helper('dim/dim');
|
4 |
+
$data = Mage::Helper('dim/data');
|
5 |
+
$buckets = $helper->doDirectoryRequest();
|
6 |
+
|
7 |
+
$options = '';
|
8 |
+
foreach ($buckets as $key => $bucket) {
|
9 |
+
$options .= '<optgroup label="' . $key . '">';
|
10 |
+
foreach ($bucket as $bank) {
|
11 |
+
$options .= '<option value="' . $bank->DebtorBankId . '">' . $bank->DebtorBankName . '</option>';
|
12 |
+
}
|
13 |
+
$options .= '</optgroup>';
|
14 |
+
}
|
15 |
+
|
16 |
+
?>
|
17 |
+
|
18 |
+
<ul class="form-list" id="payment_form_<?php echo $this->escapeHtml($_code) ?>" style="display:none;">
|
19 |
+
<li>
|
20 |
+
<label for="dim_bank_id"
|
21 |
+
class="required"><em>*</em><?php echo $this->__('Selecteer uw bank:') ?></label>
|
22 |
+
<select name="payment[dim_bank_id]" id="dim_bank_id" class="required-entry">
|
23 |
+
<?php echo $options; ?>
|
24 |
+
</select>
|
25 |
+
</li>
|
26 |
+
<?php if ($data->getConfig('SequenceTypeCustomer')) :?>
|
27 |
+
<li>
|
28 |
+
<label for="dim_sequence_type"
|
29 |
+
class="required"><em>*</em><?php echo $this->__('Machtiging type:') ?></label>
|
30 |
+
<select name="payment[dim_sequence_type]" id="dim_sequence_type" class="required-entry">
|
31 |
+
<option value="OOFF">Machtiging eenmalige SEPA incasso</option>
|
32 |
+
<option value="RCUR">Machtiging doorlopende SEPA incasso</option>
|
33 |
+
</select>
|
34 |
+
</li>
|
35 |
+
<?php endif;?>
|
36 |
+
</ul>
|
app/design/frontend/base/default/template/xrec/page/exception.phtml
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<div class="page-title">
|
3 |
+
<h3>Betaling mislukt / Payment failed</h3>
|
4 |
+
</div>
|
5 |
+
<?php echo $this->getException(); ?>
|
6 |
+
|
7 |
+
|
8 |
+
<div class="buttons-set">
|
9 |
+
<p class="back-link"><a href="<?php echo $this->escapeHtml($this->getUrl()) ?>"><small>« </small><?php echo $this->__('Homepage') ?></a></p>
|
10 |
+
</div>
|
app/design/frontend/base/default/template/xrec/page/fail.phtml
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$_code = $this->getMethodCode();
|
3 |
+
$helper = Mage::Helper('dim/dim');
|
4 |
+
$data = Mage::Helper('dim/data');
|
5 |
+
$buckets = $helper->doDirectoryRequest();
|
6 |
+
|
7 |
+
$options = '';
|
8 |
+
foreach ($buckets as $key => $bucket) {
|
9 |
+
$options .= '<optgroup label="' . $key . '">';
|
10 |
+
foreach ($bucket as $bank) {
|
11 |
+
$options .= '<option value="' . $bank->DebtorBankId . '">' . $bank->DebtorBankName . '</option>';
|
12 |
+
}
|
13 |
+
$options .= '</optgroup>';
|
14 |
+
}
|
15 |
+
?>
|
16 |
+
<div class="page-title">
|
17 |
+
<h3>Betaling mislukt / Payment failed</h3>
|
18 |
+
</div>
|
19 |
+
|
20 |
+
De betaling is helaas mislukt. Probeer het bedrag van
|
21 |
+
€<?php echo number_format($this->getOrder()->getGrandTotal(),2) ?> nogmaals af te rekenen met Digitaal Incassomachtigen.
|
22 |
+
|
23 |
+
<br /><br />
|
24 |
+
|
25 |
+
<form name="xrec_dim_dim" id="xrec_dim_dim" action="<?php echo $this->escapeHtml($this->getForm()) ?>" method="post">
|
26 |
+
<input type="hidden" name="order_id" value="<?php echo $this->escapeHtml($this->getOrder()->getId()) ?>" />
|
27 |
+
<ul class="form-list">
|
28 |
+
<li>
|
29 |
+
<label for="dim_bank_id" class="required"><em>*</em>
|
30 |
+
<?php echo $this->__('Selecteer uw bank:') ?>
|
31 |
+
</label>
|
32 |
+
<select name="dim_bank_id" class="required-entry" id="dim_bank_id">
|
33 |
+
<?php echo $options?>
|
34 |
+
</select>
|
35 |
+
</li>
|
36 |
+
<?php if ($data->getConfig('SequenceTypeCustomer')) :?>
|
37 |
+
<li>
|
38 |
+
<label for="dim_sequence_type"
|
39 |
+
class="required"><em>*</em><?php echo $this->__('Machtiging type:') ?></label>
|
40 |
+
<select name="dim_sequence_type" id="dim_sequence_type" class="required-entry">
|
41 |
+
<option value="OOFF">Machtiging eenmalige SEPA incasso</option>
|
42 |
+
<option value="RCUR">Machtiging doorlopende SEPA incasso</option>
|
43 |
+
</select>
|
44 |
+
</li>
|
45 |
+
<?php endif;?>
|
46 |
+
<li>
|
47 |
+
<button class="form-button" style="padding:5px;" type="submit">Betalen</button>
|
48 |
+
</li>
|
49 |
+
</ul>
|
50 |
+
</form>
|
51 |
+
|
52 |
+
<div class="buttons-set">
|
53 |
+
<p class="back-link">
|
54 |
+
<a href="<?php echo $this->escapeHtml(Mage::getBaseUrl()) ?>">
|
55 |
+
<small>« </small>
|
56 |
+
<?php echo $this->__('Homepage') ?>
|
57 |
+
</a>
|
58 |
+
</p>
|
59 |
+
</div>
|
60 |
+
|
61 |
+
<script type="text/javascript">
|
62 |
+
//< ![CDATA[
|
63 |
+
var dimForm = new VarienForm('xrec_dim_dim');
|
64 |
+
//]]>
|
65 |
+
</script>
|
app/etc/modules/Xrec_Dim.xml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Xrec_Dim>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
<depends>
|
8 |
+
<Mage_Payment />
|
9 |
+
</depends>
|
10 |
+
</Xrec_Dim>
|
11 |
+
</modules>
|
12 |
+
</config>
|
lib/Communicator/.DS_Store
ADDED
Binary file
|
lib/Communicator/B2BCommunicator.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once 'CoreCommunicator.php';
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Description of Communicator
|
7 |
+
*/
|
8 |
+
class B2BCommunicator extends CoreCommunicator {
|
9 |
+
|
10 |
+
const LOCAL_INSTRUMENT = 'B2B';
|
11 |
+
const PRODUCT_ID = 'NL:BVN:eMandatesB2B:1.0';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Initiates a new B2BCommunicator
|
15 |
+
*/
|
16 |
+
function __construct(Configuration $configuration, $logger = false) {
|
17 |
+
parent::__construct($configuration, $logger);
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Performs a CancellationRequest and returns the appropiate CancellationResponse
|
22 |
+
*
|
23 |
+
* @param CancellationRequest $cancellationRequest
|
24 |
+
* @return \CancellationResponse
|
25 |
+
*/
|
26 |
+
public function Cancel(CancellationRequest $cancellationRequest) {
|
27 |
+
$cancellationRequest->logger = $this->logger;
|
28 |
+
$this->logger->Log("sending cancellation transaction request");
|
29 |
+
$c = get_called_class();
|
30 |
+
|
31 |
+
$AcquirerTrxReq = new AcquirerTrxRequest(
|
32 |
+
$c::PRODUCT_ID, $c::VERSION, new AcquirerTrxReqMerchant(
|
33 |
+
$this->Configuration->contractID, $this->Configuration->contractSubID, $this->Configuration->merchantReturnURL
|
34 |
+
), $cancellationRequest->DebtorBankId, new AcquirerTrxReqTransaction(
|
35 |
+
$cancellationRequest->EntranceCode, !empty($cancellationRequest->ExpirationPeriod) ? $cancellationRequest->ExpirationPeriod : null, $cancellationRequest->Language, $cancellationRequest
|
36 |
+
)
|
37 |
+
);
|
38 |
+
|
39 |
+
try {
|
40 |
+
$this->logger->Log("building idx message");
|
41 |
+
// Serialize
|
42 |
+
$docTree = $AcquirerTrxReq->toXml($c::LOCAL_INSTRUMENT);
|
43 |
+
|
44 |
+
// Send the Request
|
45 |
+
$response = $this->PerformRequest($docTree, $this->Configuration->AcquirerUrl_TransactionReq);
|
46 |
+
// Validate the Response and validate signature
|
47 |
+
XmlValidator::isValidatXML($response, XmlValidator::SCHEMA_IDX, $this->logger);
|
48 |
+
$this->signer->verify($response, $this->Configuration->crtFileAquirer);
|
49 |
+
|
50 |
+
return new CancellationResponse($response);
|
51 |
+
} catch (Exception $ex) {
|
52 |
+
return new CancellationResponse($ex->getMessage(), (!empty($response) ? $response : ''));
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
}
|
lib/Communicator/Configuration/Configuration.php
ADDED
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
/**.
|
5 |
+
* Description of Configuration
|
6 |
+
*/
|
7 |
+
class Configuration {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* A passphrase for the keyFile
|
11 |
+
* @var string
|
12 |
+
*/
|
13 |
+
public $passphrase;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* A string which specifies the path to the private key file used by the crtFile to sign messages to the creditor bank.
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
public $keyFile;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* A string which specifies the path to the certificate to use to sign messages to the creditor bank.
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
public $crtFile;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* A string which specifies the path to the certificate to use to validate messages from the creditor bank.
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $crtFileAquirer;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* eMandate.ContractID as supplied to you by the creditor bank.
|
35 |
+
* If the eMandate.ContractID has less than 9 digits, use leading zeros to fill out the field.
|
36 |
+
* @var string
|
37 |
+
*/
|
38 |
+
public $contractID;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* eMandate.ContractSubId as supplied to you by the creditor bank.
|
42 |
+
* If you do not have a ContractSubId, use 0 for this field.
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
public $contractSubID;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* A valid URL to which the debtor banks redirects to, after the debtor has authorized a transaction.
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
public $merchantReturnURL;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* The URL to which the library sends Directory request messages
|
55 |
+
* @var string
|
56 |
+
*/
|
57 |
+
public $AcquirerUrl_DirectoryReq;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* The URL to which the library sends Transaction messages (including eMandates messages).
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
public $AcquirerUrl_TransactionReq;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* The URL to which the library sends Status request messages.
|
67 |
+
* @var string
|
68 |
+
*/
|
69 |
+
public $AcquirerUrl_StatusReq;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Enables or Disables the xml logs
|
73 |
+
* @var bool
|
74 |
+
*/
|
75 |
+
public $enableXMLLogs;
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Path to the logs folder
|
79 |
+
* eg: logs/
|
80 |
+
* @var string
|
81 |
+
*/
|
82 |
+
public $logPath;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Folder name pattern for date() function
|
86 |
+
* eg: "Y-m-d" will produce: "2015-03-11"
|
87 |
+
* eg: end result will be: "logs/2015-03-11/115423.321-DirectoryRes.xml"
|
88 |
+
* @var string
|
89 |
+
*/
|
90 |
+
public $folderNamePattern;
|
91 |
+
|
92 |
+
/**
|
93 |
+
* File name prefix pattern for date() function
|
94 |
+
* eg: "His.u" will produce: "115423.321"
|
95 |
+
* eg: end result will be: "logs/2015-03-11/115423.321-DirectoryRes.xml"
|
96 |
+
* @var string
|
97 |
+
*/
|
98 |
+
public $fileNamePrefix;
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Enables or Disables the internal logs
|
102 |
+
* @var bool
|
103 |
+
*/
|
104 |
+
public $enableInternalLogs;
|
105 |
+
|
106 |
+
/**
|
107 |
+
* The file name for internal logs
|
108 |
+
* This file will be saved in the same path as the xml logs
|
109 |
+
* eg: "emandates.txt" will produce: "logs/2015-03-11/emandates.txt"
|
110 |
+
* @var type
|
111 |
+
*/
|
112 |
+
public $fileName;
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Constructor that highlights all required fields for this object
|
116 |
+
*
|
117 |
+
* @param string $passphrase
|
118 |
+
* @param string $keyFile
|
119 |
+
* @param string $crtFile
|
120 |
+
* @param string $crtFileAquirer
|
121 |
+
* @param string $contractID
|
122 |
+
* @param string $contractSubID
|
123 |
+
* @param string $merchantReturnURL
|
124 |
+
* @param string $AcquirerUrl_DirectoryReq
|
125 |
+
* @param string $AcquirerUrl_TransactionReq
|
126 |
+
* @param bool $enableXMLLogs
|
127 |
+
* @param string $logPath
|
128 |
+
* @param string $folderNamePattern
|
129 |
+
* @param string $fileNamePrefix
|
130 |
+
* @param bool $enableInternalLogs
|
131 |
+
* @param string $fileName
|
132 |
+
*/
|
133 |
+
public function __construct($passphrase, $keyFile, $crtFile, $crtFileAquirer, $contractID, $contractSubID, $merchantReturnURL, $AcquirerUrl_DirectoryReq, $AcquirerUrl_TransactionReq, $AcquirerUrl_StatusReq, $enableXMLLogs, $logPath, $folderNamePattern, $fileNamePrefix, $enableInternalLogs, $fileName) {
|
134 |
+
$this->passphrase = $passphrase;
|
135 |
+
$this->keyFile = $keyFile;
|
136 |
+
$this->crtFile = $crtFile;
|
137 |
+
$this->crtFileAquirer = $crtFileAquirer;
|
138 |
+
$this->contractID = $contractID;
|
139 |
+
$this->contractSubID = $contractSubID;
|
140 |
+
$this->merchantReturnURL = $merchantReturnURL;
|
141 |
+
$this->AcquirerUrl_DirectoryReq = $AcquirerUrl_DirectoryReq;
|
142 |
+
$this->AcquirerUrl_TransactionReq = $AcquirerUrl_TransactionReq;
|
143 |
+
$this->AcquirerUrl_StatusReq = $AcquirerUrl_StatusReq;
|
144 |
+
$this->enableXMLLogs = $enableXMLLogs;
|
145 |
+
$this->logPath = $logPath;
|
146 |
+
$this->folderNamePattern = $folderNamePattern;
|
147 |
+
$this->fileNamePrefix = $fileNamePrefix;
|
148 |
+
$this->enableInternalLogs = $enableInternalLogs;
|
149 |
+
$this->fileName = $fileName;
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Returns the Configuration object base on the configuration file settings
|
154 |
+
*
|
155 |
+
* @global array $emandates_config_params
|
156 |
+
* @return \Configuration
|
157 |
+
*/
|
158 |
+
public static function getDefault() {
|
159 |
+
global $emandates_config_params;
|
160 |
+
|
161 |
+
return new Configuration(
|
162 |
+
$emandates_config_params['passphrase'],
|
163 |
+
$emandates_config_params['keyFile'],
|
164 |
+
$emandates_config_params['crtFile'],
|
165 |
+
$emandates_config_params['crtFileAquirer'],
|
166 |
+
|
167 |
+
$emandates_config_params['contractID'],
|
168 |
+
$emandates_config_params['contractSubID'],
|
169 |
+
$emandates_config_params['merchantReturnURL'],
|
170 |
+
|
171 |
+
$emandates_config_params['AcquirerUrl_DirectoryReq'],
|
172 |
+
$emandates_config_params['AcquirerUrl_TransactionReq'],
|
173 |
+
$emandates_config_params['AcquirerUrl_StatusReq'],
|
174 |
+
|
175 |
+
$emandates_config_params['enableXMLLogs'],
|
176 |
+
$emandates_config_params['logPath'],
|
177 |
+
$emandates_config_params['folderNamePattern'],
|
178 |
+
$emandates_config_params['fileNamePrefix'],
|
179 |
+
|
180 |
+
$emandates_config_params['enableInternalLogs'],
|
181 |
+
$emandates_config_params['fileName']
|
182 |
+
);
|
183 |
+
}
|
184 |
+
|
185 |
+
}
|
lib/Communicator/CoreCommunicator.php
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once dirname(__FILE__) . "/Configuration/Configuration.php";
|
4 |
+
require_once dirname(__FILE__) . "/B2BCommunicator.php";
|
5 |
+
require_once dirname(__FILE__) . "/Libraries/XmlUtility.php";
|
6 |
+
|
7 |
+
/* DIRECTORY */
|
8 |
+
require_once dirname(__FILE__) . "/Entities/DirectoryRequest.php";
|
9 |
+
require_once dirname(__FILE__) . "/Entities/DirectoryResponse.php";
|
10 |
+
|
11 |
+
/* TRANSACTION */
|
12 |
+
require_once dirname(__FILE__) . "/Entities/AcquirerTrxRequest.php";
|
13 |
+
|
14 |
+
/* NEW eMANDATE */
|
15 |
+
require_once dirname(__FILE__) . "/Entities/NewMandateRequest.php";
|
16 |
+
require_once dirname(__FILE__) . "/Entities/NewMandateResponse.php";
|
17 |
+
|
18 |
+
/* STATUS */
|
19 |
+
require_once dirname(__FILE__) . "/Entities/AcquirerStatusRequest.php";
|
20 |
+
require_once dirname(__FILE__) . "/Entities/AcquirerStatusResponse.php";
|
21 |
+
|
22 |
+
/* CANCEL */
|
23 |
+
require_once dirname(__FILE__) . "/Entities/CancellationRequest.php";
|
24 |
+
require_once dirname(__FILE__) . "/Entities/CancellationResponse.php";
|
25 |
+
|
26 |
+
/* AMEND */
|
27 |
+
require_once dirname(__FILE__) . "/Entities/AmendmentRequest.php";
|
28 |
+
require_once dirname(__FILE__) . "/Entities/AmendmentResponse.php";
|
29 |
+
|
30 |
+
/* Signer and Validator */
|
31 |
+
require_once dirname(__FILE__) . "/Libraries/XmlSecurity.php";
|
32 |
+
require_once dirname(__FILE__) . "/Libraries/XmlValidator.php";
|
33 |
+
|
34 |
+
require_once dirname(__FILE__) . '/Libraries/CommunicatorException.php';
|
35 |
+
require_once dirname(__FILE__) . '/Libraries/MessageIdGenerator.php';
|
36 |
+
require_once dirname(__FILE__) . '/Libraries/Logger.php';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Description of Communicator
|
40 |
+
*/
|
41 |
+
class CoreCommunicator {
|
42 |
+
|
43 |
+
const LOCAL_INSTRUMENT = 'CORE';
|
44 |
+
const VERSION = '1.0.0';
|
45 |
+
const PRODUCT_ID = 'NL:BVN:eMandatesCore:1.0';
|
46 |
+
|
47 |
+
/**
|
48 |
+
* The configuration object used in the Communicator
|
49 |
+
*
|
50 |
+
* @var Configuration
|
51 |
+
*/
|
52 |
+
protected $Configuration;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* The logger object use to log xml and internal messages
|
56 |
+
*
|
57 |
+
* @var Logger
|
58 |
+
*/
|
59 |
+
protected $logger;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* The singer object used to sign requests and verify response
|
63 |
+
*
|
64 |
+
* @var XmlSecurity
|
65 |
+
*/
|
66 |
+
protected $signer;
|
67 |
+
|
68 |
+
public function __construct(Configuration $configuration, $logger = false) {
|
69 |
+
|
70 |
+
$this->Configuration = $configuration;
|
71 |
+
|
72 |
+
$this->logger = ($logger ? $logger : new Logger($configuration));
|
73 |
+
$this->signer = new XmlSecurity($this->logger);
|
74 |
+
|
75 |
+
$this->logger->Log(get_called_class() . " initialized");
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Performs a DirectoryRequest and returns the apropiate DirectoryResponse
|
80 |
+
*
|
81 |
+
* @return \DirectoryResponse
|
82 |
+
*/
|
83 |
+
public function Directory() {
|
84 |
+
$this->logger->Log("sending new directory request");
|
85 |
+
$c = get_called_class();
|
86 |
+
|
87 |
+
$DirectoryReq = new DirectoryRequest(
|
88 |
+
$c::PRODUCT_ID, $c::VERSION, new Merchant($this->Configuration->contractID, $this->Configuration->contractSubID)
|
89 |
+
);
|
90 |
+
|
91 |
+
|
92 |
+
try {
|
93 |
+
$this->logger->Log("building idx message");
|
94 |
+
// Serialize the DirectoryReq
|
95 |
+
$docTree = $DirectoryReq->toXml();
|
96 |
+
|
97 |
+
// Send the Request
|
98 |
+
$response = $this->PerformRequest($docTree, $this->Configuration->AcquirerUrl_DirectoryReq);
|
99 |
+
|
100 |
+
// Validate the Response and validate signature
|
101 |
+
|
102 |
+
XmlValidator::isValidatXML($response, XmlValidator::SCHEMA_IDX, $this->logger);
|
103 |
+
$this->signer->verify($response, $this->Configuration->crtFileAquirer);
|
104 |
+
|
105 |
+
return new DirectoryResponse($response);
|
106 |
+
} catch (Exception $ex) {
|
107 |
+
return new DirectoryResponse($ex->getMessage(), (!empty($response) ? $response : ''));
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Performs a new mandate request using the provided mandate
|
113 |
+
*
|
114 |
+
* @param NewMandateRequest $NewMandateRequest
|
115 |
+
* @return NewMandateResponse
|
116 |
+
*/
|
117 |
+
public function NewMandate(NewMandateRequest $NewMandateRequest) {
|
118 |
+
$NewMandateRequest->logger = $this->logger;
|
119 |
+
$this->logger->Log("sending new eMandate transaction");
|
120 |
+
$c = get_called_class();
|
121 |
+
|
122 |
+
$AcquirerTrxReq = new AcquirerTrxRequest(
|
123 |
+
$c::PRODUCT_ID, $c::VERSION, new AcquirerTrxReqMerchant(
|
124 |
+
$this->Configuration->contractID, $this->Configuration->contractSubID, $this->Configuration->merchantReturnURL
|
125 |
+
), $NewMandateRequest->DebtorBankId, new AcquirerTrxReqTransaction(
|
126 |
+
$NewMandateRequest->EntranceCode, !empty($NewMandateRequest->ExpirationPeriod) ? $NewMandateRequest->ExpirationPeriod : null, $NewMandateRequest->Language, $NewMandateRequest
|
127 |
+
)
|
128 |
+
);
|
129 |
+
|
130 |
+
try {
|
131 |
+
$this->logger->Log("building idx message");
|
132 |
+
// Serialize
|
133 |
+
$docTree = $AcquirerTrxReq->toXml($c::LOCAL_INSTRUMENT);
|
134 |
+
|
135 |
+
|
136 |
+
// Send the Request
|
137 |
+
$response = $this->PerformRequest($docTree, $this->Configuration->AcquirerUrl_TransactionReq);
|
138 |
+
|
139 |
+
// Validate the Response and validate signature
|
140 |
+
XmlValidator::isValidatXML($response, XmlValidator::SCHEMA_IDX, $this->logger);
|
141 |
+
$this->signer->verify($response, $this->Configuration->crtFileAquirer);
|
142 |
+
|
143 |
+
return new NewMandateResponse($response);
|
144 |
+
} catch (Exception $ex) {
|
145 |
+
return new NewMandateResponse($ex->getMessage(), (!empty($response) ? $response : ''));
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Performs a status request usign the provided $statusRequest
|
151 |
+
*
|
152 |
+
* @param StatusRequest $statusRequest
|
153 |
+
* @return AcquirerStatusResponse
|
154 |
+
*/
|
155 |
+
public function GetStatus(StatusRequest $statusRequest) {
|
156 |
+
$this->logger->Log("sending new status request");
|
157 |
+
$c = get_called_class();
|
158 |
+
|
159 |
+
$AcquirerStatusReq = new AcquirerStatusRequest(
|
160 |
+
$c::PRODUCT_ID, $c::VERSION, new AcquirerStatusReqMerchant(
|
161 |
+
$this->Configuration->contractID, $this->Configuration->contractSubID
|
162 |
+
), new AcquirerStatusReqTransaction(
|
163 |
+
$statusRequest->TransactionId
|
164 |
+
)
|
165 |
+
);
|
166 |
+
try {
|
167 |
+
$this->logger->Log("building idx message");
|
168 |
+
// Serialize
|
169 |
+
$docTree = $AcquirerStatusReq->toXml();
|
170 |
+
|
171 |
+
// Send the Request
|
172 |
+
$response = $this->PerformRequest($docTree, $this->Configuration->AcquirerUrl_StatusReq);
|
173 |
+
// Validate the Response and validate signature
|
174 |
+
XmlValidator::isValidatXML($response, XmlValidator::SCHEMA_IDX, $this->logger);
|
175 |
+
$this->signer->verify($response, $this->Configuration->crtFileAquirer);
|
176 |
+
|
177 |
+
return new AcquirerStatusResponse($response, $this->logger);
|
178 |
+
} catch (Exception $ex) {
|
179 |
+
return new AcquirerStatusResponse($ex->getMessage(), $this->logger, (!empty($response) ? $response : ''));
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Performs an amendment to a mandate using the provided $amendmentRequest
|
185 |
+
*
|
186 |
+
* @param AmendmentRequest $amendmentRequest
|
187 |
+
* @return AmendmentResponse
|
188 |
+
*/
|
189 |
+
public function Amend(AmendmentRequest $amendmentRequest) {
|
190 |
+
$amendmentRequest->logger = $this->logger;
|
191 |
+
$this->logger->Log("sending new amend request");
|
192 |
+
$c = get_called_class();
|
193 |
+
|
194 |
+
$AcquirerTrxReq = new AcquirerTrxRequest(
|
195 |
+
$c::PRODUCT_ID, $c::VERSION, new AcquirerTrxReqMerchant(
|
196 |
+
$this->Configuration->contractID, $this->Configuration->contractSubID, $this->Configuration->merchantReturnURL
|
197 |
+
), $amendmentRequest->DebtorBankId, new AcquirerTrxReqTransaction(
|
198 |
+
$amendmentRequest->EntranceCode, !empty($amendmentRequest->ExpirationPeriod) ? $amendmentRequest->ExpirationPeriod : null, $amendmentRequest->Language, $amendmentRequest
|
199 |
+
)
|
200 |
+
);
|
201 |
+
|
202 |
+
try {
|
203 |
+
$this->logger->Log("building idx message");
|
204 |
+
// Serialize
|
205 |
+
$docTree = $AcquirerTrxReq->toXml($c::LOCAL_INSTRUMENT);
|
206 |
+
|
207 |
+
// Send the Request
|
208 |
+
$response = $this->PerformRequest($docTree, $this->Configuration->AcquirerUrl_TransactionReq);
|
209 |
+
|
210 |
+
// Validate the Response and validate signature
|
211 |
+
XmlValidator::isValidatXML($response, XmlValidator::SCHEMA_IDX, $this->logger);
|
212 |
+
$this->signer->verify($response, $this->Configuration->crtFileAquirer);
|
213 |
+
|
214 |
+
return new AmendmentResponse($response);
|
215 |
+
} catch (Exception $ex) {
|
216 |
+
return new AmendmentResponse($ex->getMessage(), (!empty($response) ? $response : ''));
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
/*
|
221 |
+
* *************************************************************************
|
222 |
+
* PROTECTED METHODS
|
223 |
+
* *************************************************************************
|
224 |
+
*/
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Sends the xml to the provided url and returns the response
|
228 |
+
* Throws an Exception if there was something wrong with the curl
|
229 |
+
*
|
230 |
+
* @param string $xml
|
231 |
+
* @param string $url
|
232 |
+
* @return string
|
233 |
+
* @throws Exception
|
234 |
+
*/
|
235 |
+
protected function PerformRequest($docTree, $url) {
|
236 |
+
|
237 |
+
// Sign the xml
|
238 |
+
$docTree = $this->signer->sign($docTree, $this->Configuration->crtFile, $this->Configuration->keyFile, $this->Configuration->passphrase);
|
239 |
+
|
240 |
+
// Validate the request xml against the .xsd schema
|
241 |
+
if (XmlValidator::isValidatXML($docTree->saveXML(), XmlValidator::SCHEMA_IDX, $this->logger)) {
|
242 |
+
|
243 |
+
$this->logger->Log("sending request to {{$url}} ");
|
244 |
+
|
245 |
+
// Log the xml before sending
|
246 |
+
$this->logger->LogXmlMessage($docTree);
|
247 |
+
|
248 |
+
//setting the curl parameters.
|
249 |
+
$headers = array(
|
250 |
+
"Content-type: text/xml;charset=\"UTF-8\"",
|
251 |
+
);
|
252 |
+
|
253 |
+
$ch = curl_init();
|
254 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
255 |
+
curl_setopt($ch, CURLOPT_POST, 1);
|
256 |
+
|
257 |
+
// send xml request to server
|
258 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
259 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
260 |
+
|
261 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $docTree->saveXML());
|
262 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
263 |
+
|
264 |
+
curl_setopt($ch, CURLOPT_VERBOSE, 0);
|
265 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
266 |
+
$data = curl_exec($ch);
|
267 |
+
|
268 |
+
// check for curl errors
|
269 |
+
if ($data === false) {
|
270 |
+
$error = curl_error($ch);
|
271 |
+
curl_close($ch);
|
272 |
+
|
273 |
+
$this->logger->Log($error);
|
274 |
+
throw new Exception($error);
|
275 |
+
} else {
|
276 |
+
curl_close($ch);
|
277 |
+
|
278 |
+
$doc = @simplexml_load_string($data);
|
279 |
+
if (!$doc) {
|
280 |
+
$this->logger->Log("Raw Response : " . $data);
|
281 |
+
throw new CommunicatorException($data);
|
282 |
+
}
|
283 |
+
|
284 |
+
// Log the xml received
|
285 |
+
$this->logger->LogXmlMessage($data, true);
|
286 |
+
|
287 |
+
return $data;
|
288 |
+
}
|
289 |
+
}
|
290 |
+
}
|
291 |
+
|
292 |
+
}
|
lib/Communicator/Entities/AcquirerStatusRequest.php
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Describes a status request
|
5 |
+
*
|
6 |
+
*/
|
7 |
+
class AcquirerStatusRequest {
|
8 |
+
|
9 |
+
const XMLNS = "http://www.betaalvereniging.nl/iDx/messages/Merchant-Acquirer/1.0.0";
|
10 |
+
const XSD = "http://www.w3.org/2001/XMLSchema";
|
11 |
+
const XSI = "http://www.w3.org/2001/XMLSchema-instance";
|
12 |
+
|
13 |
+
public $productID;
|
14 |
+
public $version;
|
15 |
+
public $dateTime;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* The merchant object
|
19 |
+
* @var AcquirerStatusReqMerchant
|
20 |
+
*/
|
21 |
+
public $merchant;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* The transaction ID to check
|
25 |
+
* @var AcquirerStatusReqTransaction
|
26 |
+
*/
|
27 |
+
public $Transaction;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Constructor that highlights all required fields for this object
|
31 |
+
*
|
32 |
+
* @param string $productID
|
33 |
+
* @param string $version
|
34 |
+
* @param AcquirerStatusReqMerchant $merchant
|
35 |
+
* @param AcquirerStatusReqTransaction $Transaction
|
36 |
+
*/
|
37 |
+
function __construct($productID, $version, AcquirerStatusReqMerchant $merchant, AcquirerStatusReqTransaction $Transaction) {
|
38 |
+
$this->productID = $productID;
|
39 |
+
$this->version = $version;
|
40 |
+
$this->dateTime = date('Y-m-d\TH:i:s' . substr((string) microtime(), 1, 4) . '\Z');
|
41 |
+
$this->merchant = $merchant;
|
42 |
+
$this->Transaction = $Transaction;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Serializes the object into an AcquirerStatusReq
|
47 |
+
*
|
48 |
+
* @return \DOMDocument
|
49 |
+
*/
|
50 |
+
public function toXml() {
|
51 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
52 |
+
|
53 |
+
/* create the root element of the xml tree */
|
54 |
+
$AcquirerStatusReq = $domtree->createElementNS(self::XMLNS, 'AcquirerStatusReq');
|
55 |
+
$AcquirerStatusReq->setAttribute('xmlns:xsd', self::XSD);
|
56 |
+
$AcquirerStatusReq->setAttribute('xmlns:xsi', self::XSI);
|
57 |
+
|
58 |
+
$AcquirerStatusReq->setAttribute('productID', $this->productID);
|
59 |
+
$AcquirerStatusReq->setAttribute('version', $this->version);
|
60 |
+
$domtree->appendChild($AcquirerStatusReq);
|
61 |
+
|
62 |
+
/* create the timetamp */
|
63 |
+
$createDateTimestamp = $domtree->createElement('createDateTimestamp', $this->dateTime);
|
64 |
+
$AcquirerStatusReq->appendChild($createDateTimestamp);
|
65 |
+
|
66 |
+
/* create the merchant element and it's sub elements */
|
67 |
+
$Merchant = $domtree->createElement('Merchant'); {
|
68 |
+
$Merchant->appendChild($domtree->createElement('merchantID', $this->merchant->merchantID));
|
69 |
+
$Merchant->appendChild($domtree->createElement('subID', $this->merchant->merchantSubID));
|
70 |
+
}
|
71 |
+
$AcquirerStatusReq->appendChild($Merchant);
|
72 |
+
|
73 |
+
/* create the Transaction elem */
|
74 |
+
$AcquirerStatusReq->appendChild($domtree->importNode($this->Transaction->toXML(), true));
|
75 |
+
|
76 |
+
return $domtree;
|
77 |
+
}
|
78 |
+
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Description of Merchant
|
83 |
+
*
|
84 |
+
*/
|
85 |
+
class AcquirerStatusReqMerchant {
|
86 |
+
|
87 |
+
public $merchantID;
|
88 |
+
public $merchantSubID;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Constructor that highlights the required fields
|
92 |
+
*
|
93 |
+
* @param string $merchantID
|
94 |
+
* @param string $merchantSubID
|
95 |
+
*/
|
96 |
+
public function __construct($merchantID, $merchantSubID) {
|
97 |
+
$this->merchantID = $merchantID;
|
98 |
+
$this->merchantSubID = $merchantSubID;
|
99 |
+
}
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Description of Transaction
|
105 |
+
*
|
106 |
+
*/
|
107 |
+
class AcquirerStatusReqTransaction {
|
108 |
+
|
109 |
+
public $transactionID;
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Constructor that highlights the required fields
|
113 |
+
*
|
114 |
+
* @param string $transactionID
|
115 |
+
*/
|
116 |
+
function __construct($transactionID) {
|
117 |
+
$this->transactionID = $transactionID;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Serializes the object into a Transaction
|
122 |
+
*
|
123 |
+
* @return DOMElement
|
124 |
+
*/
|
125 |
+
public function toXML() {
|
126 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
127 |
+
|
128 |
+
/* create the Transaction elem */
|
129 |
+
$Transaction = $domtree->createElement('Transaction');
|
130 |
+
|
131 |
+
/* create the transactionID elem */
|
132 |
+
$transactionID = $domtree->createElement('transactionID', $this->transactionID);
|
133 |
+
$Transaction->appendChild($transactionID);
|
134 |
+
|
135 |
+
return $Transaction;
|
136 |
+
}
|
137 |
+
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Describes a status request
|
142 |
+
*/
|
143 |
+
class StatusRequest {
|
144 |
+
|
145 |
+
/**
|
146 |
+
* The transaction ID to check
|
147 |
+
* @var string
|
148 |
+
*/
|
149 |
+
public $TransactionId;
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Constructor that highlights all required fields for this object
|
153 |
+
*
|
154 |
+
* @param string $TransactionId
|
155 |
+
*/
|
156 |
+
function __construct($TransactionId) {
|
157 |
+
$this->TransactionId = $TransactionId;
|
158 |
+
}
|
159 |
+
|
160 |
+
}
|
lib/Communicator/Entities/AcquirerStatusResponse.php
ADDED
@@ -0,0 +1,333 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents a status response
|
5 |
+
*/
|
6 |
+
class AcquirerStatusResponse {
|
7 |
+
|
8 |
+
const STATUS_OPEN = "Open";
|
9 |
+
const STATUS_PENDING = "Pending";
|
10 |
+
const STATUS_SUCCESS = "Success";
|
11 |
+
const STATUS_FAILURE = "Failure";
|
12 |
+
const STATUS_EXPIRED = "Expired";
|
13 |
+
const STATUS_CANCELLED = "Cancelled";
|
14 |
+
|
15 |
+
/**
|
16 |
+
* true if an error occurred, or false when no errors were encountered
|
17 |
+
* @var bool
|
18 |
+
*/
|
19 |
+
public $IsError = false;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Object that holds the error if one occurs; when there are no errors, this is set to null
|
23 |
+
* @var ErrorResponse
|
24 |
+
*/
|
25 |
+
public $Error = null;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* The transaction ID
|
29 |
+
* @var type
|
30 |
+
*/
|
31 |
+
public $TransactionId = null;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Possible values: Open, Pending, Success, Failure, Expired, Cancelled
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
public $Status = null;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* DateTime when the status was created, or null if no such date available (for example, when mandate has expired)
|
41 |
+
* @var DateTime
|
42 |
+
*/
|
43 |
+
public $StatusDateTimestamp = null;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* The acceptance report returned in the status response
|
47 |
+
* @var AcceptanceReport
|
48 |
+
*/
|
49 |
+
public $AcceptanceReport;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* The object used to log internal messages and the xml files
|
53 |
+
*
|
54 |
+
* @var Logger
|
55 |
+
*/
|
56 |
+
public $logger;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* The response XML
|
60 |
+
*
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
public $RawMessage;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Deserializes the xml provided into a AcquirerStatusRes
|
67 |
+
*
|
68 |
+
* @param string $xml
|
69 |
+
* @throws CommunicatorException
|
70 |
+
*/
|
71 |
+
public function __construct($xml, $logger, $response_xml = false) {
|
72 |
+
$this->logger = $logger;
|
73 |
+
|
74 |
+
$this->RawMessage = (!empty($response_xml) || $response_xml === '' ? $response_xml : $xml);
|
75 |
+
$data = XmlUtility::parse($xml);
|
76 |
+
|
77 |
+
if ($data->getName() == 'AcquirerErrorRes' || $data->getName() == 'Exception') {
|
78 |
+
$this->_buildAcquirerErrorRes($data);
|
79 |
+
} else if ($data->getName() != 'AcquirerStatusRes') {
|
80 |
+
throw new CommunicatorException($data->getName() . ' was not expected.');
|
81 |
+
} else {
|
82 |
+
$this->Status = (string) $data->Transaction->status;
|
83 |
+
|
84 |
+
if ($this->Status == AcquirerStatusResponse::STATUS_SUCCESS) {
|
85 |
+
//validate status response p012
|
86 |
+
$this->_validateResponseDocument($xml);
|
87 |
+
}
|
88 |
+
$this->_buildStatusResponse($data);
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
private function _buildAcquirerErrorRes($data) {
|
93 |
+
$this->Error = new ErrorResponse($data);
|
94 |
+
$this->IsError = true;
|
95 |
+
}
|
96 |
+
|
97 |
+
private function _buildStatusResponse($data) {
|
98 |
+
$this->TransactionId = (string) $data->Transaction->transactionID;
|
99 |
+
$this->StatusDateTimestamp = new DateTime((string) $data->Directory->DirectoryDateTimestamp);
|
100 |
+
|
101 |
+
if ($this->Status == AcquirerStatusResponse::STATUS_SUCCESS) {
|
102 |
+
$temp_dom = new DOMDocument('1.0', 'UTF-8');
|
103 |
+
$temp_dom->loadXML($data->asXML());
|
104 |
+
$Document = $temp_dom->getElementsByTagName('Document');
|
105 |
+
|
106 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
107 |
+
$domtree->appendChild($domtree->importNode($Document->item(0), true));
|
108 |
+
|
109 |
+
$this->AcceptanceReport = new AcceptanceReport($domtree);
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Validates the Document of the xml provided
|
115 |
+
*
|
116 |
+
* @param string $xml
|
117 |
+
*/
|
118 |
+
private function _validateResponseDocument($xml) {
|
119 |
+
$temp_dom = new DOMDocument('1.0', 'UTF-8');
|
120 |
+
$temp_dom->loadXML($xml);
|
121 |
+
$Document = $temp_dom->getElementsByTagName('Document');
|
122 |
+
|
123 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
124 |
+
$domtree->appendChild($domtree->importNode($Document->item(0), true));
|
125 |
+
|
126 |
+
XmlValidator::isValidatXML($domtree->saveXML(), XmlValidator::SCHEMA_PAIN012, $this->logger);
|
127 |
+
}
|
128 |
+
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Received as part of a status response, corresponding to the pain.012 message
|
133 |
+
*/
|
134 |
+
class AcceptanceReport {
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Message Identification
|
138 |
+
* @var string
|
139 |
+
*/
|
140 |
+
public $MessageId;
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Message timestamp
|
144 |
+
* @var DateTime
|
145 |
+
*/
|
146 |
+
public $DateTime;
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Validation reference
|
150 |
+
* @var string
|
151 |
+
*/
|
152 |
+
public $ValidationReference;
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Original Message ID
|
156 |
+
* @var string
|
157 |
+
*/
|
158 |
+
public $OriginalMessageId;
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Refers to the type of validation request that preceded the acceptance report
|
162 |
+
* @var string
|
163 |
+
*/
|
164 |
+
public $MessageNameId;
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Whether or not the mandate is accepted by the debtor
|
168 |
+
* @var bool
|
169 |
+
*/
|
170 |
+
public $AcceptedResult;
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Original mandate ID
|
174 |
+
* @var string
|
175 |
+
*/
|
176 |
+
public $OriginalMandateId;
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Mandate request ID
|
180 |
+
* @var string
|
181 |
+
*/
|
182 |
+
public $MandateRequestId;
|
183 |
+
|
184 |
+
/**
|
185 |
+
* SEPA
|
186 |
+
* @var string
|
187 |
+
*/
|
188 |
+
public $ServiceLevelCode;
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Core or B2B
|
192 |
+
* @var string
|
193 |
+
*/
|
194 |
+
public $LocalInstrumentCode;
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Sequence Type: sequenceType or one-off
|
198 |
+
* @var string
|
199 |
+
*/
|
200 |
+
public $SequenceType;
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Maximum amount
|
204 |
+
* @var string
|
205 |
+
*/
|
206 |
+
public $MaxAmount;
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Reason for eMandate
|
210 |
+
* @var string
|
211 |
+
*/
|
212 |
+
public $eMandateReason;
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Direct Debit ID of the Creditor
|
216 |
+
* @var string
|
217 |
+
*/
|
218 |
+
public $CreditorId;
|
219 |
+
|
220 |
+
/**
|
221 |
+
* SEPA
|
222 |
+
* @var string
|
223 |
+
*/
|
224 |
+
public $SchemeName;
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Name of the Creditor
|
228 |
+
* @var string
|
229 |
+
*/
|
230 |
+
public $CreditorName;
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Country of the postal address of the Creditor
|
234 |
+
* @var string
|
235 |
+
*/
|
236 |
+
public $CreditorCountry;
|
237 |
+
|
238 |
+
/**
|
239 |
+
* The Creditor’s address: P.O. Box or street name + building + add-on + Postcode + City.
|
240 |
+
* Second Address line only to be used if 70 chars are exceeded in the first line
|
241 |
+
* @var array(string)
|
242 |
+
*/
|
243 |
+
public $CreditorAddressLine = array();
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Name of the company (or daughter-company, or label etc.) for which the Creditor is processing eMandates.
|
247 |
+
* May only be used when meaningfully different from CreditorName
|
248 |
+
* @var string
|
249 |
+
*/
|
250 |
+
public $CreditorTradeName;
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Account holder name of the account that is used for the eMandate
|
254 |
+
* @var string
|
255 |
+
*/
|
256 |
+
public $DebtorAccountName;
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Reference ID that identifies the Debtor to the Creditor. Issued by the Creditor
|
260 |
+
* @var string
|
261 |
+
*/
|
262 |
+
public $DebtorReference;
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Debtor’s bank account number
|
266 |
+
* @var string
|
267 |
+
*/
|
268 |
+
public $DebtorIBAN;
|
269 |
+
|
270 |
+
/**
|
271 |
+
* BIC of the Debtor bank
|
272 |
+
* @var string
|
273 |
+
*/
|
274 |
+
public $DebtorBankId;
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Name of the person signing the eMandate. In case of multiple signing, all signer names must be included in this field, separated by commas.
|
278 |
+
* If the total would exceed the maximum of 70 characters, the names are cut off at 65 characters and “e.a.” is added after the last name.
|
279 |
+
* @var string
|
280 |
+
*/
|
281 |
+
public $DebtorSignerName;
|
282 |
+
|
283 |
+
/**
|
284 |
+
* The response XML
|
285 |
+
*
|
286 |
+
* @var string
|
287 |
+
*/
|
288 |
+
public $RawMessage;
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Deserializes the data into an AcceptanceReport
|
292 |
+
*
|
293 |
+
* @param SimpleXMLElement $data
|
294 |
+
*/
|
295 |
+
public function __construct($data) {
|
296 |
+
$xpath = new DOMXpath($data);
|
297 |
+
$xpath->registerNamespace("p", "urn:iso:std:iso:20022:tech:xsd:pain.012.001.04");
|
298 |
+
|
299 |
+
$grpHdr = '/p:Document/p:MndtAccptncRpt/p:GrpHdr';
|
300 |
+
$accDtls = '/p:Document/p:MndtAccptncRpt/p:UndrlygAccptncDtls';
|
301 |
+
|
302 |
+
$this->MessageId = (string) $xpath->evaluate($grpHdr . '/p:MsgId')->item(0)->nodeValue;
|
303 |
+
$this->DateTime = new DateTime((string) $xpath->evaluate($grpHdr . '/p:CreDtTm')->item(0)->nodeValue );
|
304 |
+
$this->ValidationReference = (string) $xpath->evaluate($grpHdr . '/p:Authstn/p:Prtry')->item(0)->nodeValue;
|
305 |
+
$this->OriginalMessageId = (string) $xpath->evaluate($accDtls . '/p:OrgnlMsgInf/p:MsgId')->item(0)->nodeValue;
|
306 |
+
$this->MessageNameId = (string) $xpath->evaluate($accDtls . '/p:OrgnlMsgInf/p:MsgNmId')->item(0)->nodeValue;
|
307 |
+
$this->AcceptedResult = (string) $xpath->evaluate($accDtls . '/p:AccptncRslt/p:Accptd')->item(0)->nodeValue;
|
308 |
+
|
309 |
+
$origMndt = $accDtls . '/p:OrgnlMndt/p:OrgnlMndt';
|
310 |
+
|
311 |
+
$this->OriginalMandateId = (string) $xpath->evaluate($origMndt . '/p:MndtId')->item(0)->nodeValue;
|
312 |
+
$this->MandateRequestId = (string) $xpath->evaluate($origMndt . '/p:MndtReqId')->item(0)->nodeValue;
|
313 |
+
$this->LocalInstrumentCode = (string) $xpath->evaluate($origMndt . '/p:Tp/p:LclInstrm/p:Cd')->item(0)->nodeValue;
|
314 |
+
$this->SequenceType = (string) $xpath->evaluate($origMndt . '/p:Ocrncs/p:SeqTp')->item(0)->nodeValue;
|
315 |
+
$this->MaxAmount = (int) $xpath->evaluate($origMndt . '/p:MaxAmt/p:Value')->item(0)->nodeValue;
|
316 |
+
$this->ServiceLevelCode = (string) $xpath->evaluate($origMndt . '/p:Tp/p:SvcLvl/p:Cd')->item(0)->nodeValue;
|
317 |
+
$this->eMandateReason = (string) $xpath->evaluate($origMndt . '/p:Rsn/p:Cd')->item(0)->nodeValue;
|
318 |
+
$this->CreditorId = (string) $xpath->evaluate($origMndt . '/p:CdtrSchmeId/p:Id/p:PrvtId/p:Othr/p:Id')->item(0)->nodeValue;
|
319 |
+
$this->SchemeName = (string) $xpath->evaluate($origMndt . '/p:CdtrSchmeId/p:Id/p:PrvtId/p:Othr/p:SchmeNm/p:Cd')->item(0)->nodeValue;
|
320 |
+
$this->CreditorName = (string) $xpath->evaluate($origMndt . '/p:Cdtr/p:Nm')->item(0)->nodeValue;
|
321 |
+
$this->CreditorCountry = (string) $xpath->evaluate($origMndt . '/p:Cdtr/p:PstlAdr/p:Ctry')->item(0)->nodeValue;
|
322 |
+
$this->CreditorAddressLine = (string) $xpath->evaluate($origMndt . '/p:Cdtr/p:PstlAdr/p:AdrLine')->item(0)->nodeValue;
|
323 |
+
$this->CreditorTradeName = (string) $xpath->evaluate($origMndt . '/p:UltmtCdtr/p:Nm')->item(0)->nodeValue;
|
324 |
+
$this->DebtorAccountName = (string) $xpath->evaluate($origMndt . '/p:Dbtr/p:Nm')->item(0)->nodeValue;;
|
325 |
+
$this->DebtorReference = (string) $xpath->evaluate($origMndt . '/p:Dbtr/p:Id/p:PrvtId/p:Othr/p:Id')->item(0)->nodeValue;
|
326 |
+
$this->DebtorIBAN = (string) $xpath->evaluate($origMndt . '/p:DbtrAcct/p:Id/p:IBAN')->item(0)->nodeValue;
|
327 |
+
$this->DebtorBankId = (string) $xpath->evaluate($origMndt . '/p:DbtrAgt/p:FinInstnId/p:BICFI')->item(0)->nodeValue;
|
328 |
+
$this->DebtorSignerName = (string) $xpath->evaluate($origMndt . '/p:UltmtDbtr/p:Nm')->item(0)->nodeValue;
|
329 |
+
|
330 |
+
$this->RawMessage = $data->saveXML();
|
331 |
+
}
|
332 |
+
|
333 |
+
}
|
lib/Communicator/Entities/AcquirerTrxRequest.php
ADDED
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* AquirerTrxReq description
|
5 |
+
*/
|
6 |
+
class AcquirerTrxRequest {
|
7 |
+
|
8 |
+
const XMLNS = "http://www.betaalvereniging.nl/iDx/messages/Merchant-Acquirer/1.0.0";
|
9 |
+
const XSD = "http://www.w3.org/2001/XMLSchema";
|
10 |
+
const XSI = "http://www.w3.org/2001/XMLSchema-instance";
|
11 |
+
|
12 |
+
public $productID;
|
13 |
+
public $version;
|
14 |
+
public $dateTime;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* The merchant object
|
18 |
+
* @var AcquirerTrxReqMerchant
|
19 |
+
*/
|
20 |
+
public $merchant;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* The Bank id
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $issuerID;
|
27 |
+
|
28 |
+
/**
|
29 |
+
*
|
30 |
+
* @var AcquirerTrxReqTransaction
|
31 |
+
*/
|
32 |
+
public $Transaction;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Constructor that highlights the required fields
|
36 |
+
*
|
37 |
+
* @param string $productID
|
38 |
+
* @param string $version
|
39 |
+
* @param AcquirerTrxReqMerchant $merchant
|
40 |
+
* @param string $issuerID
|
41 |
+
* @param AcquirerTrxReqTransaction $Transaction
|
42 |
+
*/
|
43 |
+
public function __construct($productID, $version, AcquirerTrxReqMerchant $merchant, $issuerID, AcquirerTrxReqTransaction $Transaction) {
|
44 |
+
$this->productID = $productID;
|
45 |
+
$this->version = $version;
|
46 |
+
$this->dateTime = date('Y-m-d\TH:i:s'.substr((string)microtime(), 1, 4).'\Z');
|
47 |
+
$this->merchant = $merchant;
|
48 |
+
$this->issuerID = $issuerID;
|
49 |
+
$this->Transaction = $Transaction;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Serializes the object into an AcquirerTrxReq
|
54 |
+
*
|
55 |
+
* @param string $LocalInstrumentCode
|
56 |
+
* @return \DOMDocument
|
57 |
+
*/
|
58 |
+
public function toXml($LocalInstrumentCode) {
|
59 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
60 |
+
|
61 |
+
/* create the root element of the xml tree */
|
62 |
+
$AcquirerTrxReq = $domtree->createElementNS(self::XMLNS, 'AcquirerTrxReq');
|
63 |
+
$AcquirerTrxReq->setAttribute('xmlns:xsd', self::XSD);
|
64 |
+
$AcquirerTrxReq->setAttribute('xmlns:xsi', self::XSI);
|
65 |
+
|
66 |
+
$AcquirerTrxReq->setAttribute('productID', $this->productID);
|
67 |
+
$AcquirerTrxReq->setAttribute('version', $this->version);
|
68 |
+
$domtree->appendChild($AcquirerTrxReq);
|
69 |
+
|
70 |
+
/* create the timetamp */
|
71 |
+
$createDateTimestamp = $domtree->createElement('createDateTimestamp', $this->dateTime);
|
72 |
+
$AcquirerTrxReq->appendChild($createDateTimestamp);
|
73 |
+
|
74 |
+
/* create the Issuer */
|
75 |
+
$issuer = $domtree->createElement('Issuer'); {
|
76 |
+
$issuer->appendChild(new DOMElement('issuerID', $this->issuerID));
|
77 |
+
}
|
78 |
+
$AcquirerTrxReq->appendChild($issuer);
|
79 |
+
|
80 |
+
/* create the merchant element and it's sub elements */
|
81 |
+
$Merchant = $domtree->createElement('Merchant'); {
|
82 |
+
$Merchant->appendChild($domtree->createElement('merchantID', $this->merchant->merchantID));
|
83 |
+
$Merchant->appendChild($domtree->createElement('subID', $this->merchant->merchantSubID));
|
84 |
+
$Merchant->appendChild($domtree->createElement('merchantReturnURL', $this->merchant->merchantReturnURL));
|
85 |
+
}
|
86 |
+
$AcquirerTrxReq->appendChild($Merchant);
|
87 |
+
|
88 |
+
/* create the Transaction elem */
|
89 |
+
$AcquirerTrxReq->appendChild($domtree->importNode($this->Transaction->toXML($LocalInstrumentCode), true));
|
90 |
+
|
91 |
+
return $domtree;
|
92 |
+
}
|
93 |
+
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Description of Merchant
|
98 |
+
*/
|
99 |
+
class AcquirerTrxReqMerchant {
|
100 |
+
|
101 |
+
public $merchantID;
|
102 |
+
public $merchantSubID;
|
103 |
+
public $merchantReturnURL;
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Constructor that highlights the required fields
|
107 |
+
*
|
108 |
+
* @param string $merchantID
|
109 |
+
* @param string $merchantSubID
|
110 |
+
* @param string $merchantReturnURL
|
111 |
+
*/
|
112 |
+
public function __construct($merchantID, $merchantSubID, $merchantReturnURL) {
|
113 |
+
$this->merchantID = $merchantID;
|
114 |
+
$this->merchantSubID = $merchantSubID;
|
115 |
+
$this->merchantReturnURL = $merchantReturnURL;
|
116 |
+
}
|
117 |
+
|
118 |
+
}
|
119 |
+
|
120 |
+
class AcquirerTrxReqTransaction {
|
121 |
+
|
122 |
+
public $entranceCode;
|
123 |
+
public $expirationPeriod;
|
124 |
+
public $language;
|
125 |
+
|
126 |
+
/**
|
127 |
+
*
|
128 |
+
* @var NewMandateRequest | AmendmentRequest | CancellationRequest
|
129 |
+
*/
|
130 |
+
public $container;
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Constructor that highlights the required fields
|
134 |
+
*
|
135 |
+
* @param string $entranceCode
|
136 |
+
* @param DateInterval $expirationPeriod
|
137 |
+
* @param string $language
|
138 |
+
* @param NewMandateRequest | AmendmentRequest | CancellationRequest $container
|
139 |
+
*/
|
140 |
+
public function __construct($entranceCode, $expirationPeriod, $language, $container) {
|
141 |
+
$this->entranceCode = $entranceCode;
|
142 |
+
$this->expirationPeriod = $expirationPeriod;
|
143 |
+
$this->language = $language;
|
144 |
+
$this->container = $container;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Serializes the object into a Transaction
|
149 |
+
*
|
150 |
+
* @param string $LocalInstrumentCode
|
151 |
+
* @return DOMElement
|
152 |
+
*/
|
153 |
+
public function toXml($LocalInstrumentCode) {
|
154 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
155 |
+
|
156 |
+
/* create the Transaction elem */
|
157 |
+
$Transaction = $domtree->createElement('Transaction');
|
158 |
+
|
159 |
+
if (!empty($this->expirationPeriod)) {
|
160 |
+
$expirationPeriod = $domtree->createElement('expirationPeriod', $this->DateIntervalToStr($this->expirationPeriod));
|
161 |
+
$Transaction->appendChild($expirationPeriod);
|
162 |
+
}
|
163 |
+
|
164 |
+
$language = $domtree->createElement('language', $this->language);
|
165 |
+
$Transaction->appendChild($language);
|
166 |
+
|
167 |
+
$entranceCode = $domtree->createElement('entranceCode', $this->entranceCode);
|
168 |
+
$Transaction->appendChild($entranceCode);
|
169 |
+
|
170 |
+
/* create the container element */
|
171 |
+
$container = $domtree->createElement('container');
|
172 |
+
$container->appendChild($domtree->importNode($this->container->toXML($LocalInstrumentCode), true));
|
173 |
+
$Transaction->appendChild($container);
|
174 |
+
|
175 |
+
return $Transaction;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Returns the str representation of a DateInterval
|
180 |
+
*
|
181 |
+
* @param DateInterval $dateInterval
|
182 |
+
* @return string
|
183 |
+
*/
|
184 |
+
private function DateIntervalToStr($dateInterval) {
|
185 |
+
$interval = 'P';
|
186 |
+
|
187 |
+
$allowedKeys = array('y', 'm', 'd', 'h', 'i', 's');
|
188 |
+
$timeKeys = array('h', 'i', 's');
|
189 |
+
$addedTime = false;
|
190 |
+
|
191 |
+
foreach (get_object_vars($dateInterval) as $key => $value) {
|
192 |
+
if (in_array($key, $allowedKeys)) {
|
193 |
+
if (in_array($key, $timeKeys) && !$addedTime && !empty($value)) {
|
194 |
+
$interval .= 'T';
|
195 |
+
$addedTime = true;
|
196 |
+
}
|
197 |
+
if (!empty($value)) {
|
198 |
+
$interval .= $value . ( $key == 'i' ? 'M' : strtoupper($key));
|
199 |
+
}
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
return $interval;
|
204 |
+
}
|
205 |
+
|
206 |
+
}
|
lib/Communicator/Entities/AmendmentRequest.php
ADDED
@@ -0,0 +1,351 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Describes an amendment request
|
5 |
+
*/
|
6 |
+
class AmendmentRequest {
|
7 |
+
|
8 |
+
const XMLNS = "urn:iso:std:iso:20022:tech:xsd:pain.010.001.04";
|
9 |
+
const XSD = "http://www.w3.org/2001/XMLSchema";
|
10 |
+
const XSI = "http://www.w3.org/2001/XMLSchema-instance";
|
11 |
+
const NOT_PROVIDED = 'NOTPROVIDED';
|
12 |
+
const SEPA = 'SEPA';
|
13 |
+
const MD16 = 'MD16';
|
14 |
+
const CCY = 'EUR';
|
15 |
+
|
16 |
+
/**
|
17 |
+
* An 'authentication identifier' to facilitate continuation of the session between creditor and debtor, even
|
18 |
+
* if the existing session has been lost. It enables the creditor to recognise the debtor associated with a (completed) transaction.
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
public $EntranceCode;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* This field enables the debtor bank's site to select the debtor's preferred language (e.g. the language selected on the creditor's site),
|
25 |
+
* if the debtor bank's site supports this: Dutch = 'nl', English = 'en'
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
public $Language;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Optional: The period of validity of the transaction request as stated by the creditor measured from the receipt by the debtor bank.
|
32 |
+
* The debtor must authorise the transaction within this period.
|
33 |
+
* @var DateInterval
|
34 |
+
*/
|
35 |
+
public $ExpirationPeriod;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Message ID for pain message
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public $MessageId;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* ID that identifies the mandate and is issued by the creditor
|
45 |
+
* @var string
|
46 |
+
*/
|
47 |
+
public $eMandateId;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Reason of the mandate
|
51 |
+
* @var string
|
52 |
+
*/
|
53 |
+
public $eMandateReason;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Reference ID that identifies the debtor to creditor, which is issued by the creditor
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
public $DebtorReference;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* BIC of the Debtor Bank
|
63 |
+
* @var string
|
64 |
+
*/
|
65 |
+
public $DebtorBankId;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* A purchaseID that acts as a reference from eMandate to the purchase-order
|
69 |
+
* @var string
|
70 |
+
*/
|
71 |
+
public $PurchaseId;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Indicates type of eMandate: one-off or sequenceType direct debit.
|
75 |
+
* @var string
|
76 |
+
*/
|
77 |
+
public $SequenceType;
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Maximum amount. Not allowed for Core, optional for B2B.
|
81 |
+
* @var string
|
82 |
+
*/
|
83 |
+
public $MaxAmount;
|
84 |
+
|
85 |
+
/**
|
86 |
+
* IBAN of the original mandate
|
87 |
+
* @var string
|
88 |
+
*/
|
89 |
+
public $OriginalIBAN;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* BankID of the original mandate
|
93 |
+
* @var string
|
94 |
+
*/
|
95 |
+
public $OriginalDebtorBankId;
|
96 |
+
|
97 |
+
/**
|
98 |
+
* The object used to log internal messages and the xml files
|
99 |
+
*
|
100 |
+
* @var Logger
|
101 |
+
*/
|
102 |
+
public $logger;
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Constructor that highlights all required fields for this object
|
106 |
+
*
|
107 |
+
* @param string $entranceCode
|
108 |
+
* @param string $language
|
109 |
+
* @param string $eMandateId
|
110 |
+
* @param string $eMandateReason
|
111 |
+
* @param string $debtorReference
|
112 |
+
* @param string $debtorBankId
|
113 |
+
* @param string $purchaseId
|
114 |
+
* @param string $sequenceType
|
115 |
+
* @param string $originalIBAN
|
116 |
+
* @param string $originalDebtorBankId
|
117 |
+
* @param string $messageId - optional
|
118 |
+
* @param string $maxAmount - optional
|
119 |
+
* @param DateInterval $expirationPeriod - optional
|
120 |
+
*/
|
121 |
+
public function __construct(
|
122 |
+
$entranceCode, $language, $eMandateId, $eMandateReason, $debtorReference, $debtorBankId, $purchaseId, $sequenceType, $originalIBAN, $originalDebtorBankId, $messageId = '', $maxAmount = '', $expirationPeriod = null) {
|
123 |
+
|
124 |
+
/* setting the required fields */
|
125 |
+
$this->EntranceCode = $entranceCode;
|
126 |
+
$this->Language = $language;
|
127 |
+
$this->eMandateId = $eMandateId;
|
128 |
+
$this->eMandateReason = $eMandateReason;
|
129 |
+
$this->DebtorReference = $debtorReference;
|
130 |
+
$this->DebtorBankId = $debtorBankId;
|
131 |
+
$this->PurchaseId = $purchaseId;
|
132 |
+
$this->SequenceType = $sequenceType;
|
133 |
+
$this->OriginalIBAN = $originalIBAN;
|
134 |
+
$this->OriginalDebtorBankId = $originalDebtorBankId;
|
135 |
+
$this->MessageId = $messageId;
|
136 |
+
|
137 |
+
/* setting the optional fields */
|
138 |
+
$this->MaxAmount = str_replace(',', '.', $maxAmount);
|
139 |
+
$this->ExpirationPeriod = $expirationPeriod;
|
140 |
+
|
141 |
+
if (empty($this->MessageId)) {
|
142 |
+
$this->MessageId = MessageIdGenerator::NewMessageId();
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Serializes the object into a Document
|
148 |
+
*
|
149 |
+
* @param string $LocalInstrumentCode
|
150 |
+
* @return DOMElement
|
151 |
+
*/
|
152 |
+
public function toXml($LocalInstrumentCode) {
|
153 |
+
$this->logger->Log("building eMandate");
|
154 |
+
$this->validateExpirationPeriodAndMaxAmount();
|
155 |
+
|
156 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
157 |
+
|
158 |
+
/* create the Document element with it's namespaces */
|
159 |
+
$Document = $domtree->createElement('Document');
|
160 |
+
$Document->setAttribute('xmlns', self::XMLNS);
|
161 |
+
$Document->setAttribute('xmlns:xsd', self::XSD);
|
162 |
+
$Document->setAttribute('xmlns:xsi', self::XSI); {
|
163 |
+
/* create the MndtAmdmntReq element */
|
164 |
+
$MndtAmdmntReq = $domtree->createElement('MndtAmdmntReq'); {
|
165 |
+
/* create the GrpHdr element */
|
166 |
+
$GrpHdr = $domtree->createElement('GrpHdr'); {
|
167 |
+
$GrpHdr->appendChild(new DOMElement('MsgId', $this->MessageId));
|
168 |
+
$GrpHdr->appendChild(new DOMElement('CreDtTm', date('Y-m-d\TH:i:s'.substr((string)microtime(), 1, 4).'\Z')));
|
169 |
+
}
|
170 |
+
$MndtAmdmntReq->appendChild($GrpHdr);
|
171 |
+
|
172 |
+
/* create the UndrlygAmdmntDtls element */
|
173 |
+
$UndrlygAmdmntDtls = $domtree->createElement('UndrlygAmdmntDtls'); {
|
174 |
+
/* create the AmdmntRsn element */
|
175 |
+
$AmdmntRsn = $domtree->createElement('AmdmntRsn'); {
|
176 |
+
/* create the Rsn element */
|
177 |
+
$Rsn = $domtree->createElement('Rsn');
|
178 |
+
$Rsn->appendChild(new DOMElement('Cd', self::MD16));
|
179 |
+
$AmdmntRsn->appendChild($Rsn);
|
180 |
+
}
|
181 |
+
$UndrlygAmdmntDtls->appendChild($AmdmntRsn);
|
182 |
+
|
183 |
+
/* create the Mndt element */
|
184 |
+
$Mndt = $domtree->createElement('Mndt'); {
|
185 |
+
/* create the MndtId element */
|
186 |
+
$Mndt->appendChild($domtree->createElement('MndtId', $this->eMandateId));
|
187 |
+
|
188 |
+
/* create the MndtReqId element */
|
189 |
+
$Mndt->appendChild($domtree->createElement('MndtReqId', self::NOT_PROVIDED));
|
190 |
+
|
191 |
+
/* create Tp element */
|
192 |
+
$Tp = $domtree->createElement('Tp'); {
|
193 |
+
/* create SvcLvl element */
|
194 |
+
$SvcLvl = $domtree->createElement('SvcLvl');
|
195 |
+
$SvcLvl->appendChild(new DOMElement('Cd', self::SEPA));
|
196 |
+
$Tp->appendChild($SvcLvl);
|
197 |
+
|
198 |
+
/* create LclInstrm element */
|
199 |
+
$LclInstrm = $domtree->createElement('LclInstrm');
|
200 |
+
$LclInstrm->appendChild(new DOMElement('Cd', $LocalInstrumentCode));
|
201 |
+
$Tp->appendChild($LclInstrm);
|
202 |
+
}
|
203 |
+
$Mndt->appendChild($Tp);
|
204 |
+
|
205 |
+
/* create Ocrncs element */
|
206 |
+
$Ocrncs = $domtree->createElement('Ocrncs');
|
207 |
+
$Ocrncs->appendChild(new DOMElement('SeqTp', $this->SequenceType));
|
208 |
+
$Mndt->appendChild($Ocrncs);
|
209 |
+
|
210 |
+
/* create MaxAmt element */
|
211 |
+
if (!empty($this->MaxAmount) && $LocalInstrumentCode == B2BCommunicator::LOCAL_INSTRUMENT) {
|
212 |
+
$MaxAmt = $domtree->createElement('MaxAmt', $this->MaxAmount);
|
213 |
+
$MaxAmt->setAttribute('Ccy', self::CCY);
|
214 |
+
$Mndt->appendChild($MaxAmt);
|
215 |
+
}
|
216 |
+
|
217 |
+
/* create Rsn element */
|
218 |
+
if (!empty($this->eMandateReason)) {
|
219 |
+
$Rsn1 = $domtree->createElement('Rsn');
|
220 |
+
$Rsn1->appendChild(new DOMElement('Prtry', $this->eMandateReason));
|
221 |
+
$Mndt->appendChild($Rsn1);
|
222 |
+
}
|
223 |
+
|
224 |
+
/* create Cdtr element */
|
225 |
+
$Mndt->appendChild(new DOMElement('Cdtr'));
|
226 |
+
|
227 |
+
/* create Dbtr element */
|
228 |
+
$Dbtr = $domtree->createElement('Dbtr'); {
|
229 |
+
if (!empty($this->DebtorReference)) {
|
230 |
+
$Id = $domtree->createElement('Id'); {
|
231 |
+
$PrvtId = $domtree->createElement('PrvtId'); {
|
232 |
+
$Othr = $domtree->createElement('Othr');
|
233 |
+
$Othr->appendChild(new DOMElement('Id', $this->DebtorReference));
|
234 |
+
$PrvtId->appendChild($Othr);
|
235 |
+
}
|
236 |
+
}
|
237 |
+
$Id->appendChild($PrvtId);
|
238 |
+
$Dbtr->appendChild($Id);
|
239 |
+
}
|
240 |
+
}
|
241 |
+
$Mndt->appendChild($Dbtr);
|
242 |
+
|
243 |
+
/* create the DbtrAgt element */
|
244 |
+
$DbtrAgt = $domtree->createElement('DbtrAgt'); {
|
245 |
+
$FinInstnId = $domtree->createElement('FinInstnId');
|
246 |
+
$FinInstnId->appendChild(new DOMElement('BICFI', $this->DebtorBankId));
|
247 |
+
$DbtrAgt->appendChild($FinInstnId);
|
248 |
+
}
|
249 |
+
$Mndt->appendChild($DbtrAgt);
|
250 |
+
|
251 |
+
/* create the RfrdDoc element */
|
252 |
+
if (!empty($this->PurchaseId)) {
|
253 |
+
$RfrdDoc = $domtree->createElement('RfrdDoc'); {
|
254 |
+
$Tp = $domtree->createElement('Tp'); {
|
255 |
+
$CdOrPrtry = $domtree->createElement('CdOrPrtry');
|
256 |
+
$CdOrPrtry->appendChild(new DOMElement('Prtry', $this->PurchaseId));
|
257 |
+
$Tp->appendChild($CdOrPrtry);
|
258 |
+
}
|
259 |
+
$RfrdDoc->appendChild($Tp);
|
260 |
+
}
|
261 |
+
$Mndt->appendChild($RfrdDoc);
|
262 |
+
}
|
263 |
+
}
|
264 |
+
$UndrlygAmdmntDtls->appendChild($Mndt);
|
265 |
+
|
266 |
+
/* create the OrgnlMndt element */
|
267 |
+
$OrgnlMndt1 = $domtree->createElement('OrgnlMndt');
|
268 |
+
$OrgnlMndt = $domtree->createElement('OrgnlMndt'); {
|
269 |
+
/* create the MndtId element */
|
270 |
+
$OrgnlMndt->appendChild($domtree->createElement('MndtId', $this->eMandateId));
|
271 |
+
|
272 |
+
/* create Cdtr element */
|
273 |
+
$OrgnlMndt->appendChild(new DOMElement('Cdtr'));
|
274 |
+
|
275 |
+
/* create Dbtr element */
|
276 |
+
$Dbtr = $domtree->createElement('Dbtr');
|
277 |
+
$OrgnlMndt->appendChild($Dbtr);
|
278 |
+
|
279 |
+
/* create DbtrAcct element */
|
280 |
+
$DbtrAcct = $domtree->createElement('DbtrAcct'); {
|
281 |
+
$Id = $domtree->createElement('Id');
|
282 |
+
$Id->appendChild(new DOMElement('IBAN', $this->OriginalIBAN));
|
283 |
+
$DbtrAcct->appendChild($Id);
|
284 |
+
}
|
285 |
+
$OrgnlMndt->appendChild($DbtrAcct);
|
286 |
+
|
287 |
+
/* create the DbtrAgt element */
|
288 |
+
$DbtrAgt = $domtree->createElement('DbtrAgt'); {
|
289 |
+
$FinInstnId = $domtree->createElement('FinInstnId');
|
290 |
+
$FinInstnId->appendChild(new DOMElement('BICFI', $this->OriginalDebtorBankId));
|
291 |
+
$DbtrAgt->appendChild($FinInstnId);
|
292 |
+
}
|
293 |
+
$OrgnlMndt->appendChild($DbtrAgt);
|
294 |
+
}
|
295 |
+
$OrgnlMndt1->appendChild($OrgnlMndt);
|
296 |
+
$UndrlygAmdmntDtls->appendChild($OrgnlMndt1);
|
297 |
+
}
|
298 |
+
$MndtAmdmntReq->appendChild($UndrlygAmdmntDtls);
|
299 |
+
}
|
300 |
+
$Document->appendChild($MndtAmdmntReq);
|
301 |
+
}
|
302 |
+
|
303 |
+
$domtree->appendChild($Document);
|
304 |
+
|
305 |
+
XmlValidator::isValidatXML($domtree->saveXML(), XmlValidator::SCHEMA_PAIN010, $this->logger);
|
306 |
+
|
307 |
+
return $Document;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Validates that the ExpirationPeriod is not greater than 7days
|
312 |
+
* and that the MaxAmount respects the standard
|
313 |
+
* @throws CommunicatorException
|
314 |
+
*/
|
315 |
+
private function validateExpirationPeriodAndMaxAmount(){
|
316 |
+
|
317 |
+
//EXPIRATION PERIOD
|
318 |
+
if(!empty($this->ExpirationPeriod)){
|
319 |
+
$max_future = new DateTime();
|
320 |
+
$max_future->add(new DateInterval('P7DT1S')); // max plus one second
|
321 |
+
|
322 |
+
$future = new DateTime();
|
323 |
+
$future->add($this->ExpirationPeriod);
|
324 |
+
|
325 |
+
$check_interval2 = $max_future->diff($future);
|
326 |
+
|
327 |
+
if($check_interval2->invert == 0){
|
328 |
+
throw new CommunicatorException('The Expiration Period should not be greater than 7 days!');
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
//MAX AMOUNT
|
333 |
+
if ($this->MaxAmount !== '' && !is_numeric($this->MaxAmount)) {
|
334 |
+
throw new CommunicatorException('The MaxAmount should be a number.');
|
335 |
+
}
|
336 |
+
|
337 |
+
if ($this->MaxAmount !== '' && (float) $this->MaxAmount == 0) {
|
338 |
+
throw new CommunicatorException('The MaxAmount cannot be 0.');
|
339 |
+
}
|
340 |
+
|
341 |
+
$tempMaxAmount = str_replace('.', '', $this->MaxAmount);
|
342 |
+
$pos = strpos($this->MaxAmount, '.');
|
343 |
+
$pos = ($pos !== false ? $pos : strlen($this->MaxAmount));
|
344 |
+
|
345 |
+
$decimals = substr($this->MaxAmount, $pos + 1);
|
346 |
+
if (!empty($this->MaxAmount) && (strlen($tempMaxAmount) > 11 || strlen($decimals) > 2)) {
|
347 |
+
throw new CommunicatorException('The MaxAmount should have maximum 2 decimals and the total number of digits should be maximum 11.');
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
}
|
lib/Communicator/Entities/AmendmentResponse.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents an amendment response
|
5 |
+
*/
|
6 |
+
class AmendmentResponse {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* true if an error occurred, or false when no errors were encountered
|
10 |
+
* @var bool
|
11 |
+
*/
|
12 |
+
public $IsError = false;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Object that holds the error if one occurs; when there are no errors, this is set to null
|
16 |
+
* @var ErrorResponse
|
17 |
+
*/
|
18 |
+
public $Error = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The URL to which to redirect the creditor so they can authorize the transaction
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
public $IssuerAuthenticationUrl = null;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* The transaction ID
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $TransactionId = null;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* DateTime set to when this transaction was created
|
34 |
+
* @var DateTime
|
35 |
+
*/
|
36 |
+
public $TransactionCreateDateTimestamp;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* The response XML
|
40 |
+
*
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
public $RawMessage;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Deserializes the xml provided into an AmendmentResponse
|
47 |
+
*
|
48 |
+
* @param string $xml
|
49 |
+
* @throws CommunicatorException
|
50 |
+
*/
|
51 |
+
public function __construct($xml, $response_xml = false) {
|
52 |
+
$this->RawMessage = (!empty($response_xml) || $response_xml === '' ? $response_xml : $xml);
|
53 |
+
$data = XmlUtility::parse($xml);
|
54 |
+
|
55 |
+
if ($data->getName() == 'AcquirerErrorRes' || $data->getName() == 'Exception') {
|
56 |
+
$this->_buildAcquirerErrorRes($data);
|
57 |
+
} else if ($data->getName() != 'AcquirerTrxRes') {
|
58 |
+
throw new CommunicatorException($data->getName() . ' was not expected.');
|
59 |
+
} else {
|
60 |
+
$this->_buildAmendmentRes($data);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
private function _buildAcquirerErrorRes($data) {
|
65 |
+
$this->Error = new ErrorResponse($data);
|
66 |
+
$this->IsError = true;
|
67 |
+
$this->TransactionCreateDateTimestamp = new DateTime((string) $data->createDateTimestamp);
|
68 |
+
}
|
69 |
+
|
70 |
+
private function _buildAmendmentRes($data) {
|
71 |
+
$this->IssuerAuthenticationUrl = (string) $data->Issuer->issuerAuthenticationURL;
|
72 |
+
$this->TransactionId = (string) $data->Transaction->transactionID;
|
73 |
+
|
74 |
+
$this->TransactionCreateDateTimestamp = new DateTime((string) $data->Transaction->transactionCreateDateTimestamp);
|
75 |
+
}
|
76 |
+
}
|
lib/Communicator/Entities/CancellationRequest.php
ADDED
@@ -0,0 +1,318 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Describes a cancellation request
|
5 |
+
*/
|
6 |
+
class CancellationRequest {
|
7 |
+
|
8 |
+
const XMLNS = "urn:iso:std:iso:20022:tech:xsd:pain.011.001.04";
|
9 |
+
const XSD = "http://www.w3.org/2001/XMLSchema";
|
10 |
+
const XSI = "http://www.w3.org/2001/XMLSchema-instance";
|
11 |
+
const NOT_PROVIDED = 'NOTPROVIDED';
|
12 |
+
const SEPA = 'SEPA';
|
13 |
+
const MD16 = 'MD16';
|
14 |
+
const CCY = 'EUR';
|
15 |
+
|
16 |
+
/**
|
17 |
+
* An 'authentication identifier' to facilitate continuation of the session between creditor and debtor, even
|
18 |
+
* if the existing session has been lost. It enables the creditor to recognise the debtor associated with a (completed) transaction.
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
public $EntranceCode;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* This field enables the debtor bank's site to select the debtor's preferred language (e.g. the language selected on the creditor's site),
|
25 |
+
* if the debtor bank's site supports this: Dutch = 'nl', English = 'en'
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
public $Language;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Optional: The period of validity of the transaction request as stated by the creditor measured from the receipt by the debtor bank.
|
32 |
+
* The debtor must authorise the transaction within this period.
|
33 |
+
* @var DateInterval
|
34 |
+
*/
|
35 |
+
public $ExpirationPeriod;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* BIC of the Debtor Bank
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public $DebtorBankId;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Message ID for pain message
|
45 |
+
* @var string
|
46 |
+
*/
|
47 |
+
public $MessageId;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* ID that identifies the mandate and is issued by the creditor
|
51 |
+
* @var string
|
52 |
+
*/
|
53 |
+
public $eMandateId;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Indicates type of eMandate: one-off or sequenceType direct debit.
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
public $SequenceType;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Reason of the mandate
|
63 |
+
* @var string
|
64 |
+
*/
|
65 |
+
public $eMandateReason;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Reference ID that identifies the debtor to creditor, which is issued by the creditor
|
69 |
+
* @var string
|
70 |
+
*/
|
71 |
+
public $DebtorReference;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* A purchaseID that acts as a reference from eMandate to the purchase-order
|
75 |
+
* @var string
|
76 |
+
*/
|
77 |
+
public $PurchaseId;
|
78 |
+
|
79 |
+
/**
|
80 |
+
* IBAN of the original mandate
|
81 |
+
* @var string
|
82 |
+
*/
|
83 |
+
public $OriginalIBAN;
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Maximum amount. Not allowed for Core, optional for B2B.
|
87 |
+
* @var string
|
88 |
+
*/
|
89 |
+
public $MaxAmount;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* The object used to log internal messages and the xml files
|
93 |
+
*
|
94 |
+
* @var Logger
|
95 |
+
*/
|
96 |
+
public $logger;
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Constructor that highlights all required fields for this object; use this one to specify your own messageId
|
100 |
+
*
|
101 |
+
* @param string $entranceCode
|
102 |
+
* @param string $language
|
103 |
+
* @param string $eMandateId
|
104 |
+
* @param string $eMandateReason
|
105 |
+
* @param string $debtorReference
|
106 |
+
* @param string $debtorBankId
|
107 |
+
* @param string $purchaseId
|
108 |
+
* @param string $sequenceType
|
109 |
+
* @param string $originalIBAN
|
110 |
+
* @param string $messageId - optional
|
111 |
+
* @param string $maxAmount - optional
|
112 |
+
* @param DateInterval $expirationPeriod - optional
|
113 |
+
*/
|
114 |
+
public function __construct($entranceCode, $language, $eMandateId, $eMandateReason, $debtorReference, $debtorBankId, $purchaseId, $sequenceType, $originalIBAN, $messageId = '', $maxAmount = '', $expirationPeriod = null) {
|
115 |
+
|
116 |
+
$this->EntranceCode = $entranceCode;
|
117 |
+
$this->Language = $language;
|
118 |
+
$this->eMandateId = $eMandateId;
|
119 |
+
$this->eMandateReason = $eMandateReason;
|
120 |
+
$this->DebtorReference = $debtorReference;
|
121 |
+
$this->DebtorBankId = $debtorBankId;
|
122 |
+
$this->PurchaseId = $purchaseId;
|
123 |
+
$this->SequenceType = $sequenceType;
|
124 |
+
$this->OriginalIBAN = $originalIBAN;
|
125 |
+
$this->MessageId = $messageId;
|
126 |
+
|
127 |
+
/* setting the optional fields */
|
128 |
+
$this->MaxAmount = str_replace(',', '.', $maxAmount);
|
129 |
+
$this->ExpirationPeriod = $expirationPeriod;
|
130 |
+
|
131 |
+
if (empty($this->MessageId)) {
|
132 |
+
$this->MessageId = MessageIdGenerator::NewMessageId();
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Serializes the object into a Document
|
138 |
+
*
|
139 |
+
* @param string $LocalInstrumentCode
|
140 |
+
* @return DOMElement
|
141 |
+
*/
|
142 |
+
public function toXml($LocalInstrumentCode) {
|
143 |
+
$this->logger->Log("building eMandate");
|
144 |
+
$this->validateExpirationPeriodAndMaxAmount();
|
145 |
+
|
146 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
147 |
+
|
148 |
+
/* create the Document element with it's namespaces */
|
149 |
+
$Document = $domtree->createElement('Document');
|
150 |
+
$Document->setAttribute('xmlns', self::XMLNS);
|
151 |
+
$Document->setAttribute('xmlns:xsd', self::XSD);
|
152 |
+
$Document->setAttribute('xmlns:xsi', self::XSI); {
|
153 |
+
/* create the MndtCxlReq element */
|
154 |
+
$MndtCxlReq = $domtree->createElement('MndtCxlReq'); {
|
155 |
+
/* create the GrpHdr element */
|
156 |
+
$GrpHdr = $domtree->createElement('GrpHdr'); {
|
157 |
+
$GrpHdr->appendChild(new DOMElement('MsgId', $this->MessageId));
|
158 |
+
$GrpHdr->appendChild(new DOMElement('CreDtTm', date('Y-m-d\TH:i:s'.substr((string)microtime(), 1, 4).'\Z')));
|
159 |
+
}
|
160 |
+
$MndtCxlReq->appendChild($GrpHdr);
|
161 |
+
|
162 |
+
/* create the UndrlygCxlDtls element */
|
163 |
+
$UndrlygCxlDtls = $domtree->createElement('UndrlygCxlDtls'); {
|
164 |
+
/* create the CxlRsn element */
|
165 |
+
$CxlRsn = $domtree->createElement('CxlRsn'); {
|
166 |
+
/* create the Rsn element */
|
167 |
+
$Rsn = $domtree->createElement('Rsn');
|
168 |
+
$Rsn->appendChild(new DOMElement('Cd', self::MD16));
|
169 |
+
$CxlRsn->appendChild($Rsn);
|
170 |
+
}
|
171 |
+
$UndrlygCxlDtls->appendChild($CxlRsn);
|
172 |
+
|
173 |
+
/* create the OrgnlMndt element */
|
174 |
+
$OrgnlMndt1 = $domtree->createElement('OrgnlMndt');
|
175 |
+
$OrgnlMndt = $domtree->createElement('OrgnlMndt'); {
|
176 |
+
/* create the MndtId element */
|
177 |
+
$OrgnlMndt->appendChild($domtree->createElement('MndtId', $this->eMandateId));
|
178 |
+
|
179 |
+
/* create the MndtReqId element */
|
180 |
+
$OrgnlMndt->appendChild($domtree->createElement('MndtReqId', self::NOT_PROVIDED));
|
181 |
+
|
182 |
+
/* create Tp element */
|
183 |
+
$Tp = $domtree->createElement('Tp'); {
|
184 |
+
/* create SvcLvl element */
|
185 |
+
$SvcLvl = $domtree->createElement('SvcLvl');
|
186 |
+
$SvcLvl->appendChild(new DOMElement('Cd', self::SEPA));
|
187 |
+
$Tp->appendChild($SvcLvl);
|
188 |
+
|
189 |
+
/* create LclInstrm element */
|
190 |
+
$LclInstrm = $domtree->createElement('LclInstrm');
|
191 |
+
$LclInstrm->appendChild(new DOMElement('Cd', $LocalInstrumentCode));
|
192 |
+
$Tp->appendChild($LclInstrm);
|
193 |
+
}
|
194 |
+
$OrgnlMndt->appendChild($Tp);
|
195 |
+
|
196 |
+
/* create Ocrncs element */
|
197 |
+
$Ocrncs = $domtree->createElement('Ocrncs');
|
198 |
+
$Ocrncs->appendChild(new DOMElement('SeqTp', $this->SequenceType));
|
199 |
+
$OrgnlMndt->appendChild($Ocrncs);
|
200 |
+
|
201 |
+
/* create MaxAmt element */
|
202 |
+
if (!empty($this->MaxAmount) && $LocalInstrumentCode == B2BCommunicator::LOCAL_INSTRUMENT) {
|
203 |
+
$MaxAmt = $domtree->createElement('MaxAmt', $this->MaxAmount);
|
204 |
+
$MaxAmt->setAttribute('Ccy', self::CCY);
|
205 |
+
$OrgnlMndt->appendChild($MaxAmt);
|
206 |
+
}
|
207 |
+
/* create Rsn element */
|
208 |
+
if (!empty($this->eMandateReason)) {
|
209 |
+
$Rsn1 = $domtree->createElement('Rsn');
|
210 |
+
$Rsn1->appendChild(new DOMElement('Prtry', $this->eMandateReason));
|
211 |
+
$OrgnlMndt->appendChild($Rsn1);
|
212 |
+
}
|
213 |
+
|
214 |
+
/* create Cdtr element */
|
215 |
+
$OrgnlMndt->appendChild(new DOMElement('Cdtr'));
|
216 |
+
|
217 |
+
/* create Dbtr element */
|
218 |
+
$Dbtr = $domtree->createElement('Dbtr'); {
|
219 |
+
if (!empty($this->DebtorReference)) {
|
220 |
+
$Id = $domtree->createElement('Id'); {
|
221 |
+
$PrvtId = $domtree->createElement('PrvtId'); {
|
222 |
+
$Othr = $domtree->createElement('Othr');
|
223 |
+
$Othr->appendChild(new DOMElement('Id', $this->DebtorReference));
|
224 |
+
$PrvtId->appendChild($Othr);
|
225 |
+
}
|
226 |
+
}
|
227 |
+
$Id->appendChild($PrvtId);
|
228 |
+
$Dbtr->appendChild($Id);
|
229 |
+
}
|
230 |
+
}
|
231 |
+
$OrgnlMndt->appendChild($Dbtr);
|
232 |
+
|
233 |
+
/* create DbtrAcct element */
|
234 |
+
$DbtrAcct = $domtree->createElement('DbtrAcct'); {
|
235 |
+
$Id = $domtree->createElement('Id');
|
236 |
+
$Id->appendChild(new DOMElement('IBAN', $this->OriginalIBAN));
|
237 |
+
$DbtrAcct->appendChild($Id);
|
238 |
+
}
|
239 |
+
$OrgnlMndt->appendChild($DbtrAcct);
|
240 |
+
|
241 |
+
/* create the DbtrAgt element */
|
242 |
+
$DbtrAgt = $domtree->createElement('DbtrAgt'); {
|
243 |
+
$FinInstnId = $domtree->createElement('FinInstnId');
|
244 |
+
$FinInstnId->appendChild(new DOMElement('BICFI', $this->DebtorBankId));
|
245 |
+
$DbtrAgt->appendChild($FinInstnId);
|
246 |
+
}
|
247 |
+
$OrgnlMndt->appendChild($DbtrAgt);
|
248 |
+
|
249 |
+
/* create the RfrdDoc element */
|
250 |
+
if (!empty($this->PurchaseId)) {
|
251 |
+
$RfrdDoc = $domtree->createElement('RfrdDoc'); {
|
252 |
+
$Tp = $domtree->createElement('Tp'); {
|
253 |
+
$CdOrPrtry = $domtree->createElement('CdOrPrtry');
|
254 |
+
$CdOrPrtry->appendChild(new DOMElement('Prtry', $this->PurchaseId));
|
255 |
+
$Tp->appendChild($CdOrPrtry);
|
256 |
+
}
|
257 |
+
$RfrdDoc->appendChild($Tp);
|
258 |
+
}
|
259 |
+
$OrgnlMndt->appendChild($RfrdDoc);
|
260 |
+
}
|
261 |
+
}
|
262 |
+
$OrgnlMndt1->appendChild($OrgnlMndt);
|
263 |
+
$UndrlygCxlDtls->appendChild($OrgnlMndt1);
|
264 |
+
}
|
265 |
+
$MndtCxlReq->appendChild($UndrlygCxlDtls);
|
266 |
+
}
|
267 |
+
$Document->appendChild($MndtCxlReq);
|
268 |
+
}
|
269 |
+
|
270 |
+
$domtree->appendChild($Document);
|
271 |
+
|
272 |
+
XmlValidator::isValidatXML($domtree->saveXML(), XmlValidator::SCHEMA_PAIN011, $this->logger);
|
273 |
+
|
274 |
+
return $Document;
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Validates that the ExpirationPeriod is not greater than 7days
|
279 |
+
* and that the MaxAmount respects the standard
|
280 |
+
* @throws CommunicatorException
|
281 |
+
*/
|
282 |
+
private function validateExpirationPeriodAndMaxAmount(){
|
283 |
+
|
284 |
+
//EXPIRATION PERIOD
|
285 |
+
if(!empty($this->ExpirationPeriod)){
|
286 |
+
$max_future = new DateTime();
|
287 |
+
$max_future->add(new DateInterval('P7DT1S')); // max plus one second
|
288 |
+
|
289 |
+
$future = new DateTime();
|
290 |
+
$future->add($this->ExpirationPeriod);
|
291 |
+
|
292 |
+
$check_interval2 = $max_future->diff($future);
|
293 |
+
|
294 |
+
if($check_interval2->invert == 0){
|
295 |
+
throw new CommunicatorException('The Expiration Period should not be greater than 7 days!');
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
//MAX AMOUNT
|
300 |
+
if ($this->MaxAmount !== '' && !is_numeric($this->MaxAmount)) {
|
301 |
+
throw new CommunicatorException('The MaxAmount should be a number.');
|
302 |
+
}
|
303 |
+
|
304 |
+
if ($this->MaxAmount !== '' && (float) $this->MaxAmount == 0) {
|
305 |
+
throw new CommunicatorException('The MaxAmount cannot be 0.');
|
306 |
+
}
|
307 |
+
|
308 |
+
$tempMaxAmount = str_replace('.', '', $this->MaxAmount);
|
309 |
+
$pos = strpos($this->MaxAmount, '.');
|
310 |
+
$pos = ($pos !== false ? $pos : strlen($this->MaxAmount));
|
311 |
+
|
312 |
+
$decimals = substr($this->MaxAmount, $pos + 1);
|
313 |
+
if (!empty($this->MaxAmount) && (strlen($tempMaxAmount) > 11 || strlen($decimals) > 2)) {
|
314 |
+
throw new CommunicatorException('The MaxAmount should have maximum 2 decimals and the total number of digits should be maximum 11.');
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
}
|
lib/Communicator/Entities/CancellationResponse.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Represents a cancellation response
|
5 |
+
*/
|
6 |
+
class CancellationResponse {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* true if an error occurred, or false when no errors were encountered
|
10 |
+
* @var bool
|
11 |
+
*/
|
12 |
+
public $IsError = false;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Object that holds the error if one occurs; when there are no errors, this is set to null
|
16 |
+
* @var ErrorResponse
|
17 |
+
*/
|
18 |
+
public $Error = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The URL to which to redirect the creditor so they can authorize the transaction
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
public $IssuerAuthenticationUrl = null;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* The transaction ID
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $TransactionId = null;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* DateTime set to when this transaction was created
|
34 |
+
* @var DateTime
|
35 |
+
*/
|
36 |
+
public $TransactionCreateDateTimestamp;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* The response XML
|
40 |
+
*
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
public $RawMessage;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Deserializes the xml into an CancellationResponse
|
47 |
+
*
|
48 |
+
* @param string $xml
|
49 |
+
* @throws CommunicatorException
|
50 |
+
*/
|
51 |
+
public function __construct($xml, $response_xml = false) {
|
52 |
+
$this->RawMessage = (!empty($response_xml) || $response_xml === '' ? $response_xml : $xml);
|
53 |
+
$data = XmlUtility::parse($xml);
|
54 |
+
|
55 |
+
if ($data->getName() == 'AcquirerErrorRes' || $data->getName() == 'Exception') {
|
56 |
+
$this->_buildAcquirerErrorRes($data);
|
57 |
+
} else if ($data->getName() != 'AcquirerTrxRes') {
|
58 |
+
throw new CommunicatorException($data->getName() . ' was not expected.');
|
59 |
+
} else {
|
60 |
+
$this->_buildCancellationRes($data);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
private function _buildAcquirerErrorRes($data) {
|
65 |
+
$this->Error = new ErrorResponse($data);
|
66 |
+
$this->IsError = true;
|
67 |
+
$this->TransactionCreateDateTimestamp = new DateTime((string) $data->createDateTimestamp);
|
68 |
+
}
|
69 |
+
|
70 |
+
private function _buildCancellationRes($data) {
|
71 |
+
$this->IssuerAuthenticationUrl = (string) $data->Issuer->issuerAuthenticationURL;
|
72 |
+
$this->TransactionId = (string) $data->Transaction->transactionID;
|
73 |
+
|
74 |
+
$this->TransactionCreateDateTimestamp = new DateTime((string) $data->Transaction->transactionCreateDateTimestamp);
|
75 |
+
}
|
76 |
+
}
|
lib/Communicator/Entities/DirectoryRequest.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Description of DirectoryRequest
|
5 |
+
*/
|
6 |
+
class DirectoryRequest {
|
7 |
+
const XMLNS = "http://www.betaalvereniging.nl/iDx/messages/Merchant-Acquirer/1.0.0";
|
8 |
+
const XSD = "http://www.w3.org/2001/XMLSchema";
|
9 |
+
const XSI = "http://www.w3.org/2001/XMLSchema-instance";
|
10 |
+
|
11 |
+
public $productID;
|
12 |
+
public $version;
|
13 |
+
public $dateTime;
|
14 |
+
public $merchant;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Constructor that highlights the required fields
|
18 |
+
*
|
19 |
+
* @param string $productID
|
20 |
+
* @param string $version
|
21 |
+
* @param Merchant $merchant
|
22 |
+
*/
|
23 |
+
public function __construct($productID, $version, Merchant $merchant) {
|
24 |
+
$this->productID = $productID;
|
25 |
+
$this->version = $version;
|
26 |
+
$this->dateTime = date('Y-m-d\TH:i:s'.substr((string)microtime(), 1, 4).'\Z');
|
27 |
+
$this->merchant = $merchant;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Serializes the object into a DirectoryReq
|
32 |
+
*
|
33 |
+
* @return \DOMDocument
|
34 |
+
*/
|
35 |
+
public function toXml() {
|
36 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
37 |
+
|
38 |
+
/* create the root element of the xml tree */
|
39 |
+
$DirectoryReq = $domtree->createElementNS(self::XMLNS, 'DirectoryReq');
|
40 |
+
$DirectoryReq->setAttribute('xmlns:xsd', self::XSD);
|
41 |
+
$DirectoryReq->setAttribute('xmlns:xsi', self::XSI);
|
42 |
+
|
43 |
+
$DirectoryReq->setAttribute('productID', $this->productID);
|
44 |
+
$DirectoryReq->setAttribute('version', $this->version);
|
45 |
+
$domtree->appendChild($DirectoryReq);
|
46 |
+
|
47 |
+
/* create the timetamp */
|
48 |
+
$createDateTimestamp = $domtree->createElement('createDateTimestamp', $this->dateTime);
|
49 |
+
$DirectoryReq->appendChild($createDateTimestamp);
|
50 |
+
|
51 |
+
/* create the merchant element and it's sub elements */
|
52 |
+
$Merchant = $domtree->createElement('Merchant');
|
53 |
+
$Merchant->appendChild($domtree->createElement('merchantID', $this->merchant->merchantID));
|
54 |
+
$Merchant->appendChild($domtree->createElement('subID', $this->merchant->merchantSubID));
|
55 |
+
$DirectoryReq->appendChild($Merchant);
|
56 |
+
//-----[END] Build the XML
|
57 |
+
|
58 |
+
return $domtree;
|
59 |
+
}
|
60 |
+
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Description of Merchant
|
65 |
+
*/
|
66 |
+
class Merchant {
|
67 |
+
|
68 |
+
public $merchantID;
|
69 |
+
public $merchantSubID;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Constructor that highlights the required fields
|
73 |
+
*
|
74 |
+
* @param string $merchantID
|
75 |
+
* @param string $merchantSubID
|
76 |
+
*/
|
77 |
+
public function __construct($merchantID, $merchantSubID) {
|
78 |
+
$this->merchantID = $merchantID;
|
79 |
+
$this->merchantSubID = $merchantSubID;
|
80 |
+
}
|
81 |
+
|
82 |
+
}
|
lib/Communicator/Entities/DirectoryResponse.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once dirname(__FILE__) . "./ErrorResponse.php";
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Description of DebtorBank
|
7 |
+
*/
|
8 |
+
class DebtorBank {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Country name
|
12 |
+
* @var string
|
13 |
+
*/
|
14 |
+
public $DebtorBankCountry;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* BIC
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
public $DebtorBankId;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Bank name
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $DebtorBankName;
|
27 |
+
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Describes a directory response
|
32 |
+
*/
|
33 |
+
class DirectoryResponse {
|
34 |
+
|
35 |
+
/**
|
36 |
+
* true if an error occurred, or false when no errors were encountered
|
37 |
+
* @var bool
|
38 |
+
*/
|
39 |
+
public $IsError = false;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Object that holds the error if one occurs; when there are no errors, this is set to null
|
43 |
+
* @var ErrorResponse
|
44 |
+
*/
|
45 |
+
public $Error = null;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* DateTime set to when this directory was last updated
|
49 |
+
* @var DateTime
|
50 |
+
*/
|
51 |
+
public $DirectoryDateTimestamp;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* List of available debtor banks *
|
55 |
+
* @var array
|
56 |
+
*/
|
57 |
+
public $DebtorBanks = array();
|
58 |
+
|
59 |
+
/**
|
60 |
+
* The response XML
|
61 |
+
*
|
62 |
+
* @var string
|
63 |
+
*/
|
64 |
+
public $RawMessage;
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Deserializes the xml into a DirectoryRes
|
68 |
+
*
|
69 |
+
* @param string $xml
|
70 |
+
* @throws CommunicatorException
|
71 |
+
*/
|
72 |
+
public function __construct($xml, $response_xml = false) {
|
73 |
+
$this->RawMessage = (!empty($response_xml) || $response_xml === '' ? $response_xml : $xml);
|
74 |
+
$data = XmlUtility::parse($xml);
|
75 |
+
|
76 |
+
if ($data->getName() == 'AcquirerErrorRes' || $data->getName() == 'Exception') {
|
77 |
+
$this->_buildAcquirerErrorRes($data);
|
78 |
+
} else if ($data->getName() != 'DirectoryRes') {
|
79 |
+
throw new CommunicatorException($data->getName() . ' was not expected.');
|
80 |
+
} else {
|
81 |
+
$this->_buildDirectoryRes($data);
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
private function _buildAcquirerErrorRes($data) {
|
86 |
+
$this->Error = new ErrorResponse($data);
|
87 |
+
$this->IsError = true;
|
88 |
+
$this->DirectoryDateTimestamp = new DateTime((string) $data->createDateTimestamp);
|
89 |
+
$this->DebtorBanks = null;
|
90 |
+
}
|
91 |
+
|
92 |
+
private function _buildDirectoryRes($data) {
|
93 |
+
$this->DirectoryDateTimestamp = new DateTime((string) $data->Directory->DirectoryDateTimestamp);
|
94 |
+
|
95 |
+
if (!empty($data->Directory->Country)) {
|
96 |
+
foreach ($data->Directory->Country as $countryElem) {
|
97 |
+
if (!empty($countryElem->Issuer)) {
|
98 |
+
foreach ($countryElem->Issuer as $IssuerElem) {
|
99 |
+
$debtor = new DebtorBank();
|
100 |
+
$debtor->DebtorBankId = (string) $IssuerElem->issuerID;
|
101 |
+
$debtor->DebtorBankName = (string) $IssuerElem->issuerName;
|
102 |
+
|
103 |
+
$debtor->DebtorBankCountry = (string) $countryElem->countryNames;
|
104 |
+
|
105 |
+
$this->DebtorBanks[] = $debtor;
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
109 |
+
}
|
110 |
+
}
|
111 |
+
}
|
lib/Communicator/Entities/ErrorResponse.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Describes an error response
|
5 |
+
*/
|
6 |
+
class ErrorResponse {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Unique identification of the error occurring within the iDx transaction
|
10 |
+
* @var string
|
11 |
+
*/
|
12 |
+
public $ErrorCode;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Descriptive text accompanying Error.errorCode
|
16 |
+
* @var string
|
17 |
+
*/
|
18 |
+
public $ErrorMessage;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Details of the error
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
public $ErrorDetails;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Suggestions aimed at resolving the problem
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $SuggestedAction;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* A (standardised) message that the merchant should show to the consumer
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public $ConsumerMessage;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Builds an ErrorResponse from the errRes received
|
40 |
+
*
|
41 |
+
* @param SimpleXMLElement $errRes
|
42 |
+
*/
|
43 |
+
public function __construct(SimpleXMLElement $errRes) {
|
44 |
+
|
45 |
+
$this->ErrorCode = (string) $errRes->Error->errorCode;
|
46 |
+
$this->ErrorMessage = (string) $errRes->Error->errorMessage;
|
47 |
+
$this->ErrorDetails = (string) $errRes->Error->errorDetail;
|
48 |
+
$this->SuggestedAction = (string) $errRes->Error->suggestedAction;
|
49 |
+
$this->ConsumerMessage = (string) $errRes->Error->consumerMessage;
|
50 |
+
}
|
51 |
+
|
52 |
+
}
|
lib/Communicator/Entities/NewMandateRequest.php
ADDED
@@ -0,0 +1,289 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Description of eMandate
|
5 |
+
*/
|
6 |
+
class NewMandateRequest {
|
7 |
+
|
8 |
+
const XMLNS = "urn:iso:std:iso:20022:tech:xsd:pain.009.001.04";
|
9 |
+
const XSD = "http://www.w3.org/2001/XMLSchema";
|
10 |
+
const XSI = "http://www.w3.org/2001/XMLSchema-instance";
|
11 |
+
const NOT_PROVIDED = 'NOTPROVIDED';
|
12 |
+
const SEPA = 'SEPA';
|
13 |
+
const CCY = 'EUR';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* An 'authentication identifier' to facilitate continuation of the session between creditor and debtor, even
|
17 |
+
* if the existing session has been lost. It enables the creditor to recognise the debtor associated with a (completed) transaction.
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
public $EntranceCode;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* This field enables the debtor bank's site to select the debtor's preferred language (e.g. the language selected on the creditor's site),
|
24 |
+
* if the debtor bank's site supports this: Dutch = 'nl', English = 'en'
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
public $Language;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Message ID for pain message
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
public $MessageId;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* ID that identifies the mandate and is issued by the creditor
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
public $eMandateId;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Reason of the mandate
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
public $eMandateReason;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Reference ID that identifies the debtor to creditor, which is issued by the creditor
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
public $DebtorReference;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* BIC of the Debtor Bank
|
55 |
+
* @var string
|
56 |
+
*/
|
57 |
+
public $DebtorBankId;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* A purchaseID that acts as a reference from eMandate to the purchase-order
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
public $PurchaseId;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Indicates type of eMandate: one-off or sequenceType direct debit.
|
67 |
+
* @var type
|
68 |
+
*/
|
69 |
+
public $SequenceType;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Optional: The period of validity of the transaction request as stated by the creditor measured from the receipt by the debtor bank.
|
73 |
+
* The debtor must authorise the transaction within this period.
|
74 |
+
* @var DateInterval
|
75 |
+
*/
|
76 |
+
public $ExpirationPeriod;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Maximum amount. Not allowed for Core, optional for B2B.
|
80 |
+
* @var string
|
81 |
+
*/
|
82 |
+
public $MaxAmount;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* The object used to log internal messages and the xml files
|
86 |
+
*
|
87 |
+
* @var Logger
|
88 |
+
*/
|
89 |
+
public $logger;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Constructor that highlights all required fields for this object
|
93 |
+
*
|
94 |
+
* @param string $entranceCode
|
95 |
+
* @param string $language
|
96 |
+
* @param string $messageId
|
97 |
+
* @param string $eMandateId
|
98 |
+
* @param string $eMandateReason
|
99 |
+
* @param string $debtorReference
|
100 |
+
* @param string $debtorBankId
|
101 |
+
* @param string $purchaseId
|
102 |
+
* @param string $sequenceType
|
103 |
+
* @param string $maxAmount - optional
|
104 |
+
* @param DateInterval $expirationPeriod - optional
|
105 |
+
*/
|
106 |
+
public function __construct($entranceCode, $language, $messageId, $eMandateId, $eMandateReason, $debtorReference, $debtorBankId, $purchaseId, $sequenceType, $maxAmount = '', $expirationPeriod = null) {
|
107 |
+
|
108 |
+
/* setting the required fields */
|
109 |
+
$this->EntranceCode = $entranceCode;
|
110 |
+
$this->Language = $language;
|
111 |
+
$this->MessageId = $messageId;
|
112 |
+
$this->eMandateId = $eMandateId;
|
113 |
+
$this->eMandateReason = $eMandateReason;
|
114 |
+
$this->DebtorReference = $debtorReference;
|
115 |
+
$this->DebtorBankId = $debtorBankId;
|
116 |
+
$this->PurchaseId = $purchaseId;
|
117 |
+
$this->SequenceType = $sequenceType;
|
118 |
+
|
119 |
+
/* setting the optional fields */
|
120 |
+
$this->MaxAmount = str_replace(',', '.', $maxAmount);
|
121 |
+
$this->ExpirationPeriod = $expirationPeriod;
|
122 |
+
|
123 |
+
if (empty($this->MessageId)) {
|
124 |
+
$this->MessageId = MessageIdGenerator::NewMessageId();
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Serializes the object into a Document
|
130 |
+
*
|
131 |
+
* @param string $LocalInstrumentCode
|
132 |
+
* @return DOMElement
|
133 |
+
*/
|
134 |
+
public function toXml($LocalInstrumentCode) {
|
135 |
+
$this->logger->Log("building eMandate");
|
136 |
+
$this->validateExpirationPeriodAndMaxAmount();
|
137 |
+
|
138 |
+
$domtree = new DOMDocument('1.0', 'UTF-8');
|
139 |
+
|
140 |
+
/* create the Document element with it's namespaces */
|
141 |
+
$Document = $domtree->createElement('Document');
|
142 |
+
$Document->setAttribute('xmlns', self::XMLNS);
|
143 |
+
$Document->setAttribute('xmlns:xsd', self::XSD);
|
144 |
+
$Document->setAttribute('xmlns:xsi', self::XSI); {
|
145 |
+
/* create the MndtInitnReq element */
|
146 |
+
$MndtInitnReq = $domtree->createElement('MndtInitnReq'); {
|
147 |
+
/* create the GrpHdr element */
|
148 |
+
$GrpHdr = $domtree->createElement('GrpHdr'); {
|
149 |
+
/* create the MsgId and the CreDtTm elements */
|
150 |
+
$GrpHdr->appendChild(new DOMElement('MsgId', $this->MessageId));
|
151 |
+
$GrpHdr->appendChild(new DOMElement('CreDtTm', date('Y-m-d\TH:i:s'.substr((string)microtime(), 1, 4).'\Z')));
|
152 |
+
}
|
153 |
+
$MndtInitnReq->appendChild($GrpHdr);
|
154 |
+
|
155 |
+
/* create the Mndt element */
|
156 |
+
$Mndt = $domtree->createElement('Mndt'); {
|
157 |
+
/* create MndtId elemnt */
|
158 |
+
$Mndt->appendChild(new DOMElement('MndtId', $this->eMandateId));
|
159 |
+
|
160 |
+
/* create MndtReqId element */
|
161 |
+
$Mndt->appendChild(new DOMElement('MndtReqId', self::NOT_PROVIDED));
|
162 |
+
|
163 |
+
/* create Tp element */
|
164 |
+
$Tp = $domtree->createElement('Tp'); {
|
165 |
+
/* create SvcLvl element */
|
166 |
+
$SvcLvl = $domtree->createElement('SvcLvl');
|
167 |
+
$SvcLvl->appendChild(new DOMElement('Cd', self::SEPA));
|
168 |
+
$Tp->appendChild($SvcLvl);
|
169 |
+
|
170 |
+
/* create LclInstrm element */
|
171 |
+
$LclInstrm = $domtree->createElement('LclInstrm');
|
172 |
+
$LclInstrm->appendChild(new DOMElement('Cd', $LocalInstrumentCode));
|
173 |
+
$Tp->appendChild($LclInstrm);
|
174 |
+
}
|
175 |
+
$Mndt->appendChild($Tp);
|
176 |
+
|
177 |
+
/* create Ocrncs element */
|
178 |
+
$Ocrncs = $domtree->createElement('Ocrncs');
|
179 |
+
$Ocrncs->appendChild(new DOMElement('SeqTp', $this->SequenceType));
|
180 |
+
$Mndt->appendChild($Ocrncs);
|
181 |
+
|
182 |
+
/* create MaxAmt element */
|
183 |
+
if (!empty($this->MaxAmount) && $LocalInstrumentCode == B2BCommunicator::LOCAL_INSTRUMENT) {
|
184 |
+
$MaxAmt = $domtree->createElement('MaxAmt', $this->MaxAmount);
|
185 |
+
$MaxAmt->setAttribute('Ccy', self::CCY);
|
186 |
+
$Mndt->appendChild($MaxAmt);
|
187 |
+
}
|
188 |
+
|
189 |
+
/* create Rsn element */
|
190 |
+
if (!empty($this->eMandateReason)) {
|
191 |
+
$Rsn = $domtree->createElement('Rsn');
|
192 |
+
$Rsn->appendChild(new DOMElement('Prtry', $this->eMandateReason));
|
193 |
+
$Mndt->appendChild($Rsn);
|
194 |
+
}
|
195 |
+
|
196 |
+
/* create Cdtr element */
|
197 |
+
$Mndt->appendChild(new DOMElement('Cdtr'));
|
198 |
+
|
199 |
+
/* create Dbtr element */
|
200 |
+
$Dbtr = $domtree->createElement('Dbtr'); {
|
201 |
+
if (!empty($this->DebtorReference)) {
|
202 |
+
$Id = $domtree->createElement('Id'); {
|
203 |
+
$PrvtId = $domtree->createElement('PrvtId'); {
|
204 |
+
$Othr = $domtree->createElement('Othr');
|
205 |
+
$Othr->appendChild(new DOMElement('Id', $this->DebtorReference));
|
206 |
+
$PrvtId->appendChild($Othr);
|
207 |
+
}
|
208 |
+
}
|
209 |
+
$Id->appendChild($PrvtId);
|
210 |
+
$Dbtr->appendChild($Id);
|
211 |
+
}
|
212 |
+
}
|
213 |
+
$Mndt->appendChild($Dbtr);
|
214 |
+
|
215 |
+
/* create DbtrAgt element */
|
216 |
+
$DbtrAgt = $domtree->createElement('DbtrAgt'); {
|
217 |
+
$FinInstnId = $domtree->createElement('FinInstnId');
|
218 |
+
$FinInstnId->appendChild(new DOMElement('BICFI', $this->DebtorBankId));
|
219 |
+
$DbtrAgt->appendChild($FinInstnId);
|
220 |
+
}
|
221 |
+
$Mndt->appendChild($DbtrAgt);
|
222 |
+
|
223 |
+
/* create RfrdDoc element */
|
224 |
+
if (!empty($this->PurchaseId)) {
|
225 |
+
$RfrdDoc = $domtree->createElement('RfrdDoc'); {
|
226 |
+
$Tp = $domtree->createElement('Tp'); {
|
227 |
+
$CdOrPrtry = $domtree->createElement('CdOrPrtry');
|
228 |
+
$CdOrPrtry->appendChild(new DOMElement('Prtry', $this->PurchaseId));
|
229 |
+
$Tp->appendChild($CdOrPrtry);
|
230 |
+
}
|
231 |
+
$RfrdDoc->appendChild($Tp);
|
232 |
+
}
|
233 |
+
$Mndt->appendChild($RfrdDoc);
|
234 |
+
}
|
235 |
+
}
|
236 |
+
$MndtInitnReq->appendChild($Mndt);
|
237 |
+
}
|
238 |
+
$Document->appendChild($MndtInitnReq);
|
239 |
+
}
|
240 |
+
|
241 |
+
$domtree->appendChild($Document);
|
242 |
+
|
243 |
+
XmlValidator::isValidatXML($domtree->saveXML(), XmlValidator::SCHEMA_PAIN009, $this->logger);
|
244 |
+
|
245 |
+
return $Document;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Validates that the ExpirationPeriod is not greater than 7days
|
250 |
+
* and that the MaxAmount respects the standard
|
251 |
+
* @throws CommunicatorException
|
252 |
+
*/
|
253 |
+
private function validateExpirationPeriodAndMaxAmount(){
|
254 |
+
|
255 |
+
//EXPIRATION PERIOD
|
256 |
+
if(!empty($this->ExpirationPeriod)){
|
257 |
+
$max_future = new DateTime();
|
258 |
+
$max_future->add(new DateInterval('P7DT1S')); // max plus one second
|
259 |
+
|
260 |
+
$future = new DateTime();
|
261 |
+
$future->add($this->ExpirationPeriod);
|
262 |
+
|
263 |
+
$check_interval2 = $max_future->diff($future);
|
264 |
+
|
265 |
+
if($check_interval2->invert == 0){
|
266 |
+
throw new CommunicatorException('The Expiration Period should not be greater than 7 days!');
|
267 |
+
}
|
268 |
+
}
|
269 |
+
|
270 |
+
//MAX AMOUNT
|
271 |
+
if ($this->MaxAmount !== '' && !is_numeric($this->MaxAmount)) {
|
272 |
+
throw new CommunicatorException('The MaxAmount should be a number.');
|
273 |
+
}
|
274 |
+
|
275 |
+
if ($this->MaxAmount !== '' && (float) $this->MaxAmount == 0) {
|
276 |
+
throw new CommunicatorException('The MaxAmount cannot be 0.');
|
277 |
+
}
|
278 |
+
|
279 |
+
$tempMaxAmount = str_replace('.', '', $this->MaxAmount);
|
280 |
+
$pos = strpos($this->MaxAmount, '.');
|
281 |
+
$pos = ($pos !== false ? $pos : strlen($this->MaxAmount));
|
282 |
+
|
283 |
+
$decimals = substr($this->MaxAmount, $pos + 1);
|
284 |
+
if (!empty($this->MaxAmount) && (strlen($tempMaxAmount) > 11 || strlen($decimals) > 2)) {
|
285 |
+
throw new CommunicatorException('The MaxAmount should have maximum 2 decimals and the total number of digits should be maximum 11.');
|
286 |
+
}
|
287 |
+
}
|
288 |
+
|
289 |
+
}
|
lib/Communicator/Entities/NewMandateResponse.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Describes a new mandate response
|
5 |
+
*/
|
6 |
+
class NewMandateResponse {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* true if an error occurred, or false when no errors were encountered
|
10 |
+
* @var bool
|
11 |
+
*/
|
12 |
+
public $IsError = false;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Object that holds the error if one occurs; when there are no errors, this is set to null
|
16 |
+
* @var ErrorResponse
|
17 |
+
*/
|
18 |
+
public $Error = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The URL to which to redirect the creditor so they can authorize the transaction
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
public $IssuerAuthenticationUrl = null;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* The transaction ID
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $TransactionId = null;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* DateTime set to when this transaction was created
|
34 |
+
* @var DateTime
|
35 |
+
*/
|
36 |
+
public $TransactionCreateDateTimestamp;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* The response XML
|
40 |
+
*
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
public $RawMessage;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Deserializes the xml into a NewMandateResponse
|
47 |
+
*
|
48 |
+
* @param string $xml
|
49 |
+
* @throws CommunicatorException
|
50 |
+
*/
|
51 |
+
public function __construct($xml, $response_xml = false) {
|
52 |
+
$this->RawMessage = (!empty($response_xml) || $response_xml === '' ? $response_xml : $xml);
|
53 |
+
$data = XmlUtility::parse($xml);
|
54 |
+
|
55 |
+
if ($data->getName() == 'AcquirerErrorRes' || $data->getName() == 'Exception') {
|
56 |
+
$this->_buildAcquirerErrorRes($data);
|
57 |
+
} else if ($data->getName() != 'AcquirerTrxRes') {
|
58 |
+
throw new CommunicatorException($data->getName() . ' was not expected.');
|
59 |
+
} else {
|
60 |
+
$this->_buildNewMandateResponse($data);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
private function _buildAcquirerErrorRes($data) {
|
65 |
+
$this->Error = new ErrorResponse($data);
|
66 |
+
$this->IsError = true;
|
67 |
+
$this->TransactionCreateDateTimestamp = new DateTime((string) $data->createDateTimestamp);
|
68 |
+
}
|
69 |
+
|
70 |
+
private function _buildNewMandateResponse($data) {
|
71 |
+
$this->IssuerAuthenticationUrl = (string) $data->Issuer->issuerAuthenticationURL;
|
72 |
+
$this->TransactionId = (string) $data->Transaction->transactionID;
|
73 |
+
|
74 |
+
$this->TransactionCreateDateTimestamp = new DateTime((string) $data->Transaction->transactionCreateDateTimestamp);
|
75 |
+
}
|
76 |
+
}
|
lib/Communicator/Libraries/CommunicatorException.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* To change this license header, choose License Headers in Project Properties.
|
5 |
+
* To change this template file, choose Tools | Templates
|
6 |
+
* and open the template in the editor.
|
7 |
+
*/
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Description of CommunicatorException
|
11 |
+
*/
|
12 |
+
class CommunicatorException extends Exception {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Createst an Exception with custom message so it can be parsed by the ErrorResponse
|
16 |
+
*
|
17 |
+
* @param string $message
|
18 |
+
* @param string | int $code
|
19 |
+
*/
|
20 |
+
public function __construct($message, $code = false) {
|
21 |
+
// some code
|
22 |
+
$new_message = "
|
23 |
+
<Exception>
|
24 |
+
<Error>
|
25 |
+
<errorCode>$code</errorCode>
|
26 |
+
<errorMessage>$message</errorMessage>
|
27 |
+
</Error>
|
28 |
+
</Exception>
|
29 |
+
";
|
30 |
+
// make sure everything is assigned properly
|
31 |
+
parent::__construct($new_message, $code);
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
lib/Communicator/Libraries/Logger.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Description of Logger
|
5 |
+
*/
|
6 |
+
class Logger {
|
7 |
+
|
8 |
+
protected $enableXMLLogs;
|
9 |
+
protected $logPath;
|
10 |
+
protected $folderNamePattern;
|
11 |
+
protected $fileNamePrefix;
|
12 |
+
protected $enableInternalLogs;
|
13 |
+
protected $fileName;
|
14 |
+
|
15 |
+
public function __construct(Configuration $configuration) {
|
16 |
+
$this->enableXMLLogs = $configuration->enableXMLLogs;
|
17 |
+
$this->logPath = $configuration->logPath;
|
18 |
+
$this->folderNamePattern = $configuration->folderNamePattern;
|
19 |
+
$this->fileNamePrefix = $configuration->fileNamePrefix;
|
20 |
+
$this->enableInternalLogs = $configuration->enableInternalLogs;
|
21 |
+
$this->fileName = $configuration->fileName;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Logs a trace message to the config['fileName']
|
26 |
+
*
|
27 |
+
* @param string $message
|
28 |
+
*/
|
29 |
+
public function Log($message) {
|
30 |
+
$callers = debug_backtrace();
|
31 |
+
$this->Write($callers[1]['function'], $message);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Saves the desired dom or xml into the logPath folder
|
36 |
+
*
|
37 |
+
* @param DOMDocument/string $dom
|
38 |
+
*/
|
39 |
+
public function LogXmlMessage($dom, $isXML = false) {
|
40 |
+
|
41 |
+
if ($this->enableXMLLogs) {
|
42 |
+
if ($isXML) {
|
43 |
+
$domtree = new DOMDocument();
|
44 |
+
$domtree->loadXML($dom);
|
45 |
+
|
46 |
+
$dom = $domtree;
|
47 |
+
}
|
48 |
+
|
49 |
+
$dirName = $this->logPath . date($this->folderNamePattern);
|
50 |
+
if (!file_exists($dirName)) {
|
51 |
+
mkdir($dirName, 0777, true);
|
52 |
+
}
|
53 |
+
|
54 |
+
$t = microtime(true);
|
55 |
+
$micro = sprintf("%06d", ($t - floor($t)) * 1000000);
|
56 |
+
$d = new DateTime(date('Y-m-d H:i:s.' . $micro, $t));
|
57 |
+
|
58 |
+
$dom->save($dirName . '/' . $d->format($this->fileNamePrefix) . '-' . (!empty($dom->documentElement->localName) ? $dom->documentElement->localName : '') . '.xml');
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
public function Write($function, $message) {
|
63 |
+
|
64 |
+
if ($this->enableInternalLogs) {
|
65 |
+
$dirName = $this->logPath . date($this->folderNamePattern);
|
66 |
+
if (!file_exists($dirName)) {
|
67 |
+
mkdir($dirName, 0777, true);
|
68 |
+
}
|
69 |
+
|
70 |
+
file_put_contents($dirName . '/' . $this->fileName, date('Y-m-d H:i:s : ') . $function . '() - ' . $message . "\n", FILE_APPEND);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
}
|
lib/Communicator/Libraries/MessageIdGenerator.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class that automatically generates MessageId's. You may use this to set the MessageId field manually, or you can use
|
5 |
+
* the constructors for NewMandateRequest, AmendmentRequest or CancellationRequest to do it automatically.
|
6 |
+
*/
|
7 |
+
class MessageIdGenerator {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Returns a string of 16 alphanumeric characters
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
public static function NewMessageId() {
|
14 |
+
$ok = false;
|
15 |
+
while (!$ok) {
|
16 |
+
$charid = strtoupper(md5(uniqid(rand(), true)));
|
17 |
+
$hyphen = ''; //chr(45); // "-"
|
18 |
+
$uuid = ''//chr(123)// "{"
|
19 |
+
. substr($charid, 0, 8) . $hyphen
|
20 |
+
. substr($charid, 8, 4) . $hyphen
|
21 |
+
. substr($charid, 12, 4) . $hyphen
|
22 |
+
. substr($charid, 16, 4) . $hyphen
|
23 |
+
. substr($charid, 20, 12)
|
24 |
+
. ''; //chr(125); // "}"
|
25 |
+
$base64 = preg_replace("/[^A-Za-z0-9 ]/", '', base64_encode($uuid));
|
26 |
+
$base64 = substr($base64, 0, 16);
|
27 |
+
|
28 |
+
if (strlen($base64) == 16) {
|
29 |
+
$ok = true;
|
30 |
+
}
|
31 |
+
}
|
32 |
+
return $base64;
|
33 |
+
}
|
34 |
+
|
35 |
+
}
|
lib/Communicator/Libraries/XmlSecurity.php
ADDED
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once dirname(__FILE__) . './xmlseclibs.php';
|
4 |
+
require_once dirname(__FILE__) . './CommunicatorException.php';
|
5 |
+
|
6 |
+
const BEGIN_CERTIFICATE = '-----BEGIN CERTIFICATE-----';
|
7 |
+
const END_CERTIFICATE = '-----END CERTIFICATE-----';
|
8 |
+
|
9 |
+
class XmlSecurity {
|
10 |
+
|
11 |
+
private $logger;
|
12 |
+
|
13 |
+
function __construct($logger) {
|
14 |
+
$this->logger = $logger;
|
15 |
+
}
|
16 |
+
|
17 |
+
public function sign(DOMDocument $docTree, $privateCertificatePath, $privateKeyPath, $passphrase) {
|
18 |
+
$this->logger->Log("signing xml...");
|
19 |
+
|
20 |
+
/* The GOOD thing that fixed the xignature */
|
21 |
+
$doc = new DOMDocument();
|
22 |
+
$doc->loadXML($docTree->saveXML());
|
23 |
+
|
24 |
+
$signature = new XMLSecurityDSig();
|
25 |
+
$signature->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
|
26 |
+
$signature->addReference(
|
27 |
+
$doc,
|
28 |
+
XMLSecurityDSig::SHA256,
|
29 |
+
array(
|
30 |
+
'http://www.w3.org/2000/09/xmldsig#enveloped-signature',
|
31 |
+
'http://www.w3.org/2001/10/xml-exc-c14n#'
|
32 |
+
),
|
33 |
+
array('force_uri' => true)
|
34 |
+
);
|
35 |
+
|
36 |
+
$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private'));
|
37 |
+
|
38 |
+
$key->passphrase = $passphrase;
|
39 |
+
$key->loadKey($privateKeyPath, TRUE);
|
40 |
+
|
41 |
+
$signature->sign($key);
|
42 |
+
|
43 |
+
$fingerprint = $this->getFingerprint($privateCertificatePath);
|
44 |
+
|
45 |
+
$this->logger->Log("embedding thumbprint: {{$fingerprint}}");
|
46 |
+
|
47 |
+
$signature->addKeyInfoAndName($fingerprint);
|
48 |
+
|
49 |
+
$signature->appendSignature($doc->documentElement);
|
50 |
+
|
51 |
+
$this->logger->Log("finished signing xml");
|
52 |
+
|
53 |
+
return $doc;
|
54 |
+
}
|
55 |
+
|
56 |
+
private function checkIdxSignature($doc, $certificatePath) {
|
57 |
+
$signature = new XMLSecurityDSig();
|
58 |
+
|
59 |
+
$signature->locateSignature($doc);
|
60 |
+
$signature->canonicalizeSignedInfo();
|
61 |
+
|
62 |
+
try {
|
63 |
+
$signature->validateReference();
|
64 |
+
} catch (Exception $ex) {
|
65 |
+
$this->logger->Log("Reference Validation Failed");
|
66 |
+
throw new CommunicatorException('Reference Validation Failed', $ex->getCode());
|
67 |
+
}
|
68 |
+
|
69 |
+
$key = $signature->locateKey();
|
70 |
+
if (!$key) {
|
71 |
+
$this->logger->Log("Cannot locate the key");
|
72 |
+
throw new CommunicatorException('Cannot locate the key.');
|
73 |
+
}
|
74 |
+
|
75 |
+
$key->loadKey($this->normalizeCertificate($certificatePath));
|
76 |
+
|
77 |
+
if ($signature->verify($key) == 1) {
|
78 |
+
$this->logger->Log("signature is valid");
|
79 |
+
return true;
|
80 |
+
} else {
|
81 |
+
$this->logger->Log("The signature could not be verified.");
|
82 |
+
throw new CommunicatorException('The signature could not be verified.');
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
public function checkEmandateSignature($emandatedoc) {
|
87 |
+
$str = $emandatedoc->saveXML();
|
88 |
+
$str = str_replace(' xmlns:default="http://www.w3.org/2000/09/xmldsig#"', '', str_replace('default:', '', $str));
|
89 |
+
|
90 |
+
$emandatedoc->loadXML($str);
|
91 |
+
|
92 |
+
$certificate = $emandatedoc->getElementsByTagNameNS('http://www.w3.org/2000/09/xmldsig#', 'X509Certificate')->item(0);
|
93 |
+
$cert = $this->normalizeEmbeddedCertificate($certificate->nodeValue);
|
94 |
+
|
95 |
+
$signature = new XMLSecurityDSig();
|
96 |
+
|
97 |
+
$signature->locateSignature($emandatedoc);
|
98 |
+
$signature->canonicalizeSignedInfo();
|
99 |
+
|
100 |
+
try {
|
101 |
+
$signature->validateReference();
|
102 |
+
} catch (Exception $ex) {
|
103 |
+
$this->logger->Log("emandate signature: reference validation failed");
|
104 |
+
throw new CommunicatorException('emandate signature: reference validation failed', $ex->getCode());
|
105 |
+
}
|
106 |
+
|
107 |
+
$key = $signature->locateKey();
|
108 |
+
if (!$key) {
|
109 |
+
$this->logger->Log("emandate signature: cannot locate the key");
|
110 |
+
throw new CommunicatorException('emandate signature: cannot locate the key.');
|
111 |
+
}
|
112 |
+
|
113 |
+
$key->loadKey($cert);
|
114 |
+
|
115 |
+
if ($signature->verify($key) == 1) {
|
116 |
+
$this->logger->Log("emandate signature: signature is valid");
|
117 |
+
return true;
|
118 |
+
} else {
|
119 |
+
$this->logger->Log("emandate signature: the signature could not be verified.");
|
120 |
+
throw new CommunicatorException('emandate signature: the signature could not be verified.');
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
public function verify($xml, $certificatePath) {
|
125 |
+
$this->logger->Log("checking signature...");
|
126 |
+
|
127 |
+
$doc = new DOMDocument();
|
128 |
+
$doc->loadXML($xml);
|
129 |
+
|
130 |
+
$signature = new XMLSecurityDSig();
|
131 |
+
if ($signature->signaturesCount($doc) == 2) {
|
132 |
+
// TODO: first check emandate signature
|
133 |
+
$eMandate = $doc->getElementsByTagNameNS('urn:iso:std:iso:20022:tech:xsd:pain.012.001.04', 'Document')->item(0);
|
134 |
+
$newEmandate = $eMandate->cloneNode(TRUE);
|
135 |
+
$emandatedoc = new DOMDocument();
|
136 |
+
$newEmandate = $emandatedoc->importNode($newEmandate, TRUE);
|
137 |
+
$emandatedoc->appendChild($newEmandate);
|
138 |
+
|
139 |
+
$this->checkEmandateSignature($emandatedoc);
|
140 |
+
}
|
141 |
+
|
142 |
+
return $this->checkIdxSignature($doc, $certificatePath);
|
143 |
+
}
|
144 |
+
|
145 |
+
private function getFingerprint($path) {
|
146 |
+
$contents = $this->normalizeCertificate($path);
|
147 |
+
|
148 |
+
if (is_null($contents) || $contents == false) {
|
149 |
+
$this->logger->Log("Empty signing certificate.");
|
150 |
+
throw new CommunicatorException('Empty signing certificate.');
|
151 |
+
}
|
152 |
+
|
153 |
+
$contents = str_replace(END_CERTIFICATE, '', str_replace(BEGIN_CERTIFICATE, '', $contents));
|
154 |
+
$contents = base64_decode($contents);
|
155 |
+
return strtoupper(sha1($contents));
|
156 |
+
}
|
157 |
+
|
158 |
+
private function normalizeCertificate($path) {
|
159 |
+
$origcontent = file_get_contents($path);
|
160 |
+
|
161 |
+
if (is_null($origcontent) || $origcontent == false) {
|
162 |
+
$this->logger->Log("Empty acquirer certificate.");
|
163 |
+
throw new CommunicatorException('Empty acquirer certificate.');
|
164 |
+
}
|
165 |
+
|
166 |
+
$count = substr_count($origcontent, "\n");
|
167 |
+
if ($count > 5) {
|
168 |
+
return $origcontent;
|
169 |
+
}
|
170 |
+
|
171 |
+
$contents = str_replace(END_CERTIFICATE, '', str_replace(BEGIN_CERTIFICATE, '', $origcontent));
|
172 |
+
|
173 |
+
$blocks = array();
|
174 |
+
while (strlen($contents) > 0) {
|
175 |
+
array_push($blocks, substr($contents, 0, 64));
|
176 |
+
$contents = substr($contents, 64);
|
177 |
+
$contents = ltrim($contents);
|
178 |
+
}
|
179 |
+
|
180 |
+
$str = BEGIN_CERTIFICATE . "\r\n" . implode("\r\n", $blocks) . "\r\n" . END_CERTIFICATE;
|
181 |
+
|
182 |
+
return $str;
|
183 |
+
}
|
184 |
+
|
185 |
+
private function normalizeEmbeddedCertificate($text) {
|
186 |
+
$blocks = array();
|
187 |
+
$contents = $text;
|
188 |
+
while (strlen($contents) > 0) {
|
189 |
+
array_push($blocks, substr($contents, 0, 64));
|
190 |
+
$contents = substr($contents, 64);
|
191 |
+
$contents = ltrim($contents);
|
192 |
+
}
|
193 |
+
|
194 |
+
$str = BEGIN_CERTIFICATE . "\r\n" . implode("\r\n", $blocks) . "\r\n" . END_CERTIFICATE;
|
195 |
+
|
196 |
+
return $str;
|
197 |
+
}
|
198 |
+
}
|
lib/Communicator/Libraries/XmlUtility.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Utility class for processing XML documents
|
5 |
+
*/
|
6 |
+
class XmlUtility {
|
7 |
+
|
8 |
+
public static function parse($xml) {
|
9 |
+
$xml = preg_replace("/(<\\/?)[\\w]*?:/m", '$1', $xml);
|
10 |
+
$xml = preg_replace("/xmlns:[\\w]*?=\"[^\"]*?\"/m", '', $xml);
|
11 |
+
|
12 |
+
$element = simplexml_load_string($xml);
|
13 |
+
return $element;
|
14 |
+
}
|
15 |
+
}
|
lib/Communicator/Libraries/XmlValidator.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Description of XmlValidator
|
5 |
+
*/
|
6 |
+
class XmlValidator {
|
7 |
+
|
8 |
+
const SCHEMA_IDX = 'SchemaIDX';
|
9 |
+
const SCHEMA_PAIN009 = 'SchemaPain009';
|
10 |
+
const SCHEMA_PAIN010 = 'SchemaPain010';
|
11 |
+
const SCHEMA_PAIN011 = 'SchemaPain011';
|
12 |
+
const SCHEMA_PAIN012 = 'SchemaPain012';
|
13 |
+
|
14 |
+
public $SchemaIDX;
|
15 |
+
public $SchemaPain009;
|
16 |
+
public $SchemaPain010;
|
17 |
+
public $SchemaPain011;
|
18 |
+
public $SchemaPain012;
|
19 |
+
|
20 |
+
function __construct() {
|
21 |
+
|
22 |
+
$this->SchemaIDX = dirname(__FILE__) . './../schemas/idx.merchant-acquirer.1.0.xsd';
|
23 |
+
$this->SchemaPain009 = dirname(__FILE__) . './../schemas/pain.009.001.04.xsd';
|
24 |
+
$this->SchemaPain010 = dirname(__FILE__) . './../schemas/pain.010.001.04.xsd';
|
25 |
+
$this->SchemaPain011 = dirname(__FILE__) . './../schemas/pain.011.001.04.xsd';
|
26 |
+
$this->SchemaPain012 = dirname(__FILE__) . './../schemas/pain.012.001.04.xsd';
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Validates the xml provided against the xsd schema
|
31 |
+
*
|
32 |
+
* @param string $xml
|
33 |
+
* @return boolean
|
34 |
+
* @throws Exception
|
35 |
+
*/
|
36 |
+
public static function isValidatXML($xml, $schemaName, $logger) {
|
37 |
+
$validator = new self();
|
38 |
+
|
39 |
+
libxml_use_internal_errors(true);
|
40 |
+
|
41 |
+
$document = new DOMDocument();
|
42 |
+
$document->loadXML($xml);
|
43 |
+
|
44 |
+
if (!$document->schemaValidate($validator->$schemaName)) {
|
45 |
+
|
46 |
+
foreach (libxml_get_errors() as $error) {
|
47 |
+
$logger->Log("xml schema is not valid: {{$error->message}}");
|
48 |
+
throw new CommunicatorException($error->message, $error->code);
|
49 |
+
}
|
50 |
+
return false;
|
51 |
+
}
|
52 |
+
$logger->Log("xml schema is valid");
|
53 |
+
return true;
|
54 |
+
}
|
55 |
+
|
56 |
+
}
|
lib/Communicator/Libraries/xmlseclibs.php
ADDED
@@ -0,0 +1,1853 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* xmlseclibs.php
|
4 |
+
*
|
5 |
+
* Copyright (c) 2007-2013, Robert Richards <rrichards@cdatazone.org>.
|
6 |
+
* All rights reserved.
|
7 |
+
*
|
8 |
+
* Redistribution and use in source and binary forms, with or without
|
9 |
+
* modification, are permitted provided that the following conditions
|
10 |
+
* are met:
|
11 |
+
*
|
12 |
+
* * Redistributions of source code must retain the above copyright
|
13 |
+
* notice, this list of conditions and the following disclaimer.
|
14 |
+
*
|
15 |
+
* * Redistributions in binary form must reproduce the above copyright
|
16 |
+
* notice, this list of conditions and the following disclaimer in
|
17 |
+
* the documentation and/or other materials provided with the
|
18 |
+
* distribution.
|
19 |
+
*
|
20 |
+
* * Neither the name of Robert Richards nor the names of his
|
21 |
+
* contributors may be used to endorse or promote products derived
|
22 |
+
* from this software without specific prior written permission.
|
23 |
+
*
|
24 |
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
25 |
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
26 |
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
27 |
+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
28 |
+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
29 |
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
30 |
+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
31 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
32 |
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
33 |
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
34 |
+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
35 |
+
* POSSIBILITY OF SUCH DAMAGE.
|
36 |
+
*
|
37 |
+
* @author Robert Richards <rrichards@cdatazone.org>
|
38 |
+
* @copyright 2007-2013 Robert Richards <rrichards@cdatazone.org>
|
39 |
+
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
40 |
+
* @version 1.3.1
|
41 |
+
*/
|
42 |
+
|
43 |
+
/*
|
44 |
+
Functions to generate simple cases of Exclusive Canonical XML - Callable function is C14NGeneral()
|
45 |
+
i.e.: $canonical = C14NGeneral($domelement, TRUE);
|
46 |
+
*/
|
47 |
+
|
48 |
+
/* helper function */
|
49 |
+
function sortAndAddAttrs($element, $arAtts) {
|
50 |
+
$newAtts = array();
|
51 |
+
foreach ($arAtts AS $attnode) {
|
52 |
+
$newAtts[$attnode->nodeName] = $attnode;
|
53 |
+
}
|
54 |
+
ksort($newAtts);
|
55 |
+
foreach ($newAtts as $attnode) {
|
56 |
+
$element->setAttribute($attnode->nodeName, $attnode->nodeValue);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
/* helper function */
|
61 |
+
function canonical($tree, $element, $withcomments) {
|
62 |
+
if ($tree->nodeType != XML_DOCUMENT_NODE) {
|
63 |
+
$dom = $tree->ownerDocument;
|
64 |
+
} else {
|
65 |
+
$dom = $tree;
|
66 |
+
}
|
67 |
+
if ($element->nodeType != XML_ELEMENT_NODE) {
|
68 |
+
if ($element->nodeType == XML_DOCUMENT_NODE) {
|
69 |
+
foreach ($element->childNodes AS $node) {
|
70 |
+
canonical($dom, $node, $withcomments);
|
71 |
+
}
|
72 |
+
return;
|
73 |
+
}
|
74 |
+
if ($element->nodeType == XML_COMMENT_NODE && ! $withcomments) {
|
75 |
+
return;
|
76 |
+
}
|
77 |
+
$tree->appendChild($dom->importNode($element, TRUE));
|
78 |
+
return;
|
79 |
+
}
|
80 |
+
$arNS = array();
|
81 |
+
if ($element->namespaceURI != "") {
|
82 |
+
if ($element->prefix == "") {
|
83 |
+
$elCopy = $dom->createElementNS($element->namespaceURI, $element->nodeName);
|
84 |
+
} else {
|
85 |
+
$prefix = $tree->lookupPrefix($element->namespaceURI);
|
86 |
+
if ($prefix == $element->prefix) {
|
87 |
+
$elCopy = $dom->createElementNS($element->namespaceURI, $element->nodeName);
|
88 |
+
} else {
|
89 |
+
$elCopy = $dom->createElement($element->nodeName);
|
90 |
+
$arNS[$element->namespaceURI] = $element->prefix;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
} else {
|
94 |
+
$elCopy = $dom->createElement($element->nodeName);
|
95 |
+
}
|
96 |
+
$tree->appendChild($elCopy);
|
97 |
+
|
98 |
+
/* Create DOMXPath based on original document */
|
99 |
+
$xPath = new DOMXPath($element->ownerDocument);
|
100 |
+
|
101 |
+
/* Get namespaced attributes */
|
102 |
+
$arAtts = $xPath->query('attribute::*[namespace-uri(.) != ""]', $element);
|
103 |
+
|
104 |
+
/* Create an array with namespace URIs as keys, and sort them */
|
105 |
+
foreach ($arAtts AS $attnode) {
|
106 |
+
if (array_key_exists($attnode->namespaceURI, $arNS) &&
|
107 |
+
($arNS[$attnode->namespaceURI] == $attnode->prefix)) {
|
108 |
+
continue;
|
109 |
+
}
|
110 |
+
$prefix = $tree->lookupPrefix($attnode->namespaceURI);
|
111 |
+
if ($prefix != $attnode->prefix) {
|
112 |
+
$arNS[$attnode->namespaceURI] = $attnode->prefix;
|
113 |
+
} else {
|
114 |
+
$arNS[$attnode->namespaceURI] = NULL;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
if (count($arNS) > 0) {
|
118 |
+
asort($arNS);
|
119 |
+
}
|
120 |
+
|
121 |
+
/* Add namespace nodes */
|
122 |
+
foreach ($arNS AS $namespaceURI=>$prefix) {
|
123 |
+
if ($prefix != NULL) {
|
124 |
+
$elCopy->setAttributeNS("http://www.w3.org/2000/xmlns/",
|
125 |
+
"xmlns:".$prefix, $namespaceURI);
|
126 |
+
}
|
127 |
+
}
|
128 |
+
if (count($arNS) > 0) {
|
129 |
+
ksort($arNS);
|
130 |
+
}
|
131 |
+
|
132 |
+
/* Get attributes not in a namespace, and then sort and add them */
|
133 |
+
$arAtts = $xPath->query('attribute::*[namespace-uri(.) = ""]', $element);
|
134 |
+
sortAndAddAttrs($elCopy, $arAtts);
|
135 |
+
|
136 |
+
/* Loop through the URIs, and then sort and add attributes within that namespace */
|
137 |
+
foreach ($arNS as $nsURI=>$prefix) {
|
138 |
+
$arAtts = $xPath->query('attribute::*[namespace-uri(.) = "'.$nsURI.'"]', $element);
|
139 |
+
sortAndAddAttrs($elCopy, $arAtts);
|
140 |
+
}
|
141 |
+
|
142 |
+
foreach ($element->childNodes AS $node) {
|
143 |
+
canonical($elCopy, $node, $withcomments);
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
/*
|
148 |
+
$element - DOMElement for which to produce the canonical version of
|
149 |
+
$exclusive - boolean to indicate exclusive canonicalization (must pass TRUE)
|
150 |
+
$withcomments - boolean indicating wether or not to include comments in canonicalized form
|
151 |
+
*/
|
152 |
+
function C14NGeneral($element, $exclusive=FALSE, $withcomments=FALSE) {
|
153 |
+
/* IF PHP 5.2+ then use built in canonical functionality */
|
154 |
+
$php_version = explode('.', PHP_VERSION);
|
155 |
+
if (($php_version[0] > 5) || ($php_version[0] == 5 && $php_version[1] >= 2) ) {
|
156 |
+
return $element->C14N($exclusive, $withcomments);
|
157 |
+
}
|
158 |
+
|
159 |
+
/* Must be element or document */
|
160 |
+
if (! $element instanceof DOMElement && ! $element instanceof DOMDocument) {
|
161 |
+
return NULL;
|
162 |
+
}
|
163 |
+
/* Currently only exclusive XML is supported */
|
164 |
+
if ($exclusive == FALSE) {
|
165 |
+
throw new Exception("Only exclusive canonicalization is supported in this version of PHP");
|
166 |
+
}
|
167 |
+
|
168 |
+
$copyDoc = new DOMDocument();
|
169 |
+
canonical($copyDoc, $element, $withcomments);
|
170 |
+
return $copyDoc->saveXML($copyDoc->documentElement, LIBXML_NOEMPTYTAG);
|
171 |
+
}
|
172 |
+
|
173 |
+
class XMLSecurityKey {
|
174 |
+
const TRIPLEDES_CBC = 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc';
|
175 |
+
const AES128_CBC = 'http://www.w3.org/2001/04/xmlenc#aes128-cbc';
|
176 |
+
const AES192_CBC = 'http://www.w3.org/2001/04/xmlenc#aes192-cbc';
|
177 |
+
const AES256_CBC = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc';
|
178 |
+
const RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5';
|
179 |
+
const RSA_OAEP_MGF1P = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p';
|
180 |
+
const DSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1';
|
181 |
+
const RSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
|
182 |
+
const RSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
|
183 |
+
const RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384';
|
184 |
+
const RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512';
|
185 |
+
|
186 |
+
private $cryptParams = array();
|
187 |
+
public $type = 0;
|
188 |
+
public $key = NULL;
|
189 |
+
public $passphrase = "";
|
190 |
+
public $iv = NULL;
|
191 |
+
public $name = NULL;
|
192 |
+
public $keyChain = NULL;
|
193 |
+
public $isEncrypted = FALSE;
|
194 |
+
public $encryptedCtx = NULL;
|
195 |
+
public $guid = NULL;
|
196 |
+
|
197 |
+
/**
|
198 |
+
* This variable contains the certificate as a string if this key represents an X509-certificate.
|
199 |
+
* If this key doesn't represent a certificate, this will be NULL.
|
200 |
+
*/
|
201 |
+
private $x509Certificate = NULL;
|
202 |
+
|
203 |
+
/* This variable contains the certificate thunbprint if we have loaded an X509-certificate. */
|
204 |
+
private $X509Thumbprint = NULL;
|
205 |
+
|
206 |
+
public function __construct($type, $params=NULL) {
|
207 |
+
srand();
|
208 |
+
switch ($type) {
|
209 |
+
case (XMLSecurityKey::TRIPLEDES_CBC):
|
210 |
+
$this->cryptParams['library'] = 'mcrypt';
|
211 |
+
$this->cryptParams['cipher'] = MCRYPT_TRIPLEDES;
|
212 |
+
$this->cryptParams['mode'] = MCRYPT_MODE_CBC;
|
213 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc';
|
214 |
+
$this->cryptParams['keysize'] = 24;
|
215 |
+
break;
|
216 |
+
case (XMLSecurityKey::AES128_CBC):
|
217 |
+
$this->cryptParams['library'] = 'mcrypt';
|
218 |
+
$this->cryptParams['cipher'] = MCRYPT_RIJNDAEL_128;
|
219 |
+
$this->cryptParams['mode'] = MCRYPT_MODE_CBC;
|
220 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#aes128-cbc';
|
221 |
+
$this->cryptParams['keysize'] = 16;
|
222 |
+
break;
|
223 |
+
case (XMLSecurityKey::AES192_CBC):
|
224 |
+
$this->cryptParams['library'] = 'mcrypt';
|
225 |
+
$this->cryptParams['cipher'] = MCRYPT_RIJNDAEL_128;
|
226 |
+
$this->cryptParams['mode'] = MCRYPT_MODE_CBC;
|
227 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#aes192-cbc';
|
228 |
+
$this->cryptParams['keysize'] = 24;
|
229 |
+
break;
|
230 |
+
case (XMLSecurityKey::AES256_CBC):
|
231 |
+
$this->cryptParams['library'] = 'mcrypt';
|
232 |
+
$this->cryptParams['cipher'] = MCRYPT_RIJNDAEL_128;
|
233 |
+
$this->cryptParams['mode'] = MCRYPT_MODE_CBC;
|
234 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc';
|
235 |
+
$this->cryptParams['keysize'] = 32;
|
236 |
+
break;
|
237 |
+
case (XMLSecurityKey::RSA_1_5):
|
238 |
+
$this->cryptParams['library'] = 'openssl';
|
239 |
+
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
|
240 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5';
|
241 |
+
if (is_array($params) && ! empty($params['type'])) {
|
242 |
+
if ($params['type'] == 'public' || $params['type'] == 'private') {
|
243 |
+
$this->cryptParams['type'] = $params['type'];
|
244 |
+
break;
|
245 |
+
}
|
246 |
+
}
|
247 |
+
throw new Exception('Certificate "type" (private/public) must be passed via parameters');
|
248 |
+
return;
|
249 |
+
case (XMLSecurityKey::RSA_OAEP_MGF1P):
|
250 |
+
$this->cryptParams['library'] = 'openssl';
|
251 |
+
$this->cryptParams['padding'] = OPENSSL_PKCS1_OAEP_PADDING;
|
252 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p';
|
253 |
+
$this->cryptParams['hash'] = NULL;
|
254 |
+
if (is_array($params) && ! empty($params['type'])) {
|
255 |
+
if ($params['type'] == 'public' || $params['type'] == 'private') {
|
256 |
+
$this->cryptParams['type'] = $params['type'];
|
257 |
+
break;
|
258 |
+
}
|
259 |
+
}
|
260 |
+
throw new Exception('Certificate "type" (private/public) must be passed via parameters');
|
261 |
+
return;
|
262 |
+
case (XMLSecurityKey::RSA_SHA1):
|
263 |
+
$this->cryptParams['library'] = 'openssl';
|
264 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
|
265 |
+
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
|
266 |
+
if (is_array($params) && ! empty($params['type'])) {
|
267 |
+
if ($params['type'] == 'public' || $params['type'] == 'private') {
|
268 |
+
$this->cryptParams['type'] = $params['type'];
|
269 |
+
break;
|
270 |
+
}
|
271 |
+
}
|
272 |
+
throw new Exception('Certificate "type" (private/public) must be passed via parameters');
|
273 |
+
break;
|
274 |
+
case (XMLSecurityKey::RSA_SHA256):
|
275 |
+
$this->cryptParams['library'] = 'openssl';
|
276 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
|
277 |
+
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
|
278 |
+
$this->cryptParams['digest'] = 'SHA256';
|
279 |
+
if (is_array($params) && ! empty($params['type'])) {
|
280 |
+
if ($params['type'] == 'public' || $params['type'] == 'private') {
|
281 |
+
$this->cryptParams['type'] = $params['type'];
|
282 |
+
break;
|
283 |
+
}
|
284 |
+
}
|
285 |
+
throw new Exception('Certificate "type" (private/public) must be passed via parameters');
|
286 |
+
break;
|
287 |
+
case (XMLSecurityKey::RSA_SHA384):
|
288 |
+
$this->cryptParams['library'] = 'openssl';
|
289 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384';
|
290 |
+
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
|
291 |
+
$this->cryptParams['digest'] = 'SHA384';
|
292 |
+
if (is_array($params) && ! empty($params['type'])) {
|
293 |
+
if ($params['type'] == 'public' || $params['type'] == 'private') {
|
294 |
+
$this->cryptParams['type'] = $params['type'];
|
295 |
+
break;
|
296 |
+
}
|
297 |
+
}
|
298 |
+
case (XMLSecurityKey::RSA_SHA512):
|
299 |
+
$this->cryptParams['library'] = 'openssl';
|
300 |
+
$this->cryptParams['method'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512';
|
301 |
+
$this->cryptParams['padding'] = OPENSSL_PKCS1_PADDING;
|
302 |
+
$this->cryptParams['digest'] = 'SHA512';
|
303 |
+
if (is_array($params) && ! empty($params['type'])) {
|
304 |
+
if ($params['type'] == 'public' || $params['type'] == 'private') {
|
305 |
+
$this->cryptParams['type'] = $params['type'];
|
306 |
+
break;
|
307 |
+
}
|
308 |
+
}
|
309 |
+
default:
|
310 |
+
throw new Exception('Invalid Key Type');
|
311 |
+
return;
|
312 |
+
}
|
313 |
+
$this->type = $type;
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Retrieve the key size for the symmetric encryption algorithm..
|
318 |
+
*
|
319 |
+
* If the key size is unknown, or this isn't a symmetric encryption algorithm,
|
320 |
+
* NULL is returned.
|
321 |
+
*
|
322 |
+
* @return int|NULL The number of bytes in the key.
|
323 |
+
*/
|
324 |
+
public function getSymmetricKeySize() {
|
325 |
+
if (! isset($this->cryptParams['keysize'])) {
|
326 |
+
return NULL;
|
327 |
+
}
|
328 |
+
return $this->cryptParams['keysize'];
|
329 |
+
}
|
330 |
+
|
331 |
+
public function generateSessionKey() {
|
332 |
+
if (!isset($this->cryptParams['keysize'])) {
|
333 |
+
throw new Exception('Unknown key size for type "' . $this->type . '".');
|
334 |
+
}
|
335 |
+
$keysize = $this->cryptParams['keysize'];
|
336 |
+
|
337 |
+
if (function_exists('openssl_random_pseudo_bytes')) {
|
338 |
+
/* We have PHP >= 5.3 - use openssl to generate session key. */
|
339 |
+
$key = openssl_random_pseudo_bytes($keysize);
|
340 |
+
} else {
|
341 |
+
/* Generating random key using iv generation routines */
|
342 |
+
$key = mcrypt_create_iv($keysize, MCRYPT_RAND);
|
343 |
+
}
|
344 |
+
|
345 |
+
if ($this->type === XMLSecurityKey::TRIPLEDES_CBC) {
|
346 |
+
/* Make sure that the generated key has the proper parity bits set.
|
347 |
+
* Mcrypt doesn't care about the parity bits, but others may care.
|
348 |
+
*/
|
349 |
+
for ($i = 0; $i < strlen($key); $i++) {
|
350 |
+
$byte = ord($key[$i]) & 0xfe;
|
351 |
+
$parity = 1;
|
352 |
+
for ($j = 1; $j < 8; $j++) {
|
353 |
+
$parity ^= ($byte >> $j) & 1;
|
354 |
+
}
|
355 |
+
$byte |= $parity;
|
356 |
+
$key[$i] = chr($byte);
|
357 |
+
}
|
358 |
+
}
|
359 |
+
|
360 |
+
$this->key = $key;
|
361 |
+
return $key;
|
362 |
+
}
|
363 |
+
|
364 |
+
public static function getRawThumbprint($cert) {
|
365 |
+
|
366 |
+
$arCert = explode("\n", $cert);
|
367 |
+
$data = '';
|
368 |
+
$inData = FALSE;
|
369 |
+
|
370 |
+
foreach ($arCert AS $curData) {
|
371 |
+
if (! $inData) {
|
372 |
+
if (strncmp($curData, '-----BEGIN CERTIFICATE', 22) == 0) {
|
373 |
+
$inData = TRUE;
|
374 |
+
}
|
375 |
+
} else {
|
376 |
+
if (strncmp($curData, '-----END CERTIFICATE', 20) == 0) {
|
377 |
+
$inData = FALSE;
|
378 |
+
break;
|
379 |
+
}
|
380 |
+
$data .= trim($curData);
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
+
if (! empty($data)) {
|
385 |
+
return strtolower(sha1(base64_decode($data)));
|
386 |
+
}
|
387 |
+
|
388 |
+
return NULL;
|
389 |
+
}
|
390 |
+
|
391 |
+
public function loadKey($key, $isFile=FALSE, $isCert = FALSE) {
|
392 |
+
if ($isFile) {
|
393 |
+
$this->key = file_get_contents($key);
|
394 |
+
} else {
|
395 |
+
$this->key = $key;
|
396 |
+
}
|
397 |
+
if ($isCert) {
|
398 |
+
$this->key = openssl_x509_read($this->key);
|
399 |
+
openssl_x509_export($this->key, $str_cert);
|
400 |
+
$this->x509Certificate = $str_cert;
|
401 |
+
$this->key = $str_cert;
|
402 |
+
} else {
|
403 |
+
$this->x509Certificate = NULL;
|
404 |
+
}
|
405 |
+
if ($this->cryptParams['library'] == 'openssl') {
|
406 |
+
if ($this->cryptParams['type'] == 'public') {
|
407 |
+
if ($isCert) {
|
408 |
+
/* Load the thumbprint if this is an X509 certificate. */
|
409 |
+
$this->X509Thumbprint = self::getRawThumbprint($this->key);
|
410 |
+
}
|
411 |
+
$this->key = openssl_get_publickey($this->key);
|
412 |
+
} else {
|
413 |
+
$this->key = openssl_get_privatekey($this->key, $this->passphrase);
|
414 |
+
}
|
415 |
+
} else if ($this->cryptParams['cipher'] == MCRYPT_RIJNDAEL_128) {
|
416 |
+
/* Check key length */
|
417 |
+
switch ($this->type) {
|
418 |
+
case (XMLSecurityKey::AES256_CBC):
|
419 |
+
if (strlen($this->key) < 25) {
|
420 |
+
throw new Exception('Key must contain at least 25 characters for this cipher');
|
421 |
+
}
|
422 |
+
break;
|
423 |
+
case (XMLSecurityKey::AES192_CBC):
|
424 |
+
if (strlen($this->key) < 17) {
|
425 |
+
throw new Exception('Key must contain at least 17 characters for this cipher');
|
426 |
+
}
|
427 |
+
break;
|
428 |
+
}
|
429 |
+
}
|
430 |
+
}
|
431 |
+
|
432 |
+
private function encryptMcrypt($data) {
|
433 |
+
$td = mcrypt_module_open($this->cryptParams['cipher'], '', $this->cryptParams['mode'], '');
|
434 |
+
$this->iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
|
435 |
+
mcrypt_generic_init($td, $this->key, $this->iv);
|
436 |
+
if ($this->cryptParams['mode'] == MCRYPT_MODE_CBC) {
|
437 |
+
$bs = mcrypt_enc_get_block_size($td);
|
438 |
+
for ($datalen0=$datalen=strlen($data); (($datalen%$bs)!=($bs-1)); $datalen++)
|
439 |
+
$data.=chr(rand(1, 127));
|
440 |
+
$data.=chr($datalen-$datalen0+1);
|
441 |
+
}
|
442 |
+
$encrypted_data = $this->iv.mcrypt_generic($td, $data);
|
443 |
+
mcrypt_generic_deinit($td);
|
444 |
+
mcrypt_module_close($td);
|
445 |
+
return $encrypted_data;
|
446 |
+
}
|
447 |
+
|
448 |
+
private function decryptMcrypt($data) {
|
449 |
+
$td = mcrypt_module_open($this->cryptParams['cipher'], '', $this->cryptParams['mode'], '');
|
450 |
+
$iv_length = mcrypt_enc_get_iv_size($td);
|
451 |
+
|
452 |
+
$this->iv = substr($data, 0, $iv_length);
|
453 |
+
$data = substr($data, $iv_length);
|
454 |
+
|
455 |
+
mcrypt_generic_init($td, $this->key, $this->iv);
|
456 |
+
$decrypted_data = mdecrypt_generic($td, $data);
|
457 |
+
mcrypt_generic_deinit($td);
|
458 |
+
mcrypt_module_close($td);
|
459 |
+
if ($this->cryptParams['mode'] == MCRYPT_MODE_CBC) {
|
460 |
+
$dataLen = strlen($decrypted_data);
|
461 |
+
$paddingLength = substr($decrypted_data, $dataLen - 1, 1);
|
462 |
+
$decrypted_data = substr($decrypted_data, 0, $dataLen - ord($paddingLength));
|
463 |
+
}
|
464 |
+
return $decrypted_data;
|
465 |
+
}
|
466 |
+
|
467 |
+
private function encryptOpenSSL($data) {
|
468 |
+
if ($this->cryptParams['type'] == 'public') {
|
469 |
+
if (! openssl_public_encrypt($data, $encrypted_data, $this->key, $this->cryptParams['padding'])) {
|
470 |
+
throw new Exception('Failure encrypting Data');
|
471 |
+
return;
|
472 |
+
}
|
473 |
+
} else {
|
474 |
+
if (! openssl_private_encrypt($data, $encrypted_data, $this->key, $this->cryptParams['padding'])) {
|
475 |
+
throw new Exception('Failure encrypting Data');
|
476 |
+
return;
|
477 |
+
}
|
478 |
+
}
|
479 |
+
return $encrypted_data;
|
480 |
+
}
|
481 |
+
|
482 |
+
private function decryptOpenSSL($data) {
|
483 |
+
if ($this->cryptParams['type'] == 'public') {
|
484 |
+
if (! openssl_public_decrypt($data, $decrypted, $this->key, $this->cryptParams['padding'])) {
|
485 |
+
throw new Exception('Failure decrypting Data');
|
486 |
+
return;
|
487 |
+
}
|
488 |
+
} else {
|
489 |
+
if (! openssl_private_decrypt($data, $decrypted, $this->key, $this->cryptParams['padding'])) {
|
490 |
+
throw new Exception('Failure decrypting Data');
|
491 |
+
return;
|
492 |
+
}
|
493 |
+
}
|
494 |
+
return $decrypted;
|
495 |
+
}
|
496 |
+
|
497 |
+
private function signOpenSSL($data) {
|
498 |
+
$algo = OPENSSL_ALGO_SHA1;
|
499 |
+
if (! empty($this->cryptParams['digest'])) {
|
500 |
+
$algo = $this->cryptParams['digest'];
|
501 |
+
}
|
502 |
+
if (! openssl_sign ($data, $signature, $this->key, $algo)) {
|
503 |
+
throw new Exception('Failure Signing Data: ' . openssl_error_string() . ' - ' . $algo);
|
504 |
+
return;
|
505 |
+
}
|
506 |
+
return $signature;
|
507 |
+
}
|
508 |
+
|
509 |
+
private function verifyOpenSSL($data, $signature) {
|
510 |
+
$algo = OPENSSL_ALGO_SHA1;
|
511 |
+
if (! empty($this->cryptParams['digest'])) {
|
512 |
+
$algo = $this->cryptParams['digest'];
|
513 |
+
}
|
514 |
+
return openssl_verify ($data, $signature, $this->key, $algo);
|
515 |
+
}
|
516 |
+
|
517 |
+
public function encryptData($data) {
|
518 |
+
switch ($this->cryptParams['library']) {
|
519 |
+
case 'mcrypt':
|
520 |
+
return $this->encryptMcrypt($data);
|
521 |
+
break;
|
522 |
+
case 'openssl':
|
523 |
+
return $this->encryptOpenSSL($data);
|
524 |
+
break;
|
525 |
+
}
|
526 |
+
}
|
527 |
+
|
528 |
+
public function decryptData($data) {
|
529 |
+
switch ($this->cryptParams['library']) {
|
530 |
+
case 'mcrypt':
|
531 |
+
return $this->decryptMcrypt($data);
|
532 |
+
break;
|
533 |
+
case 'openssl':
|
534 |
+
return $this->decryptOpenSSL($data);
|
535 |
+
break;
|
536 |
+
}
|
537 |
+
}
|
538 |
+
|
539 |
+
public function signData($data) {
|
540 |
+
switch ($this->cryptParams['library']) {
|
541 |
+
case 'openssl':
|
542 |
+
return $this->signOpenSSL($data);
|
543 |
+
break;
|
544 |
+
}
|
545 |
+
}
|
546 |
+
|
547 |
+
public function verifySignature($data, $signature) {
|
548 |
+
switch ($this->cryptParams['library']) {
|
549 |
+
case 'openssl':
|
550 |
+
return $this->verifyOpenSSL($data, $signature);
|
551 |
+
break;
|
552 |
+
}
|
553 |
+
}
|
554 |
+
|
555 |
+
public function getAlgorith() {
|
556 |
+
return $this->cryptParams['method'];
|
557 |
+
}
|
558 |
+
|
559 |
+
static function makeAsnSegment($type, $string) {
|
560 |
+
switch ($type){
|
561 |
+
case 0x02:
|
562 |
+
if (ord($string) > 0x7f)
|
563 |
+
$string = chr(0).$string;
|
564 |
+
break;
|
565 |
+
case 0x03:
|
566 |
+
$string = chr(0).$string;
|
567 |
+
break;
|
568 |
+
}
|
569 |
+
|
570 |
+
$length = strlen($string);
|
571 |
+
|
572 |
+
if ($length < 128){
|
573 |
+
$output = sprintf("%c%c%s", $type, $length, $string);
|
574 |
+
} else if ($length < 0x0100){
|
575 |
+
$output = sprintf("%c%c%c%s", $type, 0x81, $length, $string);
|
576 |
+
} else if ($length < 0x010000) {
|
577 |
+
$output = sprintf("%c%c%c%c%s", $type, 0x82, $length/0x0100, $length%0x0100, $string);
|
578 |
+
} else {
|
579 |
+
$output = NULL;
|
580 |
+
}
|
581 |
+
return($output);
|
582 |
+
}
|
583 |
+
|
584 |
+
/* Modulus and Exponent must already be base64 decoded */
|
585 |
+
static function convertRSA($modulus, $exponent) {
|
586 |
+
/* make an ASN publicKeyInfo */
|
587 |
+
$exponentEncoding = XMLSecurityKey::makeAsnSegment(0x02, $exponent);
|
588 |
+
$modulusEncoding = XMLSecurityKey::makeAsnSegment(0x02, $modulus);
|
589 |
+
$sequenceEncoding = XMLSecurityKey:: makeAsnSegment(0x30, $modulusEncoding.$exponentEncoding);
|
590 |
+
$bitstringEncoding = XMLSecurityKey::makeAsnSegment(0x03, $sequenceEncoding);
|
591 |
+
$rsaAlgorithmIdentifier = pack("H*", "300D06092A864886F70D0101010500");
|
592 |
+
$publicKeyInfo = XMLSecurityKey::makeAsnSegment (0x30, $rsaAlgorithmIdentifier.$bitstringEncoding);
|
593 |
+
|
594 |
+
/* encode the publicKeyInfo in base64 and add PEM brackets */
|
595 |
+
$publicKeyInfoBase64 = base64_encode($publicKeyInfo);
|
596 |
+
$encoding = "-----BEGIN PUBLIC KEY-----\n";
|
597 |
+
$offset = 0;
|
598 |
+
while ($segment=substr($publicKeyInfoBase64, $offset, 64)){
|
599 |
+
$encoding = $encoding.$segment."\n";
|
600 |
+
$offset += 64;
|
601 |
+
}
|
602 |
+
return $encoding."-----END PUBLIC KEY-----\n";
|
603 |
+
}
|
604 |
+
|
605 |
+
public function serializeKey($parent) {
|
606 |
+
|
607 |
+
}
|
608 |
+
|
609 |
+
|
610 |
+
|
611 |
+
/**
|
612 |
+
* Retrieve the X509 certificate this key represents.
|
613 |
+
*
|
614 |
+
* Will return the X509 certificate in PEM-format if this key represents
|
615 |
+
* an X509 certificate.
|
616 |
+
*
|
617 |
+
* @return The X509 certificate or NULL if this key doesn't represent an X509-certificate.
|
618 |
+
*/
|
619 |
+
public function getX509Certificate() {
|
620 |
+
return $this->x509Certificate;
|
621 |
+
}
|
622 |
+
|
623 |
+
/* Get the thumbprint of this X509 certificate.
|
624 |
+
*
|
625 |
+
* Returns:
|
626 |
+
* The thumbprint as a lowercase 40-character hexadecimal number, or NULL
|
627 |
+
* if this isn't a X509 certificate.
|
628 |
+
*/
|
629 |
+
public function getX509Thumbprint() {
|
630 |
+
return $this->X509Thumbprint;
|
631 |
+
}
|
632 |
+
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Create key from an EncryptedKey-element.
|
636 |
+
*
|
637 |
+
* @param DOMElement $element The EncryptedKey-element.
|
638 |
+
* @return XMLSecurityKey The new key.
|
639 |
+
*/
|
640 |
+
public static function fromEncryptedKeyElement(DOMElement $element) {
|
641 |
+
|
642 |
+
$objenc = new XMLSecEnc();
|
643 |
+
$objenc->setNode($element);
|
644 |
+
if (! $objKey = $objenc->locateKey()) {
|
645 |
+
throw new Exception("Unable to locate algorithm for this Encrypted Key");
|
646 |
+
}
|
647 |
+
$objKey->isEncrypted = TRUE;
|
648 |
+
$objKey->encryptedCtx = $objenc;
|
649 |
+
XMLSecEnc::staticLocateKeyInfo($objKey, $element);
|
650 |
+
return $objKey;
|
651 |
+
}
|
652 |
+
|
653 |
+
}
|
654 |
+
|
655 |
+
class XMLSecurityDSig {
|
656 |
+
const XMLDSIGNS = 'http://www.w3.org/2000/09/xmldsig#';
|
657 |
+
const SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1';
|
658 |
+
const SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256';
|
659 |
+
const SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#sha384';
|
660 |
+
const SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512';
|
661 |
+
const RIPEMD160 = 'http://www.w3.org/2001/04/xmlenc#ripemd160';
|
662 |
+
|
663 |
+
const C14N = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
|
664 |
+
const C14N_COMMENTS = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments';
|
665 |
+
const EXC_C14N = 'http://www.w3.org/2001/10/xml-exc-c14n#';
|
666 |
+
const EXC_C14N_COMMENTS = 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments';
|
667 |
+
|
668 |
+
const template = '<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
669 |
+
<SignedInfo>
|
670 |
+
<SignatureMethod />
|
671 |
+
</SignedInfo>
|
672 |
+
</Signature>';
|
673 |
+
|
674 |
+
public $sigNode = NULL;
|
675 |
+
public $idKeys = array();
|
676 |
+
public $idNS = array();
|
677 |
+
private $signedInfo = NULL;
|
678 |
+
private $xPathCtx = NULL;
|
679 |
+
private $canonicalMethod = NULL;
|
680 |
+
private $prefix = NULL;
|
681 |
+
private $searchpfx = 'secdsig';
|
682 |
+
|
683 |
+
/* This variable contains an associative array of validated nodes. */
|
684 |
+
private $validatedNodes = NULL;
|
685 |
+
|
686 |
+
public function __construct() {
|
687 |
+
$sigdoc = new DOMDocument();
|
688 |
+
$sigdoc->loadXML(XMLSecurityDSig::template);
|
689 |
+
$this->sigNode = $sigdoc->documentElement;
|
690 |
+
}
|
691 |
+
|
692 |
+
private function resetXPathObj() {
|
693 |
+
$this->xPathCtx = NULL;
|
694 |
+
}
|
695 |
+
|
696 |
+
private function getXPathObj() {
|
697 |
+
if (empty($this->xPathCtx) && ! empty($this->sigNode)) {
|
698 |
+
$xpath = new DOMXPath($this->sigNode->ownerDocument);
|
699 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
700 |
+
$this->xPathCtx = $xpath;
|
701 |
+
}
|
702 |
+
return $this->xPathCtx;
|
703 |
+
}
|
704 |
+
|
705 |
+
static function generate_GUID($prefix='pfx') {
|
706 |
+
$uuid = md5(uniqid(rand(), true));
|
707 |
+
$guid = $prefix.substr($uuid,0,8)."-".
|
708 |
+
substr($uuid,8,4)."-".
|
709 |
+
substr($uuid,12,4)."-".
|
710 |
+
substr($uuid,16,4)."-".
|
711 |
+
substr($uuid,20,12);
|
712 |
+
return $guid;
|
713 |
+
}
|
714 |
+
|
715 |
+
public function signaturesCount($objDoc) {
|
716 |
+
if ($objDoc instanceof DOMDocument) {
|
717 |
+
$xpath = new DOMXPath($objDoc);
|
718 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
719 |
+
$query = ".//secdsig:Signature";
|
720 |
+
$nodeset = $xpath->query($query, $objDoc);
|
721 |
+
return $nodeset->length;
|
722 |
+
}
|
723 |
+
return NULL;
|
724 |
+
}
|
725 |
+
|
726 |
+
public function locateSignature($objDoc) {
|
727 |
+
if ($objDoc instanceof DOMDocument) {
|
728 |
+
$doc = $objDoc;
|
729 |
+
} else {
|
730 |
+
$doc = $objDoc->ownerDocument;
|
731 |
+
}
|
732 |
+
if ($doc) {
|
733 |
+
$xpath = new DOMXPath($doc);
|
734 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
735 |
+
$query = ".//secdsig:Signature";
|
736 |
+
$nodeset = $xpath->query($query, $objDoc);
|
737 |
+
$count = $nodeset->length;
|
738 |
+
$this->sigNode = $nodeset->item($count - 1);
|
739 |
+
return $this->sigNode;
|
740 |
+
}
|
741 |
+
return NULL;
|
742 |
+
}
|
743 |
+
|
744 |
+
public function createNewSignNode($name, $value=NULL) {
|
745 |
+
$doc = $this->sigNode->ownerDocument;
|
746 |
+
if ($this->prefix != null) {
|
747 |
+
$name = $this->prefix . ':' . $name;
|
748 |
+
}
|
749 |
+
if (!is_null($value)) {
|
750 |
+
$node = $doc->createElementNS(XMLSecurityDSig::XMLDSIGNS, $name, $value);
|
751 |
+
} else {
|
752 |
+
$node = $doc->createElementNS(XMLSecurityDSig::XMLDSIGNS, $name);
|
753 |
+
}
|
754 |
+
return $node;
|
755 |
+
}
|
756 |
+
|
757 |
+
public function setCanonicalMethod($method) {
|
758 |
+
switch ($method) {
|
759 |
+
case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315':
|
760 |
+
case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments':
|
761 |
+
case 'http://www.w3.org/2001/10/xml-exc-c14n#':
|
762 |
+
case 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments':
|
763 |
+
$this->canonicalMethod = $method;
|
764 |
+
break;
|
765 |
+
default:
|
766 |
+
throw new Exception('Invalid Canonical Method');
|
767 |
+
}
|
768 |
+
if ($xpath = $this->getXPathObj()) {
|
769 |
+
$query = './'.$this->searchpfx.':SignedInfo';
|
770 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
771 |
+
if ($sinfo = $nodeset->item(0)) {
|
772 |
+
$query = './'.$this->searchpfx.'CanonicalizationMethod';
|
773 |
+
$nodeset = $xpath->query($query, $sinfo);
|
774 |
+
if (! ($canonNode = $nodeset->item(0))) {
|
775 |
+
$canonNode = $this->createNewSignNode('CanonicalizationMethod');
|
776 |
+
$sinfo->insertBefore($canonNode, $sinfo->firstChild);
|
777 |
+
}
|
778 |
+
$canonNode->setAttribute('Algorithm', $this->canonicalMethod);
|
779 |
+
}
|
780 |
+
}
|
781 |
+
}
|
782 |
+
|
783 |
+
private function canonicalizeData($node, $canonicalmethod, $arXPath=NULL, $prefixList=NULL) {
|
784 |
+
$exclusive = FALSE;
|
785 |
+
$withComments = FALSE;
|
786 |
+
switch ($canonicalmethod) {
|
787 |
+
case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315':
|
788 |
+
$exclusive = FALSE;
|
789 |
+
$withComments = FALSE;
|
790 |
+
break;
|
791 |
+
case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments':
|
792 |
+
$withComments = TRUE;
|
793 |
+
break;
|
794 |
+
case 'http://www.w3.org/2001/10/xml-exc-c14n#':
|
795 |
+
$exclusive = TRUE;
|
796 |
+
break;
|
797 |
+
case 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments':
|
798 |
+
$exclusive = TRUE;
|
799 |
+
$withComments = TRUE;
|
800 |
+
break;
|
801 |
+
}
|
802 |
+
/* Support PHP versions < 5.2 not containing C14N methods in DOM extension */
|
803 |
+
$php_version = explode('.', PHP_VERSION);
|
804 |
+
if (($php_version[0] < 5) || ($php_version[0] == 5 && $php_version[1] < 2) ) {
|
805 |
+
if (! is_null($arXPath)) {
|
806 |
+
throw new Exception("PHP 5.2.0 or higher is required to perform XPath Transformations");
|
807 |
+
}
|
808 |
+
return C14NGeneral($node, $exclusive, $withComments);
|
809 |
+
}
|
810 |
+
return $node->C14N($exclusive, $withComments, $arXPath, $prefixList);
|
811 |
+
}
|
812 |
+
|
813 |
+
public function canonicalizeSignedInfo() {
|
814 |
+
|
815 |
+
$doc = $this->sigNode->ownerDocument;
|
816 |
+
$canonicalmethod = NULL;
|
817 |
+
if ($doc) {
|
818 |
+
$xpath = $this->getXPathObj();
|
819 |
+
$query = "./secdsig:SignedInfo";
|
820 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
821 |
+
if ($signInfoNode = $nodeset->item(0)) {
|
822 |
+
$query = "./secdsig:CanonicalizationMethod";
|
823 |
+
$nodeset = $xpath->query($query, $signInfoNode);
|
824 |
+
if ($canonNode = $nodeset->item(0)) {
|
825 |
+
$canonicalmethod = $canonNode->getAttribute('Algorithm');
|
826 |
+
}
|
827 |
+
$this->signedInfo = $this->canonicalizeData($signInfoNode, $canonicalmethod);
|
828 |
+
return $this->signedInfo;
|
829 |
+
}
|
830 |
+
}
|
831 |
+
return NULL;
|
832 |
+
}
|
833 |
+
|
834 |
+
public function calculateDigest ($digestAlgorithm, $data) {
|
835 |
+
switch ($digestAlgorithm) {
|
836 |
+
case XMLSecurityDSig::SHA1:
|
837 |
+
$alg = 'sha1';
|
838 |
+
break;
|
839 |
+
case XMLSecurityDSig::SHA256:
|
840 |
+
$alg = 'sha256';
|
841 |
+
break;
|
842 |
+
case XMLSecurityDSig::SHA384:
|
843 |
+
$alg = 'sha384';
|
844 |
+
break;
|
845 |
+
case XMLSecurityDSig::SHA512:
|
846 |
+
$alg = 'sha512';
|
847 |
+
break;
|
848 |
+
case XMLSecurityDSig::RIPEMD160:
|
849 |
+
$alg = 'ripemd160';
|
850 |
+
break;
|
851 |
+
default:
|
852 |
+
throw new Exception("Cannot validate digest: Unsupported Algorith <$digestAlgorithm>");
|
853 |
+
}
|
854 |
+
if (function_exists('hash')) {
|
855 |
+
return base64_encode(hash($alg, $data, TRUE));
|
856 |
+
} elseif (function_exists('mhash')) {
|
857 |
+
$alg = "MHASH_" . strtoupper($alg);
|
858 |
+
return base64_encode(mhash(constant($alg), $data));
|
859 |
+
} elseif ($alg === 'sha1') {
|
860 |
+
return base64_encode(sha1($data, TRUE));
|
861 |
+
} else {
|
862 |
+
throw new Exception('xmlseclibs is unable to calculate a digest. Maybe you need the mhash library?');
|
863 |
+
}
|
864 |
+
}
|
865 |
+
|
866 |
+
public function validateDigest($refNode, $data) {
|
867 |
+
$xpath = new DOMXPath($refNode->ownerDocument);
|
868 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
869 |
+
$query = 'string(./secdsig:DigestMethod/@Algorithm)';
|
870 |
+
$digestAlgorithm = $xpath->evaluate($query, $refNode);
|
871 |
+
$digValue = $this->calculateDigest($digestAlgorithm, $data);
|
872 |
+
$query = 'string(./secdsig:DigestValue)';
|
873 |
+
$digestValue = $xpath->evaluate($query, $refNode);
|
874 |
+
return ($digValue == $digestValue);
|
875 |
+
}
|
876 |
+
|
877 |
+
public function processTransforms($refNode, $objData, $includeCommentNodes = TRUE) {
|
878 |
+
$data = $objData;
|
879 |
+
$xpath = new DOMXPath($refNode->ownerDocument);
|
880 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
881 |
+
$query = './secdsig:Transforms/secdsig:Transform';
|
882 |
+
$nodelist = $xpath->query($query, $refNode);
|
883 |
+
$canonicalMethod = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
|
884 |
+
$arXPath = NULL;
|
885 |
+
$prefixList = NULL;
|
886 |
+
foreach ($nodelist AS $transform) {
|
887 |
+
$algorithm = $transform->getAttribute("Algorithm");
|
888 |
+
switch ($algorithm) {
|
889 |
+
case 'http://www.w3.org/2001/10/xml-exc-c14n#':
|
890 |
+
case 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments':
|
891 |
+
|
892 |
+
if(!$includeCommentNodes) {
|
893 |
+
/* We remove comment nodes by forcing it to use a canonicalization
|
894 |
+
* without comments.
|
895 |
+
*/
|
896 |
+
$canonicalMethod = 'http://www.w3.org/2001/10/xml-exc-c14n#';
|
897 |
+
} else {
|
898 |
+
$canonicalMethod = $algorithm;
|
899 |
+
}
|
900 |
+
|
901 |
+
$node = $transform->firstChild;
|
902 |
+
while ($node) {
|
903 |
+
if ($node->localName == 'InclusiveNamespaces') {
|
904 |
+
if ($pfx = $node->getAttribute('PrefixList')) {
|
905 |
+
$arpfx = array();
|
906 |
+
$pfxlist = explode(" ", $pfx);
|
907 |
+
foreach ($pfxlist AS $pfx) {
|
908 |
+
$val = trim($pfx);
|
909 |
+
if (! empty($val)) {
|
910 |
+
$arpfx[] = $val;
|
911 |
+
}
|
912 |
+
}
|
913 |
+
if (count($arpfx) > 0) {
|
914 |
+
$prefixList = $arpfx;
|
915 |
+
}
|
916 |
+
}
|
917 |
+
break;
|
918 |
+
}
|
919 |
+
$node = $node->nextSibling;
|
920 |
+
}
|
921 |
+
break;
|
922 |
+
case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315':
|
923 |
+
case 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments':
|
924 |
+
if(!$includeCommentNodes) {
|
925 |
+
/* We remove comment nodes by forcing it to use a canonicalization
|
926 |
+
* without comments.
|
927 |
+
*/
|
928 |
+
$canonicalMethod = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
|
929 |
+
} else {
|
930 |
+
$canonicalMethod = $algorithm;
|
931 |
+
}
|
932 |
+
|
933 |
+
break;
|
934 |
+
case 'http://www.w3.org/TR/1999/REC-xpath-19991116':
|
935 |
+
$node = $transform->firstChild;
|
936 |
+
while ($node) {
|
937 |
+
if ($node->localName == 'XPath') {
|
938 |
+
$arXPath = array();
|
939 |
+
$arXPath['query'] = '(.//. | .//@* | .//namespace::*)['.$node->nodeValue.']';
|
940 |
+
$arXpath['namespaces'] = array();
|
941 |
+
$nslist = $xpath->query('./namespace::*', $node);
|
942 |
+
foreach ($nslist AS $nsnode) {
|
943 |
+
if ($nsnode->localName != "xml") {
|
944 |
+
$arXPath['namespaces'][$nsnode->localName] = $nsnode->nodeValue;
|
945 |
+
}
|
946 |
+
}
|
947 |
+
break;
|
948 |
+
}
|
949 |
+
$node = $node->nextSibling;
|
950 |
+
}
|
951 |
+
break;
|
952 |
+
}
|
953 |
+
}
|
954 |
+
if ($data instanceof DOMNode) {
|
955 |
+
$data = $this->canonicalizeData($objData, $canonicalMethod, $arXPath, $prefixList);
|
956 |
+
}
|
957 |
+
return $data;
|
958 |
+
}
|
959 |
+
|
960 |
+
public function processRefNode($refNode) {
|
961 |
+
$dataObject = NULL;
|
962 |
+
|
963 |
+
/*
|
964 |
+
* Depending on the URI, we may not want to include comments in the result
|
965 |
+
* See: http://www.w3.org/TR/xmldsig-core/#sec-ReferenceProcessingModel
|
966 |
+
*/
|
967 |
+
$includeCommentNodes = TRUE;
|
968 |
+
|
969 |
+
if ($uri = $refNode->getAttribute("URI")) {
|
970 |
+
$arUrl = parse_url($uri);
|
971 |
+
if (empty($arUrl['path'])) {
|
972 |
+
if ($identifier = $arUrl['fragment']) {
|
973 |
+
|
974 |
+
/* This reference identifies a node with the given id by using
|
975 |
+
* a URI on the form "#identifier". This should not include comments.
|
976 |
+
*/
|
977 |
+
$includeCommentNodes = FALSE;
|
978 |
+
|
979 |
+
$xPath = new DOMXPath($refNode->ownerDocument);
|
980 |
+
if ($this->idNS && is_array($this->idNS)) {
|
981 |
+
foreach ($this->idNS AS $nspf=>$ns) {
|
982 |
+
$xPath->registerNamespace($nspf, $ns);
|
983 |
+
}
|
984 |
+
}
|
985 |
+
$iDlist = '@Id="'.$identifier.'"';
|
986 |
+
if (is_array($this->idKeys)) {
|
987 |
+
foreach ($this->idKeys AS $idKey) {
|
988 |
+
$iDlist .= " or @$idKey='$identifier'";
|
989 |
+
}
|
990 |
+
}
|
991 |
+
$query = '//*['.$iDlist.']';
|
992 |
+
$dataObject = $xPath->query($query)->item(0);
|
993 |
+
} else {
|
994 |
+
$dataObject = $refNode->ownerDocument;
|
995 |
+
}
|
996 |
+
} else {
|
997 |
+
$dataObject = file_get_contents($arUrl);
|
998 |
+
}
|
999 |
+
} else {
|
1000 |
+
/* This reference identifies the root node with an empty URI. This should
|
1001 |
+
* not include comments.
|
1002 |
+
*/
|
1003 |
+
$includeCommentNodes = FALSE;
|
1004 |
+
|
1005 |
+
$dataObject = $refNode->ownerDocument;
|
1006 |
+
}
|
1007 |
+
$data = $this->processTransforms($refNode, $dataObject, $includeCommentNodes);
|
1008 |
+
if (!$this->validateDigest($refNode, $data)) {
|
1009 |
+
return FALSE;
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
if ($dataObject instanceof DOMNode) {
|
1013 |
+
/* Add this node to the list of validated nodes. */
|
1014 |
+
if(! empty($identifier)) {
|
1015 |
+
$this->validatedNodes[$identifier] = $dataObject;
|
1016 |
+
} else {
|
1017 |
+
$this->validatedNodes[] = $dataObject;
|
1018 |
+
}
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
return TRUE;
|
1022 |
+
}
|
1023 |
+
|
1024 |
+
public function getRefNodeID($refNode) {
|
1025 |
+
if ($uri = $refNode->getAttribute("URI")) {
|
1026 |
+
$arUrl = parse_url($uri);
|
1027 |
+
if (empty($arUrl['path'])) {
|
1028 |
+
if ($identifier = $arUrl['fragment']) {
|
1029 |
+
return $identifier;
|
1030 |
+
}
|
1031 |
+
}
|
1032 |
+
}
|
1033 |
+
return null;
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
public function getRefIDs() {
|
1037 |
+
$refids = array();
|
1038 |
+
$doc = $this->sigNode->ownerDocument;
|
1039 |
+
|
1040 |
+
$xpath = $this->getXPathObj();
|
1041 |
+
$query = "./secdsig:SignedInfo/secdsig:Reference";
|
1042 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
1043 |
+
if ($nodeset->length == 0) {
|
1044 |
+
throw new Exception("Reference nodes not found");
|
1045 |
+
}
|
1046 |
+
foreach ($nodeset AS $refNode) {
|
1047 |
+
$refids[] = $this->getRefNodeID($refNode);
|
1048 |
+
}
|
1049 |
+
return $refids;
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
public function validateReference() {
|
1053 |
+
$doc = $this->sigNode->ownerDocument;
|
1054 |
+
if (! $doc->isSameNode($this->sigNode)) {
|
1055 |
+
$this->sigNode->parentNode->removeChild($this->sigNode);
|
1056 |
+
}
|
1057 |
+
$xpath = $this->getXPathObj();
|
1058 |
+
$query = "./secdsig:SignedInfo/secdsig:Reference";
|
1059 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
1060 |
+
if ($nodeset->length == 0) {
|
1061 |
+
throw new Exception("Reference nodes not found");
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
/* Initialize/reset the list of validated nodes. */
|
1065 |
+
$this->validatedNodes = array();
|
1066 |
+
|
1067 |
+
foreach ($nodeset AS $refNode) {
|
1068 |
+
if (! $this->processRefNode($refNode)) {
|
1069 |
+
/* Clear the list of validated nodes. */
|
1070 |
+
$this->validatedNodes = NULL;
|
1071 |
+
throw new Exception("Reference validation failed");
|
1072 |
+
}
|
1073 |
+
}
|
1074 |
+
return TRUE;
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
private function addRefInternal($sinfoNode, $node, $algorithm, $arTransforms=NULL, $options=NULL) {
|
1078 |
+
$prefix = NULL;
|
1079 |
+
$prefix_ns = NULL;
|
1080 |
+
$id_name = 'Id';
|
1081 |
+
$overwrite_id = TRUE;
|
1082 |
+
$force_uri = FALSE;
|
1083 |
+
|
1084 |
+
if (is_array($options)) {
|
1085 |
+
$prefix = empty($options['prefix'])?NULL:$options['prefix'];
|
1086 |
+
$prefix_ns = empty($options['prefix_ns'])?NULL:$options['prefix_ns'];
|
1087 |
+
$id_name = empty($options['id_name'])?'Id':$options['id_name'];
|
1088 |
+
$overwrite_id = !isset($options['overwrite'])?TRUE:(bool)$options['overwrite'];
|
1089 |
+
$force_uri = !isset($options['force_uri'])?FALSE:(bool)$options['force_uri'];
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
$attname = $id_name;
|
1093 |
+
if (! empty($prefix)) {
|
1094 |
+
$attname = $prefix.':'.$attname;
|
1095 |
+
}
|
1096 |
+
|
1097 |
+
$refNode = $this->createNewSignNode('Reference');
|
1098 |
+
$sinfoNode->appendChild($refNode);
|
1099 |
+
|
1100 |
+
if (! $node instanceof DOMDocument) {
|
1101 |
+
$uri = NULL;
|
1102 |
+
if (! $overwrite_id) {
|
1103 |
+
$uri = $node->getAttributeNS($prefix_ns, $id_name);
|
1104 |
+
}
|
1105 |
+
if (empty($uri)) {
|
1106 |
+
$uri = XMLSecurityDSig::generate_GUID();
|
1107 |
+
$node->setAttributeNS($prefix_ns, $attname, $uri);
|
1108 |
+
}
|
1109 |
+
$refNode->setAttribute("URI", '#'.$uri);
|
1110 |
+
} elseif ($force_uri) {
|
1111 |
+
$refNode->setAttribute("URI", '');
|
1112 |
+
}
|
1113 |
+
|
1114 |
+
$transNodes = $this->createNewSignNode('Transforms');
|
1115 |
+
$refNode->appendChild($transNodes);
|
1116 |
+
|
1117 |
+
if (is_array($arTransforms)) {
|
1118 |
+
foreach ($arTransforms AS $transform) {
|
1119 |
+
$transNode = $this->createNewSignNode('Transform');
|
1120 |
+
$transNodes->appendChild($transNode);
|
1121 |
+
if (is_array($transform) &&
|
1122 |
+
(! empty($transform['http://www.w3.org/TR/1999/REC-xpath-19991116'])) &&
|
1123 |
+
(! empty($transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['query']))) {
|
1124 |
+
$transNode->setAttribute('Algorithm', 'http://www.w3.org/TR/1999/REC-xpath-19991116');
|
1125 |
+
$XPathNode = $this->createNewSignNode('XPath', $transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['query']);
|
1126 |
+
$transNode->appendChild($XPathNode);
|
1127 |
+
if (! empty($transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['namespaces'])) {
|
1128 |
+
foreach ($transform['http://www.w3.org/TR/1999/REC-xpath-19991116']['namespaces'] AS $prefix => $namespace) {
|
1129 |
+
$XPathNode->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:$prefix", $namespace);
|
1130 |
+
}
|
1131 |
+
}
|
1132 |
+
} else {
|
1133 |
+
$transNode->setAttribute('Algorithm', $transform);
|
1134 |
+
}
|
1135 |
+
}
|
1136 |
+
} elseif (! empty($this->canonicalMethod)) {
|
1137 |
+
$transNode = $this->createNewSignNode('Transform');
|
1138 |
+
$transNodes->appendChild($transNode);
|
1139 |
+
$transNode->setAttribute('Algorithm', $this->canonicalMethod);
|
1140 |
+
}
|
1141 |
+
|
1142 |
+
$canonicalData = $this->processTransforms($refNode, $node);
|
1143 |
+
$digValue = $this->calculateDigest($algorithm, $canonicalData);
|
1144 |
+
|
1145 |
+
$digestMethod = $this->createNewSignNode('DigestMethod');
|
1146 |
+
$refNode->appendChild($digestMethod);
|
1147 |
+
$digestMethod->setAttribute('Algorithm', $algorithm);
|
1148 |
+
|
1149 |
+
$digestValue = $this->createNewSignNode('DigestValue', $digValue);
|
1150 |
+
$refNode->appendChild($digestValue);
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
public function addReference($node, $algorithm, $arTransforms=NULL, $options=NULL) {
|
1154 |
+
if ($xpath = $this->getXPathObj()) {
|
1155 |
+
$query = "./secdsig:SignedInfo";
|
1156 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
1157 |
+
if ($sInfo = $nodeset->item(0)) {
|
1158 |
+
$this->addRefInternal($sInfo, $node, $algorithm, $arTransforms, $options);
|
1159 |
+
}
|
1160 |
+
}
|
1161 |
+
}
|
1162 |
+
|
1163 |
+
public function addReferenceList($arNodes, $algorithm, $arTransforms=NULL, $options=NULL) {
|
1164 |
+
if ($xpath = $this->getXPathObj()) {
|
1165 |
+
$query = "./secdsig:SignedInfo";
|
1166 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
1167 |
+
if ($sInfo = $nodeset->item(0)) {
|
1168 |
+
foreach ($arNodes AS $node) {
|
1169 |
+
$this->addRefInternal($sInfo, $node, $algorithm, $arTransforms, $options);
|
1170 |
+
}
|
1171 |
+
}
|
1172 |
+
}
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
public function addObject($data, $mimetype=NULL, $encoding=NULL) {
|
1176 |
+
$objNode = $this->createNewSignNode('Object');
|
1177 |
+
$this->sigNode->appendChild($objNode);
|
1178 |
+
if (! empty($mimetype)) {
|
1179 |
+
$objNode->setAtribute('MimeType', $mimetype);
|
1180 |
+
}
|
1181 |
+
if (! empty($encoding)) {
|
1182 |
+
$objNode->setAttribute('Encoding', $encoding);
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
if ($data instanceof DOMElement) {
|
1186 |
+
$newData = $this->sigNode->ownerDocument->importNode($data, TRUE);
|
1187 |
+
} else {
|
1188 |
+
$newData = $this->sigNode->ownerDocument->createTextNode($data);
|
1189 |
+
}
|
1190 |
+
$objNode->appendChild($newData);
|
1191 |
+
|
1192 |
+
return $objNode;
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
public function locateKey($node=NULL) {
|
1196 |
+
if (empty($node)) {
|
1197 |
+
$node = $this->sigNode;
|
1198 |
+
}
|
1199 |
+
if (! $node instanceof DOMNode) {
|
1200 |
+
return NULL;
|
1201 |
+
}
|
1202 |
+
if ($doc = $node->ownerDocument) {
|
1203 |
+
$xpath = new DOMXPath($doc);
|
1204 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
1205 |
+
$query = "string(./secdsig:SignedInfo/secdsig:SignatureMethod/@Algorithm)";
|
1206 |
+
$algorithm = $xpath->evaluate($query, $node);
|
1207 |
+
if ($algorithm) {
|
1208 |
+
try {
|
1209 |
+
$objKey = new XMLSecurityKey($algorithm, array('type'=>'public'));
|
1210 |
+
} catch (Exception $e) {
|
1211 |
+
return NULL;
|
1212 |
+
}
|
1213 |
+
return $objKey;
|
1214 |
+
}
|
1215 |
+
}
|
1216 |
+
return NULL;
|
1217 |
+
}
|
1218 |
+
|
1219 |
+
public function verify($objKey) {
|
1220 |
+
$doc = $this->sigNode->ownerDocument;
|
1221 |
+
$xpath = new DOMXPath($doc);
|
1222 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
1223 |
+
$query = "string(./secdsig:SignatureValue)";
|
1224 |
+
$sigValue = $xpath->evaluate($query, $this->sigNode);
|
1225 |
+
if (empty($sigValue)) {
|
1226 |
+
throw new Exception("Unable to locate SignatureValue");
|
1227 |
+
}
|
1228 |
+
return $objKey->verifySignature($this->signedInfo, base64_decode($sigValue));
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
public function signData($objKey, $data) {
|
1232 |
+
return $objKey->signData($data);
|
1233 |
+
}
|
1234 |
+
|
1235 |
+
public function sign($objKey, $appendToNode = NULL) {
|
1236 |
+
// If we have a parent node append it now so C14N properly works
|
1237 |
+
if ($appendToNode != NULL) {
|
1238 |
+
$this->resetXPathObj();
|
1239 |
+
$this->appendSignature($appendToNode);
|
1240 |
+
$this->sigNode = $appendToNode->lastChild;
|
1241 |
+
}
|
1242 |
+
if ($xpath = $this->getXPathObj()) {
|
1243 |
+
$query = "./secdsig:SignedInfo";
|
1244 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
1245 |
+
if ($sInfo = $nodeset->item(0)) {
|
1246 |
+
$query = "./secdsig:SignatureMethod";
|
1247 |
+
$nodeset = $xpath->query($query, $sInfo);
|
1248 |
+
$sMethod = $nodeset->item(0);
|
1249 |
+
$sMethod->setAttribute('Algorithm', $objKey->type);
|
1250 |
+
$data = $this->canonicalizeData($sInfo, $this->canonicalMethod);
|
1251 |
+
$sigValue = base64_encode($this->signData($objKey, $data));
|
1252 |
+
$sigValueNode = $this->createNewSignNode('SignatureValue', $sigValue);
|
1253 |
+
if ($infoSibling = $sInfo->nextSibling) {
|
1254 |
+
$infoSibling->parentNode->insertBefore($sigValueNode, $infoSibling);
|
1255 |
+
} else {
|
1256 |
+
$this->sigNode->appendChild($sigValueNode);
|
1257 |
+
}
|
1258 |
+
}
|
1259 |
+
}
|
1260 |
+
}
|
1261 |
+
|
1262 |
+
public function appendCert() {
|
1263 |
+
|
1264 |
+
}
|
1265 |
+
|
1266 |
+
public function appendKey($objKey, $parent=NULL) {
|
1267 |
+
$objKey->serializeKey($parent);
|
1268 |
+
}
|
1269 |
+
|
1270 |
+
|
1271 |
+
/**
|
1272 |
+
* This function inserts the signature element.
|
1273 |
+
*
|
1274 |
+
* The signature element will be appended to the element, unless $beforeNode is specified. If $beforeNode
|
1275 |
+
* is specified, the signature element will be inserted as the last element before $beforeNode.
|
1276 |
+
*
|
1277 |
+
* @param $node The node the signature element should be inserted into.
|
1278 |
+
* @param $beforeNode The node the signature element should be located before.
|
1279 |
+
*
|
1280 |
+
* @return DOMNode The signature element node
|
1281 |
+
*/
|
1282 |
+
public function insertSignature($node, $beforeNode = NULL) {
|
1283 |
+
|
1284 |
+
$document = $node->ownerDocument;
|
1285 |
+
$signatureElement = $document->importNode($this->sigNode, TRUE);
|
1286 |
+
|
1287 |
+
if($beforeNode == NULL) {
|
1288 |
+
return $node->insertBefore($signatureElement);
|
1289 |
+
} else {
|
1290 |
+
return $node->insertBefore($signatureElement, $beforeNode);
|
1291 |
+
}
|
1292 |
+
}
|
1293 |
+
|
1294 |
+
public function appendSignature($parentNode, $insertBefore = FALSE) {
|
1295 |
+
$beforeNode = $insertBefore ? $parentNode->firstChild : NULL;
|
1296 |
+
return $this->insertSignature($parentNode, $beforeNode);
|
1297 |
+
}
|
1298 |
+
|
1299 |
+
static function get509XCert($cert, $isPEMFormat=TRUE) {
|
1300 |
+
$certs = XMLSecurityDSig::staticGet509XCerts($cert, $isPEMFormat);
|
1301 |
+
if (! empty($certs)) {
|
1302 |
+
return $certs[0];
|
1303 |
+
}
|
1304 |
+
return '';
|
1305 |
+
}
|
1306 |
+
|
1307 |
+
static function staticGet509XCerts($certs, $isPEMFormat=TRUE) {
|
1308 |
+
if ($isPEMFormat) {
|
1309 |
+
$data = '';
|
1310 |
+
$certlist = array();
|
1311 |
+
$arCert = explode("\n", $certs);
|
1312 |
+
$inData = FALSE;
|
1313 |
+
foreach ($arCert AS $curData) {
|
1314 |
+
if (! $inData) {
|
1315 |
+
if (strncmp($curData, '-----BEGIN CERTIFICATE', 22) == 0) {
|
1316 |
+
$inData = TRUE;
|
1317 |
+
}
|
1318 |
+
} else {
|
1319 |
+
if (strncmp($curData, '-----END CERTIFICATE', 20) == 0) {
|
1320 |
+
$inData = FALSE;
|
1321 |
+
$certlist[] = $data;
|
1322 |
+
$data = '';
|
1323 |
+
continue;
|
1324 |
+
}
|
1325 |
+
$data .= trim($curData);
|
1326 |
+
}
|
1327 |
+
}
|
1328 |
+
return $certlist;
|
1329 |
+
} else {
|
1330 |
+
return array($certs);
|
1331 |
+
}
|
1332 |
+
}
|
1333 |
+
|
1334 |
+
static function staticAdd509Cert($parentRef, $cert, $isPEMFormat=TRUE, $isURL=False, $xpath=NULL, $options=NULL) {
|
1335 |
+
if ($isURL) {
|
1336 |
+
$cert = file_get_contents($cert);
|
1337 |
+
}
|
1338 |
+
if (! $parentRef instanceof DOMElement) {
|
1339 |
+
throw new Exception('Invalid parent Node parameter');
|
1340 |
+
}
|
1341 |
+
$baseDoc = $parentRef->ownerDocument;
|
1342 |
+
|
1343 |
+
if (empty($xpath)) {
|
1344 |
+
$xpath = new DOMXPath($parentRef->ownerDocument);
|
1345 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
1346 |
+
}
|
1347 |
+
|
1348 |
+
$query = "./secdsig:KeyInfo";
|
1349 |
+
$nodeset = $xpath->query($query, $parentRef);
|
1350 |
+
$keyInfo = $nodeset->item(0);
|
1351 |
+
if (! $keyInfo) {
|
1352 |
+
$inserted = FALSE;
|
1353 |
+
$keyInfo = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:KeyInfo');
|
1354 |
+
|
1355 |
+
$query = "./secdsig:Object";
|
1356 |
+
$nodeset = $xpath->query($query, $parentRef);
|
1357 |
+
if ($sObject = $nodeset->item(0)) {
|
1358 |
+
$sObject->parentNode->insertBefore($keyInfo, $sObject);
|
1359 |
+
$inserted = TRUE;
|
1360 |
+
}
|
1361 |
+
|
1362 |
+
if (! $inserted) {
|
1363 |
+
$parentRef->appendChild($keyInfo);
|
1364 |
+
}
|
1365 |
+
}
|
1366 |
+
|
1367 |
+
// Add all certs if there are more than one
|
1368 |
+
$certs = XMLSecurityDSig::staticGet509XCerts($cert, $isPEMFormat);
|
1369 |
+
|
1370 |
+
// Attach X509 data node
|
1371 |
+
$x509DataNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509Data');
|
1372 |
+
$keyInfo->appendChild($x509DataNode);
|
1373 |
+
|
1374 |
+
$issuerSerial = FALSE;
|
1375 |
+
$subjectName = FALSE;
|
1376 |
+
if (is_array($options)) {
|
1377 |
+
if (! empty($options['issuerSerial'])) {
|
1378 |
+
$issuerSerial = TRUE;
|
1379 |
+
}
|
1380 |
+
}
|
1381 |
+
|
1382 |
+
// Attach all certificate nodes and any additional data
|
1383 |
+
foreach ($certs as $X509Cert){
|
1384 |
+
if ($issuerSerial) {
|
1385 |
+
if ($certData = openssl_x509_parse("-----BEGIN CERTIFICATE-----\n".chunk_split($X509Cert, 64, "\n")."-----END CERTIFICATE-----\n")) {
|
1386 |
+
if ($issuerSerial && ! empty($certData['issuer']) && ! empty($certData['serialNumber'])) {
|
1387 |
+
if (is_array($certData['issuer'])) {
|
1388 |
+
$parts = array();
|
1389 |
+
foreach ($certData['issuer'] AS $key => $value) {
|
1390 |
+
array_unshift($parts, "$key=$value" . $issuer);
|
1391 |
+
}
|
1392 |
+
$issuerName = implode(',', $parts);
|
1393 |
+
} else {
|
1394 |
+
$issuerName = $certData['issuer'];
|
1395 |
+
}
|
1396 |
+
|
1397 |
+
$x509IssuerNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509IssuerSerial');
|
1398 |
+
$x509DataNode->appendChild($x509IssuerNode);
|
1399 |
+
|
1400 |
+
$x509Node = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509IssuerName', $issuerName);
|
1401 |
+
$x509IssuerNode->appendChild($x509Node);
|
1402 |
+
$x509Node = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509SerialNumber', $certData['serialNumber']);
|
1403 |
+
$x509IssuerNode->appendChild($x509Node);
|
1404 |
+
}
|
1405 |
+
}
|
1406 |
+
|
1407 |
+
}
|
1408 |
+
$x509CertNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509Certificate', $X509Cert);
|
1409 |
+
$x509DataNode->appendChild($x509CertNode);
|
1410 |
+
}
|
1411 |
+
}
|
1412 |
+
|
1413 |
+
public function add509Cert($cert, $isPEMFormat=TRUE, $isURL=False, $options=NULL) {
|
1414 |
+
if ($xpath = $this->getXPathObj()) {
|
1415 |
+
self::staticAdd509Cert($this->sigNode, $cert, $isPEMFormat, $isURL, $xpath, $options);
|
1416 |
+
}
|
1417 |
+
}
|
1418 |
+
|
1419 |
+
function addKeyInfoAndName($keyName, $xpath = NULL) {
|
1420 |
+
|
1421 |
+
$baseDoc = $this->sigNode->ownerDocument;
|
1422 |
+
|
1423 |
+
if (empty($xpath)) {
|
1424 |
+
$xpath = new DOMXPath($baseDoc);
|
1425 |
+
$xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS);
|
1426 |
+
}
|
1427 |
+
|
1428 |
+
$query = "./secdsig:KeyInfo";
|
1429 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
1430 |
+
$keyInfo = $nodeset->item(0);
|
1431 |
+
if (!$keyInfo) {
|
1432 |
+
$inserted = FALSE;
|
1433 |
+
$keyInfo = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'KeyInfo');
|
1434 |
+
|
1435 |
+
$query = "./secdsig:Object";
|
1436 |
+
$nodeset = $xpath->query($query, $this->sigNode);
|
1437 |
+
if ($sObject = $nodeset->item(0)) {
|
1438 |
+
$sObject->parentNode->insertBefore($keyInfo, $sObject);
|
1439 |
+
$inserted = TRUE;
|
1440 |
+
}
|
1441 |
+
if (!$inserted) {
|
1442 |
+
$this->sigNode->appendChild($keyInfo);
|
1443 |
+
}
|
1444 |
+
}
|
1445 |
+
$keyInfo->appendChild($baseDoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'KeyName', $keyName));
|
1446 |
+
}
|
1447 |
+
|
1448 |
+
/* This function retrieves an associative array of the validated nodes.
|
1449 |
+
*
|
1450 |
+
* The array will contain the id of the referenced node as the key and the node itself
|
1451 |
+
* as the value.
|
1452 |
+
*
|
1453 |
+
* Returns:
|
1454 |
+
* An associative array of validated nodes or NULL if no nodes have been validated.
|
1455 |
+
*/
|
1456 |
+
public function getValidatedNodes() {
|
1457 |
+
return $this->validatedNodes;
|
1458 |
+
}
|
1459 |
+
}
|
1460 |
+
|
1461 |
+
class XMLSecEnc {
|
1462 |
+
const template = "<xenc:EncryptedData xmlns:xenc='http://www.w3.org/2001/04/xmlenc#'>
|
1463 |
+
<xenc:CipherData>
|
1464 |
+
<xenc:CipherValue></xenc:CipherValue>
|
1465 |
+
</xenc:CipherData>
|
1466 |
+
</xenc:EncryptedData>";
|
1467 |
+
|
1468 |
+
const Element = 'http://www.w3.org/2001/04/xmlenc#Element';
|
1469 |
+
const Content = 'http://www.w3.org/2001/04/xmlenc#Content';
|
1470 |
+
const URI = 3;
|
1471 |
+
const XMLENCNS = 'http://www.w3.org/2001/04/xmlenc#';
|
1472 |
+
|
1473 |
+
private $encdoc = NULL;
|
1474 |
+
private $rawNode = NULL;
|
1475 |
+
public $type = NULL;
|
1476 |
+
public $encKey = NULL;
|
1477 |
+
private $references = array();
|
1478 |
+
|
1479 |
+
public function __construct() {
|
1480 |
+
$this->_resetTemplate();
|
1481 |
+
}
|
1482 |
+
|
1483 |
+
private function _resetTemplate(){
|
1484 |
+
$this->encdoc = new DOMDocument();
|
1485 |
+
$this->encdoc->loadXML(XMLSecEnc::template);
|
1486 |
+
}
|
1487 |
+
|
1488 |
+
public function addReference($name, $node, $type) {
|
1489 |
+
if (! $node instanceOf DOMNode) {
|
1490 |
+
throw new Exception('$node is not of type DOMNode');
|
1491 |
+
}
|
1492 |
+
$curencdoc = $this->encdoc;
|
1493 |
+
$this->_resetTemplate();
|
1494 |
+
$encdoc = $this->encdoc;
|
1495 |
+
$this->encdoc = $curencdoc;
|
1496 |
+
$refuri = XMLSecurityDSig::generate_GUID();
|
1497 |
+
$element = $encdoc->documentElement;
|
1498 |
+
$element->setAttribute("Id", $refuri);
|
1499 |
+
$this->references[$name] = array("node" => $node, "type" => $type, "encnode" => $encdoc, "refuri" => $refuri);
|
1500 |
+
}
|
1501 |
+
|
1502 |
+
public function setNode($node) {
|
1503 |
+
$this->rawNode = $node;
|
1504 |
+
}
|
1505 |
+
|
1506 |
+
/**
|
1507 |
+
* Encrypt the selected node with the given key.
|
1508 |
+
*
|
1509 |
+
* @param XMLSecurityKey $objKey The encryption key and algorithm.
|
1510 |
+
* @param bool $replace Whether the encrypted node should be replaced in the original tree. Default is TRUE.
|
1511 |
+
* @return DOMElement The <xenc:EncryptedData>-element.
|
1512 |
+
*/
|
1513 |
+
public function encryptNode($objKey, $replace=TRUE) {
|
1514 |
+
$data = '';
|
1515 |
+
if (empty($this->rawNode)) {
|
1516 |
+
throw new Exception('Node to encrypt has not been set');
|
1517 |
+
}
|
1518 |
+
if (! $objKey instanceof XMLSecurityKey) {
|
1519 |
+
throw new Exception('Invalid Key');
|
1520 |
+
}
|
1521 |
+
$doc = $this->rawNode->ownerDocument;
|
1522 |
+
$xPath = new DOMXPath($this->encdoc);
|
1523 |
+
$objList = $xPath->query('/xenc:EncryptedData/xenc:CipherData/xenc:CipherValue');
|
1524 |
+
$cipherValue = $objList->item(0);
|
1525 |
+
if ($cipherValue == NULL) {
|
1526 |
+
throw new Exception('Error locating CipherValue element within template');
|
1527 |
+
}
|
1528 |
+
switch ($this->type) {
|
1529 |
+
case (XMLSecEnc::Element):
|
1530 |
+
$data = $doc->saveXML($this->rawNode);
|
1531 |
+
$this->encdoc->documentElement->setAttribute('Type', XMLSecEnc::Element);
|
1532 |
+
break;
|
1533 |
+
case (XMLSecEnc::Content):
|
1534 |
+
$children = $this->rawNode->childNodes;
|
1535 |
+
foreach ($children AS $child) {
|
1536 |
+
$data .= $doc->saveXML($child);
|
1537 |
+
}
|
1538 |
+
$this->encdoc->documentElement->setAttribute('Type', XMLSecEnc::Content);
|
1539 |
+
break;
|
1540 |
+
default:
|
1541 |
+
throw new Exception('Type is currently not supported');
|
1542 |
+
return;
|
1543 |
+
}
|
1544 |
+
|
1545 |
+
$encMethod = $this->encdoc->documentElement->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:EncryptionMethod'));
|
1546 |
+
$encMethod->setAttribute('Algorithm', $objKey->getAlgorith());
|
1547 |
+
$cipherValue->parentNode->parentNode->insertBefore($encMethod, $cipherValue->parentNode->parentNode->firstChild);
|
1548 |
+
|
1549 |
+
$strEncrypt = base64_encode($objKey->encryptData($data));
|
1550 |
+
$value = $this->encdoc->createTextNode($strEncrypt);
|
1551 |
+
$cipherValue->appendChild($value);
|
1552 |
+
|
1553 |
+
if ($replace) {
|
1554 |
+
switch ($this->type) {
|
1555 |
+
case (XMLSecEnc::Element):
|
1556 |
+
if ($this->rawNode->nodeType == XML_DOCUMENT_NODE) {
|
1557 |
+
return $this->encdoc;
|
1558 |
+
}
|
1559 |
+
$importEnc = $this->rawNode->ownerDocument->importNode($this->encdoc->documentElement, TRUE);
|
1560 |
+
$this->rawNode->parentNode->replaceChild($importEnc, $this->rawNode);
|
1561 |
+
return $importEnc;
|
1562 |
+
break;
|
1563 |
+
case (XMLSecEnc::Content):
|
1564 |
+
$importEnc = $this->rawNode->ownerDocument->importNode($this->encdoc->documentElement, TRUE);
|
1565 |
+
while($this->rawNode->firstChild) {
|
1566 |
+
$this->rawNode->removeChild($this->rawNode->firstChild);
|
1567 |
+
}
|
1568 |
+
$this->rawNode->appendChild($importEnc);
|
1569 |
+
return $importEnc;
|
1570 |
+
break;
|
1571 |
+
}
|
1572 |
+
} else {
|
1573 |
+
return $this->encdoc->documentElement;
|
1574 |
+
}
|
1575 |
+
}
|
1576 |
+
|
1577 |
+
public function encryptReferences($objKey) {
|
1578 |
+
$curRawNode = $this->rawNode;
|
1579 |
+
$curType = $this->type;
|
1580 |
+
foreach ($this->references AS $name=>$reference) {
|
1581 |
+
$this->encdoc = $reference["encnode"];
|
1582 |
+
$this->rawNode = $reference["node"];
|
1583 |
+
$this->type = $reference["type"];
|
1584 |
+
try {
|
1585 |
+
$encNode = $this->encryptNode($objKey);
|
1586 |
+
$this->references[$name]["encnode"] = $encNode;
|
1587 |
+
} catch (Exception $e) {
|
1588 |
+
$this->rawNode = $curRawNode;
|
1589 |
+
$this->type = $curType;
|
1590 |
+
throw $e;
|
1591 |
+
}
|
1592 |
+
}
|
1593 |
+
$this->rawNode = $curRawNode;
|
1594 |
+
$this->type = $curType;
|
1595 |
+
}
|
1596 |
+
|
1597 |
+
/**
|
1598 |
+
* Retrieve the CipherValue text from this encrypted node.
|
1599 |
+
*
|
1600 |
+
* @return string|NULL The Ciphervalue text, or NULL if no CipherValue is found.
|
1601 |
+
*/
|
1602 |
+
public function getCipherValue() {
|
1603 |
+
if (empty($this->rawNode)) {
|
1604 |
+
throw new Exception('Node to decrypt has not been set');
|
1605 |
+
}
|
1606 |
+
|
1607 |
+
$doc = $this->rawNode->ownerDocument;
|
1608 |
+
$xPath = new DOMXPath($doc);
|
1609 |
+
$xPath->registerNamespace('xmlencr', XMLSecEnc::XMLENCNS);
|
1610 |
+
/* Only handles embedded content right now and not a reference */
|
1611 |
+
$query = "./xmlencr:CipherData/xmlencr:CipherValue";
|
1612 |
+
$nodeset = $xPath->query($query, $this->rawNode);
|
1613 |
+
$node = $nodeset->item(0);
|
1614 |
+
|
1615 |
+
if (!$node) {
|
1616 |
+
return NULL;
|
1617 |
+
}
|
1618 |
+
|
1619 |
+
return base64_decode($node->nodeValue);
|
1620 |
+
}
|
1621 |
+
|
1622 |
+
/**
|
1623 |
+
* Decrypt this encrypted node.
|
1624 |
+
*
|
1625 |
+
* The behaviour of this function depends on the value of $replace.
|
1626 |
+
* If $replace is FALSE, we will return the decrypted data as a string.
|
1627 |
+
* If $replace is TRUE, we will insert the decrypted element(s) into the
|
1628 |
+
* document, and return the decrypted element(s).
|
1629 |
+
*
|
1630 |
+
* @params XMLSecurityKey $objKey The decryption key that should be used when decrypting the node.
|
1631 |
+
* @params boolean $replace Whether we should replace the encrypted node in the XML document with the decrypted data. The default is TRUE.
|
1632 |
+
* @return string|DOMElement The decrypted data.
|
1633 |
+
*/
|
1634 |
+
public function decryptNode($objKey, $replace=TRUE) {
|
1635 |
+
if (! $objKey instanceof XMLSecurityKey) {
|
1636 |
+
throw new Exception('Invalid Key');
|
1637 |
+
}
|
1638 |
+
|
1639 |
+
$encryptedData = $this->getCipherValue();
|
1640 |
+
if ($encryptedData) {
|
1641 |
+
$decrypted = $objKey->decryptData($encryptedData);
|
1642 |
+
if ($replace) {
|
1643 |
+
switch ($this->type) {
|
1644 |
+
case (XMLSecEnc::Element):
|
1645 |
+
$newdoc = new DOMDocument();
|
1646 |
+
$newdoc->loadXML($decrypted);
|
1647 |
+
if ($this->rawNode->nodeType == XML_DOCUMENT_NODE) {
|
1648 |
+
return $newdoc;
|
1649 |
+
}
|
1650 |
+
$importEnc = $this->rawNode->ownerDocument->importNode($newdoc->documentElement, TRUE);
|
1651 |
+
$this->rawNode->parentNode->replaceChild($importEnc, $this->rawNode);
|
1652 |
+
return $importEnc;
|
1653 |
+
break;
|
1654 |
+
case (XMLSecEnc::Content):
|
1655 |
+
if ($this->rawNode->nodeType == XML_DOCUMENT_NODE) {
|
1656 |
+
$doc = $this->rawNode;
|
1657 |
+
} else {
|
1658 |
+
$doc = $this->rawNode->ownerDocument;
|
1659 |
+
}
|
1660 |
+
$newFrag = $doc->createDocumentFragment();
|
1661 |
+
$newFrag->appendXML($decrypted);
|
1662 |
+
$parent = $this->rawNode->parentNode;
|
1663 |
+
$parent->replaceChild($newFrag, $this->rawNode);
|
1664 |
+
return $parent;
|
1665 |
+
break;
|
1666 |
+
default:
|
1667 |
+
return $decrypted;
|
1668 |
+
}
|
1669 |
+
} else {
|
1670 |
+
return $decrypted;
|
1671 |
+
}
|
1672 |
+
} else {
|
1673 |
+
throw new Exception("Cannot locate encrypted data");
|
1674 |
+
}
|
1675 |
+
}
|
1676 |
+
|
1677 |
+
public function encryptKey($srcKey, $rawKey, $append=TRUE) {
|
1678 |
+
if ((! $srcKey instanceof XMLSecurityKey) || (! $rawKey instanceof XMLSecurityKey)) {
|
1679 |
+
throw new Exception('Invalid Key');
|
1680 |
+
}
|
1681 |
+
$strEncKey = base64_encode($srcKey->encryptData($rawKey->key));
|
1682 |
+
$root = $this->encdoc->documentElement;
|
1683 |
+
$encKey = $this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:EncryptedKey');
|
1684 |
+
if ($append) {
|
1685 |
+
$keyInfo = $root->insertBefore($this->encdoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'dsig:KeyInfo'), $root->firstChild);
|
1686 |
+
$keyInfo->appendChild($encKey);
|
1687 |
+
} else {
|
1688 |
+
$this->encKey = $encKey;
|
1689 |
+
}
|
1690 |
+
$encMethod = $encKey->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:EncryptionMethod'));
|
1691 |
+
$encMethod->setAttribute('Algorithm', $srcKey->getAlgorith());
|
1692 |
+
if (! empty($srcKey->name)) {
|
1693 |
+
$keyInfo = $encKey->appendChild($this->encdoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'dsig:KeyInfo'));
|
1694 |
+
$keyInfo->appendChild($this->encdoc->createElementNS('http://www.w3.org/2000/09/xmldsig#', 'dsig:KeyName', $srcKey->name));
|
1695 |
+
}
|
1696 |
+
$cipherData = $encKey->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:CipherData'));
|
1697 |
+
$cipherData->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:CipherValue', $strEncKey));
|
1698 |
+
if (is_array($this->references) && count($this->references) > 0) {
|
1699 |
+
$refList = $encKey->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:ReferenceList'));
|
1700 |
+
foreach ($this->references AS $name=>$reference) {
|
1701 |
+
$refuri = $reference["refuri"];
|
1702 |
+
$dataRef = $refList->appendChild($this->encdoc->createElementNS(XMLSecEnc::XMLENCNS, 'xenc:DataReference'));
|
1703 |
+
$dataRef->setAttribute("URI", '#' . $refuri);
|
1704 |
+
}
|
1705 |
+
}
|
1706 |
+
return;
|
1707 |
+
}
|
1708 |
+
|
1709 |
+
public function decryptKey($encKey) {
|
1710 |
+
if (! $encKey->isEncrypted) {
|
1711 |
+
throw new Exception("Key is not Encrypted");
|
1712 |
+
}
|
1713 |
+
if (empty($encKey->key)) {
|
1714 |
+
throw new Exception("Key is missing data to perform the decryption");
|
1715 |
+
}
|
1716 |
+
return $this->decryptNode($encKey, FALSE);
|
1717 |
+
}
|
1718 |
+
|
1719 |
+
public function locateEncryptedData($element) {
|
1720 |
+
if ($element instanceof DOMDocument) {
|
1721 |
+
$doc = $element;
|
1722 |
+
} else {
|
1723 |
+
$doc = $element->ownerDocument;
|
1724 |
+
}
|
1725 |
+
if ($doc) {
|
1726 |
+
$xpath = new DOMXPath($doc);
|
1727 |
+
$query = "//*[local-name()='EncryptedData' and namespace-uri()='".XMLSecEnc::XMLENCNS."']";
|
1728 |
+
$nodeset = $xpath->query($query);
|
1729 |
+
return $nodeset->item(0);
|
1730 |
+
}
|
1731 |
+
return NULL;
|
1732 |
+
}
|
1733 |
+
|
1734 |
+
public function locateKey($node=NULL) {
|
1735 |
+
if (empty($node)) {
|
1736 |
+
$node = $this->rawNode;
|
1737 |
+
}
|
1738 |
+
if (! $node instanceof DOMNode) {
|
1739 |
+
return NULL;
|
1740 |
+
}
|
1741 |
+
if ($doc = $node->ownerDocument) {
|
1742 |
+
$xpath = new DOMXPath($doc);
|
1743 |
+
$xpath->registerNamespace('xmlsecenc', XMLSecEnc::XMLENCNS);
|
1744 |
+
$query = ".//xmlsecenc:EncryptionMethod";
|
1745 |
+
$nodeset = $xpath->query($query, $node);
|
1746 |
+
if ($encmeth = $nodeset->item(0)) {
|
1747 |
+
$attrAlgorithm = $encmeth->getAttribute("Algorithm");
|
1748 |
+
try {
|
1749 |
+
$objKey = new XMLSecurityKey($attrAlgorithm, array('type'=>'private'));
|
1750 |
+
} catch (Exception $e) {
|
1751 |
+
return NULL;
|
1752 |
+
}
|
1753 |
+
return $objKey;
|
1754 |
+
}
|
1755 |
+
}
|
1756 |
+
return NULL;
|
1757 |
+
}
|
1758 |
+
|
1759 |
+
static function staticLocateKeyInfo($objBaseKey=NULL, $node=NULL) {
|
1760 |
+
if (empty($node) || (! $node instanceof DOMNode)) {
|
1761 |
+
return NULL;
|
1762 |
+
}
|
1763 |
+
$doc = $node->ownerDocument;
|
1764 |
+
if (!$doc) {
|
1765 |
+
return NULL;
|
1766 |
+
}
|
1767 |
+
|
1768 |
+
$xpath = new DOMXPath($doc);
|
1769 |
+
$xpath->registerNamespace('xmlsecenc', XMLSecEnc::XMLENCNS);
|
1770 |
+
$xpath->registerNamespace('xmlsecdsig', XMLSecurityDSig::XMLDSIGNS);
|
1771 |
+
$query = "./xmlsecdsig:KeyInfo";
|
1772 |
+
$nodeset = $xpath->query($query, $node);
|
1773 |
+
$encmeth = $nodeset->item(0);
|
1774 |
+
if (!$encmeth) {
|
1775 |
+
/* No KeyInfo in EncryptedData / EncryptedKey. */
|
1776 |
+
return $objBaseKey;
|
1777 |
+
}
|
1778 |
+
|
1779 |
+
foreach ($encmeth->childNodes AS $child) {
|
1780 |
+
switch ($child->localName) {
|
1781 |
+
case 'KeyName':
|
1782 |
+
if (! empty($objBaseKey)) {
|
1783 |
+
$objBaseKey->name = $child->nodeValue;
|
1784 |
+
}
|
1785 |
+
break;
|
1786 |
+
case 'KeyValue':
|
1787 |
+
foreach ($child->childNodes AS $keyval) {
|
1788 |
+
switch ($keyval->localName) {
|
1789 |
+
case 'DSAKeyValue':
|
1790 |
+
throw new Exception("DSAKeyValue currently not supported");
|
1791 |
+
break;
|
1792 |
+
case 'RSAKeyValue':
|
1793 |
+
$modulus = NULL;
|
1794 |
+
$exponent = NULL;
|
1795 |
+
if ($modulusNode = $keyval->getElementsByTagName('Modulus')->item(0)) {
|
1796 |
+
$modulus = base64_decode($modulusNode->nodeValue);
|
1797 |
+
}
|
1798 |
+
if ($exponentNode = $keyval->getElementsByTagName('Exponent')->item(0)) {
|
1799 |
+
$exponent = base64_decode($exponentNode->nodeValue);
|
1800 |
+
}
|
1801 |
+
if (empty($modulus) || empty($exponent)) {
|
1802 |
+
throw new Exception("Missing Modulus or Exponent");
|
1803 |
+
}
|
1804 |
+
$publicKey = XMLSecurityKey::convertRSA($modulus, $exponent);
|
1805 |
+
$objBaseKey->loadKey($publicKey);
|
1806 |
+
break;
|
1807 |
+
}
|
1808 |
+
}
|
1809 |
+
break;
|
1810 |
+
case 'RetrievalMethod':
|
1811 |
+
$type = $child->getAttribute('Type');
|
1812 |
+
if ($type !== 'http://www.w3.org/2001/04/xmlenc#EncryptedKey') {
|
1813 |
+
/* Unsupported key type. */
|
1814 |
+
break;
|
1815 |
+
}
|
1816 |
+
$uri = $child->getAttribute('URI');
|
1817 |
+
if ($uri[0] !== '#') {
|
1818 |
+
/* URI not a reference - unsupported. */
|
1819 |
+
break;
|
1820 |
+
}
|
1821 |
+
$id = substr($uri, 1);
|
1822 |
+
|
1823 |
+
$query = "//xmlsecenc:EncryptedKey[@Id='$id']";
|
1824 |
+
$keyElement = $xpath->query($query)->item(0);
|
1825 |
+
if (!$keyElement) {
|
1826 |
+
throw new Exception("Unable to locate EncryptedKey with @Id='$id'.");
|
1827 |
+
}
|
1828 |
+
|
1829 |
+
return XMLSecurityKey::fromEncryptedKeyElement($keyElement);
|
1830 |
+
case 'EncryptedKey':
|
1831 |
+
return XMLSecurityKey::fromEncryptedKeyElement($child);
|
1832 |
+
case 'X509Data':
|
1833 |
+
if ($x509certNodes = $child->getElementsByTagName('X509Certificate')) {
|
1834 |
+
if ($x509certNodes->length > 0) {
|
1835 |
+
$x509cert = $x509certNodes->item(0)->textContent;
|
1836 |
+
$x509cert = str_replace(array("\r", "\n"), "", $x509cert);
|
1837 |
+
$x509cert = "-----BEGIN CERTIFICATE-----\n".chunk_split($x509cert, 64, "\n")."-----END CERTIFICATE-----\n";
|
1838 |
+
$objBaseKey->loadKey($x509cert, FALSE, TRUE);
|
1839 |
+
}
|
1840 |
+
}
|
1841 |
+
break;
|
1842 |
+
}
|
1843 |
+
}
|
1844 |
+
return $objBaseKey;
|
1845 |
+
}
|
1846 |
+
|
1847 |
+
public function locateKeyInfo($objBaseKey=NULL, $node=NULL) {
|
1848 |
+
if (empty($node)) {
|
1849 |
+
$node = $this->rawNode;
|
1850 |
+
}
|
1851 |
+
return XMLSecEnc::staticLocateKeyInfo($objBaseKey, $node);
|
1852 |
+
}
|
1853 |
+
}
|
lib/Communicator/schemas/idx.merchant-acquirer.1.0.xsd
ADDED
@@ -0,0 +1,369 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!-- iDx Messages version 1.0.0: interface Merchant/Acquirer -->
|
3 |
+
<!-- Copyright © Betaalvereniging -->
|
4 |
+
<xs:schema xmlns="http://www.betaalvereniging.nl/iDx/messages/Merchant-Acquirer/1.0.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" targetNamespace="http://www.betaalvereniging.nl/iDx/messages/Merchant-Acquirer/1.0.0" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0.0">
|
5 |
+
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
|
6 |
+
<xs:annotation>
|
7 |
+
<xs:documentation>elements defined</xs:documentation>
|
8 |
+
</xs:annotation>
|
9 |
+
<xs:element name="DirectoryReq">
|
10 |
+
<xs:annotation>
|
11 |
+
<xs:documentation>Directory Request (A)</xs:documentation>
|
12 |
+
</xs:annotation>
|
13 |
+
<xs:complexType>
|
14 |
+
<xs:sequence>
|
15 |
+
<xs:element name="createDateTimestamp" type="dateTime"/>
|
16 |
+
<xs:element name="Merchant">
|
17 |
+
<xs:complexType>
|
18 |
+
<xs:sequence>
|
19 |
+
<xs:element name="merchantID" type="Merchant.merchantID"/>
|
20 |
+
<xs:element name="subID" type="Merchant.subID"/>
|
21 |
+
</xs:sequence>
|
22 |
+
</xs:complexType>
|
23 |
+
</xs:element>
|
24 |
+
<xs:element ref="ds:Signature"/>
|
25 |
+
</xs:sequence>
|
26 |
+
<xs:attributeGroup ref="MessageAttributes"/>
|
27 |
+
</xs:complexType>
|
28 |
+
</xs:element>
|
29 |
+
<xs:element name="DirectoryRes">
|
30 |
+
<xs:annotation>
|
31 |
+
<xs:documentation>Directory Response (A')</xs:documentation>
|
32 |
+
</xs:annotation>
|
33 |
+
<xs:complexType>
|
34 |
+
<xs:sequence>
|
35 |
+
<xs:element name="createDateTimestamp" type="dateTime"/>
|
36 |
+
<xs:element name="Acquirer">
|
37 |
+
<xs:complexType>
|
38 |
+
<xs:sequence>
|
39 |
+
<xs:element name="acquirerID" type="Acquirer.acquirerID"/>
|
40 |
+
</xs:sequence>
|
41 |
+
</xs:complexType>
|
42 |
+
</xs:element>
|
43 |
+
<xs:element name="Directory">
|
44 |
+
<xs:complexType>
|
45 |
+
<xs:sequence>
|
46 |
+
<xs:element name="directoryDateTimestamp" type="dateTime"/>
|
47 |
+
<xs:element name="Country" maxOccurs="unbounded">
|
48 |
+
<xs:complexType>
|
49 |
+
<xs:sequence>
|
50 |
+
<xs:element name="countryNames" type="Country.countryNames"/>
|
51 |
+
<xs:element name="Issuer" maxOccurs="unbounded">
|
52 |
+
<xs:complexType>
|
53 |
+
<xs:sequence>
|
54 |
+
<xs:element name="issuerID" type="Issuer.issuerID"/>
|
55 |
+
<xs:element name="issuerName" type="Issuer.issuerName"/>
|
56 |
+
</xs:sequence>
|
57 |
+
</xs:complexType>
|
58 |
+
</xs:element>
|
59 |
+
</xs:sequence>
|
60 |
+
</xs:complexType>
|
61 |
+
</xs:element>
|
62 |
+
</xs:sequence>
|
63 |
+
</xs:complexType>
|
64 |
+
</xs:element>
|
65 |
+
<xs:element ref="ds:Signature"/>
|
66 |
+
</xs:sequence>
|
67 |
+
<xs:attributeGroup ref="MessageAttributes"/>
|
68 |
+
</xs:complexType>
|
69 |
+
</xs:element>
|
70 |
+
<xs:element name="AcquirerTrxReq">
|
71 |
+
<xs:annotation>
|
72 |
+
<xs:documentation>Acquirer Transaction Request (B)</xs:documentation>
|
73 |
+
</xs:annotation>
|
74 |
+
<xs:complexType>
|
75 |
+
<xs:sequence>
|
76 |
+
<xs:element name="createDateTimestamp" type="dateTime"/>
|
77 |
+
<xs:element name="Issuer">
|
78 |
+
<xs:complexType>
|
79 |
+
<xs:sequence>
|
80 |
+
<xs:element name="issuerID" type="Issuer.issuerID"/>
|
81 |
+
</xs:sequence>
|
82 |
+
</xs:complexType>
|
83 |
+
</xs:element>
|
84 |
+
<xs:element name="Merchant">
|
85 |
+
<xs:complexType>
|
86 |
+
<xs:sequence>
|
87 |
+
<xs:element name="merchantID" type="Merchant.merchantID"/>
|
88 |
+
<xs:element name="subID" type="Merchant.subID"/>
|
89 |
+
<xs:element name="merchantReturnURL" type="url"/>
|
90 |
+
</xs:sequence>
|
91 |
+
</xs:complexType>
|
92 |
+
</xs:element>
|
93 |
+
<xs:element name="Transaction">
|
94 |
+
<xs:complexType>
|
95 |
+
<xs:sequence>
|
96 |
+
<xs:element name="expirationPeriod" type="Transaction.expirationPeriod" minOccurs="0"/>
|
97 |
+
<xs:element name="language" type="Transaction.language"/>
|
98 |
+
<xs:element name="entranceCode" type="Transaction.entranceCode"/>
|
99 |
+
<xs:element name="container" type="Transaction.container"/>
|
100 |
+
</xs:sequence>
|
101 |
+
</xs:complexType>
|
102 |
+
</xs:element>
|
103 |
+
<xs:element ref="ds:Signature"/>
|
104 |
+
</xs:sequence>
|
105 |
+
<xs:attributeGroup ref="MessageAttributes"/>
|
106 |
+
</xs:complexType>
|
107 |
+
</xs:element>
|
108 |
+
<xs:element name="AcquirerTrxRes">
|
109 |
+
<xs:annotation>
|
110 |
+
<xs:documentation>Acquirer Transaction Response (B')</xs:documentation>
|
111 |
+
</xs:annotation>
|
112 |
+
<xs:complexType>
|
113 |
+
<xs:sequence>
|
114 |
+
<xs:element name="createDateTimestamp" type="dateTime"/>
|
115 |
+
<xs:element name="Acquirer">
|
116 |
+
<xs:complexType>
|
117 |
+
<xs:sequence>
|
118 |
+
<xs:element name="acquirerID" type="Acquirer.acquirerID"/>
|
119 |
+
</xs:sequence>
|
120 |
+
</xs:complexType>
|
121 |
+
</xs:element>
|
122 |
+
<xs:element name="Issuer">
|
123 |
+
<xs:complexType>
|
124 |
+
<xs:sequence>
|
125 |
+
<xs:element name="issuerAuthenticationURL" type="Issuer.issuerAuthenticationURL"/>
|
126 |
+
</xs:sequence>
|
127 |
+
</xs:complexType>
|
128 |
+
</xs:element>
|
129 |
+
<xs:element name="Transaction">
|
130 |
+
<xs:complexType>
|
131 |
+
<xs:sequence>
|
132 |
+
<xs:element name="transactionID" type="Transaction.transactionID"/>
|
133 |
+
<xs:element name="transactionCreateDateTimestamp" type="dateTime"/>
|
134 |
+
</xs:sequence>
|
135 |
+
</xs:complexType>
|
136 |
+
</xs:element>
|
137 |
+
<xs:element ref="ds:Signature"/>
|
138 |
+
</xs:sequence>
|
139 |
+
<xs:attributeGroup ref="MessageAttributes"/>
|
140 |
+
</xs:complexType>
|
141 |
+
</xs:element>
|
142 |
+
<xs:element name="AcquirerStatusReq">
|
143 |
+
<xs:annotation>
|
144 |
+
<xs:documentation>Acquirer Status Request (F)</xs:documentation>
|
145 |
+
</xs:annotation>
|
146 |
+
<xs:complexType>
|
147 |
+
<xs:sequence>
|
148 |
+
<xs:element name="createDateTimestamp" type="dateTime"/>
|
149 |
+
<xs:element name="Merchant">
|
150 |
+
<xs:complexType>
|
151 |
+
<xs:sequence>
|
152 |
+
<xs:element name="merchantID" type="Merchant.merchantID"/>
|
153 |
+
<xs:element name="subID" type="Merchant.subID"/>
|
154 |
+
</xs:sequence>
|
155 |
+
</xs:complexType>
|
156 |
+
</xs:element>
|
157 |
+
<xs:element name="Transaction">
|
158 |
+
<xs:complexType>
|
159 |
+
<xs:sequence>
|
160 |
+
<xs:element name="transactionID" type="Transaction.transactionID"/>
|
161 |
+
</xs:sequence>
|
162 |
+
</xs:complexType>
|
163 |
+
</xs:element>
|
164 |
+
<xs:element ref="ds:Signature"/>
|
165 |
+
</xs:sequence>
|
166 |
+
<xs:attributeGroup ref="MessageAttributes"/>
|
167 |
+
</xs:complexType>
|
168 |
+
</xs:element>
|
169 |
+
<xs:element name="AcquirerStatusRes">
|
170 |
+
<xs:annotation>
|
171 |
+
<xs:documentation>Acquirer Status Response (F')</xs:documentation>
|
172 |
+
</xs:annotation>
|
173 |
+
<xs:complexType>
|
174 |
+
<xs:sequence>
|
175 |
+
<xs:element name="createDateTimestamp" type="dateTime"/>
|
176 |
+
<xs:element name="Acquirer">
|
177 |
+
<xs:complexType>
|
178 |
+
<xs:sequence>
|
179 |
+
<xs:element name="acquirerID" type="Acquirer.acquirerID"/>
|
180 |
+
</xs:sequence>
|
181 |
+
</xs:complexType>
|
182 |
+
</xs:element>
|
183 |
+
<xs:element name="Transaction">
|
184 |
+
<xs:complexType>
|
185 |
+
<xs:sequence>
|
186 |
+
<xs:element name="transactionID" type="Transaction.transactionID"/>
|
187 |
+
<xs:element name="status" type="Transaction.status"/>
|
188 |
+
<xs:element name="statusDateTimestamp" type="dateTime" minOccurs="0"/>
|
189 |
+
<xs:element name="container" type="Transaction.container" minOccurs="0"/>
|
190 |
+
</xs:sequence>
|
191 |
+
</xs:complexType>
|
192 |
+
</xs:element>
|
193 |
+
<xs:element ref="ds:Signature"/>
|
194 |
+
</xs:sequence>
|
195 |
+
<xs:attributeGroup ref="MessageAttributes"/>
|
196 |
+
</xs:complexType>
|
197 |
+
</xs:element>
|
198 |
+
<xs:element name="AcquirerErrorRes">
|
199 |
+
<xs:annotation>
|
200 |
+
<xs:documentation>Acquirer Error Response (X')</xs:documentation>
|
201 |
+
</xs:annotation>
|
202 |
+
<xs:complexType>
|
203 |
+
<xs:sequence>
|
204 |
+
<xs:element name="createDateTimestamp" type="dateTime"/>
|
205 |
+
<xs:element name="Error">
|
206 |
+
<xs:complexType>
|
207 |
+
<xs:sequence>
|
208 |
+
<xs:element name="errorCode" type="Error.errorCode"/>
|
209 |
+
<xs:element name="errorMessage" type="Error.errorMessage"/>
|
210 |
+
<xs:element name="errorDetail" type="Error.errorDetail" minOccurs="0"/>
|
211 |
+
<xs:element name="suggestedAction" type="Error.suggestedAction" minOccurs="0"/>
|
212 |
+
<xs:element name="consumerMessage" type="Error.consumerMessage" minOccurs="0"/>
|
213 |
+
<xs:element name="container" type="Transaction.container" minOccurs="0"/>
|
214 |
+
</xs:sequence>
|
215 |
+
</xs:complexType>
|
216 |
+
</xs:element>
|
217 |
+
<xs:element ref="ds:Signature"/>
|
218 |
+
</xs:sequence>
|
219 |
+
<xs:attributeGroup ref="MessageAttributes"/>
|
220 |
+
</xs:complexType>
|
221 |
+
</xs:element>
|
222 |
+
<xs:annotation>
|
223 |
+
<xs:documentation>simpleTypes defined</xs:documentation>
|
224 |
+
</xs:annotation>
|
225 |
+
<xs:simpleType name="Acquirer.acquirerID">
|
226 |
+
<xs:restriction base="xs:token">
|
227 |
+
<xs:length value="4" fixed="true"/>
|
228 |
+
<xs:pattern value="[0-9]+"/>
|
229 |
+
</xs:restriction>
|
230 |
+
</xs:simpleType>
|
231 |
+
<xs:simpleType name="Country.countryNames">
|
232 |
+
<xs:restriction base="xs:token">
|
233 |
+
<xs:minLength value="1"/>
|
234 |
+
<xs:maxLength value="128"/>
|
235 |
+
</xs:restriction>
|
236 |
+
</xs:simpleType>
|
237 |
+
<xs:simpleType name="Error.consumerMessage">
|
238 |
+
<xs:restriction base="xs:string">
|
239 |
+
<xs:maxLength value="512" fixed="true"/>
|
240 |
+
<xs:minLength value="1" fixed="true"/>
|
241 |
+
</xs:restriction>
|
242 |
+
</xs:simpleType>
|
243 |
+
<xs:simpleType name="Error.errorCode">
|
244 |
+
<xs:restriction base="xs:token">
|
245 |
+
<xs:length value="6" fixed="true"/>
|
246 |
+
<xs:pattern value="[A-Z]{2}[0-9]{4}"/>
|
247 |
+
</xs:restriction>
|
248 |
+
</xs:simpleType>
|
249 |
+
<xs:simpleType name="Error.errorDetail">
|
250 |
+
<xs:restriction base="xs:string">
|
251 |
+
<xs:maxLength value="256" fixed="true"/>
|
252 |
+
<xs:minLength value="1" fixed="true"/>
|
253 |
+
</xs:restriction>
|
254 |
+
</xs:simpleType>
|
255 |
+
<xs:simpleType name="Error.errorMessage">
|
256 |
+
<xs:restriction base="xs:string">
|
257 |
+
<xs:minLength value="1"/>
|
258 |
+
<xs:maxLength value="128"/>
|
259 |
+
</xs:restriction>
|
260 |
+
</xs:simpleType>
|
261 |
+
<xs:simpleType name="Error.suggestedAction">
|
262 |
+
<xs:restriction base="xs:string">
|
263 |
+
<xs:maxLength value="512" fixed="true"/>
|
264 |
+
<xs:minLength value="1" fixed="true"/>
|
265 |
+
</xs:restriction>
|
266 |
+
</xs:simpleType>
|
267 |
+
<xs:simpleType name="Issuer.issuerAuthenticationURL">
|
268 |
+
<xs:restriction base="url"/>
|
269 |
+
</xs:simpleType>
|
270 |
+
<xs:simpleType name="Issuer.issuerID">
|
271 |
+
<xs:restriction base="BIC"/>
|
272 |
+
</xs:simpleType>
|
273 |
+
<xs:simpleType name="Issuer.issuerName">
|
274 |
+
<xs:restriction base="xs:token">
|
275 |
+
<xs:maxLength value="35" fixed="true"/>
|
276 |
+
<xs:minLength value="1" fixed="true"/>
|
277 |
+
</xs:restriction>
|
278 |
+
</xs:simpleType>
|
279 |
+
<xs:simpleType name="Merchant.merchantID">
|
280 |
+
<xs:restriction base="xs:token">
|
281 |
+
<xs:length value="10" fixed="true"/>
|
282 |
+
<xs:pattern value="[0-9]+"/>
|
283 |
+
</xs:restriction>
|
284 |
+
</xs:simpleType>
|
285 |
+
<xs:simpleType name="Merchant.merchantReturnURL">
|
286 |
+
<xs:restriction base="url"/>
|
287 |
+
</xs:simpleType>
|
288 |
+
<xs:simpleType name="Merchant.subID">
|
289 |
+
<xs:restriction base="xs:nonNegativeInteger">
|
290 |
+
<xs:maxInclusive value="999999" fixed="true"/>
|
291 |
+
</xs:restriction>
|
292 |
+
</xs:simpleType>
|
293 |
+
<xs:simpleType name="Transaction.entranceCode">
|
294 |
+
<xs:restriction base="xs:token">
|
295 |
+
<xs:minLength value="1" fixed="true"/>
|
296 |
+
<xs:maxLength value="40" fixed="true"/>
|
297 |
+
<xs:pattern value="[a-zA-Z0-9]+"/>
|
298 |
+
</xs:restriction>
|
299 |
+
</xs:simpleType>
|
300 |
+
<xs:simpleType name="Transaction.expirationPeriod">
|
301 |
+
<xs:restriction base="xs:duration">
|
302 |
+
<xs:minInclusive value="PT1M" fixed="true"/>
|
303 |
+
</xs:restriction>
|
304 |
+
</xs:simpleType>
|
305 |
+
<xs:simpleType name="Transaction.language">
|
306 |
+
<xs:restriction base="language"/>
|
307 |
+
</xs:simpleType>
|
308 |
+
<xs:simpleType name="Transaction.status">
|
309 |
+
<xs:restriction base="xs:token">
|
310 |
+
<xs:pattern value="Open|Success|Failure|Expired|Cancelled|Pending"/>
|
311 |
+
</xs:restriction>
|
312 |
+
</xs:simpleType>
|
313 |
+
<xs:simpleType name="Transaction.transactionID">
|
314 |
+
<xs:restriction base="xs:token">
|
315 |
+
<xs:length value="16" fixed="true"/>
|
316 |
+
<xs:pattern value="[0-9]+"/>
|
317 |
+
</xs:restriction>
|
318 |
+
</xs:simpleType>
|
319 |
+
<xs:annotation>
|
320 |
+
<xs:documentation>basic simpleTypes defined</xs:documentation>
|
321 |
+
</xs:annotation>
|
322 |
+
<xs:simpleType name="BIC">
|
323 |
+
<xs:restriction base="xs:token">
|
324 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
325 |
+
</xs:restriction>
|
326 |
+
</xs:simpleType>
|
327 |
+
<xs:simpleType name="dateTime">
|
328 |
+
<xs:restriction base="xs:dateTime">
|
329 |
+
<xs:pattern value=".+Z"/>
|
330 |
+
</xs:restriction>
|
331 |
+
</xs:simpleType>
|
332 |
+
<xs:simpleType name="language">
|
333 |
+
<xs:restriction base="xs:token">
|
334 |
+
<xs:length value="2" fixed="true"/>
|
335 |
+
<xs:pattern value="[a-z]+"/>
|
336 |
+
</xs:restriction>
|
337 |
+
</xs:simpleType>
|
338 |
+
<xs:simpleType name="productID">
|
339 |
+
<xs:restriction base="xs:string"/>
|
340 |
+
</xs:simpleType>
|
341 |
+
<xs:simpleType name="url">
|
342 |
+
<xs:restriction base="xs:anyURI">
|
343 |
+
<xs:maxLength value="512"/>
|
344 |
+
</xs:restriction>
|
345 |
+
</xs:simpleType>
|
346 |
+
<xs:simpleType name="version">
|
347 |
+
<xs:restriction base="xs:string">
|
348 |
+
<xs:pattern value="1\.0\.0"/>
|
349 |
+
</xs:restriction>
|
350 |
+
</xs:simpleType>
|
351 |
+
<xs:annotation>
|
352 |
+
<xs:documentation>complexTypes defined</xs:documentation>
|
353 |
+
</xs:annotation>
|
354 |
+
<xs:complexType name="Transaction.container">
|
355 |
+
<xs:sequence>
|
356 |
+
<xs:any namespace="##any" maxOccurs="unbounded" processContents="lax"/>
|
357 |
+
</xs:sequence>
|
358 |
+
</xs:complexType>
|
359 |
+
<xs:annotation>
|
360 |
+
<xs:documentation>attributeGroups defined</xs:documentation>
|
361 |
+
</xs:annotation>
|
362 |
+
<xs:attributeGroup name="MessageAttributes">
|
363 |
+
<xs:annotation>
|
364 |
+
<xs:documentation>attributes of each message</xs:documentation>
|
365 |
+
</xs:annotation>
|
366 |
+
<xs:attribute name="version" type="version" use="required"/>
|
367 |
+
<xs:attribute name="productID" type="productID" use="required"/>
|
368 |
+
</xs:attributeGroup>
|
369 |
+
</xs:schema>
|
lib/Communicator/schemas/pain.009.001.04.xsd
ADDED
@@ -0,0 +1,534 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--Generated by Standards Editor (build:R1.6.2.2) on 2014 Oct 24 13:58:14, ISO 20022 version : 2013-->
|
3 |
+
<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:pain.009.001.04" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:iso:std:iso:20022:tech:xsd:pain.009.001.04">
|
4 |
+
<xs:element name="Document" type="Document"/>
|
5 |
+
<xs:complexType name="AccountIdentification4Choice">
|
6 |
+
<xs:choice>
|
7 |
+
<xs:element name="IBAN" type="IBAN2007Identifier"/>
|
8 |
+
<xs:element name="Othr" type="GenericAccountIdentification1"/>
|
9 |
+
</xs:choice>
|
10 |
+
</xs:complexType>
|
11 |
+
<xs:complexType name="AccountSchemeName1Choice">
|
12 |
+
<xs:choice>
|
13 |
+
<xs:element name="Cd" type="ExternalAccountIdentification1Code"/>
|
14 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
15 |
+
</xs:choice>
|
16 |
+
</xs:complexType>
|
17 |
+
<xs:simpleType name="ActiveCurrencyAndAmount_SimpleType">
|
18 |
+
<xs:restriction base="xs:decimal">
|
19 |
+
<xs:fractionDigits value="2"/>
|
20 |
+
<xs:totalDigits value="18"/>
|
21 |
+
<xs:minInclusive value="0"/>
|
22 |
+
</xs:restriction>
|
23 |
+
</xs:simpleType>
|
24 |
+
<xs:complexType name="ActiveCurrencyAndAmount">
|
25 |
+
<xs:simpleContent>
|
26 |
+
<xs:extension base="ActiveCurrencyAndAmount_SimpleType">
|
27 |
+
<xs:attribute name="Ccy" type="ActiveCurrencyCode" use="required"/>
|
28 |
+
</xs:extension>
|
29 |
+
</xs:simpleContent>
|
30 |
+
</xs:complexType>
|
31 |
+
<xs:simpleType name="ActiveCurrencyCode">
|
32 |
+
<xs:restriction base="xs:string">
|
33 |
+
<xs:pattern value="[A-Z]{3,3}"/>
|
34 |
+
</xs:restriction>
|
35 |
+
</xs:simpleType>
|
36 |
+
<xs:simpleType name="ActiveOrHistoricCurrencyCode">
|
37 |
+
<xs:restriction base="xs:string">
|
38 |
+
<xs:pattern value="[A-Z]{3,3}"/>
|
39 |
+
</xs:restriction>
|
40 |
+
</xs:simpleType>
|
41 |
+
<xs:simpleType name="AddressType2Code">
|
42 |
+
<xs:restriction base="xs:string">
|
43 |
+
<xs:enumeration value="ADDR"/>
|
44 |
+
<xs:enumeration value="PBOX"/>
|
45 |
+
<xs:enumeration value="HOME"/>
|
46 |
+
<xs:enumeration value="BIZZ"/>
|
47 |
+
<xs:enumeration value="MLTO"/>
|
48 |
+
<xs:enumeration value="DLVY"/>
|
49 |
+
</xs:restriction>
|
50 |
+
</xs:simpleType>
|
51 |
+
<xs:simpleType name="AnyBICIdentifier">
|
52 |
+
<xs:restriction base="xs:string">
|
53 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
54 |
+
</xs:restriction>
|
55 |
+
</xs:simpleType>
|
56 |
+
<xs:complexType name="Authorisation1Choice">
|
57 |
+
<xs:choice>
|
58 |
+
<xs:element name="Cd" type="Authorisation1Code"/>
|
59 |
+
<xs:element name="Prtry" type="Max128Text"/>
|
60 |
+
</xs:choice>
|
61 |
+
</xs:complexType>
|
62 |
+
<xs:simpleType name="Authorisation1Code">
|
63 |
+
<xs:restriction base="xs:string">
|
64 |
+
<xs:enumeration value="AUTH"/>
|
65 |
+
<xs:enumeration value="FDET"/>
|
66 |
+
<xs:enumeration value="FSUM"/>
|
67 |
+
<xs:enumeration value="ILEV"/>
|
68 |
+
</xs:restriction>
|
69 |
+
</xs:simpleType>
|
70 |
+
<xs:simpleType name="BICFIIdentifier">
|
71 |
+
<xs:restriction base="xs:string">
|
72 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
73 |
+
</xs:restriction>
|
74 |
+
</xs:simpleType>
|
75 |
+
<xs:complexType name="BranchAndFinancialInstitutionIdentification5">
|
76 |
+
<xs:sequence>
|
77 |
+
<xs:element name="FinInstnId" type="FinancialInstitutionIdentification8"/>
|
78 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BrnchId" type="BranchData2"/>
|
79 |
+
</xs:sequence>
|
80 |
+
</xs:complexType>
|
81 |
+
<xs:complexType name="BranchData2">
|
82 |
+
<xs:sequence>
|
83 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Max35Text"/>
|
84 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
85 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
86 |
+
</xs:sequence>
|
87 |
+
</xs:complexType>
|
88 |
+
<xs:complexType name="CashAccount24">
|
89 |
+
<xs:sequence>
|
90 |
+
<xs:element name="Id" type="AccountIdentification4Choice"/>
|
91 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="CashAccountType2Choice"/>
|
92 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ccy" type="ActiveOrHistoricCurrencyCode"/>
|
93 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max70Text"/>
|
94 |
+
</xs:sequence>
|
95 |
+
</xs:complexType>
|
96 |
+
<xs:complexType name="CashAccountType2Choice">
|
97 |
+
<xs:choice>
|
98 |
+
<xs:element name="Cd" type="ExternalCashAccountType1Code"/>
|
99 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
100 |
+
</xs:choice>
|
101 |
+
</xs:complexType>
|
102 |
+
<xs:complexType name="ClearingSystemIdentification2Choice">
|
103 |
+
<xs:choice>
|
104 |
+
<xs:element name="Cd" type="ExternalClearingSystemIdentification1Code"/>
|
105 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
106 |
+
</xs:choice>
|
107 |
+
</xs:complexType>
|
108 |
+
<xs:complexType name="ClearingSystemMemberIdentification2">
|
109 |
+
<xs:sequence>
|
110 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysId" type="ClearingSystemIdentification2Choice"/>
|
111 |
+
<xs:element name="MmbId" type="Max35Text"/>
|
112 |
+
</xs:sequence>
|
113 |
+
</xs:complexType>
|
114 |
+
<xs:complexType name="ContactDetails2">
|
115 |
+
<xs:sequence>
|
116 |
+
<xs:element maxOccurs="1" minOccurs="0" name="NmPrfx" type="NamePrefix1Code"/>
|
117 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
118 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PhneNb" type="PhoneNumber"/>
|
119 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MobNb" type="PhoneNumber"/>
|
120 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FaxNb" type="PhoneNumber"/>
|
121 |
+
<xs:element maxOccurs="1" minOccurs="0" name="EmailAdr" type="Max2048Text"/>
|
122 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="Max35Text"/>
|
123 |
+
</xs:sequence>
|
124 |
+
</xs:complexType>
|
125 |
+
<xs:simpleType name="CountryCode">
|
126 |
+
<xs:restriction base="xs:string">
|
127 |
+
<xs:pattern value="[A-Z]{2,2}"/>
|
128 |
+
</xs:restriction>
|
129 |
+
</xs:simpleType>
|
130 |
+
<xs:complexType name="DateAndPlaceOfBirth">
|
131 |
+
<xs:sequence>
|
132 |
+
<xs:element name="BirthDt" type="ISODate"/>
|
133 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PrvcOfBirth" type="Max35Text"/>
|
134 |
+
<xs:element name="CityOfBirth" type="Max35Text"/>
|
135 |
+
<xs:element name="CtryOfBirth" type="CountryCode"/>
|
136 |
+
</xs:sequence>
|
137 |
+
</xs:complexType>
|
138 |
+
<xs:complexType name="DatePeriodDetails1">
|
139 |
+
<xs:sequence>
|
140 |
+
<xs:element name="FrDt" type="ISODate"/>
|
141 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ToDt" type="ISODate"/>
|
142 |
+
</xs:sequence>
|
143 |
+
</xs:complexType>
|
144 |
+
<xs:simpleType name="DecimalNumber">
|
145 |
+
<xs:restriction base="xs:decimal">
|
146 |
+
<xs:fractionDigits value="17"/>
|
147 |
+
<xs:totalDigits value="18"/>
|
148 |
+
</xs:restriction>
|
149 |
+
</xs:simpleType>
|
150 |
+
<xs:complexType name="Document">
|
151 |
+
<xs:sequence>
|
152 |
+
<xs:element name="MndtInitnReq" type="MandateInitiationRequestV04"/>
|
153 |
+
</xs:sequence>
|
154 |
+
</xs:complexType>
|
155 |
+
<xs:simpleType name="DocumentType6Code">
|
156 |
+
<xs:restriction base="xs:string">
|
157 |
+
<xs:enumeration value="MSIN"/>
|
158 |
+
<xs:enumeration value="CNFA"/>
|
159 |
+
<xs:enumeration value="DNFA"/>
|
160 |
+
<xs:enumeration value="CINV"/>
|
161 |
+
<xs:enumeration value="CREN"/>
|
162 |
+
<xs:enumeration value="DEBN"/>
|
163 |
+
<xs:enumeration value="HIRI"/>
|
164 |
+
<xs:enumeration value="SBIN"/>
|
165 |
+
<xs:enumeration value="CMCN"/>
|
166 |
+
<xs:enumeration value="SOAC"/>
|
167 |
+
<xs:enumeration value="DISP"/>
|
168 |
+
<xs:enumeration value="BOLD"/>
|
169 |
+
<xs:enumeration value="VCHR"/>
|
170 |
+
<xs:enumeration value="AROI"/>
|
171 |
+
<xs:enumeration value="TSUT"/>
|
172 |
+
<xs:enumeration value="PUOR"/>
|
173 |
+
</xs:restriction>
|
174 |
+
</xs:simpleType>
|
175 |
+
<xs:simpleType name="ExternalAccountIdentification1Code">
|
176 |
+
<xs:restriction base="xs:string">
|
177 |
+
<xs:minLength value="1"/>
|
178 |
+
<xs:maxLength value="4"/>
|
179 |
+
</xs:restriction>
|
180 |
+
</xs:simpleType>
|
181 |
+
<xs:simpleType name="ExternalCashAccountType1Code">
|
182 |
+
<xs:restriction base="xs:string">
|
183 |
+
<xs:minLength value="1"/>
|
184 |
+
<xs:maxLength value="4"/>
|
185 |
+
</xs:restriction>
|
186 |
+
</xs:simpleType>
|
187 |
+
<xs:simpleType name="ExternalClearingSystemIdentification1Code">
|
188 |
+
<xs:restriction base="xs:string">
|
189 |
+
<xs:minLength value="1"/>
|
190 |
+
<xs:maxLength value="5"/>
|
191 |
+
</xs:restriction>
|
192 |
+
</xs:simpleType>
|
193 |
+
<xs:simpleType name="ExternalFinancialInstitutionIdentification1Code">
|
194 |
+
<xs:restriction base="xs:string">
|
195 |
+
<xs:minLength value="1"/>
|
196 |
+
<xs:maxLength value="4"/>
|
197 |
+
</xs:restriction>
|
198 |
+
</xs:simpleType>
|
199 |
+
<xs:simpleType name="ExternalLocalInstrument1Code">
|
200 |
+
<xs:restriction base="xs:string">
|
201 |
+
<xs:minLength value="1"/>
|
202 |
+
<xs:maxLength value="35"/>
|
203 |
+
</xs:restriction>
|
204 |
+
</xs:simpleType>
|
205 |
+
<xs:simpleType name="ExternalMandateSetupReason1Code">
|
206 |
+
<xs:restriction base="xs:string">
|
207 |
+
<xs:minLength value="1"/>
|
208 |
+
<xs:maxLength value="4"/>
|
209 |
+
</xs:restriction>
|
210 |
+
</xs:simpleType>
|
211 |
+
<xs:simpleType name="ExternalOrganisationIdentification1Code">
|
212 |
+
<xs:restriction base="xs:string">
|
213 |
+
<xs:minLength value="1"/>
|
214 |
+
<xs:maxLength value="4"/>
|
215 |
+
</xs:restriction>
|
216 |
+
</xs:simpleType>
|
217 |
+
<xs:simpleType name="ExternalPersonIdentification1Code">
|
218 |
+
<xs:restriction base="xs:string">
|
219 |
+
<xs:minLength value="1"/>
|
220 |
+
<xs:maxLength value="4"/>
|
221 |
+
</xs:restriction>
|
222 |
+
</xs:simpleType>
|
223 |
+
<xs:simpleType name="ExternalServiceLevel1Code">
|
224 |
+
<xs:restriction base="xs:string">
|
225 |
+
<xs:minLength value="1"/>
|
226 |
+
<xs:maxLength value="4"/>
|
227 |
+
</xs:restriction>
|
228 |
+
</xs:simpleType>
|
229 |
+
<xs:complexType name="FinancialIdentificationSchemeName1Choice">
|
230 |
+
<xs:choice>
|
231 |
+
<xs:element name="Cd" type="ExternalFinancialInstitutionIdentification1Code"/>
|
232 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
233 |
+
</xs:choice>
|
234 |
+
</xs:complexType>
|
235 |
+
<xs:complexType name="FinancialInstitutionIdentification8">
|
236 |
+
<xs:sequence>
|
237 |
+
<!-- Made BICFI mandatory, previously this line was: -->
|
238 |
+
<!-- <xs:element maxOccurs="1" minOccurs="0" name="BICFI" type="BICFIIdentifier"/> -->
|
239 |
+
<xs:element name="BICFI" type="BICFIIdentifier"/>
|
240 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysMmbId" type="ClearingSystemMemberIdentification2"/>
|
241 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
242 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
243 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="GenericFinancialIdentification1"/>
|
244 |
+
</xs:sequence>
|
245 |
+
</xs:complexType>
|
246 |
+
<xs:complexType name="Frequency21Choice">
|
247 |
+
<xs:choice>
|
248 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
249 |
+
<xs:element name="Prd" type="FrequencyPeriod1"/>
|
250 |
+
</xs:choice>
|
251 |
+
</xs:complexType>
|
252 |
+
<xs:simpleType name="Frequency6Code">
|
253 |
+
<xs:restriction base="xs:string">
|
254 |
+
<xs:enumeration value="YEAR"/>
|
255 |
+
<xs:enumeration value="MNTH"/>
|
256 |
+
<xs:enumeration value="QURT"/>
|
257 |
+
<xs:enumeration value="MIAN"/>
|
258 |
+
<xs:enumeration value="WEEK"/>
|
259 |
+
<xs:enumeration value="DAIL"/>
|
260 |
+
<xs:enumeration value="ADHO"/>
|
261 |
+
<xs:enumeration value="INDA"/>
|
262 |
+
<xs:enumeration value="FRTN"/>
|
263 |
+
</xs:restriction>
|
264 |
+
</xs:simpleType>
|
265 |
+
<xs:complexType name="FrequencyPeriod1">
|
266 |
+
<xs:sequence>
|
267 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
268 |
+
<xs:element name="CntPerPrd" type="DecimalNumber"/>
|
269 |
+
</xs:sequence>
|
270 |
+
</xs:complexType>
|
271 |
+
<xs:complexType name="GenericAccountIdentification1">
|
272 |
+
<xs:sequence>
|
273 |
+
<xs:element name="Id" type="Max34Text"/>
|
274 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="AccountSchemeName1Choice"/>
|
275 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
276 |
+
</xs:sequence>
|
277 |
+
</xs:complexType>
|
278 |
+
<xs:complexType name="GenericFinancialIdentification1">
|
279 |
+
<xs:sequence>
|
280 |
+
<xs:element name="Id" type="Max35Text"/>
|
281 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="FinancialIdentificationSchemeName1Choice"/>
|
282 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
283 |
+
</xs:sequence>
|
284 |
+
</xs:complexType>
|
285 |
+
<xs:complexType name="GenericOrganisationIdentification1">
|
286 |
+
<xs:sequence>
|
287 |
+
<xs:element name="Id" type="Max35Text"/>
|
288 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="OrganisationIdentificationSchemeName1Choice"/>
|
289 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
290 |
+
</xs:sequence>
|
291 |
+
</xs:complexType>
|
292 |
+
<xs:complexType name="GenericPersonIdentification1">
|
293 |
+
<xs:sequence>
|
294 |
+
<xs:element name="Id" type="Max35Text"/>
|
295 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="PersonIdentificationSchemeName1Choice"/>
|
296 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
297 |
+
</xs:sequence>
|
298 |
+
</xs:complexType>
|
299 |
+
<xs:complexType name="GroupHeader47">
|
300 |
+
<xs:sequence>
|
301 |
+
<xs:element name="MsgId" type="Max35Text"/>
|
302 |
+
<xs:element name="CreDtTm" type="ISODateTime"/>
|
303 |
+
<xs:element maxOccurs="2" minOccurs="0" name="Authstn" type="Authorisation1Choice"/>
|
304 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InitgPty" type="PartyIdentification43"/>
|
305 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstgAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
306 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstdAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
307 |
+
</xs:sequence>
|
308 |
+
</xs:complexType>
|
309 |
+
<xs:simpleType name="IBAN2007Identifier">
|
310 |
+
<xs:restriction base="xs:string">
|
311 |
+
<xs:pattern value="[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}"/>
|
312 |
+
</xs:restriction>
|
313 |
+
</xs:simpleType>
|
314 |
+
<xs:simpleType name="ISODate">
|
315 |
+
<xs:restriction base="xs:date"/>
|
316 |
+
</xs:simpleType>
|
317 |
+
<xs:simpleType name="ISODateTime">
|
318 |
+
<xs:restriction base="xs:dateTime"/>
|
319 |
+
</xs:simpleType>
|
320 |
+
<xs:complexType name="LocalInstrument2Choice">
|
321 |
+
<xs:choice>
|
322 |
+
<xs:element name="Cd" type="ExternalLocalInstrument1Code"/>
|
323 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
324 |
+
</xs:choice>
|
325 |
+
</xs:complexType>
|
326 |
+
<xs:complexType name="Mandate7">
|
327 |
+
<xs:sequence>
|
328 |
+
<!-- Made MndtId mandatory and only able to be specified once, previously this line was: -->
|
329 |
+
<!-- <xs:element maxOccurs="unbounded" minOccurs="0" name="MndtId" type="Max35Text"/> -->
|
330 |
+
<xs:element name="MndtId" type="Max35Text"/>
|
331 |
+
<xs:element name="MndtReqId" type="Max35Text"/>
|
332 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="MandateTypeInformation1"/>
|
333 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ocrncs" type="MandateOccurrences3"/>
|
334 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ColltnAmt" type="ActiveCurrencyAndAmount"/>
|
335 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MaxAmt" type="ActiveCurrencyAndAmount"/>
|
336 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Rsn" type="MandateSetupReason1Choice"/>
|
337 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrSchmeId" type="PartyIdentification43"/>
|
338 |
+
<xs:element name="Cdtr" type="PartyIdentification43"/>
|
339 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAcct" type="CashAccount24"/>
|
340 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
341 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtCdtr" type="PartyIdentification43"/>
|
342 |
+
<xs:element name="Dbtr" type="PartyIdentification43"/>
|
343 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DbtrAcct" type="CashAccount24"/>
|
344 |
+
<xs:element name="DbtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
345 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification43"/>
|
346 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="RfrdDoc" type="ReferredDocumentInformation6"/>
|
347 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
348 |
+
</xs:sequence>
|
349 |
+
</xs:complexType>
|
350 |
+
<xs:complexType name="MandateInitiationRequestV04">
|
351 |
+
<xs:sequence>
|
352 |
+
<xs:element name="GrpHdr" type="GroupHeader47"/>
|
353 |
+
<xs:element maxOccurs="unbounded" minOccurs="1" name="Mndt" type="Mandate7"/>
|
354 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
355 |
+
</xs:sequence>
|
356 |
+
</xs:complexType>
|
357 |
+
<xs:complexType name="MandateOccurrences3">
|
358 |
+
<xs:sequence>
|
359 |
+
<xs:element name="SeqTp" type="SequenceType2Code"/>
|
360 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Frqcy" type="Frequency21Choice"/>
|
361 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Drtn" type="DatePeriodDetails1"/>
|
362 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FrstColltnDt" type="ISODate"/>
|
363 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FnlColltnDt" type="ISODate"/>
|
364 |
+
</xs:sequence>
|
365 |
+
</xs:complexType>
|
366 |
+
<xs:complexType name="MandateSetupReason1Choice">
|
367 |
+
<xs:choice>
|
368 |
+
<xs:element name="Cd" type="ExternalMandateSetupReason1Code"/>
|
369 |
+
<xs:element name="Prtry" type="Max70Text"/>
|
370 |
+
</xs:choice>
|
371 |
+
</xs:complexType>
|
372 |
+
<xs:complexType name="MandateTypeInformation1">
|
373 |
+
<xs:sequence>
|
374 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SvcLvl" type="ServiceLevel8Choice"/>
|
375 |
+
<xs:element maxOccurs="1" minOccurs="0" name="LclInstrm" type="LocalInstrument2Choice"/>
|
376 |
+
</xs:sequence>
|
377 |
+
</xs:complexType>
|
378 |
+
<xs:simpleType name="Max128Text">
|
379 |
+
<xs:restriction base="xs:string">
|
380 |
+
<xs:minLength value="1"/>
|
381 |
+
<xs:maxLength value="128"/>
|
382 |
+
</xs:restriction>
|
383 |
+
</xs:simpleType>
|
384 |
+
<xs:simpleType name="Max140Text">
|
385 |
+
<xs:restriction base="xs:string">
|
386 |
+
<xs:minLength value="1"/>
|
387 |
+
<xs:maxLength value="140"/>
|
388 |
+
</xs:restriction>
|
389 |
+
</xs:simpleType>
|
390 |
+
<xs:simpleType name="Max16Text">
|
391 |
+
<xs:restriction base="xs:string">
|
392 |
+
<xs:minLength value="1"/>
|
393 |
+
<xs:maxLength value="16"/>
|
394 |
+
</xs:restriction>
|
395 |
+
</xs:simpleType>
|
396 |
+
<xs:simpleType name="Max2048Text">
|
397 |
+
<xs:restriction base="xs:string">
|
398 |
+
<xs:minLength value="1"/>
|
399 |
+
<xs:maxLength value="2048"/>
|
400 |
+
</xs:restriction>
|
401 |
+
</xs:simpleType>
|
402 |
+
<xs:simpleType name="Max34Text">
|
403 |
+
<xs:restriction base="xs:string">
|
404 |
+
<xs:minLength value="1"/>
|
405 |
+
<xs:maxLength value="34"/>
|
406 |
+
</xs:restriction>
|
407 |
+
</xs:simpleType>
|
408 |
+
<xs:simpleType name="Max350Text">
|
409 |
+
<xs:restriction base="xs:string">
|
410 |
+
<xs:minLength value="1"/>
|
411 |
+
<xs:maxLength value="350"/>
|
412 |
+
</xs:restriction>
|
413 |
+
</xs:simpleType>
|
414 |
+
<xs:simpleType name="Max35Text">
|
415 |
+
<xs:restriction base="xs:string">
|
416 |
+
<xs:minLength value="1"/>
|
417 |
+
<xs:maxLength value="35"/>
|
418 |
+
</xs:restriction>
|
419 |
+
</xs:simpleType>
|
420 |
+
<xs:simpleType name="Max70Text">
|
421 |
+
<xs:restriction base="xs:string">
|
422 |
+
<xs:minLength value="1"/>
|
423 |
+
<xs:maxLength value="70"/>
|
424 |
+
</xs:restriction>
|
425 |
+
</xs:simpleType>
|
426 |
+
<xs:simpleType name="NamePrefix1Code">
|
427 |
+
<xs:restriction base="xs:string">
|
428 |
+
<xs:enumeration value="DOCT"/>
|
429 |
+
<xs:enumeration value="MIST"/>
|
430 |
+
<xs:enumeration value="MISS"/>
|
431 |
+
<xs:enumeration value="MADM"/>
|
432 |
+
</xs:restriction>
|
433 |
+
</xs:simpleType>
|
434 |
+
<xs:complexType name="OrganisationIdentification8">
|
435 |
+
<xs:sequence>
|
436 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AnyBIC" type="AnyBICIdentifier"/>
|
437 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericOrganisationIdentification1"/>
|
438 |
+
</xs:sequence>
|
439 |
+
</xs:complexType>
|
440 |
+
<xs:complexType name="OrganisationIdentificationSchemeName1Choice">
|
441 |
+
<xs:choice>
|
442 |
+
<xs:element name="Cd" type="ExternalOrganisationIdentification1Code"/>
|
443 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
444 |
+
</xs:choice>
|
445 |
+
</xs:complexType>
|
446 |
+
<xs:complexType name="Party11Choice">
|
447 |
+
<xs:choice>
|
448 |
+
<xs:element name="OrgId" type="OrganisationIdentification8"/>
|
449 |
+
<xs:element name="PrvtId" type="PersonIdentification5"/>
|
450 |
+
</xs:choice>
|
451 |
+
</xs:complexType>
|
452 |
+
<xs:complexType name="PartyIdentification43">
|
453 |
+
<xs:sequence>
|
454 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
455 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
456 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Party11Choice"/>
|
457 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtryOfRes" type="CountryCode"/>
|
458 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtctDtls" type="ContactDetails2"/>
|
459 |
+
</xs:sequence>
|
460 |
+
</xs:complexType>
|
461 |
+
<xs:complexType name="PersonIdentification5">
|
462 |
+
<xs:sequence>
|
463 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DtAndPlcOfBirth" type="DateAndPlaceOfBirth"/>
|
464 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericPersonIdentification1"/>
|
465 |
+
</xs:sequence>
|
466 |
+
</xs:complexType>
|
467 |
+
<xs:complexType name="PersonIdentificationSchemeName1Choice">
|
468 |
+
<xs:choice>
|
469 |
+
<xs:element name="Cd" type="ExternalPersonIdentification1Code"/>
|
470 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
471 |
+
</xs:choice>
|
472 |
+
</xs:complexType>
|
473 |
+
<xs:simpleType name="PhoneNumber">
|
474 |
+
<xs:restriction base="xs:string">
|
475 |
+
<xs:pattern value="\+[0-9]{1,3}-[0-9()+\-]{1,30}"/>
|
476 |
+
</xs:restriction>
|
477 |
+
</xs:simpleType>
|
478 |
+
<xs:complexType name="PostalAddress6">
|
479 |
+
<xs:sequence>
|
480 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AdrTp" type="AddressType2Code"/>
|
481 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Dept" type="Max70Text"/>
|
482 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SubDept" type="Max70Text"/>
|
483 |
+
<xs:element maxOccurs="1" minOccurs="0" name="StrtNm" type="Max70Text"/>
|
484 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BldgNb" type="Max16Text"/>
|
485 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstCd" type="Max16Text"/>
|
486 |
+
<xs:element maxOccurs="1" minOccurs="0" name="TwnNm" type="Max35Text"/>
|
487 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtrySubDvsn" type="Max35Text"/>
|
488 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
|
489 |
+
<xs:element maxOccurs="7" minOccurs="0" name="AdrLine" type="Max70Text"/>
|
490 |
+
</xs:sequence>
|
491 |
+
</xs:complexType>
|
492 |
+
<xs:complexType name="ReferredDocumentInformation6">
|
493 |
+
<xs:sequence>
|
494 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="ReferredDocumentType4"/>
|
495 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nb" type="Max35Text"/>
|
496 |
+
<xs:element maxOccurs="1" minOccurs="0" name="RltdDt" type="ISODate"/>
|
497 |
+
</xs:sequence>
|
498 |
+
</xs:complexType>
|
499 |
+
<xs:complexType name="ReferredDocumentType3Choice">
|
500 |
+
<xs:choice>
|
501 |
+
<xs:element name="Cd" type="DocumentType6Code"/>
|
502 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
503 |
+
</xs:choice>
|
504 |
+
</xs:complexType>
|
505 |
+
<xs:complexType name="ReferredDocumentType4">
|
506 |
+
<xs:sequence>
|
507 |
+
<xs:element name="CdOrPrtry" type="ReferredDocumentType3Choice"/>
|
508 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
509 |
+
</xs:sequence>
|
510 |
+
</xs:complexType>
|
511 |
+
<xs:simpleType name="SequenceType2Code">
|
512 |
+
<xs:restriction base="xs:string">
|
513 |
+
<xs:enumeration value="RCUR"/>
|
514 |
+
<xs:enumeration value="OOFF"/>
|
515 |
+
</xs:restriction>
|
516 |
+
</xs:simpleType>
|
517 |
+
<xs:complexType name="ServiceLevel8Choice">
|
518 |
+
<xs:choice>
|
519 |
+
<xs:element name="Cd" type="ExternalServiceLevel1Code"/>
|
520 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
521 |
+
</xs:choice>
|
522 |
+
</xs:complexType>
|
523 |
+
<xs:complexType name="SupplementaryData1">
|
524 |
+
<xs:sequence>
|
525 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PlcAndNm" type="Max350Text"/>
|
526 |
+
<xs:element name="Envlp" type="SupplementaryDataEnvelope1"/>
|
527 |
+
</xs:sequence>
|
528 |
+
</xs:complexType>
|
529 |
+
<xs:complexType name="SupplementaryDataEnvelope1">
|
530 |
+
<xs:sequence>
|
531 |
+
<xs:any namespace="##any" processContents="lax"/>
|
532 |
+
</xs:sequence>
|
533 |
+
</xs:complexType>
|
534 |
+
</xs:schema>
|
lib/Communicator/schemas/pain.010.001.04.xsd
ADDED
@@ -0,0 +1,615 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--Generated by Standards Editor (build:R1.6.2.2) on 2014 Oct 24 13:58:14, ISO 20022 version : 2013-->
|
3 |
+
<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:pain.010.001.04" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:iso:std:iso:20022:tech:xsd:pain.010.001.04">
|
4 |
+
<xs:element name="Document" type="Document"/>
|
5 |
+
<xs:complexType name="AccountIdentification4Choice">
|
6 |
+
<xs:choice>
|
7 |
+
<xs:element name="IBAN" type="IBAN2007Identifier"/>
|
8 |
+
<xs:element name="Othr" type="GenericAccountIdentification1"/>
|
9 |
+
</xs:choice>
|
10 |
+
</xs:complexType>
|
11 |
+
<xs:complexType name="AccountSchemeName1Choice">
|
12 |
+
<xs:choice>
|
13 |
+
<xs:element name="Cd" type="ExternalAccountIdentification1Code"/>
|
14 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
15 |
+
</xs:choice>
|
16 |
+
</xs:complexType>
|
17 |
+
<xs:simpleType name="ActiveCurrencyAndAmount_SimpleType">
|
18 |
+
<xs:restriction base="xs:decimal">
|
19 |
+
<xs:fractionDigits value="2"/>
|
20 |
+
<xs:totalDigits value="18"/>
|
21 |
+
<xs:minInclusive value="0"/>
|
22 |
+
</xs:restriction>
|
23 |
+
</xs:simpleType>
|
24 |
+
<xs:complexType name="ActiveCurrencyAndAmount">
|
25 |
+
<xs:simpleContent>
|
26 |
+
<xs:extension base="ActiveCurrencyAndAmount_SimpleType">
|
27 |
+
<xs:attribute name="Ccy" type="ActiveCurrencyCode" use="required"/>
|
28 |
+
</xs:extension>
|
29 |
+
</xs:simpleContent>
|
30 |
+
</xs:complexType>
|
31 |
+
<xs:simpleType name="ActiveCurrencyCode">
|
32 |
+
<xs:restriction base="xs:string">
|
33 |
+
<xs:pattern value="[A-Z]{3,3}"/>
|
34 |
+
</xs:restriction>
|
35 |
+
</xs:simpleType>
|
36 |
+
<xs:simpleType name="ActiveOrHistoricCurrencyAndAmount_SimpleType">
|
37 |
+
<xs:restriction base="xs:decimal">
|
38 |
+
<xs:fractionDigits value="2"/>
|
39 |
+
<xs:totalDigits value="18"/>
|
40 |
+
<xs:minInclusive value="0"/>
|
41 |
+
</xs:restriction>
|
42 |
+
</xs:simpleType>
|
43 |
+
<xs:complexType name="ActiveOrHistoricCurrencyAndAmount">
|
44 |
+
<xs:simpleContent>
|
45 |
+
<xs:extension base="ActiveOrHistoricCurrencyAndAmount_SimpleType">
|
46 |
+
<xs:attribute name="Ccy" type="ActiveOrHistoricCurrencyCode" use="required"/>
|
47 |
+
</xs:extension>
|
48 |
+
</xs:simpleContent>
|
49 |
+
</xs:complexType>
|
50 |
+
<xs:simpleType name="ActiveOrHistoricCurrencyCode">
|
51 |
+
<xs:restriction base="xs:string">
|
52 |
+
<xs:pattern value="[A-Z]{3,3}"/>
|
53 |
+
</xs:restriction>
|
54 |
+
</xs:simpleType>
|
55 |
+
<xs:simpleType name="AddressType2Code">
|
56 |
+
<xs:restriction base="xs:string">
|
57 |
+
<xs:enumeration value="ADDR"/>
|
58 |
+
<xs:enumeration value="PBOX"/>
|
59 |
+
<xs:enumeration value="HOME"/>
|
60 |
+
<xs:enumeration value="BIZZ"/>
|
61 |
+
<xs:enumeration value="MLTO"/>
|
62 |
+
<xs:enumeration value="DLVY"/>
|
63 |
+
</xs:restriction>
|
64 |
+
</xs:simpleType>
|
65 |
+
<xs:simpleType name="AnyBICIdentifier">
|
66 |
+
<xs:restriction base="xs:string">
|
67 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
68 |
+
</xs:restriction>
|
69 |
+
</xs:simpleType>
|
70 |
+
<xs:complexType name="Authorisation1Choice">
|
71 |
+
<xs:choice>
|
72 |
+
<xs:element name="Cd" type="Authorisation1Code"/>
|
73 |
+
<xs:element name="Prtry" type="Max128Text"/>
|
74 |
+
</xs:choice>
|
75 |
+
</xs:complexType>
|
76 |
+
<xs:simpleType name="Authorisation1Code">
|
77 |
+
<xs:restriction base="xs:string">
|
78 |
+
<xs:enumeration value="AUTH"/>
|
79 |
+
<xs:enumeration value="FDET"/>
|
80 |
+
<xs:enumeration value="FSUM"/>
|
81 |
+
<xs:enumeration value="ILEV"/>
|
82 |
+
</xs:restriction>
|
83 |
+
</xs:simpleType>
|
84 |
+
<xs:simpleType name="BICFIIdentifier">
|
85 |
+
<xs:restriction base="xs:string">
|
86 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
87 |
+
</xs:restriction>
|
88 |
+
</xs:simpleType>
|
89 |
+
<xs:complexType name="BranchAndFinancialInstitutionIdentification5">
|
90 |
+
<xs:sequence>
|
91 |
+
<xs:element name="FinInstnId" type="FinancialInstitutionIdentification8"/>
|
92 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BrnchId" type="BranchData2"/>
|
93 |
+
</xs:sequence>
|
94 |
+
</xs:complexType>
|
95 |
+
<xs:complexType name="BranchData2">
|
96 |
+
<xs:sequence>
|
97 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Max35Text"/>
|
98 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
99 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
100 |
+
</xs:sequence>
|
101 |
+
</xs:complexType>
|
102 |
+
<xs:complexType name="CashAccount24">
|
103 |
+
<xs:sequence>
|
104 |
+
<xs:element name="Id" type="AccountIdentification4Choice"/>
|
105 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="CashAccountType2Choice"/>
|
106 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ccy" type="ActiveOrHistoricCurrencyCode"/>
|
107 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max70Text"/>
|
108 |
+
</xs:sequence>
|
109 |
+
</xs:complexType>
|
110 |
+
<xs:complexType name="CashAccountType2Choice">
|
111 |
+
<xs:choice>
|
112 |
+
<xs:element name="Cd" type="ExternalCashAccountType1Code"/>
|
113 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
114 |
+
</xs:choice>
|
115 |
+
</xs:complexType>
|
116 |
+
<xs:complexType name="ClearingSystemIdentification2Choice">
|
117 |
+
<xs:choice>
|
118 |
+
<xs:element name="Cd" type="ExternalClearingSystemIdentification1Code"/>
|
119 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
120 |
+
</xs:choice>
|
121 |
+
</xs:complexType>
|
122 |
+
<xs:complexType name="ClearingSystemMemberIdentification2">
|
123 |
+
<xs:sequence>
|
124 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysId" type="ClearingSystemIdentification2Choice"/>
|
125 |
+
<xs:element name="MmbId" type="Max35Text"/>
|
126 |
+
</xs:sequence>
|
127 |
+
</xs:complexType>
|
128 |
+
<xs:complexType name="ContactDetails2">
|
129 |
+
<xs:sequence>
|
130 |
+
<xs:element maxOccurs="1" minOccurs="0" name="NmPrfx" type="NamePrefix1Code"/>
|
131 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
132 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PhneNb" type="PhoneNumber"/>
|
133 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MobNb" type="PhoneNumber"/>
|
134 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FaxNb" type="PhoneNumber"/>
|
135 |
+
<xs:element maxOccurs="1" minOccurs="0" name="EmailAdr" type="Max2048Text"/>
|
136 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="Max35Text"/>
|
137 |
+
</xs:sequence>
|
138 |
+
</xs:complexType>
|
139 |
+
<xs:simpleType name="CountryCode">
|
140 |
+
<xs:restriction base="xs:string">
|
141 |
+
<xs:pattern value="[A-Z]{2,2}"/>
|
142 |
+
</xs:restriction>
|
143 |
+
</xs:simpleType>
|
144 |
+
<xs:complexType name="DateAndPlaceOfBirth">
|
145 |
+
<xs:sequence>
|
146 |
+
<xs:element name="BirthDt" type="ISODate"/>
|
147 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PrvcOfBirth" type="Max35Text"/>
|
148 |
+
<xs:element name="CityOfBirth" type="Max35Text"/>
|
149 |
+
<xs:element name="CtryOfBirth" type="CountryCode"/>
|
150 |
+
</xs:sequence>
|
151 |
+
</xs:complexType>
|
152 |
+
<xs:complexType name="DatePeriodDetails1">
|
153 |
+
<xs:sequence>
|
154 |
+
<xs:element name="FrDt" type="ISODate"/>
|
155 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ToDt" type="ISODate"/>
|
156 |
+
</xs:sequence>
|
157 |
+
</xs:complexType>
|
158 |
+
<xs:simpleType name="DecimalNumber">
|
159 |
+
<xs:restriction base="xs:decimal">
|
160 |
+
<xs:fractionDigits value="17"/>
|
161 |
+
<xs:totalDigits value="18"/>
|
162 |
+
</xs:restriction>
|
163 |
+
</xs:simpleType>
|
164 |
+
<xs:complexType name="Document">
|
165 |
+
<xs:sequence>
|
166 |
+
<xs:element name="MndtAmdmntReq" type="MandateAmendmentRequestV04"/>
|
167 |
+
</xs:sequence>
|
168 |
+
</xs:complexType>
|
169 |
+
<xs:simpleType name="DocumentType6Code">
|
170 |
+
<xs:restriction base="xs:string">
|
171 |
+
<xs:enumeration value="MSIN"/>
|
172 |
+
<xs:enumeration value="CNFA"/>
|
173 |
+
<xs:enumeration value="DNFA"/>
|
174 |
+
<xs:enumeration value="CINV"/>
|
175 |
+
<xs:enumeration value="CREN"/>
|
176 |
+
<xs:enumeration value="DEBN"/>
|
177 |
+
<xs:enumeration value="HIRI"/>
|
178 |
+
<xs:enumeration value="SBIN"/>
|
179 |
+
<xs:enumeration value="CMCN"/>
|
180 |
+
<xs:enumeration value="SOAC"/>
|
181 |
+
<xs:enumeration value="DISP"/>
|
182 |
+
<xs:enumeration value="BOLD"/>
|
183 |
+
<xs:enumeration value="VCHR"/>
|
184 |
+
<xs:enumeration value="AROI"/>
|
185 |
+
<xs:enumeration value="TSUT"/>
|
186 |
+
<xs:enumeration value="PUOR"/>
|
187 |
+
</xs:restriction>
|
188 |
+
</xs:simpleType>
|
189 |
+
<xs:simpleType name="ExternalAccountIdentification1Code">
|
190 |
+
<xs:restriction base="xs:string">
|
191 |
+
<xs:minLength value="1"/>
|
192 |
+
<xs:maxLength value="4"/>
|
193 |
+
</xs:restriction>
|
194 |
+
</xs:simpleType>
|
195 |
+
<xs:simpleType name="ExternalCashAccountType1Code">
|
196 |
+
<xs:restriction base="xs:string">
|
197 |
+
<xs:minLength value="1"/>
|
198 |
+
<xs:maxLength value="4"/>
|
199 |
+
</xs:restriction>
|
200 |
+
</xs:simpleType>
|
201 |
+
<xs:simpleType name="ExternalClearingSystemIdentification1Code">
|
202 |
+
<xs:restriction base="xs:string">
|
203 |
+
<xs:minLength value="1"/>
|
204 |
+
<xs:maxLength value="5"/>
|
205 |
+
</xs:restriction>
|
206 |
+
</xs:simpleType>
|
207 |
+
<xs:simpleType name="ExternalFinancialInstitutionIdentification1Code">
|
208 |
+
<xs:restriction base="xs:string">
|
209 |
+
<xs:minLength value="1"/>
|
210 |
+
<xs:maxLength value="4"/>
|
211 |
+
</xs:restriction>
|
212 |
+
</xs:simpleType>
|
213 |
+
<xs:simpleType name="ExternalLocalInstrument1Code">
|
214 |
+
<xs:restriction base="xs:string">
|
215 |
+
<xs:minLength value="1"/>
|
216 |
+
<xs:maxLength value="35"/>
|
217 |
+
</xs:restriction>
|
218 |
+
</xs:simpleType>
|
219 |
+
<xs:simpleType name="ExternalMandateReason1Code">
|
220 |
+
<xs:restriction base="xs:string">
|
221 |
+
<xs:minLength value="1"/>
|
222 |
+
<xs:maxLength value="4"/>
|
223 |
+
</xs:restriction>
|
224 |
+
</xs:simpleType>
|
225 |
+
<xs:simpleType name="ExternalMandateSetupReason1Code">
|
226 |
+
<xs:restriction base="xs:string">
|
227 |
+
<xs:minLength value="1"/>
|
228 |
+
<xs:maxLength value="4"/>
|
229 |
+
</xs:restriction>
|
230 |
+
</xs:simpleType>
|
231 |
+
<xs:simpleType name="ExternalOrganisationIdentification1Code">
|
232 |
+
<xs:restriction base="xs:string">
|
233 |
+
<xs:minLength value="1"/>
|
234 |
+
<xs:maxLength value="4"/>
|
235 |
+
</xs:restriction>
|
236 |
+
</xs:simpleType>
|
237 |
+
<xs:simpleType name="ExternalPersonIdentification1Code">
|
238 |
+
<xs:restriction base="xs:string">
|
239 |
+
<xs:minLength value="1"/>
|
240 |
+
<xs:maxLength value="4"/>
|
241 |
+
</xs:restriction>
|
242 |
+
</xs:simpleType>
|
243 |
+
<xs:simpleType name="ExternalServiceLevel1Code">
|
244 |
+
<xs:restriction base="xs:string">
|
245 |
+
<xs:minLength value="1"/>
|
246 |
+
<xs:maxLength value="4"/>
|
247 |
+
</xs:restriction>
|
248 |
+
</xs:simpleType>
|
249 |
+
<xs:complexType name="FinancialIdentificationSchemeName1Choice">
|
250 |
+
<xs:choice>
|
251 |
+
<xs:element name="Cd" type="ExternalFinancialInstitutionIdentification1Code"/>
|
252 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
253 |
+
</xs:choice>
|
254 |
+
</xs:complexType>
|
255 |
+
<xs:complexType name="FinancialInstitutionIdentification8">
|
256 |
+
<xs:sequence>
|
257 |
+
<!-- Made BICFI mandatory, previously this line was: -->
|
258 |
+
<!-- <xs:element maxOccurs="1" minOccurs="0" name="BICFI" type="BICFIIdentifier"/> -->
|
259 |
+
<xs:element name="BICFI" type="BICFIIdentifier"/>
|
260 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysMmbId" type="ClearingSystemMemberIdentification2"/>
|
261 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
262 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
263 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="GenericFinancialIdentification1"/>
|
264 |
+
</xs:sequence>
|
265 |
+
</xs:complexType>
|
266 |
+
<xs:complexType name="Frequency21Choice">
|
267 |
+
<xs:choice>
|
268 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
269 |
+
<xs:element name="Prd" type="FrequencyPeriod1"/>
|
270 |
+
</xs:choice>
|
271 |
+
</xs:complexType>
|
272 |
+
<xs:simpleType name="Frequency6Code">
|
273 |
+
<xs:restriction base="xs:string">
|
274 |
+
<xs:enumeration value="YEAR"/>
|
275 |
+
<xs:enumeration value="MNTH"/>
|
276 |
+
<xs:enumeration value="QURT"/>
|
277 |
+
<xs:enumeration value="MIAN"/>
|
278 |
+
<xs:enumeration value="WEEK"/>
|
279 |
+
<xs:enumeration value="DAIL"/>
|
280 |
+
<xs:enumeration value="ADHO"/>
|
281 |
+
<xs:enumeration value="INDA"/>
|
282 |
+
<xs:enumeration value="FRTN"/>
|
283 |
+
</xs:restriction>
|
284 |
+
</xs:simpleType>
|
285 |
+
<xs:complexType name="FrequencyPeriod1">
|
286 |
+
<xs:sequence>
|
287 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
288 |
+
<xs:element name="CntPerPrd" type="DecimalNumber"/>
|
289 |
+
</xs:sequence>
|
290 |
+
</xs:complexType>
|
291 |
+
<xs:complexType name="GenericAccountIdentification1">
|
292 |
+
<xs:sequence>
|
293 |
+
<xs:element name="Id" type="Max34Text"/>
|
294 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="AccountSchemeName1Choice"/>
|
295 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
296 |
+
</xs:sequence>
|
297 |
+
</xs:complexType>
|
298 |
+
<xs:complexType name="GenericFinancialIdentification1">
|
299 |
+
<xs:sequence>
|
300 |
+
<xs:element name="Id" type="Max35Text"/>
|
301 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="FinancialIdentificationSchemeName1Choice"/>
|
302 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
303 |
+
</xs:sequence>
|
304 |
+
</xs:complexType>
|
305 |
+
<xs:complexType name="GenericOrganisationIdentification1">
|
306 |
+
<xs:sequence>
|
307 |
+
<xs:element name="Id" type="Max35Text"/>
|
308 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="OrganisationIdentificationSchemeName1Choice"/>
|
309 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
310 |
+
</xs:sequence>
|
311 |
+
</xs:complexType>
|
312 |
+
<xs:complexType name="GenericPersonIdentification1">
|
313 |
+
<xs:sequence>
|
314 |
+
<xs:element name="Id" type="Max35Text"/>
|
315 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="PersonIdentificationSchemeName1Choice"/>
|
316 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
317 |
+
</xs:sequence>
|
318 |
+
</xs:complexType>
|
319 |
+
<xs:complexType name="GroupHeader47">
|
320 |
+
<xs:sequence>
|
321 |
+
<xs:element name="MsgId" type="Max35Text"/>
|
322 |
+
<xs:element name="CreDtTm" type="ISODateTime"/>
|
323 |
+
<xs:element maxOccurs="2" minOccurs="0" name="Authstn" type="Authorisation1Choice"/>
|
324 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InitgPty" type="PartyIdentification43"/>
|
325 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstgAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
326 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstdAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
327 |
+
</xs:sequence>
|
328 |
+
</xs:complexType>
|
329 |
+
<xs:simpleType name="IBAN2007Identifier">
|
330 |
+
<xs:restriction base="xs:string">
|
331 |
+
<xs:pattern value="[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}"/>
|
332 |
+
</xs:restriction>
|
333 |
+
</xs:simpleType>
|
334 |
+
<xs:simpleType name="ISODate">
|
335 |
+
<xs:restriction base="xs:date"/>
|
336 |
+
</xs:simpleType>
|
337 |
+
<xs:simpleType name="ISODateTime">
|
338 |
+
<xs:restriction base="xs:dateTime"/>
|
339 |
+
</xs:simpleType>
|
340 |
+
<xs:complexType name="LocalInstrument2Choice">
|
341 |
+
<xs:choice>
|
342 |
+
<xs:element name="Cd" type="ExternalLocalInstrument1Code"/>
|
343 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
344 |
+
</xs:choice>
|
345 |
+
</xs:complexType>
|
346 |
+
<xs:complexType name="Mandate5">
|
347 |
+
<xs:sequence>
|
348 |
+
<xs:element name="MndtId" type="Max35Text"/>
|
349 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MndtReqId" type="Max35Text"/>
|
350 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="MandateTypeInformation1"/>
|
351 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ocrncs" type="MandateOccurrences3"/>
|
352 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ColltnAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
|
353 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MaxAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
|
354 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Rsn" type="MandateSetupReason1Choice"/>
|
355 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrSchmeId" type="PartyIdentification43"/>
|
356 |
+
<xs:element name="Cdtr" type="PartyIdentification43"/>
|
357 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAcct" type="CashAccount24"/>
|
358 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
359 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtCdtr" type="PartyIdentification43"/>
|
360 |
+
<xs:element name="Dbtr" type="PartyIdentification43"/>
|
361 |
+
<!-- Made DbtrAcct mandatory, previously this line was: -->
|
362 |
+
<!-- <xs:element maxOccurs="1" minOccurs="0" name="DbtrAcct" type="CashAccount24"/> -->
|
363 |
+
<xs:element name="DbtrAcct" type="CashAccount24"/>
|
364 |
+
<xs:element name="DbtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
365 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification43"/>
|
366 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="RfrdDoc" type="ReferredDocumentInformation6"/>
|
367 |
+
</xs:sequence>
|
368 |
+
</xs:complexType>
|
369 |
+
<xs:complexType name="Mandate6">
|
370 |
+
<xs:sequence>
|
371 |
+
<xs:element name="MndtId" type="Max35Text"/>
|
372 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MndtReqId" type="Max35Text"/>
|
373 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="MandateTypeInformation1"/>
|
374 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ocrncs" type="MandateOccurrences3"/>
|
375 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ColltnAmt" type="ActiveCurrencyAndAmount"/>
|
376 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MaxAmt" type="ActiveCurrencyAndAmount"/>
|
377 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Rsn" type="MandateSetupReason1Choice"/>
|
378 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrSchmeId" type="PartyIdentification43"/>
|
379 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Cdtr" type="PartyIdentification43"/>
|
380 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAcct" type="CashAccount24"/>
|
381 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
382 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtCdtr" type="PartyIdentification43"/>
|
383 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Dbtr" type="PartyIdentification43"/>
|
384 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DbtrAcct" type="CashAccount24"/>
|
385 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DbtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
386 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification43"/>
|
387 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="RfrdDoc" type="ReferredDocumentInformation6"/>
|
388 |
+
</xs:sequence>
|
389 |
+
</xs:complexType>
|
390 |
+
<xs:complexType name="MandateAmendment4">
|
391 |
+
<xs:sequence>
|
392 |
+
<xs:element maxOccurs="1" minOccurs="0" name="OrgnlMsgInf" type="OriginalMessageInformation1"/>
|
393 |
+
<xs:element name="AmdmntRsn" type="MandateAmendmentReason1"/>
|
394 |
+
<xs:element name="Mndt" type="Mandate6"/>
|
395 |
+
<xs:element name="OrgnlMndt" type="OriginalMandate3Choice"/>
|
396 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
397 |
+
</xs:sequence>
|
398 |
+
</xs:complexType>
|
399 |
+
<xs:complexType name="MandateAmendmentReason1">
|
400 |
+
<xs:sequence>
|
401 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Orgtr" type="PartyIdentification43"/>
|
402 |
+
<xs:element name="Rsn" type="MandateReason1Choice"/>
|
403 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="AddtlInf" type="Max105Text"/>
|
404 |
+
</xs:sequence>
|
405 |
+
</xs:complexType>
|
406 |
+
<xs:complexType name="MandateAmendmentRequestV04">
|
407 |
+
<xs:sequence>
|
408 |
+
<xs:element name="GrpHdr" type="GroupHeader47"/>
|
409 |
+
<xs:element maxOccurs="unbounded" minOccurs="1" name="UndrlygAmdmntDtls" type="MandateAmendment4"/>
|
410 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
411 |
+
</xs:sequence>
|
412 |
+
</xs:complexType>
|
413 |
+
<xs:complexType name="MandateOccurrences3">
|
414 |
+
<xs:sequence>
|
415 |
+
<xs:element name="SeqTp" type="SequenceType2Code"/>
|
416 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Frqcy" type="Frequency21Choice"/>
|
417 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Drtn" type="DatePeriodDetails1"/>
|
418 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FrstColltnDt" type="ISODate"/>
|
419 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FnlColltnDt" type="ISODate"/>
|
420 |
+
</xs:sequence>
|
421 |
+
</xs:complexType>
|
422 |
+
<xs:complexType name="MandateReason1Choice">
|
423 |
+
<xs:choice>
|
424 |
+
<xs:element name="Cd" type="ExternalMandateReason1Code"/>
|
425 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
426 |
+
</xs:choice>
|
427 |
+
</xs:complexType>
|
428 |
+
<xs:complexType name="MandateSetupReason1Choice">
|
429 |
+
<xs:choice>
|
430 |
+
<xs:element name="Cd" type="ExternalMandateSetupReason1Code"/>
|
431 |
+
<xs:element name="Prtry" type="Max70Text"/>
|
432 |
+
</xs:choice>
|
433 |
+
</xs:complexType>
|
434 |
+
<xs:complexType name="MandateTypeInformation1">
|
435 |
+
<xs:sequence>
|
436 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SvcLvl" type="ServiceLevel8Choice"/>
|
437 |
+
<xs:element maxOccurs="1" minOccurs="0" name="LclInstrm" type="LocalInstrument2Choice"/>
|
438 |
+
</xs:sequence>
|
439 |
+
</xs:complexType>
|
440 |
+
<xs:simpleType name="Max105Text">
|
441 |
+
<xs:restriction base="xs:string">
|
442 |
+
<xs:minLength value="1"/>
|
443 |
+
<xs:maxLength value="105"/>
|
444 |
+
</xs:restriction>
|
445 |
+
</xs:simpleType>
|
446 |
+
<xs:simpleType name="Max128Text">
|
447 |
+
<xs:restriction base="xs:string">
|
448 |
+
<xs:minLength value="1"/>
|
449 |
+
<xs:maxLength value="128"/>
|
450 |
+
</xs:restriction>
|
451 |
+
</xs:simpleType>
|
452 |
+
<xs:simpleType name="Max140Text">
|
453 |
+
<xs:restriction base="xs:string">
|
454 |
+
<xs:minLength value="1"/>
|
455 |
+
<xs:maxLength value="140"/>
|
456 |
+
</xs:restriction>
|
457 |
+
</xs:simpleType>
|
458 |
+
<xs:simpleType name="Max16Text">
|
459 |
+
<xs:restriction base="xs:string">
|
460 |
+
<xs:minLength value="1"/>
|
461 |
+
<xs:maxLength value="16"/>
|
462 |
+
</xs:restriction>
|
463 |
+
</xs:simpleType>
|
464 |
+
<xs:simpleType name="Max2048Text">
|
465 |
+
<xs:restriction base="xs:string">
|
466 |
+
<xs:minLength value="1"/>
|
467 |
+
<xs:maxLength value="2048"/>
|
468 |
+
</xs:restriction>
|
469 |
+
</xs:simpleType>
|
470 |
+
<xs:simpleType name="Max34Text">
|
471 |
+
<xs:restriction base="xs:string">
|
472 |
+
<xs:minLength value="1"/>
|
473 |
+
<xs:maxLength value="34"/>
|
474 |
+
</xs:restriction>
|
475 |
+
</xs:simpleType>
|
476 |
+
<xs:simpleType name="Max350Text">
|
477 |
+
<xs:restriction base="xs:string">
|
478 |
+
<xs:minLength value="1"/>
|
479 |
+
<xs:maxLength value="350"/>
|
480 |
+
</xs:restriction>
|
481 |
+
</xs:simpleType>
|
482 |
+
<xs:simpleType name="Max35Text">
|
483 |
+
<xs:restriction base="xs:string">
|
484 |
+
<xs:minLength value="1"/>
|
485 |
+
<xs:maxLength value="35"/>
|
486 |
+
</xs:restriction>
|
487 |
+
</xs:simpleType>
|
488 |
+
<xs:simpleType name="Max70Text">
|
489 |
+
<xs:restriction base="xs:string">
|
490 |
+
<xs:minLength value="1"/>
|
491 |
+
<xs:maxLength value="70"/>
|
492 |
+
</xs:restriction>
|
493 |
+
</xs:simpleType>
|
494 |
+
<xs:simpleType name="NamePrefix1Code">
|
495 |
+
<xs:restriction base="xs:string">
|
496 |
+
<xs:enumeration value="DOCT"/>
|
497 |
+
<xs:enumeration value="MIST"/>
|
498 |
+
<xs:enumeration value="MISS"/>
|
499 |
+
<xs:enumeration value="MADM"/>
|
500 |
+
</xs:restriction>
|
501 |
+
</xs:simpleType>
|
502 |
+
<xs:complexType name="OrganisationIdentification8">
|
503 |
+
<xs:sequence>
|
504 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AnyBIC" type="AnyBICIdentifier"/>
|
505 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericOrganisationIdentification1"/>
|
506 |
+
</xs:sequence>
|
507 |
+
</xs:complexType>
|
508 |
+
<xs:complexType name="OrganisationIdentificationSchemeName1Choice">
|
509 |
+
<xs:choice>
|
510 |
+
<xs:element name="Cd" type="ExternalOrganisationIdentification1Code"/>
|
511 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
512 |
+
</xs:choice>
|
513 |
+
</xs:complexType>
|
514 |
+
<xs:complexType name="OriginalMandate3Choice">
|
515 |
+
<xs:choice>
|
516 |
+
<xs:element name="OrgnlMndtId" type="Max35Text"/>
|
517 |
+
<xs:element name="OrgnlMndt" type="Mandate5"/>
|
518 |
+
</xs:choice>
|
519 |
+
</xs:complexType>
|
520 |
+
<xs:complexType name="OriginalMessageInformation1">
|
521 |
+
<xs:sequence>
|
522 |
+
<xs:element name="MsgId" type="Max35Text"/>
|
523 |
+
<xs:element name="MsgNmId" type="Max35Text"/>
|
524 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CreDtTm" type="ISODateTime"/>
|
525 |
+
</xs:sequence>
|
526 |
+
</xs:complexType>
|
527 |
+
<xs:complexType name="Party11Choice">
|
528 |
+
<xs:choice>
|
529 |
+
<xs:element name="OrgId" type="OrganisationIdentification8"/>
|
530 |
+
<xs:element name="PrvtId" type="PersonIdentification5"/>
|
531 |
+
</xs:choice>
|
532 |
+
</xs:complexType>
|
533 |
+
<xs:complexType name="PartyIdentification43">
|
534 |
+
<xs:sequence>
|
535 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
536 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
537 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Party11Choice"/>
|
538 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtryOfRes" type="CountryCode"/>
|
539 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtctDtls" type="ContactDetails2"/>
|
540 |
+
</xs:sequence>
|
541 |
+
</xs:complexType>
|
542 |
+
<xs:complexType name="PersonIdentification5">
|
543 |
+
<xs:sequence>
|
544 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DtAndPlcOfBirth" type="DateAndPlaceOfBirth"/>
|
545 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericPersonIdentification1"/>
|
546 |
+
</xs:sequence>
|
547 |
+
</xs:complexType>
|
548 |
+
<xs:complexType name="PersonIdentificationSchemeName1Choice">
|
549 |
+
<xs:choice>
|
550 |
+
<xs:element name="Cd" type="ExternalPersonIdentification1Code"/>
|
551 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
552 |
+
</xs:choice>
|
553 |
+
</xs:complexType>
|
554 |
+
<xs:simpleType name="PhoneNumber">
|
555 |
+
<xs:restriction base="xs:string">
|
556 |
+
<xs:pattern value="\+[0-9]{1,3}-[0-9()+\-]{1,30}"/>
|
557 |
+
</xs:restriction>
|
558 |
+
</xs:simpleType>
|
559 |
+
<xs:complexType name="PostalAddress6">
|
560 |
+
<xs:sequence>
|
561 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AdrTp" type="AddressType2Code"/>
|
562 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Dept" type="Max70Text"/>
|
563 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SubDept" type="Max70Text"/>
|
564 |
+
<xs:element maxOccurs="1" minOccurs="0" name="StrtNm" type="Max70Text"/>
|
565 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BldgNb" type="Max16Text"/>
|
566 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstCd" type="Max16Text"/>
|
567 |
+
<xs:element maxOccurs="1" minOccurs="0" name="TwnNm" type="Max35Text"/>
|
568 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtrySubDvsn" type="Max35Text"/>
|
569 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
|
570 |
+
<xs:element maxOccurs="7" minOccurs="0" name="AdrLine" type="Max70Text"/>
|
571 |
+
</xs:sequence>
|
572 |
+
</xs:complexType>
|
573 |
+
<xs:complexType name="ReferredDocumentInformation6">
|
574 |
+
<xs:sequence>
|
575 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="ReferredDocumentType4"/>
|
576 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nb" type="Max35Text"/>
|
577 |
+
<xs:element maxOccurs="1" minOccurs="0" name="RltdDt" type="ISODate"/>
|
578 |
+
</xs:sequence>
|
579 |
+
</xs:complexType>
|
580 |
+
<xs:complexType name="ReferredDocumentType3Choice">
|
581 |
+
<xs:choice>
|
582 |
+
<xs:element name="Cd" type="DocumentType6Code"/>
|
583 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
584 |
+
</xs:choice>
|
585 |
+
</xs:complexType>
|
586 |
+
<xs:complexType name="ReferredDocumentType4">
|
587 |
+
<xs:sequence>
|
588 |
+
<xs:element name="CdOrPrtry" type="ReferredDocumentType3Choice"/>
|
589 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
590 |
+
</xs:sequence>
|
591 |
+
</xs:complexType>
|
592 |
+
<xs:simpleType name="SequenceType2Code">
|
593 |
+
<xs:restriction base="xs:string">
|
594 |
+
<xs:enumeration value="RCUR"/>
|
595 |
+
<xs:enumeration value="OOFF"/>
|
596 |
+
</xs:restriction>
|
597 |
+
</xs:simpleType>
|
598 |
+
<xs:complexType name="ServiceLevel8Choice">
|
599 |
+
<xs:choice>
|
600 |
+
<xs:element name="Cd" type="ExternalServiceLevel1Code"/>
|
601 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
602 |
+
</xs:choice>
|
603 |
+
</xs:complexType>
|
604 |
+
<xs:complexType name="SupplementaryData1">
|
605 |
+
<xs:sequence>
|
606 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PlcAndNm" type="Max350Text"/>
|
607 |
+
<xs:element name="Envlp" type="SupplementaryDataEnvelope1"/>
|
608 |
+
</xs:sequence>
|
609 |
+
</xs:complexType>
|
610 |
+
<xs:complexType name="SupplementaryDataEnvelope1">
|
611 |
+
<xs:sequence>
|
612 |
+
<xs:any namespace="##any" processContents="lax"/>
|
613 |
+
</xs:sequence>
|
614 |
+
</xs:complexType>
|
615 |
+
</xs:schema>
|
lib/Communicator/schemas/pain.011.001.04.xsd
ADDED
@@ -0,0 +1,574 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--Generated by Standards Editor (build:R1.6.2.2) on 2014 Oct 24 13:58:14, ISO 20022 version : 2013-->
|
3 |
+
<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:pain.011.001.04" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:iso:std:iso:20022:tech:xsd:pain.011.001.04">
|
4 |
+
<xs:element name="Document" type="Document"/>
|
5 |
+
<xs:complexType name="AccountIdentification4Choice">
|
6 |
+
<xs:choice>
|
7 |
+
<xs:element name="IBAN" type="IBAN2007Identifier"/>
|
8 |
+
<xs:element name="Othr" type="GenericAccountIdentification1"/>
|
9 |
+
</xs:choice>
|
10 |
+
</xs:complexType>
|
11 |
+
<xs:complexType name="AccountSchemeName1Choice">
|
12 |
+
<xs:choice>
|
13 |
+
<xs:element name="Cd" type="ExternalAccountIdentification1Code"/>
|
14 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
15 |
+
</xs:choice>
|
16 |
+
</xs:complexType>
|
17 |
+
<xs:simpleType name="ActiveOrHistoricCurrencyAndAmount_SimpleType">
|
18 |
+
<xs:restriction base="xs:decimal">
|
19 |
+
<xs:fractionDigits value="2"/>
|
20 |
+
<xs:totalDigits value="18"/>
|
21 |
+
<xs:minInclusive value="0"/>
|
22 |
+
</xs:restriction>
|
23 |
+
</xs:simpleType>
|
24 |
+
<xs:complexType name="ActiveOrHistoricCurrencyAndAmount">
|
25 |
+
<xs:simpleContent>
|
26 |
+
<xs:extension base="ActiveOrHistoricCurrencyAndAmount_SimpleType">
|
27 |
+
<xs:attribute name="Ccy" type="ActiveOrHistoricCurrencyCode" use="required"/>
|
28 |
+
</xs:extension>
|
29 |
+
</xs:simpleContent>
|
30 |
+
</xs:complexType>
|
31 |
+
<xs:simpleType name="ActiveOrHistoricCurrencyCode">
|
32 |
+
<xs:restriction base="xs:string">
|
33 |
+
<xs:pattern value="[A-Z]{3,3}"/>
|
34 |
+
</xs:restriction>
|
35 |
+
</xs:simpleType>
|
36 |
+
<xs:simpleType name="AddressType2Code">
|
37 |
+
<xs:restriction base="xs:string">
|
38 |
+
<xs:enumeration value="ADDR"/>
|
39 |
+
<xs:enumeration value="PBOX"/>
|
40 |
+
<xs:enumeration value="HOME"/>
|
41 |
+
<xs:enumeration value="BIZZ"/>
|
42 |
+
<xs:enumeration value="MLTO"/>
|
43 |
+
<xs:enumeration value="DLVY"/>
|
44 |
+
</xs:restriction>
|
45 |
+
</xs:simpleType>
|
46 |
+
<xs:simpleType name="AnyBICIdentifier">
|
47 |
+
<xs:restriction base="xs:string">
|
48 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
49 |
+
</xs:restriction>
|
50 |
+
</xs:simpleType>
|
51 |
+
<xs:complexType name="Authorisation1Choice">
|
52 |
+
<xs:choice>
|
53 |
+
<xs:element name="Cd" type="Authorisation1Code"/>
|
54 |
+
<xs:element name="Prtry" type="Max128Text"/>
|
55 |
+
</xs:choice>
|
56 |
+
</xs:complexType>
|
57 |
+
<xs:simpleType name="Authorisation1Code">
|
58 |
+
<xs:restriction base="xs:string">
|
59 |
+
<xs:enumeration value="AUTH"/>
|
60 |
+
<xs:enumeration value="FDET"/>
|
61 |
+
<xs:enumeration value="FSUM"/>
|
62 |
+
<xs:enumeration value="ILEV"/>
|
63 |
+
</xs:restriction>
|
64 |
+
</xs:simpleType>
|
65 |
+
<xs:simpleType name="BICFIIdentifier">
|
66 |
+
<xs:restriction base="xs:string">
|
67 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
68 |
+
</xs:restriction>
|
69 |
+
</xs:simpleType>
|
70 |
+
<xs:complexType name="BranchAndFinancialInstitutionIdentification5">
|
71 |
+
<xs:sequence>
|
72 |
+
<xs:element name="FinInstnId" type="FinancialInstitutionIdentification8"/>
|
73 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BrnchId" type="BranchData2"/>
|
74 |
+
</xs:sequence>
|
75 |
+
</xs:complexType>
|
76 |
+
<xs:complexType name="BranchData2">
|
77 |
+
<xs:sequence>
|
78 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Max35Text"/>
|
79 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
80 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
81 |
+
</xs:sequence>
|
82 |
+
</xs:complexType>
|
83 |
+
<xs:complexType name="CashAccount24">
|
84 |
+
<xs:sequence>
|
85 |
+
<xs:element name="Id" type="AccountIdentification4Choice"/>
|
86 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="CashAccountType2Choice"/>
|
87 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ccy" type="ActiveOrHistoricCurrencyCode"/>
|
88 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max70Text"/>
|
89 |
+
</xs:sequence>
|
90 |
+
</xs:complexType>
|
91 |
+
<xs:complexType name="CashAccountType2Choice">
|
92 |
+
<xs:choice>
|
93 |
+
<xs:element name="Cd" type="ExternalCashAccountType1Code"/>
|
94 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
95 |
+
</xs:choice>
|
96 |
+
</xs:complexType>
|
97 |
+
<xs:complexType name="ClearingSystemIdentification2Choice">
|
98 |
+
<xs:choice>
|
99 |
+
<xs:element name="Cd" type="ExternalClearingSystemIdentification1Code"/>
|
100 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
101 |
+
</xs:choice>
|
102 |
+
</xs:complexType>
|
103 |
+
<xs:complexType name="ClearingSystemMemberIdentification2">
|
104 |
+
<xs:sequence>
|
105 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysId" type="ClearingSystemIdentification2Choice"/>
|
106 |
+
<xs:element name="MmbId" type="Max35Text"/>
|
107 |
+
</xs:sequence>
|
108 |
+
</xs:complexType>
|
109 |
+
<xs:complexType name="ContactDetails2">
|
110 |
+
<xs:sequence>
|
111 |
+
<xs:element maxOccurs="1" minOccurs="0" name="NmPrfx" type="NamePrefix1Code"/>
|
112 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
113 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PhneNb" type="PhoneNumber"/>
|
114 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MobNb" type="PhoneNumber"/>
|
115 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FaxNb" type="PhoneNumber"/>
|
116 |
+
<xs:element maxOccurs="1" minOccurs="0" name="EmailAdr" type="Max2048Text"/>
|
117 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="Max35Text"/>
|
118 |
+
</xs:sequence>
|
119 |
+
</xs:complexType>
|
120 |
+
<xs:simpleType name="CountryCode">
|
121 |
+
<xs:restriction base="xs:string">
|
122 |
+
<xs:pattern value="[A-Z]{2,2}"/>
|
123 |
+
</xs:restriction>
|
124 |
+
</xs:simpleType>
|
125 |
+
<xs:complexType name="DateAndPlaceOfBirth">
|
126 |
+
<xs:sequence>
|
127 |
+
<xs:element name="BirthDt" type="ISODate"/>
|
128 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PrvcOfBirth" type="Max35Text"/>
|
129 |
+
<xs:element name="CityOfBirth" type="Max35Text"/>
|
130 |
+
<xs:element name="CtryOfBirth" type="CountryCode"/>
|
131 |
+
</xs:sequence>
|
132 |
+
</xs:complexType>
|
133 |
+
<xs:complexType name="DatePeriodDetails1">
|
134 |
+
<xs:sequence>
|
135 |
+
<xs:element name="FrDt" type="ISODate"/>
|
136 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ToDt" type="ISODate"/>
|
137 |
+
</xs:sequence>
|
138 |
+
</xs:complexType>
|
139 |
+
<xs:simpleType name="DecimalNumber">
|
140 |
+
<xs:restriction base="xs:decimal">
|
141 |
+
<xs:fractionDigits value="17"/>
|
142 |
+
<xs:totalDigits value="18"/>
|
143 |
+
</xs:restriction>
|
144 |
+
</xs:simpleType>
|
145 |
+
<xs:complexType name="Document">
|
146 |
+
<xs:sequence>
|
147 |
+
<xs:element name="MndtCxlReq" type="MandateCancellationRequestV04"/>
|
148 |
+
</xs:sequence>
|
149 |
+
</xs:complexType>
|
150 |
+
<xs:simpleType name="DocumentType6Code">
|
151 |
+
<xs:restriction base="xs:string">
|
152 |
+
<xs:enumeration value="MSIN"/>
|
153 |
+
<xs:enumeration value="CNFA"/>
|
154 |
+
<xs:enumeration value="DNFA"/>
|
155 |
+
<xs:enumeration value="CINV"/>
|
156 |
+
<xs:enumeration value="CREN"/>
|
157 |
+
<xs:enumeration value="DEBN"/>
|
158 |
+
<xs:enumeration value="HIRI"/>
|
159 |
+
<xs:enumeration value="SBIN"/>
|
160 |
+
<xs:enumeration value="CMCN"/>
|
161 |
+
<xs:enumeration value="SOAC"/>
|
162 |
+
<xs:enumeration value="DISP"/>
|
163 |
+
<xs:enumeration value="BOLD"/>
|
164 |
+
<xs:enumeration value="VCHR"/>
|
165 |
+
<xs:enumeration value="AROI"/>
|
166 |
+
<xs:enumeration value="TSUT"/>
|
167 |
+
<xs:enumeration value="PUOR"/>
|
168 |
+
</xs:restriction>
|
169 |
+
</xs:simpleType>
|
170 |
+
<xs:simpleType name="ExternalAccountIdentification1Code">
|
171 |
+
<xs:restriction base="xs:string">
|
172 |
+
<xs:minLength value="1"/>
|
173 |
+
<xs:maxLength value="4"/>
|
174 |
+
</xs:restriction>
|
175 |
+
</xs:simpleType>
|
176 |
+
<xs:simpleType name="ExternalCashAccountType1Code">
|
177 |
+
<xs:restriction base="xs:string">
|
178 |
+
<xs:minLength value="1"/>
|
179 |
+
<xs:maxLength value="4"/>
|
180 |
+
</xs:restriction>
|
181 |
+
</xs:simpleType>
|
182 |
+
<xs:simpleType name="ExternalClearingSystemIdentification1Code">
|
183 |
+
<xs:restriction base="xs:string">
|
184 |
+
<xs:minLength value="1"/>
|
185 |
+
<xs:maxLength value="5"/>
|
186 |
+
</xs:restriction>
|
187 |
+
</xs:simpleType>
|
188 |
+
<xs:simpleType name="ExternalFinancialInstitutionIdentification1Code">
|
189 |
+
<xs:restriction base="xs:string">
|
190 |
+
<xs:minLength value="1"/>
|
191 |
+
<xs:maxLength value="4"/>
|
192 |
+
</xs:restriction>
|
193 |
+
</xs:simpleType>
|
194 |
+
<xs:simpleType name="ExternalLocalInstrument1Code">
|
195 |
+
<xs:restriction base="xs:string">
|
196 |
+
<xs:minLength value="1"/>
|
197 |
+
<xs:maxLength value="35"/>
|
198 |
+
</xs:restriction>
|
199 |
+
</xs:simpleType>
|
200 |
+
<xs:simpleType name="ExternalMandateReason1Code">
|
201 |
+
<xs:restriction base="xs:string">
|
202 |
+
<xs:minLength value="1"/>
|
203 |
+
<xs:maxLength value="4"/>
|
204 |
+
</xs:restriction>
|
205 |
+
</xs:simpleType>
|
206 |
+
<xs:simpleType name="ExternalMandateSetupReason1Code">
|
207 |
+
<xs:restriction base="xs:string">
|
208 |
+
<xs:minLength value="1"/>
|
209 |
+
<xs:maxLength value="4"/>
|
210 |
+
</xs:restriction>
|
211 |
+
</xs:simpleType>
|
212 |
+
<xs:simpleType name="ExternalOrganisationIdentification1Code">
|
213 |
+
<xs:restriction base="xs:string">
|
214 |
+
<xs:minLength value="1"/>
|
215 |
+
<xs:maxLength value="4"/>
|
216 |
+
</xs:restriction>
|
217 |
+
</xs:simpleType>
|
218 |
+
<xs:simpleType name="ExternalPersonIdentification1Code">
|
219 |
+
<xs:restriction base="xs:string">
|
220 |
+
<xs:minLength value="1"/>
|
221 |
+
<xs:maxLength value="4"/>
|
222 |
+
</xs:restriction>
|
223 |
+
</xs:simpleType>
|
224 |
+
<xs:simpleType name="ExternalServiceLevel1Code">
|
225 |
+
<xs:restriction base="xs:string">
|
226 |
+
<xs:minLength value="1"/>
|
227 |
+
<xs:maxLength value="4"/>
|
228 |
+
</xs:restriction>
|
229 |
+
</xs:simpleType>
|
230 |
+
<xs:complexType name="FinancialIdentificationSchemeName1Choice">
|
231 |
+
<xs:choice>
|
232 |
+
<xs:element name="Cd" type="ExternalFinancialInstitutionIdentification1Code"/>
|
233 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
234 |
+
</xs:choice>
|
235 |
+
</xs:complexType>
|
236 |
+
<xs:complexType name="FinancialInstitutionIdentification8">
|
237 |
+
<xs:sequence>
|
238 |
+
<!-- Made BICFI mandatory, previously this line was: -->
|
239 |
+
<!-- <xs:element maxOccurs="1" minOccurs="0" name="BICFI" type="BICFIIdentifier"/> -->
|
240 |
+
<xs:element name="BICFI" type="BICFIIdentifier"/>
|
241 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysMmbId" type="ClearingSystemMemberIdentification2"/>
|
242 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
243 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
244 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="GenericFinancialIdentification1"/>
|
245 |
+
</xs:sequence>
|
246 |
+
</xs:complexType>
|
247 |
+
<xs:complexType name="Frequency21Choice">
|
248 |
+
<xs:choice>
|
249 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
250 |
+
<xs:element name="Prd" type="FrequencyPeriod1"/>
|
251 |
+
</xs:choice>
|
252 |
+
</xs:complexType>
|
253 |
+
<xs:simpleType name="Frequency6Code">
|
254 |
+
<xs:restriction base="xs:string">
|
255 |
+
<xs:enumeration value="YEAR"/>
|
256 |
+
<xs:enumeration value="MNTH"/>
|
257 |
+
<xs:enumeration value="QURT"/>
|
258 |
+
<xs:enumeration value="MIAN"/>
|
259 |
+
<xs:enumeration value="WEEK"/>
|
260 |
+
<xs:enumeration value="DAIL"/>
|
261 |
+
<xs:enumeration value="ADHO"/>
|
262 |
+
<xs:enumeration value="INDA"/>
|
263 |
+
<xs:enumeration value="FRTN"/>
|
264 |
+
</xs:restriction>
|
265 |
+
</xs:simpleType>
|
266 |
+
<xs:complexType name="FrequencyPeriod1">
|
267 |
+
<xs:sequence>
|
268 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
269 |
+
<xs:element name="CntPerPrd" type="DecimalNumber"/>
|
270 |
+
</xs:sequence>
|
271 |
+
</xs:complexType>
|
272 |
+
<xs:complexType name="GenericAccountIdentification1">
|
273 |
+
<xs:sequence>
|
274 |
+
<xs:element name="Id" type="Max34Text"/>
|
275 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="AccountSchemeName1Choice"/>
|
276 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
277 |
+
</xs:sequence>
|
278 |
+
</xs:complexType>
|
279 |
+
<xs:complexType name="GenericFinancialIdentification1">
|
280 |
+
<xs:sequence>
|
281 |
+
<xs:element name="Id" type="Max35Text"/>
|
282 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="FinancialIdentificationSchemeName1Choice"/>
|
283 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
284 |
+
</xs:sequence>
|
285 |
+
</xs:complexType>
|
286 |
+
<xs:complexType name="GenericOrganisationIdentification1">
|
287 |
+
<xs:sequence>
|
288 |
+
<xs:element name="Id" type="Max35Text"/>
|
289 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="OrganisationIdentificationSchemeName1Choice"/>
|
290 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
291 |
+
</xs:sequence>
|
292 |
+
</xs:complexType>
|
293 |
+
<xs:complexType name="GenericPersonIdentification1">
|
294 |
+
<xs:sequence>
|
295 |
+
<xs:element name="Id" type="Max35Text"/>
|
296 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="PersonIdentificationSchemeName1Choice"/>
|
297 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
298 |
+
</xs:sequence>
|
299 |
+
</xs:complexType>
|
300 |
+
<xs:complexType name="GroupHeader47">
|
301 |
+
<xs:sequence>
|
302 |
+
<xs:element name="MsgId" type="Max35Text"/>
|
303 |
+
<xs:element name="CreDtTm" type="ISODateTime"/>
|
304 |
+
<xs:element maxOccurs="2" minOccurs="0" name="Authstn" type="Authorisation1Choice"/>
|
305 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InitgPty" type="PartyIdentification43"/>
|
306 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstgAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
307 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstdAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
308 |
+
</xs:sequence>
|
309 |
+
</xs:complexType>
|
310 |
+
<xs:simpleType name="IBAN2007Identifier">
|
311 |
+
<xs:restriction base="xs:string">
|
312 |
+
<xs:pattern value="[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}"/>
|
313 |
+
</xs:restriction>
|
314 |
+
</xs:simpleType>
|
315 |
+
<xs:simpleType name="ISODate">
|
316 |
+
<xs:restriction base="xs:date"/>
|
317 |
+
</xs:simpleType>
|
318 |
+
<xs:simpleType name="ISODateTime">
|
319 |
+
<xs:restriction base="xs:dateTime"/>
|
320 |
+
</xs:simpleType>
|
321 |
+
<xs:complexType name="LocalInstrument2Choice">
|
322 |
+
<xs:choice>
|
323 |
+
<xs:element name="Cd" type="ExternalLocalInstrument1Code"/>
|
324 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
325 |
+
</xs:choice>
|
326 |
+
</xs:complexType>
|
327 |
+
<xs:complexType name="Mandate5">
|
328 |
+
<xs:sequence>
|
329 |
+
<xs:element name="MndtId" type="Max35Text"/>
|
330 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MndtReqId" type="Max35Text"/>
|
331 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="MandateTypeInformation1"/>
|
332 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ocrncs" type="MandateOccurrences3"/>
|
333 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ColltnAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
|
334 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MaxAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
|
335 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Rsn" type="MandateSetupReason1Choice"/>
|
336 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrSchmeId" type="PartyIdentification43"/>
|
337 |
+
<xs:element name="Cdtr" type="PartyIdentification43"/>
|
338 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAcct" type="CashAccount24"/>
|
339 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
340 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtCdtr" type="PartyIdentification43"/>
|
341 |
+
<xs:element name="Dbtr" type="PartyIdentification43"/>
|
342 |
+
<!-- Made DbtrAcct mandatory, previously this line was: -->
|
343 |
+
<!-- <xs:element maxOccurs="1" minOccurs="0" name="DbtrAcct" type="CashAccount24"/> -->
|
344 |
+
<xs:element name="DbtrAcct" type="CashAccount24"/>
|
345 |
+
<xs:element name="DbtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
346 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification43"/>
|
347 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="RfrdDoc" type="ReferredDocumentInformation6"/>
|
348 |
+
</xs:sequence>
|
349 |
+
</xs:complexType>
|
350 |
+
<xs:complexType name="MandateCancellation4">
|
351 |
+
<xs:sequence>
|
352 |
+
<xs:element maxOccurs="1" minOccurs="0" name="OrgnlMsgInf" type="OriginalMessageInformation1"/>
|
353 |
+
<xs:element name="CxlRsn" type="PaymentCancellationReason1"/>
|
354 |
+
<xs:element name="OrgnlMndt" type="OriginalMandate3Choice"/>
|
355 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
356 |
+
</xs:sequence>
|
357 |
+
</xs:complexType>
|
358 |
+
<xs:complexType name="MandateCancellationRequestV04">
|
359 |
+
<xs:sequence>
|
360 |
+
<xs:element name="GrpHdr" type="GroupHeader47"/>
|
361 |
+
<xs:element maxOccurs="unbounded" minOccurs="1" name="UndrlygCxlDtls" type="MandateCancellation4"/>
|
362 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
363 |
+
</xs:sequence>
|
364 |
+
</xs:complexType>
|
365 |
+
<xs:complexType name="MandateOccurrences3">
|
366 |
+
<xs:sequence>
|
367 |
+
<xs:element name="SeqTp" type="SequenceType2Code"/>
|
368 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Frqcy" type="Frequency21Choice"/>
|
369 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Drtn" type="DatePeriodDetails1"/>
|
370 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FrstColltnDt" type="ISODate"/>
|
371 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FnlColltnDt" type="ISODate"/>
|
372 |
+
</xs:sequence>
|
373 |
+
</xs:complexType>
|
374 |
+
<xs:complexType name="MandateReason1Choice">
|
375 |
+
<xs:choice>
|
376 |
+
<xs:element name="Cd" type="ExternalMandateReason1Code"/>
|
377 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
378 |
+
</xs:choice>
|
379 |
+
</xs:complexType>
|
380 |
+
<xs:complexType name="MandateSetupReason1Choice">
|
381 |
+
<xs:choice>
|
382 |
+
<xs:element name="Cd" type="ExternalMandateSetupReason1Code"/>
|
383 |
+
<xs:element name="Prtry" type="Max70Text"/>
|
384 |
+
</xs:choice>
|
385 |
+
</xs:complexType>
|
386 |
+
<xs:complexType name="MandateTypeInformation1">
|
387 |
+
<xs:sequence>
|
388 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SvcLvl" type="ServiceLevel8Choice"/>
|
389 |
+
<xs:element maxOccurs="1" minOccurs="0" name="LclInstrm" type="LocalInstrument2Choice"/>
|
390 |
+
</xs:sequence>
|
391 |
+
</xs:complexType>
|
392 |
+
<xs:simpleType name="Max105Text">
|
393 |
+
<xs:restriction base="xs:string">
|
394 |
+
<xs:minLength value="1"/>
|
395 |
+
<xs:maxLength value="105"/>
|
396 |
+
</xs:restriction>
|
397 |
+
</xs:simpleType>
|
398 |
+
<xs:simpleType name="Max128Text">
|
399 |
+
<xs:restriction base="xs:string">
|
400 |
+
<xs:minLength value="1"/>
|
401 |
+
<xs:maxLength value="128"/>
|
402 |
+
</xs:restriction>
|
403 |
+
</xs:simpleType>
|
404 |
+
<xs:simpleType name="Max140Text">
|
405 |
+
<xs:restriction base="xs:string">
|
406 |
+
<xs:minLength value="1"/>
|
407 |
+
<xs:maxLength value="140"/>
|
408 |
+
</xs:restriction>
|
409 |
+
</xs:simpleType>
|
410 |
+
<xs:simpleType name="Max16Text">
|
411 |
+
<xs:restriction base="xs:string">
|
412 |
+
<xs:minLength value="1"/>
|
413 |
+
<xs:maxLength value="16"/>
|
414 |
+
</xs:restriction>
|
415 |
+
</xs:simpleType>
|
416 |
+
<xs:simpleType name="Max2048Text">
|
417 |
+
<xs:restriction base="xs:string">
|
418 |
+
<xs:minLength value="1"/>
|
419 |
+
<xs:maxLength value="2048"/>
|
420 |
+
</xs:restriction>
|
421 |
+
</xs:simpleType>
|
422 |
+
<xs:simpleType name="Max34Text">
|
423 |
+
<xs:restriction base="xs:string">
|
424 |
+
<xs:minLength value="1"/>
|
425 |
+
<xs:maxLength value="34"/>
|
426 |
+
</xs:restriction>
|
427 |
+
</xs:simpleType>
|
428 |
+
<xs:simpleType name="Max350Text">
|
429 |
+
<xs:restriction base="xs:string">
|
430 |
+
<xs:minLength value="1"/>
|
431 |
+
<xs:maxLength value="350"/>
|
432 |
+
</xs:restriction>
|
433 |
+
</xs:simpleType>
|
434 |
+
<xs:simpleType name="Max35Text">
|
435 |
+
<xs:restriction base="xs:string">
|
436 |
+
<xs:minLength value="1"/>
|
437 |
+
<xs:maxLength value="35"/>
|
438 |
+
</xs:restriction>
|
439 |
+
</xs:simpleType>
|
440 |
+
<xs:simpleType name="Max70Text">
|
441 |
+
<xs:restriction base="xs:string">
|
442 |
+
<xs:minLength value="1"/>
|
443 |
+
<xs:maxLength value="70"/>
|
444 |
+
</xs:restriction>
|
445 |
+
</xs:simpleType>
|
446 |
+
<xs:simpleType name="NamePrefix1Code">
|
447 |
+
<xs:restriction base="xs:string">
|
448 |
+
<xs:enumeration value="DOCT"/>
|
449 |
+
<xs:enumeration value="MIST"/>
|
450 |
+
<xs:enumeration value="MISS"/>
|
451 |
+
<xs:enumeration value="MADM"/>
|
452 |
+
</xs:restriction>
|
453 |
+
</xs:simpleType>
|
454 |
+
<xs:complexType name="OrganisationIdentification8">
|
455 |
+
<xs:sequence>
|
456 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AnyBIC" type="AnyBICIdentifier"/>
|
457 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericOrganisationIdentification1"/>
|
458 |
+
</xs:sequence>
|
459 |
+
</xs:complexType>
|
460 |
+
<xs:complexType name="OrganisationIdentificationSchemeName1Choice">
|
461 |
+
<xs:choice>
|
462 |
+
<xs:element name="Cd" type="ExternalOrganisationIdentification1Code"/>
|
463 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
464 |
+
</xs:choice>
|
465 |
+
</xs:complexType>
|
466 |
+
<xs:complexType name="OriginalMandate3Choice">
|
467 |
+
<xs:choice>
|
468 |
+
<xs:element name="OrgnlMndtId" type="Max35Text"/>
|
469 |
+
<xs:element name="OrgnlMndt" type="Mandate5"/>
|
470 |
+
</xs:choice>
|
471 |
+
</xs:complexType>
|
472 |
+
<xs:complexType name="OriginalMessageInformation1">
|
473 |
+
<xs:sequence>
|
474 |
+
<xs:element name="MsgId" type="Max35Text"/>
|
475 |
+
<xs:element name="MsgNmId" type="Max35Text"/>
|
476 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CreDtTm" type="ISODateTime"/>
|
477 |
+
</xs:sequence>
|
478 |
+
</xs:complexType>
|
479 |
+
<xs:complexType name="Party11Choice">
|
480 |
+
<xs:choice>
|
481 |
+
<xs:element name="OrgId" type="OrganisationIdentification8"/>
|
482 |
+
<xs:element name="PrvtId" type="PersonIdentification5"/>
|
483 |
+
</xs:choice>
|
484 |
+
</xs:complexType>
|
485 |
+
<xs:complexType name="PartyIdentification43">
|
486 |
+
<xs:sequence>
|
487 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
488 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
489 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Party11Choice"/>
|
490 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtryOfRes" type="CountryCode"/>
|
491 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtctDtls" type="ContactDetails2"/>
|
492 |
+
</xs:sequence>
|
493 |
+
</xs:complexType>
|
494 |
+
<xs:complexType name="PaymentCancellationReason1">
|
495 |
+
<xs:sequence>
|
496 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Orgtr" type="PartyIdentification43"/>
|
497 |
+
<xs:element name="Rsn" type="MandateReason1Choice"/>
|
498 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="AddtlInf" type="Max105Text"/>
|
499 |
+
</xs:sequence>
|
500 |
+
</xs:complexType>
|
501 |
+
<xs:complexType name="PersonIdentification5">
|
502 |
+
<xs:sequence>
|
503 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DtAndPlcOfBirth" type="DateAndPlaceOfBirth"/>
|
504 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericPersonIdentification1"/>
|
505 |
+
</xs:sequence>
|
506 |
+
</xs:complexType>
|
507 |
+
<xs:complexType name="PersonIdentificationSchemeName1Choice">
|
508 |
+
<xs:choice>
|
509 |
+
<xs:element name="Cd" type="ExternalPersonIdentification1Code"/>
|
510 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
511 |
+
</xs:choice>
|
512 |
+
</xs:complexType>
|
513 |
+
<xs:simpleType name="PhoneNumber">
|
514 |
+
<xs:restriction base="xs:string">
|
515 |
+
<xs:pattern value="\+[0-9]{1,3}-[0-9()+\-]{1,30}"/>
|
516 |
+
</xs:restriction>
|
517 |
+
</xs:simpleType>
|
518 |
+
<xs:complexType name="PostalAddress6">
|
519 |
+
<xs:sequence>
|
520 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AdrTp" type="AddressType2Code"/>
|
521 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Dept" type="Max70Text"/>
|
522 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SubDept" type="Max70Text"/>
|
523 |
+
<xs:element maxOccurs="1" minOccurs="0" name="StrtNm" type="Max70Text"/>
|
524 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BldgNb" type="Max16Text"/>
|
525 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstCd" type="Max16Text"/>
|
526 |
+
<xs:element maxOccurs="1" minOccurs="0" name="TwnNm" type="Max35Text"/>
|
527 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtrySubDvsn" type="Max35Text"/>
|
528 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
|
529 |
+
<xs:element maxOccurs="7" minOccurs="0" name="AdrLine" type="Max70Text"/>
|
530 |
+
</xs:sequence>
|
531 |
+
</xs:complexType>
|
532 |
+
<xs:complexType name="ReferredDocumentInformation6">
|
533 |
+
<xs:sequence>
|
534 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="ReferredDocumentType4"/>
|
535 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nb" type="Max35Text"/>
|
536 |
+
<xs:element maxOccurs="1" minOccurs="0" name="RltdDt" type="ISODate"/>
|
537 |
+
</xs:sequence>
|
538 |
+
</xs:complexType>
|
539 |
+
<xs:complexType name="ReferredDocumentType3Choice">
|
540 |
+
<xs:choice>
|
541 |
+
<xs:element name="Cd" type="DocumentType6Code"/>
|
542 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
543 |
+
</xs:choice>
|
544 |
+
</xs:complexType>
|
545 |
+
<xs:complexType name="ReferredDocumentType4">
|
546 |
+
<xs:sequence>
|
547 |
+
<xs:element name="CdOrPrtry" type="ReferredDocumentType3Choice"/>
|
548 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
549 |
+
</xs:sequence>
|
550 |
+
</xs:complexType>
|
551 |
+
<xs:simpleType name="SequenceType2Code">
|
552 |
+
<xs:restriction base="xs:string">
|
553 |
+
<xs:enumeration value="RCUR"/>
|
554 |
+
<xs:enumeration value="OOFF"/>
|
555 |
+
</xs:restriction>
|
556 |
+
</xs:simpleType>
|
557 |
+
<xs:complexType name="ServiceLevel8Choice">
|
558 |
+
<xs:choice>
|
559 |
+
<xs:element name="Cd" type="ExternalServiceLevel1Code"/>
|
560 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
561 |
+
</xs:choice>
|
562 |
+
</xs:complexType>
|
563 |
+
<xs:complexType name="SupplementaryData1">
|
564 |
+
<xs:sequence>
|
565 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PlcAndNm" type="Max350Text"/>
|
566 |
+
<xs:element name="Envlp" type="SupplementaryDataEnvelope1"/>
|
567 |
+
</xs:sequence>
|
568 |
+
</xs:complexType>
|
569 |
+
<xs:complexType name="SupplementaryDataEnvelope1">
|
570 |
+
<xs:sequence>
|
571 |
+
<xs:any namespace="##any" processContents="lax"/>
|
572 |
+
</xs:sequence>
|
573 |
+
</xs:complexType>
|
574 |
+
</xs:schema>
|
lib/Communicator/schemas/pain.012.001.04.xsd
ADDED
@@ -0,0 +1,573 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--Generated by Standards Editor (build:R1.6.2.2) on 2014 Oct 24 13:58:13, ISO 20022 version : 2013-->
|
3 |
+
<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:pain.012.001.04" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:iso:std:iso:20022:tech:xsd:pain.012.001.04">
|
4 |
+
<xs:element name="Document" type="Document"/>
|
5 |
+
<xs:complexType name="AcceptanceResult6">
|
6 |
+
<xs:sequence>
|
7 |
+
<xs:element name="Accptd" type="YesNoIndicator"/>
|
8 |
+
<xs:element maxOccurs="1" minOccurs="0" name="RjctRsn" type="MandateReason1Choice"/>
|
9 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="AddtlRjctRsnInf" type="Max105Text"/>
|
10 |
+
</xs:sequence>
|
11 |
+
</xs:complexType>
|
12 |
+
<xs:complexType name="AccountIdentification4Choice">
|
13 |
+
<xs:choice>
|
14 |
+
<xs:element name="IBAN" type="IBAN2007Identifier"/>
|
15 |
+
<xs:element name="Othr" type="GenericAccountIdentification1"/>
|
16 |
+
</xs:choice>
|
17 |
+
</xs:complexType>
|
18 |
+
<xs:complexType name="AccountSchemeName1Choice">
|
19 |
+
<xs:choice>
|
20 |
+
<xs:element name="Cd" type="ExternalAccountIdentification1Code"/>
|
21 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
22 |
+
</xs:choice>
|
23 |
+
</xs:complexType>
|
24 |
+
<xs:simpleType name="ActiveOrHistoricCurrencyAndAmount_SimpleType">
|
25 |
+
<xs:restriction base="xs:decimal">
|
26 |
+
<xs:fractionDigits value="5"/>
|
27 |
+
<xs:totalDigits value="18"/>
|
28 |
+
<xs:minInclusive value="0"/>
|
29 |
+
</xs:restriction>
|
30 |
+
</xs:simpleType>
|
31 |
+
<xs:complexType name="ActiveOrHistoricCurrencyAndAmount">
|
32 |
+
<xs:simpleContent>
|
33 |
+
<xs:extension base="ActiveOrHistoricCurrencyAndAmount_SimpleType">
|
34 |
+
<xs:attribute name="Ccy" type="ActiveOrHistoricCurrencyCode" use="required"/>
|
35 |
+
</xs:extension>
|
36 |
+
</xs:simpleContent>
|
37 |
+
</xs:complexType>
|
38 |
+
<xs:simpleType name="ActiveOrHistoricCurrencyCode">
|
39 |
+
<xs:restriction base="xs:string">
|
40 |
+
<xs:pattern value="[A-Z]{3,3}"/>
|
41 |
+
</xs:restriction>
|
42 |
+
</xs:simpleType>
|
43 |
+
<xs:simpleType name="AddressType2Code">
|
44 |
+
<xs:restriction base="xs:string">
|
45 |
+
<xs:enumeration value="ADDR"/>
|
46 |
+
<xs:enumeration value="PBOX"/>
|
47 |
+
<xs:enumeration value="HOME"/>
|
48 |
+
<xs:enumeration value="BIZZ"/>
|
49 |
+
<xs:enumeration value="MLTO"/>
|
50 |
+
<xs:enumeration value="DLVY"/>
|
51 |
+
</xs:restriction>
|
52 |
+
</xs:simpleType>
|
53 |
+
<xs:simpleType name="AnyBICIdentifier">
|
54 |
+
<xs:restriction base="xs:string">
|
55 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
56 |
+
</xs:restriction>
|
57 |
+
</xs:simpleType>
|
58 |
+
<xs:complexType name="Authorisation1Choice">
|
59 |
+
<xs:choice>
|
60 |
+
<xs:element name="Cd" type="Authorisation1Code"/>
|
61 |
+
<xs:element name="Prtry" type="Max128Text"/>
|
62 |
+
</xs:choice>
|
63 |
+
</xs:complexType>
|
64 |
+
<xs:simpleType name="Authorisation1Code">
|
65 |
+
<xs:restriction base="xs:string">
|
66 |
+
<xs:enumeration value="AUTH"/>
|
67 |
+
<xs:enumeration value="FDET"/>
|
68 |
+
<xs:enumeration value="FSUM"/>
|
69 |
+
<xs:enumeration value="ILEV"/>
|
70 |
+
</xs:restriction>
|
71 |
+
</xs:simpleType>
|
72 |
+
<xs:simpleType name="BICFIIdentifier">
|
73 |
+
<xs:restriction base="xs:string">
|
74 |
+
<xs:pattern value="[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}"/>
|
75 |
+
</xs:restriction>
|
76 |
+
</xs:simpleType>
|
77 |
+
<xs:complexType name="BranchAndFinancialInstitutionIdentification5">
|
78 |
+
<xs:sequence>
|
79 |
+
<xs:element name="FinInstnId" type="FinancialInstitutionIdentification8"/>
|
80 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BrnchId" type="BranchData2"/>
|
81 |
+
</xs:sequence>
|
82 |
+
</xs:complexType>
|
83 |
+
<xs:complexType name="BranchData2">
|
84 |
+
<xs:sequence>
|
85 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Max35Text"/>
|
86 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
87 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
88 |
+
</xs:sequence>
|
89 |
+
</xs:complexType>
|
90 |
+
<xs:complexType name="CashAccount24">
|
91 |
+
<xs:sequence>
|
92 |
+
<xs:element name="Id" type="AccountIdentification4Choice"/>
|
93 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="CashAccountType2Choice"/>
|
94 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ccy" type="ActiveOrHistoricCurrencyCode"/>
|
95 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max70Text"/>
|
96 |
+
</xs:sequence>
|
97 |
+
</xs:complexType>
|
98 |
+
<xs:complexType name="CashAccountType2Choice">
|
99 |
+
<xs:choice>
|
100 |
+
<xs:element name="Cd" type="ExternalCashAccountType1Code"/>
|
101 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
102 |
+
</xs:choice>
|
103 |
+
</xs:complexType>
|
104 |
+
<xs:complexType name="ClearingSystemIdentification2Choice">
|
105 |
+
<xs:choice>
|
106 |
+
<xs:element name="Cd" type="ExternalClearingSystemIdentification1Code"/>
|
107 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
108 |
+
</xs:choice>
|
109 |
+
</xs:complexType>
|
110 |
+
<xs:complexType name="ClearingSystemMemberIdentification2">
|
111 |
+
<xs:sequence>
|
112 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysId" type="ClearingSystemIdentification2Choice"/>
|
113 |
+
<xs:element name="MmbId" type="Max35Text"/>
|
114 |
+
</xs:sequence>
|
115 |
+
</xs:complexType>
|
116 |
+
<xs:complexType name="ContactDetails2">
|
117 |
+
<xs:sequence>
|
118 |
+
<xs:element maxOccurs="1" minOccurs="0" name="NmPrfx" type="NamePrefix1Code"/>
|
119 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
120 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PhneNb" type="PhoneNumber"/>
|
121 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MobNb" type="PhoneNumber"/>
|
122 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FaxNb" type="PhoneNumber"/>
|
123 |
+
<xs:element maxOccurs="1" minOccurs="0" name="EmailAdr" type="Max2048Text"/>
|
124 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="Max35Text"/>
|
125 |
+
</xs:sequence>
|
126 |
+
</xs:complexType>
|
127 |
+
<xs:simpleType name="CountryCode">
|
128 |
+
<xs:restriction base="xs:string">
|
129 |
+
<xs:pattern value="[A-Z]{2,2}"/>
|
130 |
+
</xs:restriction>
|
131 |
+
</xs:simpleType>
|
132 |
+
<xs:complexType name="DateAndPlaceOfBirth">
|
133 |
+
<xs:sequence>
|
134 |
+
<xs:element name="BirthDt" type="ISODate"/>
|
135 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PrvcOfBirth" type="Max35Text"/>
|
136 |
+
<xs:element name="CityOfBirth" type="Max35Text"/>
|
137 |
+
<xs:element name="CtryOfBirth" type="CountryCode"/>
|
138 |
+
</xs:sequence>
|
139 |
+
</xs:complexType>
|
140 |
+
<xs:complexType name="DatePeriodDetails1">
|
141 |
+
<xs:sequence>
|
142 |
+
<xs:element name="FrDt" type="ISODate"/>
|
143 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ToDt" type="ISODate"/>
|
144 |
+
</xs:sequence>
|
145 |
+
</xs:complexType>
|
146 |
+
<xs:simpleType name="DecimalNumber">
|
147 |
+
<xs:restriction base="xs:decimal">
|
148 |
+
<xs:fractionDigits value="17"/>
|
149 |
+
<xs:totalDigits value="18"/>
|
150 |
+
</xs:restriction>
|
151 |
+
</xs:simpleType>
|
152 |
+
<xs:complexType name="Document">
|
153 |
+
<xs:sequence>
|
154 |
+
<xs:element name="MndtAccptncRpt" type="MandateAcceptanceReportV04"/>
|
155 |
+
</xs:sequence>
|
156 |
+
</xs:complexType>
|
157 |
+
<xs:simpleType name="DocumentType6Code">
|
158 |
+
<xs:restriction base="xs:string">
|
159 |
+
<xs:enumeration value="MSIN"/>
|
160 |
+
<xs:enumeration value="CNFA"/>
|
161 |
+
<xs:enumeration value="DNFA"/>
|
162 |
+
<xs:enumeration value="CINV"/>
|
163 |
+
<xs:enumeration value="CREN"/>
|
164 |
+
<xs:enumeration value="DEBN"/>
|
165 |
+
<xs:enumeration value="HIRI"/>
|
166 |
+
<xs:enumeration value="SBIN"/>
|
167 |
+
<xs:enumeration value="CMCN"/>
|
168 |
+
<xs:enumeration value="SOAC"/>
|
169 |
+
<xs:enumeration value="DISP"/>
|
170 |
+
<xs:enumeration value="BOLD"/>
|
171 |
+
<xs:enumeration value="VCHR"/>
|
172 |
+
<xs:enumeration value="AROI"/>
|
173 |
+
<xs:enumeration value="TSUT"/>
|
174 |
+
<xs:enumeration value="PUOR"/>
|
175 |
+
</xs:restriction>
|
176 |
+
</xs:simpleType>
|
177 |
+
<xs:simpleType name="ExternalAccountIdentification1Code">
|
178 |
+
<xs:restriction base="xs:string">
|
179 |
+
<xs:minLength value="1"/>
|
180 |
+
<xs:maxLength value="4"/>
|
181 |
+
</xs:restriction>
|
182 |
+
</xs:simpleType>
|
183 |
+
<xs:simpleType name="ExternalCashAccountType1Code">
|
184 |
+
<xs:restriction base="xs:string">
|
185 |
+
<xs:minLength value="1"/>
|
186 |
+
<xs:maxLength value="4"/>
|
187 |
+
</xs:restriction>
|
188 |
+
</xs:simpleType>
|
189 |
+
<xs:simpleType name="ExternalClearingSystemIdentification1Code">
|
190 |
+
<xs:restriction base="xs:string">
|
191 |
+
<xs:minLength value="1"/>
|
192 |
+
<xs:maxLength value="5"/>
|
193 |
+
</xs:restriction>
|
194 |
+
</xs:simpleType>
|
195 |
+
<xs:simpleType name="ExternalFinancialInstitutionIdentification1Code">
|
196 |
+
<xs:restriction base="xs:string">
|
197 |
+
<xs:minLength value="1"/>
|
198 |
+
<xs:maxLength value="4"/>
|
199 |
+
</xs:restriction>
|
200 |
+
</xs:simpleType>
|
201 |
+
<xs:simpleType name="ExternalLocalInstrument1Code">
|
202 |
+
<xs:restriction base="xs:string">
|
203 |
+
<xs:minLength value="1"/>
|
204 |
+
<xs:maxLength value="35"/>
|
205 |
+
</xs:restriction>
|
206 |
+
</xs:simpleType>
|
207 |
+
<xs:simpleType name="ExternalMandateReason1Code">
|
208 |
+
<xs:restriction base="xs:string">
|
209 |
+
<xs:minLength value="1"/>
|
210 |
+
<xs:maxLength value="4"/>
|
211 |
+
</xs:restriction>
|
212 |
+
</xs:simpleType>
|
213 |
+
<xs:simpleType name="ExternalMandateSetupReason1Code">
|
214 |
+
<xs:restriction base="xs:string">
|
215 |
+
<xs:minLength value="1"/>
|
216 |
+
<xs:maxLength value="4"/>
|
217 |
+
</xs:restriction>
|
218 |
+
</xs:simpleType>
|
219 |
+
<xs:simpleType name="ExternalOrganisationIdentification1Code">
|
220 |
+
<xs:restriction base="xs:string">
|
221 |
+
<xs:minLength value="1"/>
|
222 |
+
<xs:maxLength value="4"/>
|
223 |
+
</xs:restriction>
|
224 |
+
</xs:simpleType>
|
225 |
+
<xs:simpleType name="ExternalPersonIdentification1Code">
|
226 |
+
<xs:restriction base="xs:string">
|
227 |
+
<xs:minLength value="1"/>
|
228 |
+
<xs:maxLength value="4"/>
|
229 |
+
</xs:restriction>
|
230 |
+
</xs:simpleType>
|
231 |
+
<xs:simpleType name="ExternalServiceLevel1Code">
|
232 |
+
<xs:restriction base="xs:string">
|
233 |
+
<xs:minLength value="1"/>
|
234 |
+
<xs:maxLength value="4"/>
|
235 |
+
</xs:restriction>
|
236 |
+
</xs:simpleType>
|
237 |
+
<xs:complexType name="FinancialIdentificationSchemeName1Choice">
|
238 |
+
<xs:choice>
|
239 |
+
<xs:element name="Cd" type="ExternalFinancialInstitutionIdentification1Code"/>
|
240 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
241 |
+
</xs:choice>
|
242 |
+
</xs:complexType>
|
243 |
+
<xs:complexType name="FinancialInstitutionIdentification8">
|
244 |
+
<xs:sequence>
|
245 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BICFI" type="BICFIIdentifier"/>
|
246 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysMmbId" type="ClearingSystemMemberIdentification2"/>
|
247 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
248 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
249 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="GenericFinancialIdentification1"/>
|
250 |
+
</xs:sequence>
|
251 |
+
</xs:complexType>
|
252 |
+
<xs:complexType name="Frequency21Choice">
|
253 |
+
<xs:choice>
|
254 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
255 |
+
<xs:element name="Prd" type="FrequencyPeriod1"/>
|
256 |
+
</xs:choice>
|
257 |
+
</xs:complexType>
|
258 |
+
<xs:simpleType name="Frequency6Code">
|
259 |
+
<xs:restriction base="xs:string">
|
260 |
+
<xs:enumeration value="YEAR"/>
|
261 |
+
<xs:enumeration value="MNTH"/>
|
262 |
+
<xs:enumeration value="QURT"/>
|
263 |
+
<xs:enumeration value="MIAN"/>
|
264 |
+
<xs:enumeration value="WEEK"/>
|
265 |
+
<xs:enumeration value="DAIL"/>
|
266 |
+
<xs:enumeration value="ADHO"/>
|
267 |
+
<xs:enumeration value="INDA"/>
|
268 |
+
<xs:enumeration value="FRTN"/>
|
269 |
+
</xs:restriction>
|
270 |
+
</xs:simpleType>
|
271 |
+
<xs:complexType name="FrequencyPeriod1">
|
272 |
+
<xs:sequence>
|
273 |
+
<xs:element name="Tp" type="Frequency6Code"/>
|
274 |
+
<xs:element name="CntPerPrd" type="DecimalNumber"/>
|
275 |
+
</xs:sequence>
|
276 |
+
</xs:complexType>
|
277 |
+
<xs:complexType name="GenericAccountIdentification1">
|
278 |
+
<xs:sequence>
|
279 |
+
<xs:element name="Id" type="Max34Text"/>
|
280 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="AccountSchemeName1Choice"/>
|
281 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
282 |
+
</xs:sequence>
|
283 |
+
</xs:complexType>
|
284 |
+
<xs:complexType name="GenericFinancialIdentification1">
|
285 |
+
<xs:sequence>
|
286 |
+
<xs:element name="Id" type="Max35Text"/>
|
287 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="FinancialIdentificationSchemeName1Choice"/>
|
288 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
289 |
+
</xs:sequence>
|
290 |
+
</xs:complexType>
|
291 |
+
<xs:complexType name="GenericOrganisationIdentification1">
|
292 |
+
<xs:sequence>
|
293 |
+
<xs:element name="Id" type="Max35Text"/>
|
294 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="OrganisationIdentificationSchemeName1Choice"/>
|
295 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
296 |
+
</xs:sequence>
|
297 |
+
</xs:complexType>
|
298 |
+
<xs:complexType name="GenericPersonIdentification1">
|
299 |
+
<xs:sequence>
|
300 |
+
<xs:element name="Id" type="Max35Text"/>
|
301 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="PersonIdentificationSchemeName1Choice"/>
|
302 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
303 |
+
</xs:sequence>
|
304 |
+
</xs:complexType>
|
305 |
+
<xs:complexType name="GroupHeader47">
|
306 |
+
<xs:sequence>
|
307 |
+
<xs:element name="MsgId" type="Max35Text"/>
|
308 |
+
<xs:element name="CreDtTm" type="ISODateTime"/>
|
309 |
+
<xs:element maxOccurs="2" minOccurs="0" name="Authstn" type="Authorisation1Choice"/>
|
310 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InitgPty" type="PartyIdentification43"/>
|
311 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstgAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
312 |
+
<xs:element maxOccurs="1" minOccurs="0" name="InstdAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
313 |
+
</xs:sequence>
|
314 |
+
</xs:complexType>
|
315 |
+
<xs:simpleType name="IBAN2007Identifier">
|
316 |
+
<xs:restriction base="xs:string">
|
317 |
+
<xs:pattern value="[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}"/>
|
318 |
+
</xs:restriction>
|
319 |
+
</xs:simpleType>
|
320 |
+
<xs:simpleType name="ISODate">
|
321 |
+
<xs:restriction base="xs:date"/>
|
322 |
+
</xs:simpleType>
|
323 |
+
<xs:simpleType name="ISODateTime">
|
324 |
+
<xs:restriction base="xs:dateTime"/>
|
325 |
+
</xs:simpleType>
|
326 |
+
<xs:complexType name="LocalInstrument2Choice">
|
327 |
+
<xs:choice>
|
328 |
+
<xs:element name="Cd" type="ExternalLocalInstrument1Code"/>
|
329 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
330 |
+
</xs:choice>
|
331 |
+
</xs:complexType>
|
332 |
+
<xs:complexType name="Mandate5">
|
333 |
+
<xs:sequence>
|
334 |
+
<xs:element name="MndtId" type="Max35Text"/>
|
335 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MndtReqId" type="Max35Text"/>
|
336 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="MandateTypeInformation1"/>
|
337 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ocrncs" type="MandateOccurrences3"/>
|
338 |
+
<xs:element maxOccurs="1" minOccurs="0" name="ColltnAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
|
339 |
+
<xs:element maxOccurs="1" minOccurs="0" name="MaxAmt" type="ActiveOrHistoricCurrencyAndAmount"/>
|
340 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Rsn" type="MandateSetupReason1Choice"/>
|
341 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrSchmeId" type="PartyIdentification43"/>
|
342 |
+
<xs:element name="Cdtr" type="PartyIdentification43"/>
|
343 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAcct" type="CashAccount24"/>
|
344 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CdtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
345 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtCdtr" type="PartyIdentification43"/>
|
346 |
+
<xs:element name="Dbtr" type="PartyIdentification43"/>
|
347 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DbtrAcct" type="CashAccount24"/>
|
348 |
+
<xs:element name="DbtrAgt" type="BranchAndFinancialInstitutionIdentification5"/>
|
349 |
+
<xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification43"/>
|
350 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="RfrdDoc" type="ReferredDocumentInformation6"/>
|
351 |
+
</xs:sequence>
|
352 |
+
</xs:complexType>
|
353 |
+
<xs:complexType name="MandateAcceptance4">
|
354 |
+
<xs:sequence>
|
355 |
+
<xs:element maxOccurs="1" minOccurs="0" name="OrgnlMsgInf" type="OriginalMessageInformation1"/>
|
356 |
+
<xs:element name="AccptncRslt" type="AcceptanceResult6"/>
|
357 |
+
<xs:element name="OrgnlMndt" type="OriginalMandate3Choice"/>
|
358 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
359 |
+
</xs:sequence>
|
360 |
+
</xs:complexType>
|
361 |
+
<xs:complexType name="MandateAcceptanceReportV04">
|
362 |
+
<xs:sequence>
|
363 |
+
<xs:element name="GrpHdr" type="GroupHeader47"/>
|
364 |
+
<xs:element maxOccurs="unbounded" minOccurs="1" name="UndrlygAccptncDtls" type="MandateAcceptance4"/>
|
365 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="SplmtryData" type="SupplementaryData1"/>
|
366 |
+
</xs:sequence>
|
367 |
+
</xs:complexType>
|
368 |
+
<xs:complexType name="MandateOccurrences3">
|
369 |
+
<xs:sequence>
|
370 |
+
<xs:element name="SeqTp" type="SequenceType2Code"/>
|
371 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Frqcy" type="Frequency21Choice"/>
|
372 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Drtn" type="DatePeriodDetails1"/>
|
373 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FrstColltnDt" type="ISODate"/>
|
374 |
+
<xs:element maxOccurs="1" minOccurs="0" name="FnlColltnDt" type="ISODate"/>
|
375 |
+
</xs:sequence>
|
376 |
+
</xs:complexType>
|
377 |
+
<xs:complexType name="MandateReason1Choice">
|
378 |
+
<xs:choice>
|
379 |
+
<xs:element name="Cd" type="ExternalMandateReason1Code"/>
|
380 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
381 |
+
</xs:choice>
|
382 |
+
</xs:complexType>
|
383 |
+
<xs:complexType name="MandateSetupReason1Choice">
|
384 |
+
<xs:choice>
|
385 |
+
<xs:element name="Cd" type="ExternalMandateSetupReason1Code"/>
|
386 |
+
<xs:element name="Prtry" type="Max70Text"/>
|
387 |
+
</xs:choice>
|
388 |
+
</xs:complexType>
|
389 |
+
<xs:complexType name="MandateTypeInformation1">
|
390 |
+
<xs:sequence>
|
391 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SvcLvl" type="ServiceLevel8Choice"/>
|
392 |
+
<xs:element maxOccurs="1" minOccurs="0" name="LclInstrm" type="LocalInstrument2Choice"/>
|
393 |
+
</xs:sequence>
|
394 |
+
</xs:complexType>
|
395 |
+
<xs:simpleType name="Max105Text">
|
396 |
+
<xs:restriction base="xs:string">
|
397 |
+
<xs:minLength value="1"/>
|
398 |
+
<xs:maxLength value="105"/>
|
399 |
+
</xs:restriction>
|
400 |
+
</xs:simpleType>
|
401 |
+
<xs:simpleType name="Max128Text">
|
402 |
+
<xs:restriction base="xs:string">
|
403 |
+
<xs:minLength value="1"/>
|
404 |
+
<xs:maxLength value="128"/>
|
405 |
+
</xs:restriction>
|
406 |
+
</xs:simpleType>
|
407 |
+
<xs:simpleType name="Max140Text">
|
408 |
+
<xs:restriction base="xs:string">
|
409 |
+
<xs:minLength value="1"/>
|
410 |
+
<xs:maxLength value="140"/>
|
411 |
+
</xs:restriction>
|
412 |
+
</xs:simpleType>
|
413 |
+
<xs:simpleType name="Max16Text">
|
414 |
+
<xs:restriction base="xs:string">
|
415 |
+
<xs:minLength value="1"/>
|
416 |
+
<xs:maxLength value="16"/>
|
417 |
+
</xs:restriction>
|
418 |
+
</xs:simpleType>
|
419 |
+
<xs:simpleType name="Max2048Text">
|
420 |
+
<xs:restriction base="xs:string">
|
421 |
+
<xs:minLength value="1"/>
|
422 |
+
<xs:maxLength value="2048"/>
|
423 |
+
</xs:restriction>
|
424 |
+
</xs:simpleType>
|
425 |
+
<xs:simpleType name="Max34Text">
|
426 |
+
<xs:restriction base="xs:string">
|
427 |
+
<xs:minLength value="1"/>
|
428 |
+
<xs:maxLength value="34"/>
|
429 |
+
</xs:restriction>
|
430 |
+
</xs:simpleType>
|
431 |
+
<xs:simpleType name="Max350Text">
|
432 |
+
<xs:restriction base="xs:string">
|
433 |
+
<xs:minLength value="1"/>
|
434 |
+
<xs:maxLength value="350"/>
|
435 |
+
</xs:restriction>
|
436 |
+
</xs:simpleType>
|
437 |
+
<xs:simpleType name="Max35Text">
|
438 |
+
<xs:restriction base="xs:string">
|
439 |
+
<xs:minLength value="1"/>
|
440 |
+
<xs:maxLength value="35"/>
|
441 |
+
</xs:restriction>
|
442 |
+
</xs:simpleType>
|
443 |
+
<xs:simpleType name="Max70Text">
|
444 |
+
<xs:restriction base="xs:string">
|
445 |
+
<xs:minLength value="1"/>
|
446 |
+
<xs:maxLength value="70"/>
|
447 |
+
</xs:restriction>
|
448 |
+
</xs:simpleType>
|
449 |
+
<xs:simpleType name="NamePrefix1Code">
|
450 |
+
<xs:restriction base="xs:string">
|
451 |
+
<xs:enumeration value="DOCT"/>
|
452 |
+
<xs:enumeration value="MIST"/>
|
453 |
+
<xs:enumeration value="MISS"/>
|
454 |
+
<xs:enumeration value="MADM"/>
|
455 |
+
</xs:restriction>
|
456 |
+
</xs:simpleType>
|
457 |
+
<xs:complexType name="OrganisationIdentification8">
|
458 |
+
<xs:sequence>
|
459 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AnyBIC" type="AnyBICIdentifier"/>
|
460 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericOrganisationIdentification1"/>
|
461 |
+
</xs:sequence>
|
462 |
+
</xs:complexType>
|
463 |
+
<xs:complexType name="OrganisationIdentificationSchemeName1Choice">
|
464 |
+
<xs:choice>
|
465 |
+
<xs:element name="Cd" type="ExternalOrganisationIdentification1Code"/>
|
466 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
467 |
+
</xs:choice>
|
468 |
+
</xs:complexType>
|
469 |
+
<xs:complexType name="OriginalMandate3Choice">
|
470 |
+
<xs:choice>
|
471 |
+
<xs:element name="OrgnlMndtId" type="Max35Text"/>
|
472 |
+
<xs:element name="OrgnlMndt" type="Mandate5"/>
|
473 |
+
</xs:choice>
|
474 |
+
</xs:complexType>
|
475 |
+
<xs:complexType name="OriginalMessageInformation1">
|
476 |
+
<xs:sequence>
|
477 |
+
<xs:element name="MsgId" type="Max35Text"/>
|
478 |
+
<xs:element name="MsgNmId" type="Max35Text"/>
|
479 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CreDtTm" type="ISODateTime"/>
|
480 |
+
</xs:sequence>
|
481 |
+
</xs:complexType>
|
482 |
+
<xs:complexType name="Party11Choice">
|
483 |
+
<xs:choice>
|
484 |
+
<xs:element name="OrgId" type="OrganisationIdentification8"/>
|
485 |
+
<xs:element name="PrvtId" type="PersonIdentification5"/>
|
486 |
+
</xs:choice>
|
487 |
+
</xs:complexType>
|
488 |
+
<xs:complexType name="PartyIdentification43">
|
489 |
+
<xs:sequence>
|
490 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
|
491 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress6"/>
|
492 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Party11Choice"/>
|
493 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtryOfRes" type="CountryCode"/>
|
494 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtctDtls" type="ContactDetails2"/>
|
495 |
+
</xs:sequence>
|
496 |
+
</xs:complexType>
|
497 |
+
<xs:complexType name="PersonIdentification5">
|
498 |
+
<xs:sequence>
|
499 |
+
<xs:element maxOccurs="1" minOccurs="0" name="DtAndPlcOfBirth" type="DateAndPlaceOfBirth"/>
|
500 |
+
<xs:element maxOccurs="unbounded" minOccurs="0" name="Othr" type="GenericPersonIdentification1"/>
|
501 |
+
</xs:sequence>
|
502 |
+
</xs:complexType>
|
503 |
+
<xs:complexType name="PersonIdentificationSchemeName1Choice">
|
504 |
+
<xs:choice>
|
505 |
+
<xs:element name="Cd" type="ExternalPersonIdentification1Code"/>
|
506 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
507 |
+
</xs:choice>
|
508 |
+
</xs:complexType>
|
509 |
+
<xs:simpleType name="PhoneNumber">
|
510 |
+
<xs:restriction base="xs:string">
|
511 |
+
<xs:pattern value="\+[0-9]{1,3}-[0-9()+\-]{1,30}"/>
|
512 |
+
</xs:restriction>
|
513 |
+
</xs:simpleType>
|
514 |
+
<xs:complexType name="PostalAddress6">
|
515 |
+
<xs:sequence>
|
516 |
+
<xs:element maxOccurs="1" minOccurs="0" name="AdrTp" type="AddressType2Code"/>
|
517 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Dept" type="Max70Text"/>
|
518 |
+
<xs:element maxOccurs="1" minOccurs="0" name="SubDept" type="Max70Text"/>
|
519 |
+
<xs:element maxOccurs="1" minOccurs="0" name="StrtNm" type="Max70Text"/>
|
520 |
+
<xs:element maxOccurs="1" minOccurs="0" name="BldgNb" type="Max16Text"/>
|
521 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PstCd" type="Max16Text"/>
|
522 |
+
<xs:element maxOccurs="1" minOccurs="0" name="TwnNm" type="Max35Text"/>
|
523 |
+
<xs:element maxOccurs="1" minOccurs="0" name="CtrySubDvsn" type="Max35Text"/>
|
524 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
|
525 |
+
<xs:element maxOccurs="7" minOccurs="0" name="AdrLine" type="Max70Text"/>
|
526 |
+
</xs:sequence>
|
527 |
+
</xs:complexType>
|
528 |
+
<xs:complexType name="ReferredDocumentInformation6">
|
529 |
+
<xs:sequence>
|
530 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Tp" type="ReferredDocumentType4"/>
|
531 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Nb" type="Max35Text"/>
|
532 |
+
<xs:element maxOccurs="1" minOccurs="0" name="RltdDt" type="ISODate"/>
|
533 |
+
</xs:sequence>
|
534 |
+
</xs:complexType>
|
535 |
+
<xs:complexType name="ReferredDocumentType3Choice">
|
536 |
+
<xs:choice>
|
537 |
+
<xs:element name="Cd" type="DocumentType6Code"/>
|
538 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
539 |
+
</xs:choice>
|
540 |
+
</xs:complexType>
|
541 |
+
<xs:complexType name="ReferredDocumentType4">
|
542 |
+
<xs:sequence>
|
543 |
+
<xs:element name="CdOrPrtry" type="ReferredDocumentType3Choice"/>
|
544 |
+
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
|
545 |
+
</xs:sequence>
|
546 |
+
</xs:complexType>
|
547 |
+
<xs:simpleType name="SequenceType2Code">
|
548 |
+
<xs:restriction base="xs:string">
|
549 |
+
<xs:enumeration value="RCUR"/>
|
550 |
+
<xs:enumeration value="OOFF"/>
|
551 |
+
</xs:restriction>
|
552 |
+
</xs:simpleType>
|
553 |
+
<xs:complexType name="ServiceLevel8Choice">
|
554 |
+
<xs:choice>
|
555 |
+
<xs:element name="Cd" type="ExternalServiceLevel1Code"/>
|
556 |
+
<xs:element name="Prtry" type="Max35Text"/>
|
557 |
+
</xs:choice>
|
558 |
+
</xs:complexType>
|
559 |
+
<xs:complexType name="SupplementaryData1">
|
560 |
+
<xs:sequence>
|
561 |
+
<xs:element maxOccurs="1" minOccurs="0" name="PlcAndNm" type="Max350Text"/>
|
562 |
+
<xs:element name="Envlp" type="SupplementaryDataEnvelope1"/>
|
563 |
+
</xs:sequence>
|
564 |
+
</xs:complexType>
|
565 |
+
<xs:complexType name="SupplementaryDataEnvelope1">
|
566 |
+
<xs:sequence>
|
567 |
+
<xs:any namespace="##any" processContents="lax"/>
|
568 |
+
</xs:sequence>
|
569 |
+
</xs:complexType>
|
570 |
+
<xs:simpleType name="YesNoIndicator">
|
571 |
+
<xs:restriction base="xs:boolean"/>
|
572 |
+
</xs:simpleType>
|
573 |
+
</xs:schema>
|
lib/Communicator/schemas/xmldsig-core-schema.xsd
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
2 |
+
<!-- Removed DTD, otherwise xsd2code.exe had problems -->
|
3 |
+
<!-- Schema for XML Signatures
|
4 |
+
http://www.w3.org/2000/09/xmldsig#
|
5 |
+
$Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $
|
6 |
+
|
7 |
+
Copyright 2001 The Internet Society and W3C (Massachusetts Institute
|
8 |
+
of Technology, Institut National de Recherche en Informatique et en
|
9 |
+
Automatique, Keio University). All Rights Reserved.
|
10 |
+
http://www.w3.org/Consortium/Legal/
|
11 |
+
|
12 |
+
This document is governed by the W3C Software License [1] as described
|
13 |
+
in the FAQ [2].
|
14 |
+
|
15 |
+
[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
|
16 |
+
[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
|
17 |
+
-->
|
18 |
+
|
19 |
+
|
20 |
+
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
21 |
+
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
22 |
+
targetNamespace="http://www.w3.org/2000/09/xmldsig#"
|
23 |
+
version="0.1" elementFormDefault="qualified">
|
24 |
+
|
25 |
+
<!-- Basic Types Defined for Signatures -->
|
26 |
+
|
27 |
+
<simpleType name="CryptoBinary">
|
28 |
+
<restriction base="base64Binary">
|
29 |
+
</restriction>
|
30 |
+
</simpleType>
|
31 |
+
|
32 |
+
<!-- Start Signature -->
|
33 |
+
|
34 |
+
<element name="Signature" type="ds:SignatureType"/>
|
35 |
+
<complexType name="SignatureType">
|
36 |
+
<sequence>
|
37 |
+
<element ref="ds:SignedInfo"/>
|
38 |
+
<element ref="ds:SignatureValue"/>
|
39 |
+
<element ref="ds:KeyInfo" minOccurs="0"/>
|
40 |
+
<element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/>
|
41 |
+
</sequence>
|
42 |
+
<attribute name="Id" type="ID" use="optional"/>
|
43 |
+
</complexType>
|
44 |
+
|
45 |
+
<element name="SignatureValue" type="ds:SignatureValueType"/>
|
46 |
+
<complexType name="SignatureValueType">
|
47 |
+
<simpleContent>
|
48 |
+
<extension base="base64Binary">
|
49 |
+
<attribute name="Id" type="ID" use="optional"/>
|
50 |
+
</extension>
|
51 |
+
</simpleContent>
|
52 |
+
</complexType>
|
53 |
+
|
54 |
+
<!-- Start SignedInfo -->
|
55 |
+
|
56 |
+
<element name="SignedInfo" type="ds:SignedInfoType"/>
|
57 |
+
<complexType name="SignedInfoType">
|
58 |
+
<sequence>
|
59 |
+
<element ref="ds:CanonicalizationMethod"/>
|
60 |
+
<element ref="ds:SignatureMethod"/>
|
61 |
+
<element ref="ds:Reference" maxOccurs="unbounded"/>
|
62 |
+
</sequence>
|
63 |
+
<attribute name="Id" type="ID" use="optional"/>
|
64 |
+
</complexType>
|
65 |
+
|
66 |
+
<element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/>
|
67 |
+
<complexType name="CanonicalizationMethodType" mixed="true">
|
68 |
+
<sequence>
|
69 |
+
<any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
|
70 |
+
<!-- (0,unbounded) elements from (1,1) namespace -->
|
71 |
+
</sequence>
|
72 |
+
<attribute name="Algorithm" type="anyURI" use="required"/>
|
73 |
+
</complexType>
|
74 |
+
|
75 |
+
<element name="SignatureMethod" type="ds:SignatureMethodType"/>
|
76 |
+
<complexType name="SignatureMethodType" mixed="true">
|
77 |
+
<sequence>
|
78 |
+
<element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/>
|
79 |
+
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
80 |
+
<!-- (0,unbounded) elements from (1,1) external namespace -->
|
81 |
+
</sequence>
|
82 |
+
<attribute name="Algorithm" type="anyURI" use="required"/>
|
83 |
+
</complexType>
|
84 |
+
|
85 |
+
<!-- Start Reference -->
|
86 |
+
|
87 |
+
<element name="Reference" type="ds:ReferenceType"/>
|
88 |
+
<complexType name="ReferenceType">
|
89 |
+
<sequence>
|
90 |
+
<element ref="ds:Transforms" minOccurs="0"/>
|
91 |
+
<element ref="ds:DigestMethod"/>
|
92 |
+
<element ref="ds:DigestValue"/>
|
93 |
+
</sequence>
|
94 |
+
<attribute name="Id" type="ID" use="optional"/>
|
95 |
+
<attribute name="URI" type="anyURI" use="optional"/>
|
96 |
+
<attribute name="Type" type="anyURI" use="optional"/>
|
97 |
+
</complexType>
|
98 |
+
|
99 |
+
<element name="Transforms" type="ds:TransformsType"/>
|
100 |
+
<complexType name="TransformsType">
|
101 |
+
<sequence>
|
102 |
+
<element ref="ds:Transform" maxOccurs="unbounded"/>
|
103 |
+
</sequence>
|
104 |
+
</complexType>
|
105 |
+
|
106 |
+
<element name="Transform" type="ds:TransformType"/>
|
107 |
+
<complexType name="TransformType" mixed="true">
|
108 |
+
<choice minOccurs="0" maxOccurs="unbounded">
|
109 |
+
<any namespace="##other" processContents="lax"/>
|
110 |
+
<!-- (1,1) elements from (0,unbounded) namespaces -->
|
111 |
+
<element name="XPath" type="string"/>
|
112 |
+
</choice>
|
113 |
+
<attribute name="Algorithm" type="anyURI" use="required"/>
|
114 |
+
</complexType>
|
115 |
+
|
116 |
+
<!-- End Reference -->
|
117 |
+
|
118 |
+
<element name="DigestMethod" type="ds:DigestMethodType"/>
|
119 |
+
<complexType name="DigestMethodType" mixed="true">
|
120 |
+
<sequence>
|
121 |
+
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
122 |
+
</sequence>
|
123 |
+
<attribute name="Algorithm" type="anyURI" use="required"/>
|
124 |
+
</complexType>
|
125 |
+
|
126 |
+
<element name="DigestValue" type="ds:DigestValueType"/>
|
127 |
+
<simpleType name="DigestValueType">
|
128 |
+
<restriction base="base64Binary"/>
|
129 |
+
</simpleType>
|
130 |
+
|
131 |
+
<!-- End SignedInfo -->
|
132 |
+
|
133 |
+
<!-- Start KeyInfo -->
|
134 |
+
|
135 |
+
<element name="KeyInfo" type="ds:KeyInfoType"/>
|
136 |
+
<complexType name="KeyInfoType" mixed="true">
|
137 |
+
<choice maxOccurs="unbounded">
|
138 |
+
<element ref="ds:KeyName"/>
|
139 |
+
<element ref="ds:KeyValue"/>
|
140 |
+
<element ref="ds:RetrievalMethod"/>
|
141 |
+
<element ref="ds:X509Data"/>
|
142 |
+
<element ref="ds:PGPData"/>
|
143 |
+
<element ref="ds:SPKIData"/>
|
144 |
+
<element ref="ds:MgmtData"/>
|
145 |
+
<any processContents="lax" namespace="##other"/>
|
146 |
+
<!-- (1,1) elements from (0,unbounded) namespaces -->
|
147 |
+
</choice>
|
148 |
+
<attribute name="Id" type="ID" use="optional"/>
|
149 |
+
</complexType>
|
150 |
+
|
151 |
+
<element name="KeyName" type="string"/>
|
152 |
+
<element name="MgmtData" type="string"/>
|
153 |
+
|
154 |
+
<element name="KeyValue" type="ds:KeyValueType"/>
|
155 |
+
<complexType name="KeyValueType" mixed="true">
|
156 |
+
<choice>
|
157 |
+
<element ref="ds:DSAKeyValue"/>
|
158 |
+
<element ref="ds:RSAKeyValue"/>
|
159 |
+
<any namespace="##other" processContents="lax"/>
|
160 |
+
</choice>
|
161 |
+
</complexType>
|
162 |
+
|
163 |
+
<element name="RetrievalMethod" type="ds:RetrievalMethodType"/>
|
164 |
+
<complexType name="RetrievalMethodType">
|
165 |
+
<sequence>
|
166 |
+
<element ref="ds:Transforms" minOccurs="0"/>
|
167 |
+
</sequence>
|
168 |
+
<attribute name="URI" type="anyURI"/>
|
169 |
+
<attribute name="Type" type="anyURI" use="optional"/>
|
170 |
+
</complexType>
|
171 |
+
|
172 |
+
<!-- Start X509Data -->
|
173 |
+
|
174 |
+
<element name="X509Data" type="ds:X509DataType"/>
|
175 |
+
<complexType name="X509DataType">
|
176 |
+
<sequence maxOccurs="unbounded">
|
177 |
+
<choice>
|
178 |
+
<element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
|
179 |
+
<element name="X509SKI" type="base64Binary"/>
|
180 |
+
<element name="X509SubjectName" type="string"/>
|
181 |
+
<element name="X509Certificate" type="base64Binary"/>
|
182 |
+
<element name="X509CRL" type="base64Binary"/>
|
183 |
+
<any namespace="##other" processContents="lax"/>
|
184 |
+
</choice>
|
185 |
+
</sequence>
|
186 |
+
</complexType>
|
187 |
+
|
188 |
+
<complexType name="X509IssuerSerialType">
|
189 |
+
<sequence>
|
190 |
+
<element name="X509IssuerName" type="string"/>
|
191 |
+
<element name="X509SerialNumber" type="integer"/>
|
192 |
+
</sequence>
|
193 |
+
</complexType>
|
194 |
+
|
195 |
+
<!-- End X509Data -->
|
196 |
+
|
197 |
+
<!-- Begin PGPData -->
|
198 |
+
|
199 |
+
<element name="PGPData" type="ds:PGPDataType"/>
|
200 |
+
<complexType name="PGPDataType">
|
201 |
+
<choice>
|
202 |
+
<sequence>
|
203 |
+
<element name="PGPKeyID" type="base64Binary"/>
|
204 |
+
<element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/>
|
205 |
+
<any namespace="##other" processContents="lax" minOccurs="0"
|
206 |
+
maxOccurs="unbounded"/>
|
207 |
+
</sequence>
|
208 |
+
<sequence>
|
209 |
+
<element name="PGPKeyPacket" type="base64Binary"/>
|
210 |
+
<any namespace="##other" processContents="lax" minOccurs="0"
|
211 |
+
maxOccurs="unbounded"/>
|
212 |
+
</sequence>
|
213 |
+
</choice>
|
214 |
+
</complexType>
|
215 |
+
|
216 |
+
<!-- End PGPData -->
|
217 |
+
|
218 |
+
<!-- Begin SPKIData -->
|
219 |
+
|
220 |
+
<element name="SPKIData" type="ds:SPKIDataType"/>
|
221 |
+
<complexType name="SPKIDataType">
|
222 |
+
<sequence maxOccurs="unbounded">
|
223 |
+
<element name="SPKISexp" type="base64Binary"/>
|
224 |
+
<any namespace="##other" processContents="lax" minOccurs="0"/>
|
225 |
+
</sequence>
|
226 |
+
</complexType>
|
227 |
+
|
228 |
+
<!-- End SPKIData -->
|
229 |
+
|
230 |
+
<!-- End KeyInfo -->
|
231 |
+
|
232 |
+
<!-- Start Object (Manifest, SignatureProperty) -->
|
233 |
+
|
234 |
+
<element name="Object" type="ds:ObjectType"/>
|
235 |
+
<complexType name="ObjectType" mixed="true">
|
236 |
+
<sequence minOccurs="0" maxOccurs="unbounded">
|
237 |
+
<any namespace="##any" processContents="lax"/>
|
238 |
+
</sequence>
|
239 |
+
<attribute name="Id" type="ID" use="optional"/>
|
240 |
+
<attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet -->
|
241 |
+
<attribute name="Encoding" type="anyURI" use="optional"/>
|
242 |
+
</complexType>
|
243 |
+
|
244 |
+
<element name="Manifest" type="ds:ManifestType"/>
|
245 |
+
<complexType name="ManifestType">
|
246 |
+
<sequence>
|
247 |
+
<element ref="ds:Reference" maxOccurs="unbounded"/>
|
248 |
+
</sequence>
|
249 |
+
<attribute name="Id" type="ID" use="optional"/>
|
250 |
+
</complexType>
|
251 |
+
|
252 |
+
<element name="SignatureProperties" type="ds:SignaturePropertiesType"/>
|
253 |
+
<complexType name="SignaturePropertiesType">
|
254 |
+
<sequence>
|
255 |
+
<element ref="ds:SignatureProperty" maxOccurs="unbounded"/>
|
256 |
+
</sequence>
|
257 |
+
<attribute name="Id" type="ID" use="optional"/>
|
258 |
+
</complexType>
|
259 |
+
|
260 |
+
<element name="SignatureProperty" type="ds:SignaturePropertyType"/>
|
261 |
+
<complexType name="SignaturePropertyType" mixed="true">
|
262 |
+
<choice maxOccurs="unbounded">
|
263 |
+
<any namespace="##other" processContents="lax"/>
|
264 |
+
<!-- (1,1) elements from (1,unbounded) namespaces -->
|
265 |
+
</choice>
|
266 |
+
<attribute name="Target" type="anyURI" use="required"/>
|
267 |
+
<attribute name="Id" type="ID" use="optional"/>
|
268 |
+
</complexType>
|
269 |
+
|
270 |
+
<!-- End Object (Manifest, SignatureProperty) -->
|
271 |
+
|
272 |
+
<!-- Start Algorithm Parameters -->
|
273 |
+
|
274 |
+
<simpleType name="HMACOutputLengthType">
|
275 |
+
<restriction base="integer"/>
|
276 |
+
</simpleType>
|
277 |
+
|
278 |
+
<!-- Start KeyValue Element-types -->
|
279 |
+
|
280 |
+
<element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
|
281 |
+
<complexType name="DSAKeyValueType">
|
282 |
+
<sequence>
|
283 |
+
<sequence minOccurs="0">
|
284 |
+
<element name="P" type="ds:CryptoBinary"/>
|
285 |
+
<element name="Q" type="ds:CryptoBinary"/>
|
286 |
+
</sequence>
|
287 |
+
<element name="G" type="ds:CryptoBinary" minOccurs="0"/>
|
288 |
+
<element name="Y" type="ds:CryptoBinary"/>
|
289 |
+
<element name="J" type="ds:CryptoBinary" minOccurs="0"/>
|
290 |
+
<sequence minOccurs="0">
|
291 |
+
<element name="Seed" type="ds:CryptoBinary"/>
|
292 |
+
<element name="PgenCounter" type="ds:CryptoBinary"/>
|
293 |
+
</sequence>
|
294 |
+
</sequence>
|
295 |
+
</complexType>
|
296 |
+
|
297 |
+
<element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
|
298 |
+
<complexType name="RSAKeyValueType">
|
299 |
+
<sequence>
|
300 |
+
<element name="Modulus" type="ds:CryptoBinary"/>
|
301 |
+
<element name="Exponent" type="ds:CryptoBinary"/>
|
302 |
+
</sequence>
|
303 |
+
</complexType>
|
304 |
+
|
305 |
+
<!-- End KeyValue Element-types -->
|
306 |
+
|
307 |
+
<!-- End Signature -->
|
308 |
+
|
309 |
+
</schema>
|
package.xml
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>XREC_DIM</name>
|
4 |
+
<version>1.0.1</version>
|
5 |
+
<stability>Stable</stability>
|
6 |
+
<license>paid</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Digitaal Incassomachtigen</summary>
|
10 |
+
<description>ING digitaal Incassomachtigen voor online betalen</description>
|
11 |
+
<notes>First Release</notes>
|
12 |
+
<authors><author><name>xrec.nl</name><user>yasarkunduz</user><email>info@xrec.nl</email></author></authors>
|
13 |
+
<date>2015-06-28</date>
|
14 |
+
<time>17:34:05</time>
|
15 |
+
<contents><target name="magecommunity"><dir name="Xrec"><dir name="Dim"><dir name="Block"><dir name="Payment"><dir name="Dim"><file name="Fail.php" hash="c02269203e5671651cfcf2f73a46f7b6"/><file name="Form.php" hash="e7d830877f011e967b7f46fbcffd31fe"/><file name="Info.php" hash="343c4a38e6314d370bb39ff1c93ef2d9"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="ef41ad5f43178e0ac59d99d2583ecdee"/><file name="Dim.php" hash="92e526ffb3e995710b242240041174b0"/></dir><dir name="Model"><file name="Dim.php" hash="165579ff6573d173bf24bab363d582e7"/></dir><dir name="controllers"><file name="DimController.php" hash="74c3986327c4a16fff873c815da8e9a0"/></dir><dir name="etc"><file name="config.xml" hash="fb8066f1b903991dc83f020aded1d487"/><file name="system.xml" hash="8be4c1a04aa031db9a25e1b145eda137"/></dir><dir name="sql"><dir name="dim_setup"><file name="mysql4-install-1.0.0.php" hash="b2007ad1be0ce4b81fc8c96f318e471c"/><file name="mysql4-uninstall-1.0.0.php" hash="343db23ebd3447bdec9fde2ad9f458ee"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="dim.xml" hash="3bc2c7454e08a67af66a9747121f5a06"/></dir><dir name="template"><dir name="xrec"><dir name="form"><file name="dim.phtml" hash="f702661da3aaf1c79c8c7645c4ddee73"/></dir><dir name="page"><file name="exception.phtml" hash="5696fc484250a35a6a4d4b796c3d0b12"/><file name="fail.phtml" hash="c970bed0050919a585c18ae2b89f9c15"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Xrec_Dim.xml" hash="a5a264a4e2ef950c283b9b81c0117098"/></dir></target><target name="magelib"><dir name="Communicator"><file name="B2BCommunicator.php" hash="94fd8863facaaaa598f5f92f134f92c9"/><dir name="Configuration"><file name="Configuration.php" hash="2141e5e7e95465e4b81afdddcd8c3621"/></dir><file name="CoreCommunicator.php" hash="ed81ce17539167a7dfab5d273a6a2810"/><dir name="Entities"><file name="AcquirerStatusRequest.php" hash="dd7308d59634e3efbd985a51e372c494"/><file name="AcquirerStatusResponse.php" hash="782857adb7fff0a36811ffbe2d5149f0"/><file name="AcquirerTrxRequest.php" hash="8111238cbfcad8ee7ac84325819b14d8"/><file name="AmendmentRequest.php" hash="3e83bf8031edcf9ff8b60e60aae6b7f0"/><file name="AmendmentResponse.php" hash="3f18c193fadbce4f65e5bf6d9648a290"/><file name="CancellationRequest.php" hash="40889429b6bff27060566db4c247acfb"/><file name="CancellationResponse.php" hash="40ed6e02dc87973da7547c052cdab3aa"/><file name="DirectoryRequest.php" hash="534bcdbde8bc375921dc7f97cc9c0d6d"/><file name="DirectoryResponse.php" hash="1abd26b8a57dc2c03734d5f5ac8e6211"/><file name="ErrorResponse.php" hash="27c734ddd2d2549e0b52d8db402e9f51"/><file name="NewMandateRequest.php" hash="1252a8a08b427ea9e7382fb5eef8069d"/><file name="NewMandateResponse.php" hash="a8e3b56452e0ff3abb51d72c3b578700"/></dir><dir name="Libraries"><file name="CommunicatorException.php" hash="ae3087f21c3d988048f77db241eb8f2e"/><file name="Logger.php" hash="ec84b8fcde853923b0301aa1361032e8"/><file name="MessageIdGenerator.php" hash="29f189dd41e544871b9545fc3d0a78d5"/><file name="XmlSecurity.php" hash="98a217e1829effdce2b003982f98c9ac"/><file name="XmlValidator.php" hash="65187ed0300108c76951567a839ddbe4"/><file name="xmlseclibs.php" hash="75aa5adc6bd69318bc83f9ca4948f578"/></dir><dir name="schemas"><file name="idx.merchant-acquirer.1.0.xsd" hash="5090a394336fa5691b391e9ca613147f"/><file name="pain.009.001.04.xsd" hash="341c5cc848c4e396c80f087bb5dc1b02"/><file name="pain.010.001.04.xsd" hash="336d47dee264e6600e60d508748a0302"/><file name="pain.011.001.04.xsd" hash="22d4bf175016b944ca6b3538801797b3"/><file name="pain.012.001.04.xsd" hash="3bc9a3bc6d9ddd5885518b0cce45f2c4"/><file name="xmldsig-core-schema.xsd" hash="ec096c98bec8ca421e284af9443546c5"/></dir><file name=".DS_Store" hash="6b79706ed0b8c42eadd16a8fc35be1b7"/></dir></target><target name="mage"><dir><dir name="var"><dir name="xrec"><dir name="dim"><dir name="cer"><file name=".DS_Store" hash="194577a7e20bdcc7afbb718f502c134c"/></dir><file name=".DS_Store" hash="b59dd545b407bbd35442197809059cc2"/></dir><file name=".DS_Store" hash="493d87106d63b713d90e5dec20b455a4"/><file name=".htaccess" hash="72617d60821288133a367f70bf39ad93"/></dir></dir></dir></target><target name="magelocale"><dir name="."><file name="Xrec_Dim.csv" hash=""/></dir></target><target name="mageskin"><dir name="frontend"><dir name="dim"><dir name="css"><file name="style.css" hash="0d98e5fa0f90cb613509f90b64b83129"/></dir><dir name="images"><file name="dim.jpg" hash="f90083a65649212e13c7b407c75ce0a7"/></dir><file name=".DS_Store" hash="144c2056ff80e19faa3722eedcf87c25"/></dir></dir></target></contents>
|
16 |
+
<compatible/>
|
17 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
18 |
+
</package>
|
skin/frontend/dim/.DS_Store
ADDED
Binary file
|
skin/frontend/dim/css/style.css
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#p_method_dim + label:before {
|
2 |
+
display: inline-block;
|
3 |
+
content:"icon";
|
4 |
+
text-indent:-999em;
|
5 |
+
width: 25px;
|
6 |
+
height: 20px;
|
7 |
+
margin-top: -3px;
|
8 |
+
background: transparent url('../images/dim.jpg') no-repeat;
|
9 |
+
}
|
skin/frontend/dim/images/dim.jpg
ADDED
Binary file
|
var/xrec/.DS_Store
ADDED
Binary file
|
var/xrec/.htaccess
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
Order deny,allow
|
2 |
+
Deny from all
|
var/xrec/dim/.DS_Store
ADDED
Binary file
|
var/xrec/dim/cer/.DS_Store
ADDED
Binary file
|