├── .editorconfig ├── README.md ├── class.SEPADirectDebitTransaction.php ├── class.SEPAException.php ├── class.SEPAGroupHeader.php ├── class.SEPAMessage.php ├── class.SEPAPaymentInfo.php ├── class.URLify.php ├── index.php └── validation_schemes ├── pain.008.001.02.austrian.003.xsd ├── pain.008.001.02.austrian.004.Korrigendum.xsd ├── pain.008.001.02.xsd ├── pain.008.001.02_GBIC_1.xsd ├── pain.008.001.02_GBIC_2.xsd ├── pain.008.001.02_GBIC_3.xsd ├── pain.008.003.02.xsd └── pain.008_codelists.xsd /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.xsd] 13 | indent_size = 4 14 | insert_final_newline = false 15 | 16 | [*.{md,Rmd,rst}] 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SEPA Direct Debit (SDD) XML Generator 2 | ==================================== 3 | 4 | ### How to use? 5 | 6 | See *index.php* for an example how to create a SEPA message. 7 | * Set the namespace according to your requirements. By default, the EPC message scheme `urn:iso:std:iso:20022:tech:xsd:pain.008.001.02` is set.
8 | * Note that the `SEPAGroupHeader` must exist only once per message. 9 | * Per message you can include multiple `SEPAPaymentInfo` blocks (e.g. one per debit sequence type). 10 | * Per `SEPAPaymentInfo` block multiple transactions `SEPADirectDebitTransaction` may be added. 11 | * It is possible to validate a message against an XSD scheme prior to generating an XML file. Therefore, have a look at the 12 | commented statement near the end of *index.php*. Currently, we include out-of-the-box support for the following schemes: 13 | * EPC: `pain.008.001.02` 14 | * Austria: 15 | * `pain.008.001.02.austrian.004.Korrigendum` 16 | * `pain.008.001.02.austrian.003` 17 | * Germany: 18 | * `pain.008.001.02_GBIC_3` (valid from 17.11.2019) 19 | * `pain.008.001.02_GBIC_2` (valid from 18.11.2018) 20 | * `pain.008.001.02_GBIC_1` (valid from 20.11.2016) 21 | * `pain.008.003.02` 22 | 23 | ### What is this? 24 | 25 | The Single Euro Payments Area (SEPA) is a payment-integration initiative of the European Union for simplification of bank transfers denominated in euro. 26 | Based on your input data, this script facilitates the process of generating a SEPA-compliant XML file for direct debit. 27 | 28 | --- 29 | 30 | #### LICENSE 31 | 32 | ![CC BY-NC](http://i.creativecommons.org/l/by-nc/3.0/88x31.png) 33 | 34 | This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/. 35 | For commercial use please contact sales@web-wack.at -------------------------------------------------------------------------------- /class.SEPADirectDebitTransaction.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright http://www.web-wack.at web wack creations 7 | * @license http://creativecommons.org/licenses/by-nc/3.0/ CC Attribution-NonCommercial 3.0 license 8 | * For commercial use please contact sales@web-wack.at 9 | */ 10 | 11 | class SEPADirectDebitTransaction { 12 | /** 13 | * Code allocated to a currency, by a maintenance agency, under an international identification 14 | * scheme as described in the latest edition of the international standard ISO 4217. 15 | */ 16 | const CURRENCY_CODE = 'EUR'; 17 | 18 | /** 19 | * The instruction identification is a point to point reference that can be used between 20 | * the instructing party and the instructed party to refer to the individual instruction. 21 | * It can be included in several messages related to the instruction. (Tag: PmtId->InstrId>) 22 | * 23 | * @var string 24 | */ 25 | private $instructionIdentification = ''; 26 | 27 | /** 28 | * The end-to-end identification can be used for reconciliation or to link tasks relating to the transaction. 29 | * It can be included in several messages related to the transaction. (Tag: PmtId->EndToEndId>) 30 | * 31 | * @var string 32 | */ 33 | private $endToEndIdentification = ''; 34 | 35 | /** 36 | * Amount of money to be moved between the debtor and creditor, before deduction of charges, 37 | * expressed in the currency as ordered by the initiating party. (Tag: InstdAmt>) 38 | * 39 | * @var float 40 | */ 41 | private $instructedAmount = 0.00; 42 | 43 | /** 44 | * Unique identification, as assigned by the creditor, 45 | * to unambiguously identify the mandate. (Tag: DrctDbtTx->MndtRltdInf->MndtId>) 46 | * 47 | * @var string 48 | */ 49 | private $mandateIdentification = ''; 50 | 51 | /** 52 | * Date on which the direct debit mandate has been signed 53 | * by the debtor. (Tag: DrctDbtTx->MndtRltdInf->DtOfSgntr>) 54 | * 55 | * @var string 56 | */ 57 | private $dateOfSignature = ''; 58 | 59 | /** 60 | * Indicator notifying whether the underlying mandate is amended or not. 61 | * (Tag: DrctDbtTx->MndtRltdInf->AmdmntInd>) 62 | * 63 | * @var string 64 | */ 65 | private $amendmentIndicator = 'false'; 66 | 67 | /** 68 | * Financial institution servicing an account for the debtor. (Tag: FinInstnId->BIC>) 69 | * 70 | * @var string 71 | */ 72 | private $debtorAgentBIC = ''; 73 | 74 | /** 75 | * Party that owes an amount of money to the (ultimate) creditor. (Tag: Nm>) 76 | * 77 | * @var string 78 | */ 79 | private $debtorName = ''; 80 | 81 | 82 | /** 83 | * Post code of a debtor's postal address (Tag: PstlAdr->PstCd>) 84 | * 85 | * @var string 86 | */ 87 | private $debtorPostalCode = ''; 88 | 89 | /** 90 | * Town name of debtor's postal address (Tag: PstlAdr->TwnNm>) 91 | * 92 | * @var string 93 | */ 94 | private $debtorTownName = ''; 95 | 96 | /** 97 | * Country code of debtor's postal address (Tag: PstlAdr->Ctry>) 98 | * 99 | * @var string 100 | */ 101 | private $debtorCountry = ''; 102 | 103 | /** 104 | * Address Line of a debtor's postal address (Tag: PstlAdr->AdrLine>) 105 | * 106 | * @var string 107 | */ 108 | private $debtorAddressLine = ''; 109 | 110 | /** 111 | * Address line 2 of a debtor's postal address (Tag: PstlAdr->AdrLine>) 112 | * 113 | * @var string 114 | */ 115 | private $debtorAddressLine2 = ''; 116 | 117 | /** 118 | * Unambiguous identification of the account of the debtor to which a debit entry will 119 | * be made as a result of the transaction. (Tag: Id->IBAN>) 120 | * 121 | * @var string 122 | */ 123 | private $debtorIBAN = ''; 124 | 125 | /** 126 | * Information supplied to enable the matching/reconciliation of an entry with the items that the 127 | * payment is intended to settle, such as commercial invoices in an accounts' receivable system. 128 | * (Tag: Ustrd>) 129 | * 130 | * @var string 131 | */ 132 | private $remittanceInformation = ''; 133 | 134 | /** 135 | * Getter for Instruction Identification (DrctDbtTxInf->PmtId->InstrId) 136 | * 137 | * @return string 138 | */ 139 | public function getInstructionIdentification() 140 | { 141 | if (empty($this->instructionIdentification)) 142 | return $this->getEndToEndIdentification(); 143 | 144 | return $this->instructionIdentification; 145 | } 146 | 147 | /** 148 | * Setter for Instruction Identification (DrctDbtTxInf->PmtId->InstrId) 149 | * 150 | * @param string $instrId 151 | * @throws SEPAException 152 | */ 153 | public function setInstructionIdentification($instrId) 154 | { 155 | $instrId = URLify::downcode($instrId, "de"); 156 | 157 | if (!preg_match("/^([\-A-Za-z0-9\+\/\?:\(\)\., ]){0,35}\z/", $instrId)) 158 | throw new SEPAException("Invalid InstructionIdentification (max. 35)."); 159 | 160 | $this->instructionIdentification = $instrId; 161 | } 162 | 163 | /** 164 | * Getter for EndToEnd Identification (DrctDbtTxInf->PmtId->EndToEndId) 165 | * 166 | * @return string 167 | */ 168 | public function getEndToEndIdentification() 169 | { 170 | return $this->endToEndIdentification; 171 | } 172 | 173 | /** 174 | * Setter for EndToEnd Identification (DrctDbtTxInf->PmtId->EndToEndId) 175 | * 176 | * @param string $endToEndId 177 | * @throws SEPAException 178 | */ 179 | public function setEndToEndIdentification($endToEndId) 180 | { 181 | $endToEndId = URLify::downcode($endToEndId, "de"); 182 | 183 | if (!preg_match("/^([\-A-Za-z0-9\+\/\?:\(\)\., ]){1,35}\z/", $endToEndId)) 184 | throw new SEPAException("Invalid EndToEndIdentification (max. 35)."); 185 | 186 | $this->endToEndIdentification = $endToEndId; 187 | } 188 | 189 | /** 190 | * Getter for Instructed Amount (DrctDbtTxInf->InstdAmt) 191 | * 192 | * @return float 193 | */ 194 | public function getInstructedAmount() 195 | { 196 | return $this->instructedAmount; 197 | } 198 | 199 | /** 200 | * Setter for Instructed Amount (DrctDbtTxInf->InstdAmt) 201 | * 202 | * @param float $instdAmt 203 | */ 204 | public function setInstructedAmount($instdAmt) 205 | { 206 | $this->instructedAmount = number_format(floatval($instdAmt), 2, '.', ''); 207 | } 208 | 209 | /** 210 | * Getter for Mandate Identification (DrctDbtTxInf->DrctDbtTx->MndtRltdInf->MndtId) 211 | * 212 | * @return string 213 | */ 214 | public function getMandateIdentification() 215 | { 216 | return $this->mandateIdentification; 217 | } 218 | 219 | /** 220 | * Setter for Mandate Identification (DrctDbtTxInf->DrctDbtTx->MndtRltdInf->MndtId) 221 | * 222 | * @param string $mndtId 223 | * @throws SEPAException 224 | */ 225 | public function setMandateIdentification($mndtId) 226 | { 227 | $mndtId = URLify::downcode($mndtId, "de"); 228 | 229 | if (!preg_match("/^([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|']){1,35}\z/", $mndtId)) 230 | throw new SEPAException("MndtId empty, contains invalid characters or too long (max. 35)."); 231 | 232 | $this->mandateIdentification = $mndtId; 233 | } 234 | 235 | /** 236 | * Getter for Mandate Identification (DrctDbtTxInf->DrctDbtTx->MndtRltdInf->DtOfSgntr) 237 | * 238 | * @return string 239 | */ 240 | public function getDateOfSignature() 241 | { 242 | return $this->dateOfSignature; 243 | } 244 | 245 | /** 246 | * Setter for Mandate Identification (DrctDbtTxInf->DrctDbtTx->MndtRltdInf->DtOfSgntr) 247 | * 248 | * @param string $dtOfSgntr 249 | */ 250 | public function setDateOfSignature($dtOfSgntr) 251 | { 252 | $this->dateOfSignature = $dtOfSgntr; 253 | } 254 | 255 | /** 256 | * Getter for Amendment Indicator (DrctDbtTxInf->DrctDbtTx->MndtRltdInf->AmdmntInd) 257 | * 258 | * @return string 259 | */ 260 | public function getAmendmentIndicator() 261 | { 262 | return $this->amendmentIndicator; 263 | } 264 | 265 | /** 266 | * Setter for Amendment Indicator (DrctDbtTxInf->DrctDbtTx->MndtRltdInf->AmdmntInd) 267 | * 268 | * @param string $amdmntInd 269 | */ 270 | public function setAmendmentIndicator($amdmntInd) 271 | { 272 | if ($amdmntInd === true || $amdmntInd == 'true') 273 | $this->amendmentIndicator = 'true'; 274 | else 275 | $this->amendmentIndicator = 'false'; 276 | } 277 | 278 | /** 279 | * Getter for Debtor Agent BIC (DbtrAgt->FinInstnId->BIC) 280 | * 281 | * @return string 282 | */ 283 | public function getDebtorAgentBIC() 284 | { 285 | return $this->debtorAgentBIC; 286 | } 287 | 288 | /** 289 | * Setter for Debtor Agent BIC (DbtrAgt->FinInstnId->BIC) 290 | * 291 | * @param string $bic 292 | * @throws SEPAException 293 | */ 294 | public function setDebtorAgentBIC($bic) 295 | { 296 | $bic = str_replace(' ', '', trim($bic)); 297 | 298 | if (!preg_match("/^[0-9a-z]{4}[a-z]{2}[0-9a-z]{2}([0-9a-z]{3})?\z/i", $bic)) 299 | throw new SEPAException("Invalid debtor BIC."); 300 | 301 | $this->debtorAgentBIC = $bic; 302 | } 303 | 304 | /** 305 | * Getter for Debtor Name (Dbtr->Nm) 306 | * 307 | * @return string 308 | */ 309 | public function getDebtorName() 310 | { 311 | return $this->debtorName; 312 | } 313 | 314 | /** 315 | * Getter for Debtor Postal Code (Dbtr->PstlAdr->PstCd) 316 | * 317 | * @return string 318 | */ 319 | public function getDebtorPostalCode() 320 | { 321 | return $this->debtorPostalCode; 322 | } 323 | 324 | /** 325 | * Setter for Debtor Postal Code (Dbtr->PstlAdr->PstCd) 326 | * 327 | * @param string $pc 328 | * @throws SEPAException 329 | */ 330 | public function setDebtorPostalCode($pc) 331 | { 332 | if (strlen($pc) == 0 || strlen($pc) > 16) 333 | throw new SEPAException("Invalid debtor postal code (max. 16 characters)."); 334 | 335 | $this->debtorPostalCode = $pc; 336 | } 337 | 338 | /** 339 | * Getter for Debtor Town Name (Dbtr->PstlAdr->TwnNm) 340 | * 341 | * @return string 342 | */ 343 | public function getDebtorTownName() { 344 | return $this->debtorTownName; 345 | } 346 | 347 | /** 348 | * Setter for Debtor Town Name (Dbtr->PstlAdr->TwnNm) 349 | * 350 | * @param string $townname 351 | * @throws SEPAException 352 | */ 353 | public function setDebtorTownName($townname) 354 | { 355 | if (strlen($townname) == 0 || strlen($townname) > 35) 356 | throw new SEPAException("Invalid debtor town name (max. 35 characters)."); 357 | 358 | $this->debtorTownName = $townname; 359 | } 360 | 361 | /** 362 | * Getter for Debtor Country Code (Dbtr->PstlAdr->Ctry) 363 | * 364 | * @return string 365 | */ 366 | public function getDebtorCountry() { 367 | return $this->debtorCountry; 368 | } 369 | 370 | /** 371 | * Setter for Debtor Country Code (Dbtr->PstlAdr->Ctry) 372 | * 373 | * @param string $ctry 374 | * @throws SEPAException 375 | */ 376 | public function setDebtorCountry($ctry) 377 | { 378 | if (strlen($ctry) != 2) 379 | throw new SEPAException("Invalid debtor country code (2 characters)."); 380 | 381 | $this->debtorCountry = $ctry; 382 | } 383 | 384 | /** 385 | * Getter for Debtor Address Line (Dbtr->PstlAdr->AdrLine) 386 | * 387 | * @return string 388 | */ 389 | public function getDebtorAddressLine() { 390 | return $this->debtorAddressLine; 391 | } 392 | 393 | /** 394 | * Setter for Debtor Address Line (Dbtr->PstlAdr->AdrLine) 395 | * 396 | * @param string $address 397 | * @throws SEPAException 398 | */ 399 | public function setDebtorAddressLine($address) 400 | { 401 | if (strlen($address) == 0 || strlen($address) > 70) 402 | throw new SEPAException("Invalid debtor address line (max. 70 characters)."); 403 | 404 | $this->debtorAddressLine = $address; 405 | } 406 | 407 | /** 408 | * Getter for Debtor Address Line 2 (Dbtr->PstlAdr->AdrLine) 409 | * 410 | * @return string 411 | */ 412 | public function getDebtorAddressLine2() { 413 | return $this->debtorAddressLine2; 414 | } 415 | 416 | /** 417 | * Setter for Debtor Address Line 2 (Dbtr->PstlAdr->AdrLine) 418 | * 419 | * @param string $address 420 | * @throws SEPAException 421 | */ 422 | public function setDebtorAddressLine2($address) 423 | { 424 | if (strlen($address) == 0 || strlen($address) > 70) 425 | throw new SEPAException("Invalid debtor address line 2 (max. 70 characters)."); 426 | 427 | $this->debtorAddressLine2 = $address; 428 | } 429 | 430 | /** 431 | * Setter for Debtor Name (Dbtr->Nm) 432 | * 433 | * @param string $dbtr 434 | * @throws SEPAException 435 | */ 436 | public function setDebtorName($dbtr) 437 | { 438 | $dbtr = URLify::downcode($dbtr, "de"); 439 | 440 | if (strlen($dbtr) == 0 || strlen($dbtr) > 70) 441 | throw new SEPAException("Invalid debtor name (max. 70 characters)."); 442 | 443 | $this->debtorName = $dbtr; 444 | } 445 | 446 | /** 447 | * Getter for Debtor IBAN (DbtrAcct->Id->IBAN) 448 | * 449 | * @return string 450 | */ 451 | public function getDebtorIBAN() 452 | { 453 | return $this->debtorIBAN; 454 | } 455 | 456 | /** 457 | * Setter for Debtor IBAN (DbtrAcct->Id->IBAN) 458 | * 459 | * @param string $iban 460 | * @throws SEPAException 461 | */ 462 | public function setDebtorIBAN($iban) 463 | { 464 | $iban = str_replace(' ', '', trim($iban)); 465 | 466 | if (!preg_match("/^[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}\z/i", $iban)) 467 | throw new SEPAException("Invalid debtor IBAN."); 468 | 469 | $this->debtorIBAN = $iban; 470 | } 471 | 472 | /** 473 | * Getter for Remittance Information (RmtInf->Ustrd) 474 | * 475 | * @return string 476 | */ 477 | public function getRemittanceInformation() 478 | { 479 | return $this->remittanceInformation; 480 | } 481 | 482 | /** 483 | * Getter for Remittance Information (RmtInf->Ustrd) 484 | * 485 | * @param string $ustrd 486 | * @throws SEPAException 487 | */ 488 | public function setRemittanceInformation($ustrd) 489 | { 490 | $ustrd = URLify::downcode($ustrd, "de"); 491 | 492 | if (!preg_match("/^([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|'| ]){0,140}\z/", $ustrd)) 493 | throw new SEPAException("RmtInf contains invalid chars or is too long (max. 140)."); 494 | 495 | $this->remittanceInformation = $ustrd; 496 | } 497 | 498 | /** 499 | * Returns a SimpleXMLElement for the SEPADirectDebitTransaction object. 500 | * 501 | * @return SimpleXMLElement object 502 | */ 503 | public function getXmlDirectDebitTransaction() 504 | { 505 | $xml = new SimpleXMLElement(""); 506 | $xml->addChild('PmtId')->addChild('InstrId', $this->getInstructionIdentification()); 507 | 508 | $endToEndId = $this->getEndToEndIdentification(); 509 | if (empty($endToEndId)) 510 | $endToEndId = 'NOTPROVIDED'; 511 | $xml->PmtId->addChild('EndToEndId', $endToEndId); 512 | 513 | $xml->addChild('InstdAmt', $this->getInstructedAmount())->addAttribute('Ccy', self::CURRENCY_CODE); 514 | 515 | $xml->addChild('DrctDbtTx')->addChild('MndtRltdInf')->addChild('MndtId', $this->getMandateIdentification()); 516 | $xml->DrctDbtTx->MndtRltdInf->addChild('DtOfSgntr', $this->getDateOfSignature()); 517 | $xml->DrctDbtTx->MndtRltdInf->addChild('AmdmntInd', $this->getAmendmentIndicator()); 518 | 519 | // The BIC is optional for national payments (IBAN only) 520 | $bic = $this->getDebtorAgentBIC(); 521 | if (!empty($bic)) 522 | $xml->addChild('DbtrAgt')->addChild('FinInstnId')->addChild('BIC', $bic); 523 | else 524 | $xml->addChild('DbtrAgt')->addChild('FinInstnId')->addChild('Othr')->addChild('Id', 'NOTPROVIDED'); 525 | 526 | $xml->addChild('Dbtr')->addChild('Nm', $this->getDebtorName()); 527 | 528 | // Add debtor postal address if specified 529 | if (!empty($this->getDebtorCountry())) { 530 | $xml->Dbtr->addChild('PstlAdr'); 531 | 532 | if (!empty($this->getDebtorPostalCode())) 533 | $xml->Dbtr->PstlAdr->addChild('PstCd', $this->getDebtorPostalCode()); 534 | if (!empty($this->getDebtorTownName())) 535 | $xml->Dbtr->PstlAdr->addChild('TwnNm', $this->getDebtorTownName()); 536 | 537 | $xml->Dbtr->PstlAdr->addChild('Ctry', $this->getDebtorCountry()); 538 | if (!empty($this->getDebtorAddressLine())) 539 | $xml->Dbtr->PstlAdr->addChild('AdrLine', $this->getDebtorAddressLine()); 540 | if (!empty($this->getDebtorAddressLine2())) 541 | $xml->Dbtr->PstlAdr->addChild('AdrLine', $this->getDebtorAddressLine2()); 542 | } 543 | 544 | $xml->addChild('DbtrAcct')->addChild('Id')->addChild('IBAN', $this->getDebtorIBAN()); 545 | 546 | $xml->addChild('RmtInf')->addChild('Ustrd', $this->getRemittanceInformation()); 547 | 548 | return $xml; 549 | } 550 | } 551 | -------------------------------------------------------------------------------- /class.SEPAException.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright http://www.web-wack.at web wack creations 7 | * @license http://creativecommons.org/licenses/by-nc/3.0/ CC Attribution-NonCommercial 3.0 license 8 | * For commercial use please contact sales@web-wack.at 9 | */ 10 | 11 | class SEPAException extends Exception 12 | { 13 | } 14 | -------------------------------------------------------------------------------- /class.SEPAGroupHeader.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright http://www.web-wack.at web wack creations 7 | * @license http://creativecommons.org/licenses/by-nc/3.0/ CC Attribution-NonCommercial 3.0 license 8 | * For commercial use please contact sales@web-wack.at 9 | */ 10 | 11 | class SEPAGroupHeader { 12 | /** 13 | * Point to point reference assigned by the instructing party and sent to the next party in the chain 14 | * to unambiguously identify the message. (Tag: ) 15 | * 16 | * @var string 17 | */ 18 | private $messageIdentification = ''; 19 | 20 | /** 21 | * Date and time at which a (group of) payment instruction(s) was created 22 | * by the instructing party. (Tag: ) 23 | * 24 | * @var DateTime object 25 | */ 26 | private $creationDateTime = null; 27 | 28 | /** 29 | * Number of individual transactions contained in the message. (Tag: ) 30 | * 31 | * @var int 32 | */ 33 | private $numberOfTransactions = 0; 34 | 35 | /** 36 | * Total of all individual amounts included in the message. (Tag: ) 37 | * 38 | * @var float 39 | */ 40 | private $controlSum = 0.00; 41 | 42 | /** 43 | * Party that initiates the payment. This can either be the creditor or a party that initiates 44 | * the direct debit on behalf of the creditor. (Tag: Nm>) 45 | * 46 | * @var string 47 | */ 48 | private $initiatingPartyName = ''; 49 | 50 | /** 51 | * Getter for Message Identification (MsgId) 52 | * 53 | * @return string 54 | */ 55 | public function getMessageIdentification() 56 | { 57 | return $this->messageIdentification; 58 | } 59 | 60 | /** 61 | * Setter for Message Identification (MsgId) 62 | * 63 | * @param $msgId 64 | * @throws SEPAException 65 | */ 66 | public function setMessageIdentification($msgId) 67 | { 68 | $msgId = URLify::downcode($msgId, "de"); 69 | 70 | if (!preg_match("/^([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|'| ]){1,35}\z/", $msgId)) 71 | throw new SEPAException("MsgId empty, contains invalid characters or too long (max. 35)."); 72 | 73 | $this->messageIdentification = $msgId; 74 | } 75 | 76 | /** 77 | * Getter for Creation Date Time (CreDtTm) 78 | * 79 | * @return DateTime object 80 | */ 81 | public function getCreationDateTime() 82 | { 83 | $creationDate = new DateTime(); 84 | 85 | if (!$this->creationDateTime) 86 | $this->creationDateTime = $creationDate->format('Y-m-d\TH:i:s'); 87 | 88 | return $this->creationDateTime; 89 | } 90 | 91 | /** 92 | * Setter for Creation Date Time (CreDtTm) 93 | * 94 | * @param string $creDtTm 95 | */ 96 | public function setCreationDateTime($creDtTm) 97 | { 98 | $this->creationDateTime = $creDtTm; 99 | } 100 | 101 | /** 102 | * Getter for Number of Transactions (NbOfTxs) 103 | * 104 | * @return int 105 | */ 106 | public function getNumberOfTransactions() 107 | { 108 | return $this->numberOfTransactions; 109 | } 110 | 111 | /** 112 | * Setter for Number of Transactions (NbOfTxs) 113 | * 114 | * @param int $nbOfTxs 115 | * @throws SEPAException 116 | */ 117 | public function setNumberOfTransactions($nbOfTxs) 118 | { 119 | if (!preg_match("/^[0-9]{1,15}\z/", $nbOfTxs)) 120 | throw new SEPAException("Invalid NbOfTxs value (max. 15 digits)."); 121 | 122 | $this->numberOfTransactions = $nbOfTxs; 123 | } 124 | 125 | /** 126 | * Getter for ControlSum (CtrlSum) 127 | * 128 | * @return float 129 | */ 130 | public function getControlSum() 131 | { 132 | return $this->controlSum; 133 | } 134 | 135 | /** 136 | * Setter for ControlSum (CtrlSum) 137 | * 138 | * @param float $ctrlSum 139 | */ 140 | public function setControlSum($ctrlSum) 141 | { 142 | $this->controlSum = floatval($ctrlSum); 143 | } 144 | 145 | /** 146 | * Getter for Initiating Party Name (InitgPty->Nm) 147 | * 148 | * @return string 149 | */ 150 | public function getInitiatingPartyName() 151 | { 152 | return $this->initiatingPartyName; 153 | } 154 | 155 | /** 156 | * Setter for Initiating Party Name (InitgPty->Nm) 157 | * 158 | * @param string $initgPty 159 | * @throws SEPAException 160 | */ 161 | public function setInitiatingPartyName($initgPty) 162 | { 163 | $initgPty = URLify::downcode($initgPty, "de"); 164 | 165 | if (strlen($initgPty) == 0 || strlen($initgPty) > 70) 166 | throw new SEPAException("Invalid initiating party name (max. 70)."); 167 | 168 | $this->initiatingPartyName = $initgPty; 169 | } 170 | 171 | /** 172 | * Returns a SimpleXMLElement for the SEPAGroupHeader object. 173 | * 174 | * @return SimpleXMLElement object 175 | */ 176 | public function getXmlGroupHeader() 177 | { 178 | $xml = new SimpleXMLElement(""); 179 | $xml->addChild('MsgId', $this->getMessageIdentification()); 180 | $xml->addChild('CreDtTm', $this->getCreationDateTime()); 181 | $xml->addChild('NbOfTxs', $this->getNumberOfTransactions()); 182 | $xml->addChild('CtrlSum', $this->getControlSum()); 183 | $xml->addChild('InitgPty')->addChild('Nm', $this->getInitiatingPartyName()); 184 | 185 | return $xml; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /class.SEPAMessage.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright http://www.web-wack.at web wack creations 7 | * @license http://creativecommons.org/licenses/by-nc/3.0/ CC Attribution-NonCommercial 3.0 license 8 | * For commercial use please contact sales@web-wack.at 9 | */ 10 | 11 | class SEPAMessage 12 | { 13 | /** 14 | * The used ISO 20022 message format. 15 | * 16 | * @var string 17 | */ 18 | private $messageDefintion = ''; 19 | 20 | /** 21 | * GroupHeader object. (Tag: ) 22 | * 23 | * @var SEPAGroupHeader object 24 | */ 25 | private $groupHeader = null; 26 | 27 | /** 28 | * A container for all PaymentInfo objects. 29 | * 30 | * @var SEPAPaymentInfo[] array 31 | */ 32 | private $paymentInfos = array(); 33 | 34 | /** 35 | * The constructor sets the used message format. 36 | * 37 | * @param string $messageDefinition 38 | */ 39 | public function __construct($messageDefinition) 40 | { 41 | $this->messageDefintion = $messageDefinition; 42 | } 43 | 44 | /** 45 | * Getter for the group header object. 46 | * 47 | * @return SEPAGroupHeader object 48 | */ 49 | public function getGroupHeader() 50 | { 51 | if (is_null($this->groupHeader)) 52 | $this->groupHeader = new SEPAGroupHeader(); 53 | 54 | return $this->groupHeader; 55 | } 56 | 57 | /** 58 | * Setter for the group header object. 59 | * 60 | * @param SEPAGroupHeader $groupHeader 61 | */ 62 | public function setGroupHeader(SEPAGroupHeader $groupHeader) 63 | { 64 | $this->groupHeader = $groupHeader; 65 | } 66 | 67 | /** 68 | * Adds a PaymentInfo object to the collection. 69 | * 70 | * @param SEPAPaymentInfo $paymentInfo 71 | */ 72 | public function addPaymentInfo(SEPAPaymentInfo $paymentInfo) 73 | { 74 | $this->paymentInfos[] = $paymentInfo; 75 | 76 | $nbOfTxs = $this->getGroupHeader()->getNumberOfTransactions() + $paymentInfo->getNumberOfTransactions(); 77 | $ctrlSum = $this->getGroupHeader()->getControlSum() + $paymentInfo->getControlSum(); 78 | $this->getGroupHeader()->setNumberOfTransactions($nbOfTxs); 79 | $this->getGroupHeader()->setControlSum($ctrlSum); 80 | } 81 | 82 | /** 83 | * Returns the message as SimpleXMLElement object. 84 | * 85 | * @return SimpleXMLElement object 86 | */ 87 | public function getXML() 88 | { 89 | // Initialize the actual message and add the group header 90 | $message = new SimpleXMLElement(""); 91 | $this->addSubtree($message, $this->getGroupHeader()->getXmlGroupHeader()); 92 | 93 | // Add all payment blocks 94 | for ($i = 0; $i < count($this->paymentInfos); $i++) 95 | $this->addSubtree($message, $this->paymentInfos[$i]->getXmlPaymentInfo()); 96 | 97 | $message->GrpHdr->NbOfTxs = $this->getGroupHeader()->getNumberOfTransactions(); 98 | $message->GrpHdr->CtrlSum = $this->getGroupHeader()->getControlSum(); 99 | 100 | // Finally add the XML structure 101 | $doc = new SimpleXMLElement(' 102 | 103 | '); 104 | $this->addSubtree($doc, $message); 105 | 106 | return $doc; 107 | } 108 | 109 | /** 110 | * Returns a printable and formatted XML message. 111 | * 112 | * @return string 113 | */ 114 | public function printXML() 115 | { 116 | @header('Content-type: text/xml'); 117 | 118 | $dom = new DOMDocument(); 119 | $dom->preserveWhiteSpace = false; 120 | $dom->formatOutput = true; 121 | $dom->loadXML($this->getXML()->asXML()); 122 | 123 | return $dom->saveXML(); 124 | } 125 | 126 | /** 127 | * Validate the generated XML over the .xsd specification. 128 | * 129 | * @param string $schemePath 130 | * @return bool 131 | */ 132 | public function validateXML($schemePath) 133 | { 134 | $dom = new DOMDocument(); 135 | $dom->loadXML($this->getXML()->asXML()); 136 | 137 | libxml_use_internal_errors(true); 138 | if (!$dom->schemaValidate($schemePath)) 139 | { 140 | echo "XML validation failed!\n"; 141 | 142 | $errors = libxml_get_errors(); 143 | for ($i = 0; $i < count($errors); $i++) 144 | echo "Error " . $errors[$i]->code . ": " . $errors[$i]->message . "\n"; 145 | 146 | return false; 147 | } 148 | 149 | return true; 150 | } 151 | 152 | /** 153 | * Creates new DOM elements from two given SimpleXMLElement objects. 154 | * 155 | * @param SimpleXMLElement $xmlTarget 156 | * @param SimpleXMLElement $xmlOrigin 157 | */ 158 | private function addSubtree(SimpleXMLElement $xmlTarget, SimpleXMLElement $xmlOrigin) 159 | { 160 | $domTarget = dom_import_simplexml($xmlTarget); 161 | $domOrigin = dom_import_simplexml($xmlOrigin); 162 | 163 | $domTarget->appendChild($domTarget->ownerDocument->importNode($domOrigin, true)); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /class.SEPAPaymentInfo.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright http://www.web-wack.at web wack creations 7 | * @license http://creativecommons.org/licenses/by-nc/3.0/ CC Attribution-NonCommercial 3.0 license 8 | * For commercial use please contact sales@web-wack.at 9 | */ 10 | 11 | class SEPAPaymentInfo 12 | { 13 | /** 14 | * Specifies the means of payment that will be used to move the amount of money. (Tag: ) 15 | * 16 | * Collection of an amount of money from the debtor's bank account by the creditor. 17 | * The amount of money and dates of collections may vary. 18 | * 19 | * @var string 20 | */ 21 | const PAYMENT_METHOD = 'DD'; 22 | 23 | /** 24 | * Specifies a pre-agreed service or level of service between the parties, 25 | * as published in an external service level code list. (Tag: Cd>) 26 | * 27 | * @var string 28 | */ 29 | const SERVICELEVEL_CODE = 'SEPA'; 30 | 31 | /** 32 | * Specifies which party/parties will bear the charges associated with the 33 | * processing of the payment transaction. (Tag: ) 34 | * 35 | * @var string 36 | */ 37 | const CHARGE_BEARER = 'SLEV'; 38 | 39 | /** 40 | * Name of the identification scheme, in a free text form. (Tag: Id->PrvtId->Othr->SchmeNm->Prtry>) 41 | * 42 | * @var string 43 | */ 44 | const PROPRIETARY_NAME = 'SEPA'; 45 | 46 | /** 47 | * Unique identification, as assigned by a sending party, to unambiguously identify the 48 | * payment information group within the message. (Tag: ) 49 | * 50 | * @var string 51 | */ 52 | private $paymentInformationIdentification = ''; 53 | 54 | /** 55 | * Identifies whether a single entry per individual transaction or a batch entry for the 56 | * sum of the amounts of all transactions within the group of a message is requested (Tag: ) 57 | * 58 | * @var string 59 | */ 60 | private $batchBooking = 'false'; 61 | 62 | /** 63 | * Number of individual transactions contained in the payment information group (Tag: ) 64 | * 65 | * @var int 66 | */ 67 | private $numberOfTransactions = 0; 68 | 69 | /** 70 | * Total of all individual amounts included in the group (Tag: ) 71 | * 72 | * @var float 73 | */ 74 | private $controlSum = 0.00; 75 | 76 | /** 77 | * Specifies the local instrument, as published in an external local instrument code list. 78 | * Only 'CORE', 'COR1', or 'B2B' are allowed. (Tag: Cd>) 79 | * 80 | * @var string 81 | */ 82 | private $localInstrumentCode = 'CORE'; 83 | 84 | /** 85 | * Identifies the direct debit sequence, such as first, recurrent, final or one-off. (Tag: ) 86 | * 87 | * @var string 88 | */ 89 | private $sequenceType = 'FRST'; 90 | 91 | /** 92 | * Date and time at which the creditor requests that the amount of money is to be 93 | * collected from the debtor. (Tag: ) 94 | * 95 | * @var DateTime object 96 | */ 97 | private $requestedCollectionDate = null; 98 | 99 | /** 100 | * Party to which an amount of money is due. (Tag: Nm>) 101 | * 102 | * @var string 103 | */ 104 | private $creditorName = ''; 105 | 106 | /** 107 | * Unambiguous identification of the account of the creditor to which a credit entry will 108 | * be posted as a result of the payment transaction. (Tag: Id->IBAN>) 109 | * 110 | * @var string 111 | */ 112 | private $creditorAccountIBAN = ''; 113 | 114 | /** 115 | * Financial institution servicing an account for the creditor. (Tag: FinInstnId->BIC>) 116 | * 117 | * @var string 118 | */ 119 | private $creditorAgentBIC = ''; 120 | 121 | /** 122 | * Credit party that signs the mandate. (Tag: Id->PrvtId->Othr->Id>) 123 | * 124 | * @var string 125 | */ 126 | private $creditorSchemeIdentification = ''; 127 | 128 | /** 129 | * A container for all transactions within this PaymentInfo. 130 | * 131 | * @var SEPADirectDebitTransaction[] array 132 | */ 133 | private $transactions = array(); 134 | 135 | /** 136 | * Getter for PaymentInformationIdentification (PmtInfId) 137 | * 138 | * @return string 139 | */ 140 | public function getPaymentInformationIdentification() 141 | { 142 | return $this->paymentInformationIdentification; 143 | } 144 | 145 | /** 146 | * Setter for PaymentInformationIdentification (PmtInfId) 147 | * 148 | * @param string $pmtInfId 149 | * @throws SEPAException 150 | */ 151 | public function setPaymentInformationIdentification($pmtInfId) 152 | { 153 | $pmtInfId = URLify::downcode($pmtInfId, "de"); 154 | 155 | if (!preg_match("/^([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|'| ]){1,35}\z/", $pmtInfId)) 156 | throw new SEPAException("PmtInfId empty, contains invalid characters or too long (max. 35)."); 157 | 158 | $this->paymentInformationIdentification = $pmtInfId; 159 | } 160 | 161 | /** 162 | * Getter for BatchBooking (BtchBookg) 163 | * 164 | * @return string 165 | */ 166 | public function getBatchBooking() 167 | { 168 | return $this->batchBooking; 169 | } 170 | 171 | /** 172 | * Setter for BatchBooking (BtchBookg) 173 | * 174 | * @param bool|string $btchBookg 175 | */ 176 | public function setBatchBooking($btchBookg) 177 | { 178 | if ($btchBookg === true || $btchBookg == 'true') 179 | $this->batchBooking = 'true'; 180 | else 181 | $this->batchBooking = 'false'; 182 | } 183 | 184 | /** 185 | * Getter for Number of Transactions (NbOfTxs) 186 | * 187 | * @return int 188 | */ 189 | public function getNumberOfTransactions() 190 | { 191 | return $this->numberOfTransactions; 192 | } 193 | 194 | /** 195 | * Getter for ControlSum (CtrlSum) 196 | * 197 | * @return float 198 | */ 199 | public function getControlSum() 200 | { 201 | return round($this->controlSum, 2); 202 | } 203 | 204 | /** 205 | * Getter for LocalInstrument->Code (LclInstrm->Cd) 206 | * 207 | * @return string 208 | */ 209 | public function getLocalInstrumentCode() 210 | { 211 | return $this->localInstrumentCode; 212 | } 213 | 214 | /** 215 | * Setter for LocalInstrument->Code (LclInstrm->Cd) 216 | * 217 | * @param string $cd 218 | * @throws SEPAException 219 | */ 220 | public function setLocalInstrumentCode($cd) 221 | { 222 | if (!preg_match("/^(B2B|COR1|CORE)\z/", $cd)) 223 | throw new SEPAException("Only 'CORE', 'COR1', or 'B2B' are allowed."); 224 | 225 | $this->localInstrumentCode = $cd; 226 | } 227 | 228 | /** 229 | * Getter for SequenceType (SeqTp) 230 | * 231 | * @return string 232 | */ 233 | public function getSequenceType() 234 | { 235 | return $this->sequenceType; 236 | } 237 | 238 | /** 239 | * Setter for SequenceType (SeqTp) 240 | * 241 | * @param string $seqTp 242 | * @throws SEPAException 243 | */ 244 | public function setSequenceType($seqTp) 245 | { 246 | if (!preg_match("/^(FNAL|FRST|OOFF|RCUR)\z/", $seqTp)) 247 | throw new SEPAException("Only 'FNAL', 'FRST', 'OOFF', or 'RCUR' are allowed."); 248 | 249 | $this->sequenceType = $seqTp; 250 | } 251 | 252 | /** 253 | * Getter for Requested Collection Date (ReqdColltnDt) 254 | * 255 | * @return DateTime object 256 | */ 257 | public function getRequestedCollectionDate() 258 | { 259 | $reqdColltnDt = new DateTime(); 260 | 261 | if (!$this->requestedCollectionDate) 262 | $this->requestedCollectionDate = $reqdColltnDt->format('Y-m-d'); 263 | 264 | return $this->requestedCollectionDate; 265 | } 266 | 267 | /** 268 | * Setter for Requested Collection Date (ReqdColltnDt) 269 | * 270 | * @param string $reqdColltnDt 271 | */ 272 | public function setRequestedCollectionDate($reqdColltnDt) 273 | { 274 | $this->requestedCollectionDate = $reqdColltnDt; 275 | } 276 | 277 | /** 278 | * Getter for Creditor Name (Cdtr->Nm) 279 | * 280 | * @return string 281 | */ 282 | public function getCreditorName() 283 | { 284 | return $this->creditorName; 285 | } 286 | 287 | /** 288 | * Setter for Creditor Name (Cdtr->Nm) 289 | * 290 | * @param string $cdtr 291 | * @throws SEPAException 292 | */ 293 | public function setCreditorName($cdtr) 294 | { 295 | $cdtr = URLify::downcode($cdtr, "de"); 296 | 297 | if (strlen($cdtr) == 0 || strlen($cdtr) > 70) 298 | throw new SEPAException("Invalid creditor name (max. 70 characters)."); 299 | 300 | $this->creditorName = $cdtr; 301 | } 302 | 303 | /** 304 | * Getter for Creditor Account IBAN (CdtrAcct->Id->IBAN) 305 | * 306 | * @return string 307 | */ 308 | public function getCreditorAccountIBAN() 309 | { 310 | return $this->creditorAccountIBAN; 311 | } 312 | 313 | /** 314 | * Setter for Creditor Account IBAN (CdtrAcct->Id->IBAN) 315 | * 316 | * @param string $iban 317 | * @throws SEPAException 318 | */ 319 | public function setCreditorAccountIBAN($iban) 320 | { 321 | $iban = str_replace(' ', '', trim($iban)); 322 | 323 | if (!preg_match("/^[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}\z/i", $iban)) 324 | throw new SEPAException("Invalid creditor IBAN."); 325 | 326 | $this->creditorAccountIBAN = $iban; 327 | } 328 | 329 | /** 330 | * Getter for Creditor Agent BIC (CdtrAgt->FinInstnId->BIC) 331 | * 332 | * @return string 333 | */ 334 | public function getCreditorAgentBIC() 335 | { 336 | return $this->creditorAgentBIC; 337 | } 338 | 339 | /** 340 | * Setter for Creditor Agent BIC (CdtrAgt->FinInstnId->BIC) 341 | * 342 | * @param string $bic 343 | * @throws SEPAException 344 | */ 345 | public function setCreditorAgentBIC($bic) 346 | { 347 | $bic = str_replace(' ', '', trim($bic)); 348 | 349 | if (!preg_match("/^[0-9a-z]{4}[a-z]{2}[0-9a-z]{2}([0-9a-z]{3})?\z/i", $bic)) 350 | throw new SEPAException("Invalid creditor BIC."); 351 | 352 | $this->creditorAgentBIC = $bic; 353 | } 354 | 355 | /** 356 | * Getter for Creditor Scheme Identification (CdtrSchmeId->Id->PrvtId->Othr->Id) 357 | * 358 | * @return string 359 | */ 360 | public function getCreditorSchemeIdentification() 361 | { 362 | return $this->creditorSchemeIdentification; 363 | } 364 | 365 | /** 366 | * Setter for Creditor Scheme Identification (CdtrSchmeId->Id->PrvtId->Othr->Id) 367 | * 368 | * @param string $cdtrSchmeId 369 | * @throws SEPAException 370 | */ 371 | public function setCreditorSchemeIdentification($cdtrSchmeId) 372 | { 373 | if (empty($cdtrSchmeId) || is_null($cdtrSchmeId)) 374 | throw new SEPAException("Invalid CreditorSchemeIdentification."); 375 | 376 | $this->creditorSchemeIdentification = $cdtrSchmeId; 377 | } 378 | 379 | /** 380 | * Adds a transaction object to the list of transactions. 381 | * 382 | * @param SEPADirectDebitTransaction $transaction 383 | */ 384 | public function addTransaction(SEPADirectDebitTransaction $transaction) 385 | { 386 | $this->transactions[] = $transaction; 387 | 388 | $this->numberOfTransactions++; 389 | $this->controlSum += $transaction->getInstructedAmount(); 390 | } 391 | 392 | /** 393 | * Returns a SimpleXMLElement for the SEPAPaymentInfo object. 394 | * 395 | * @return SimpleXMLElement object 396 | */ 397 | public function getXmlPaymentInfo() 398 | { 399 | $xml = new SimpleXMLElement(""); 400 | $xml->addChild('PmtInfId', $this->getPaymentInformationIdentification()); 401 | $xml->addChild('PmtMtd', self::PAYMENT_METHOD); 402 | $xml->addChild('BtchBookg',$this->getBatchBooking()); 403 | $xml->addChild('NbOfTxs', $this->getNumberOfTransactions()); 404 | $xml->addChild('CtrlSum', $this->getControlSum()); 405 | 406 | $xml->addChild('PmtTpInf')->addChild('SvcLvl')->addChild('Cd', self::SERVICELEVEL_CODE); 407 | $xml->PmtTpInf->addChild('LclInstrm')->addChild('Cd', $this->getLocalInstrumentCode()); 408 | $xml->PmtTpInf->addChild('SeqTp', $this->getSequenceType()); 409 | 410 | $xml->addChild('ReqdColltnDt', $this->getRequestedCollectionDate()); 411 | $xml->addChild('Cdtr')->addChild('Nm', $this->getCreditorName()); 412 | $xml->addChild('CdtrAcct')->addChild('Id')->addChild('IBAN', $this->getCreditorAccountIBAN()); 413 | 414 | // The BIC is optional for national payments (IBAN only) 415 | $bic = $this->getCreditorAgentBIC(); 416 | if (!empty($bic)) 417 | $xml->addChild('CdtrAgt')->addChild('FinInstnId')->addChild('BIC', $bic); 418 | else 419 | $xml->addChild('CdtrAgt')->addChild('FinInstnId')->addChild('Othr')->addChild('Id', 'NOTPROVIDED'); 420 | 421 | $xml->addChild('ChrgBr', self::CHARGE_BEARER); 422 | 423 | $othr = $xml->addChild('CdtrSchmeId')->addChild('Id')->addChild('PrvtId')->addChild('Othr'); 424 | $cdtrSchmeId = $this->getCreditorSchemeIdentification(); 425 | if (!empty($cdtrSchmeId)) 426 | $othr->addChild('Id', $this->getCreditorSchemeIdentification()); 427 | 428 | $othr->addChild('SchmeNm')->addChild('Prtry', self::PROPRIETARY_NAME); 429 | 430 | // Add all transactions to the current PaymentInfo block 431 | for ($i = 0; $i < $this->getNumberOfTransactions(); $i++) 432 | { 433 | $domPaymentInfo = dom_import_simplexml($xml); 434 | $domTransaction = dom_import_simplexml($this->transactions[$i]->getXmlDirectDebitTransaction()); 435 | $domPaymentInfo->appendChild($domPaymentInfo->ownerDocument->importNode($domTransaction, true)); 436 | } 437 | $xml->NbOfTxs = $this->getNumberOfTransactions(); 438 | $xml->CtrlSum = $this->getControlSum(); 439 | 440 | return $xml; 441 | } 442 | } 443 | -------------------------------------------------------------------------------- /class.URLify.php: -------------------------------------------------------------------------------- 1 | array ( /* German */ 22 | 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue', 'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss', 23 | 'ẞ' => 'SS' 24 | ), 25 | 'latin' => array ( 26 | 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A','Ă' => 'A', 'Æ' => 'AE', 'Ç' => 27 | 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 28 | 'Ï' => 'I', 'Ð' => 'D', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 29 | 'O', 'Ő' => 'O', 'Ø' => 'O','Ș' => 'S','Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ű' => 'U', 30 | 'Ý' => 'Y', 'Þ' => 'TH', 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 31 | 'a', 'å' => 'a', 'ă' => 'a', 'æ' => 'ae', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 32 | 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 33 | 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ő' => 'o', 'ø' => 'o', 'ș' => 's', 'ț' => 't', 'ù' => 'u', 'ú' => 'u', 34 | 'û' => 'u', 'ü' => 'u', 'ű' => 'u', 'ý' => 'y', 'þ' => 'th', 'ÿ' => 'y' 35 | ), 36 | 'latin_symbols' => array ( 37 | '©' => '(c)' 38 | ), 39 | 'el' => array ( /* Greek */ 40 | 'α' => 'a', 'β' => 'b', 'γ' => 'g', 'δ' => 'd', 'ε' => 'e', 'ζ' => 'z', 'η' => 'h', 'θ' => '8', 41 | 'ι' => 'i', 'κ' => 'k', 'λ' => 'l', 'μ' => 'm', 'ν' => 'n', 'ξ' => '3', 'ο' => 'o', 'π' => 'p', 42 | 'ρ' => 'r', 'σ' => 's', 'τ' => 't', 'υ' => 'y', 'φ' => 'f', 'χ' => 'x', 'ψ' => 'ps', 'ω' => 'w', 43 | 'ά' => 'a', 'έ' => 'e', 'ί' => 'i', 'ό' => 'o', 'ύ' => 'y', 'ή' => 'h', 'ώ' => 'w', 'ς' => 's', 44 | 'ϊ' => 'i', 'ΰ' => 'y', 'ϋ' => 'y', 'ΐ' => 'i', 45 | 'Α' => 'A', 'Β' => 'B', 'Γ' => 'G', 'Δ' => 'D', 'Ε' => 'E', 'Ζ' => 'Z', 'Η' => 'H', 'Θ' => '8', 46 | 'Ι' => 'I', 'Κ' => 'K', 'Λ' => 'L', 'Μ' => 'M', 'Ν' => 'N', 'Ξ' => '3', 'Ο' => 'O', 'Π' => 'P', 47 | 'Ρ' => 'R', 'Σ' => 'S', 'Τ' => 'T', 'Υ' => 'Y', 'Φ' => 'F', 'Χ' => 'X', 'Ψ' => 'PS', 'Ω' => 'W', 48 | 'Ά' => 'A', 'Έ' => 'E', 'Ί' => 'I', 'Ό' => 'O', 'Ύ' => 'Y', 'Ή' => 'H', 'Ώ' => 'W', 'Ϊ' => 'I', 49 | 'Ϋ' => 'Y' 50 | ), 51 | 'tr' => array ( /* Turkish */ 52 | 'ş' => 's', 'Ş' => 'S', 'ı' => 'i', 'İ' => 'I', 'ç' => 'c', 'Ç' => 'C', 'ü' => 'u', 'Ü' => 'U', 53 | 'ö' => 'o', 'Ö' => 'O', 'ğ' => 'g', 'Ğ' => 'G' 54 | ), 55 | 'ru' => array ( /* Russian */ 56 | 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 'ж' => 'zh', 57 | 'з' => 'z', 'и' => 'i', 'й' => 'j', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o', 58 | 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 59 | 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sh', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu', 60 | 'я' => 'ya', 61 | 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'Yo', 'Ж' => 'Zh', 62 | 'З' => 'Z', 'И' => 'I', 'Й' => 'J', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O', 63 | 'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C', 64 | 'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sh', 'Ъ' => '', 'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'Yu', 65 | 'Я' => 'Ya', 66 | '№' => '' 67 | ), 68 | 'uk' => array ( /* Ukrainian */ 69 | 'Є' => 'Ye', 'І' => 'I', 'Ї' => 'Yi', 'Ґ' => 'G', 'є' => 'ye', 'і' => 'i', 'ї' => 'yi', 'ґ' => 'g' 70 | ), 71 | 'cs' => array ( /* Czech */ 72 | 'č' => 'c', 'ď' => 'd', 'ě' => 'e', 'ň' => 'n', 'ř' => 'r', 'š' => 's', 'ť' => 't', 'ů' => 'u', 73 | 'ž' => 'z', 'Č' => 'C', 'Ď' => 'D', 'Ě' => 'E', 'Ň' => 'N', 'Ř' => 'R', 'Š' => 'S', 'Ť' => 'T', 74 | 'Ů' => 'U', 'Ž' => 'Z' 75 | ), 76 | 'pl' => array ( /* Polish */ 77 | 'ą' => 'a', 'ć' => 'c', 'ę' => 'e', 'ł' => 'l', 'ń' => 'n', 'ó' => 'o', 'ś' => 's', 'ź' => 'z', 78 | 'ż' => 'z', 'Ą' => 'A', 'Ć' => 'C', 'Ę' => 'e', 'Ł' => 'L', 'Ń' => 'N', 'Ó' => 'O', 'Ś' => 'S', 79 | 'Ź' => 'Z', 'Ż' => 'Z' 80 | ), 81 | 'ro' => array ( /* Romanian */ 82 | 'ă' => 'a', 'â' => 'a', 'î' => 'i', 'ș' => 's', 'ț' => 't' 83 | ), 84 | 'lv' => array ( /* Latvian */ 85 | 'ā' => 'a', 'č' => 'c', 'ē' => 'e', 'ģ' => 'g', 'ī' => 'i', 'ķ' => 'k', 'ļ' => 'l', 'ņ' => 'n', 86 | 'š' => 's', 'ū' => 'u', 'ž' => 'z', 'Ā' => 'A', 'Č' => 'C', 'Ē' => 'E', 'Ģ' => 'G', 'Ī' => 'i', 87 | 'Ķ' => 'k', 'Ļ' => 'L', 'Ņ' => 'N', 'Š' => 'S', 'Ū' => 'u', 'Ž' => 'Z' 88 | ), 89 | 'lt' => array ( /* Lithuanian */ 90 | 'ą' => 'a', 'č' => 'c', 'ę' => 'e', 'ė' => 'e', 'į' => 'i', 'š' => 's', 'ų' => 'u', 'ū' => 'u', 'ž' => 'z', 91 | 'Ą' => 'A', 'Č' => 'C', 'Ę' => 'E', 'Ė' => 'E', 'Į' => 'I', 'Š' => 'S', 'Ų' => 'U', 'Ū' => 'U', 'Ž' => 'Z' 92 | ), 93 | 'entities' => array ( /* some special chars */ 94 | '&' => '&', 95 | '<' => '<', 96 | '>' => '>', 97 | '"' => '"', 98 | '\'' => ''' 99 | ) 100 | ); 101 | 102 | /** 103 | * List of words to remove from URLs. 104 | */ 105 | public static $remove_list = array ( 106 | 'a', 'an', 'as', 'at', 'before', 'but', 'by', 'for', 'from', 107 | 'is', 'in', 'into', 'like', 'of', 'off', 'on', 'onto', 'per', 108 | 'since', 'than', 'the', 'this', 'that', 'to', 'up', 'via', 109 | 'with' 110 | ); 111 | 112 | /** 113 | * The character map. 114 | */ 115 | private static $map = array (); 116 | 117 | /** 118 | * The character list as a string. 119 | */ 120 | private static $chars = ''; 121 | 122 | /** 123 | * The character list as a regular expression. 124 | */ 125 | private static $regex = ''; 126 | 127 | /** 128 | * The current language 129 | */ 130 | private static $language = ''; 131 | 132 | /** 133 | * Initializes the character map. 134 | */ 135 | private static function init ($language = "") { 136 | if (count (self::$map) > 0 && (($language == "") || ($language == self::$language))) { 137 | return; 138 | } 139 | 140 | /* Is a specific map associated with $language ? */ 141 | if (isset(self::$maps[$language]) && is_array(self::$maps[$language])) { 142 | /* Move this map to end. This means it will have priority over others */ 143 | $m = self::$maps[$language]; 144 | unset(self::$maps[$language]); 145 | self::$maps[$language] = $m; 146 | } 147 | /* Reset static vars */ 148 | self::$language = $language; 149 | self::$map = array(); 150 | self::$chars = ''; 151 | 152 | foreach (self::$maps as $map) { 153 | foreach ($map as $orig => $conv) { 154 | self::$map[$orig] = $conv; 155 | self::$chars .= $orig; 156 | } 157 | } 158 | 159 | self::$regex = '/[' . self::$chars . ']/u'; 160 | } 161 | 162 | /** 163 | * Add new characters to the list. `$map` should be a hash. 164 | */ 165 | public static function add_chars ($map) { 166 | if (! is_array ($map)) { 167 | throw new LogicException ('$map must be an associative array.'); 168 | } 169 | self::$maps[] = $map; 170 | self::$map = array (); 171 | self::$chars = ''; 172 | } 173 | 174 | /** 175 | * Append words to the remove list. Accepts either single words 176 | * or an array of words. 177 | */ 178 | public static function remove_words ($words) { 179 | $words = is_array ($words) ? $words : array ($words); 180 | self::$remove_list = array_merge (self::$remove_list, $words); 181 | } 182 | 183 | /** 184 | * Transliterates characters to their ASCII equivalents. 185 | * $language specifies a priority for a specific language. 186 | * The latter is useful if languages have different rules for the same character. 187 | */ 188 | public static function downcode ($text, $language = "") { 189 | self::init ($language); 190 | 191 | if (preg_match_all (self::$regex, $text, $matches)) { 192 | for ($i = 0; $i < count ($matches[0]); $i++) { 193 | $char = $matches[0][$i]; 194 | if (isset (self::$map[$char])) { 195 | $text = str_replace ($char, self::$map[$char], $text); 196 | } 197 | } 198 | } 199 | return $text; 200 | } 201 | 202 | /** 203 | * Filters a string, e.g., "Petty theft" to "petty-theft" 204 | */ 205 | public static function filter ($text, $length = 60, $language = "", $file_name = false) { 206 | $text = self::downcode ($text,$language); 207 | 208 | // remove all these words from the string before urlifying 209 | $text = preg_replace ('/\b(' . join ('|', self::$remove_list) . ')\b/i', '', $text); 210 | 211 | // if downcode doesn't hit, the char will be stripped here 212 | $remove_pattern = ($file_name) ? '/[^-.\w\s]/' : '/[^-\w\s]/'; 213 | $text = preg_replace ($remove_pattern, '', $text); // remove unneeded chars 214 | $text = str_replace ('_', ' ', $text); // treat underscores as spaces 215 | $text = preg_replace ('/^\s+|\s+$/', '', $text); // trim leading/trailing spaces 216 | $text = preg_replace ('/[-\s]+/', '-', $text); // convert spaces to hyphens 217 | $text = strtolower ($text); // convert to lowercase 218 | return trim (substr ($text, 0, $length), '-'); // trim to first $length chars 219 | } 220 | 221 | /** 222 | * Alias of `URLify::downcode()`. 223 | */ 224 | public static function transliterate ($text) { 225 | return self::downcode ($text); 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright http://www.web-wack.at web wack creations 7 | * @license http://creativecommons.org/licenses/by-nc/3.0/ CC Attribution-NonCommercial 3.0 license 8 | * For commercial use please contact sales@web-wack.at 9 | */ 10 | 11 | require_once('class.SEPADirectDebitTransaction.php'); 12 | require_once('class.SEPAException.php'); 13 | require_once('class.SEPAGroupHeader.php'); 14 | require_once('class.SEPAMessage.php'); 15 | require_once('class.SEPAPaymentInfo.php'); 16 | require_once('class.URLify.php'); 17 | 18 | $message = new SEPAMessage('urn:iso:std:iso:20022:tech:xsd:pain.008.001.02'); 19 | $groupHeader = new SEPAGroupHeader(); // (1..1) 20 | $groupHeader->setMessageIdentification('SEPA-'.time()); // Unique ID for this job 21 | $groupHeader->setInitiatingPartyName('Web wack creations'); // Name of the party sending the job. Usually the creditor 22 | $message->setGroupHeader($groupHeader); 23 | 24 | $paymentInfo = new SEPAPaymentInfo(); // (1..n) 25 | $paymentInfo->setPaymentInformationIdentification(1); // Your own unique identifier for this batch 26 | $paymentInfo->setBatchBooking('false'); 27 | $paymentInfo->setLocalInstrumentCode('CORE'); // Other options: COR1, B2B 28 | // Type of the job and execution date 29 | $paymentInfo->setSequenceType('RCUR'); 30 | // CORE: FRST: +6 days, RCUR: +3 days, FNAL: +3 days, OOFF: +6 days 31 | // B2B: All +2 days 32 | $paymentInfo->setRequestedCollectionDate(date('Y-m-d', strtotime('+3 days'))); 33 | // Account on which payment should be recieved 34 | $paymentInfo->setCreditorName('Your creditor name'); 35 | $paymentInfo->setCreditorAccountIBAN('DE89370400440532013000'); 36 | $paymentInfo->setCreditorAgentBIC('PBNKDEFF760'); 37 | $paymentInfo->setCreditorSchemeIdentification('DE22ZZZ00000012345'); 38 | 39 | $transaction = new SEPADirectDebitTransaction(); // (1..n) 40 | $transaction->setEndToEndIdentification('blablaTest124'); // Unique transaction identifier (shown to the debtor) 41 | $transaction->setInstructedAmount(0.12); 42 | $transaction->setMandateIdentification('AT5f6789'); // Shown to the debtor 43 | $transaction->setDateOfSignature('2013-03-01'); 44 | $transaction->setAmendmentIndicator('false'); 45 | $transaction->setDebtorName('The debtor name'); 46 | $transaction->setDebtorIban('AT611904300234573201'); 47 | $transaction->setDebtorAgentBIC('INGBATWW'); 48 | $transaction->setRemittanceInformation('Invoice 1234'); // Shown to the debtor 49 | $paymentInfo->addTransaction($transaction); 50 | 51 | $message->addPaymentInfo($paymentInfo); 52 | 53 | //if ($message->validateXML('validation_schemes/pain.008.001.02_GBIC_3.xsd')) 54 | echo $message->printXML(); 55 | -------------------------------------------------------------------------------- /validation_schemes/pain.008.001.02.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | -------------------------------------------------------------------------------- /validation_schemes/pain.008.001.02_GBIC_1.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Mandatory if changes occur in ‘Mandate Identification’, otherwise not to be used. 56 | 57 | 58 | 59 | 60 | Mandatory if changes occur in 'Creditor Scheme Identification', otherwise not to be used. 61 | 62 | 63 | 64 | 65 | Mandatory if changes occur in debtor account, otherwise not to be used. 66 | 67 | 68 | 69 | 70 | If changes occur in debtor agent and SMNDA is NOT used in OrgnlDbtrAcct 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | If a Creditor Reference contains a check digit, the receiving bank is not required to validate this. 135 | If the receiving bank validates the check digit and if this validation fails, the bank may continue its processing and send the transaction to the next party in the chain. 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 177 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 178 | Transaction’ level. 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | It is recommended that this element be specified at ‘Payment Information’ level. 190 | 191 | 192 | 193 | 194 | 195 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | Mandatory if provided by the debtor in the mandate. 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | Mandatory if 'Amendment Indicator' is 'TRUE' 342 | The reason code from the Rulebook is indicated using one of the following message subelements. 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | Either ‘BIC or BEI’ or one 405 | occurrence of ‘Other’ is allowed. 406 | 407 | 408 | 409 | 410 | Either ‘Date and Place of Birth’ or one occurrence of ‘Other’ is allowed 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | Private Identification is used to identify either an organisation or a private 421 | person. 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | ‘Name’ is limited to 70 characters in length. 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | ‘Name’ is limited to 70 characters in length. 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | If present the new’ Name’ must be specified under ‘Creditor’. ‘Name’ is limited to 70 characters in length. 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | ‘Name’ is limited to 70 characters in length. 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | If present and contains ‘true’, batch booking is requested. If present and contains ‘false’, booking per transaction is requested. If element is not present, pre-agreed customer-to-bank conditions apply. 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 497 | 498 | 499 | 500 | 501 | It is recommended that this element be specified at ‘Payment Information’ level. 502 | 503 | 504 | 505 | 506 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 507 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 508 | Transaction’ level. 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | Only ‘B2B’ and 'CORE' is allowed. The mixing of different Local Instrument values is not allowed in the same message. 525 | 526 | 527 | 528 | 529 | 530 | Depending on the agreement between the Creditor and the Creditor Bank, ‘Category Purpose’ may be forwarded to the Debtor Bank. 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | Only one occurrence of ‘Other’ is allowed, and no other sub-elements are allowed. 548 | Identification must be used with an identifier described in General Message Element Specifications, Chapter 1.5.2 of the Implementation Guide. 549 | Scheme Name’ under ‘Other’ must specify ‘SEPA’ under ‘Proprietary 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | Only codes from the ISO 20022 ExternalPurposeCode list are allowed. 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | When present, the receiving bank is not obliged to validate the reference information. 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | -------------------------------------------------------------------------------- /validation_schemes/pain.008.001.02_GBIC_2.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Mandatory if changes occur in ‘Mandate Identification’, otherwise not to be used. 57 | 58 | 59 | 60 | 61 | Mandatory if changes occur in 'Creditor Scheme Identification', otherwise not to be used. 62 | 63 | 64 | 65 | 66 | Mandatory if changes occur in debtor account, otherwise not to be used. 67 | 68 | 69 | 70 | 71 | If changes occur in debtor agent and SMNDA is NOT used in OrgnlDbtrAcct 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | If a Creditor Reference contains a check digit, the receiving bank is not required to validate this. 136 | If the receiving bank validates the check digit and if this validation fails, the bank may continue its processing and send the transaction to the next party in the chain. 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 178 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 179 | Transaction’ level. 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | It is recommended that this element be specified at ‘Payment Information’ level. 192 | 193 | 194 | 195 | 196 | 197 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | Mandatory if provided by the debtor in the mandate. 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | Mandatory if 'Amendment Indicator' is 'TRUE' 344 | The reason code from the Rulebook is indicated using one of the following message subelements. 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | Either ‘BIC or BEI’ or one 407 | occurrence of ‘Other’ is allowed. 408 | 409 | 410 | 411 | 412 | Either ‘Date and Place of Birth’ or one occurrence of ‘Other’ is allowed 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | Private Identification is used to identify either an organisation or a private 423 | person. 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | ‘Name’ is limited to 70 characters in length. 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | ‘Name’ is limited to 70 characters in length. 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | If present the new’ Name’ must be specified under ‘Creditor’. ‘Name’ is limited to 70 characters in length. 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | ‘Name’ is limited to 70 characters in length. 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | If present and contains ‘true’, batch booking is requested. If present and contains ‘false’, booking per transaction is requested. If element is not present, pre-agreed customer-to-bank conditions apply. 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 499 | 500 | 501 | 502 | 503 | It is recommended that this element be specified at ‘Payment Information’ level. 504 | 505 | 506 | 507 | 508 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 509 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 510 | Transaction’ level. 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | Only ‘B2B’ and 'CORE' is allowed. The mixing of different Local Instrument values is not allowed in the same message. 527 | 528 | 529 | 530 | 531 | 532 | Depending on the agreement between the Creditor and the Creditor Bank, ‘Category Purpose’ may be forwarded to the Debtor Bank. 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | Only one occurrence of ‘Other’ is allowed, and no other sub-elements are allowed. 550 | Identification must be used with an identifier described in General Message Element Specifications, Chapter 1.5.2 of the Implementation Guide. 551 | Scheme Name’ under ‘Other’ must specify ‘SEPA’ under ‘Proprietary 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | Only codes from the ISO 20022 ExternalPurposeCode list are allowed. 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | When present, the receiving bank is not obliged to validate the reference information. 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | -------------------------------------------------------------------------------- /validation_schemes/pain.008.001.02_GBIC_3.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Mandatory if changes occur in ‘Mandate Identification’, otherwise not to be used. 55 | 56 | 57 | 58 | 59 | Mandatory if changes occur in 'Creditor Scheme Identification', otherwise not to be used. 60 | 61 | 62 | 63 | 64 | Mandatory if changes occur in debtor account, otherwise not to be used. 65 | 66 | 67 | 68 | 69 | If changes occur in debtor agent and SMNDA is NOT used in OrgnlDbtrAcct 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | If a Creditor Reference contains a check digit, the receiving bank is not required to validate this. 134 | If the receiving bank validates the check digit and if this validation fails, the bank may continue its processing and send the transaction to the next party in the chain. 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 176 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 177 | Transaction’ level. 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | It is recommended that this element be specified at ‘Payment Information’ level. 190 | 191 | 192 | 193 | 194 | 195 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | Mandatory if provided by the debtor in the mandate. 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | Mandatory if 'Amendment Indicator' is 'TRUE' 342 | The reason code from the Rulebook is indicated using one of the following message subelements. 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | Either ‘BIC or BEI’ or one 405 | occurrence of ‘Other’ is allowed. 406 | 407 | 408 | 409 | 410 | Either ‘Date and Place of Birth’ or one occurrence of ‘Other’ is allowed 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | Private Identification is used to identify either an organisation or a private 421 | person. 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | ‘Name’ is limited to 70 characters in length. 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | ‘Name’ is limited to 70 characters in length. 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | If present the new’ Name’ must be specified under ‘Creditor’. ‘Name’ is limited to 70 characters in length. 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | ‘Name’ is limited to 70 characters in length. 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | If present and contains ‘true’, batch booking is requested. If present and contains ‘false’, booking per transaction is requested. If element is not present, pre-agreed customer-to-bank conditions apply. 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 497 | 498 | 499 | 500 | 501 | It is recommended that this element be specified at ‘Payment Information’ level. 502 | 503 | 504 | 505 | 506 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 507 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 508 | Transaction’ level. 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | Only ‘B2B’ and 'CORE' is allowed. The mixing of different Local Instrument values is not allowed in the same message. 525 | 526 | 527 | 528 | 529 | 530 | Depending on the agreement between the Creditor and the Creditor Bank, ‘Category Purpose’ may be forwarded to the Debtor Bank. 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | Only one occurrence of ‘Other’ is allowed, and no other sub-elements are allowed. 548 | Identification must be used with an identifier described in General Message Element Specifications, Chapter 1.5.2 of the Implementation Guide. 549 | Scheme Name’ under ‘Other’ must specify ‘SEPA’ under ‘Proprietary 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | Only codes from the ISO 20022 ExternalPurposeCode list are allowed. 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | When present, the receiving bank is not obliged to validate the reference information. 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | -------------------------------------------------------------------------------- /validation_schemes/pain.008.003.02.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Mandatory if changes occur in ‘Mandate Identification’, otherwise not to be used. 42 | 43 | 44 | 45 | 46 | Mandatory if changes occur in 'Creditor Scheme Identification', otherwise not to be used. 47 | 48 | 49 | 50 | 51 | To be used only for changes of accounts within the same bank. 52 | 53 | 54 | 55 | 56 | To use 'Identification’ under 'Other' under 'Financial Institution Identifier with code ‘SMNDA’ to indicate same mandate with new Debtor Agent. To be used with the ‘FRST’ indicator in the ‘Sequence Type’. 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | If a Creditor Reference contains a check digit, the receiving bank is not required to validate this. 116 | If the receiving bank validates the check digit and if this validation fails, the bank may continue its processing and send the transaction to the next party in the chain. 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 158 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 159 | Transaction’ level. 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | It is recommended that this element be specified at ‘Payment Information’ level. 171 | 172 | 173 | 174 | 175 | 176 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | Mandatory if provided by the debtor in the mandate. 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | Mandatory if 'Amendment Indicator' is 'TRUE' 328 | The reason code from the Rulebook is indicated using one of the following message subelements. 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | Either ‘BIC or BEI’ or one 385 | occurrence of ‘Other’ is allowed. 386 | 387 | 388 | 389 | 390 | Either ‘Date and Place of Birth’ or one occurrence of ‘Other’ is allowed 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | Private Identification is used to identify either an organisation or a private 401 | person. 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | ‘Name’ is limited to 70 characters in length. 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | ‘Name’ is limited to 70 characters in length. 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | If present the new’ Name’ must be specified under ‘Creditor’. ‘Name’ is limited to 70 characters in length. 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | ‘Name’ is limited to 70 characters in length. 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | If present and contains ‘true’, batch booking is requested. If present and contains ‘false’, booking per transaction is requested. If element is not present, pre-agreed customer-to-bank conditions apply. 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | This data element may be present either at ‘Payment Information’ or at ‘Direct Debit Transaction Information’ level. 477 | 478 | 479 | 480 | 481 | It is recommended that this element be specified at ‘Payment Information’ level. 482 | 483 | 484 | 485 | 486 | It is recommended that all transactions within the same ‘Payment Information’ block have the same ‘Creditor Scheme Identification’. 487 | This data element must be present at either ‘Payment Information’ or ‘Direct Debit 488 | Transaction’ level. 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | Only ‘B2B’, 'CORE' or 'COR1' is allowed. The mixing of different Local Instrument values is not allowed in the same message. 505 | 506 | 507 | 508 | 509 | If 'Amendment Indicator' is 'true' and 'Original Debtor Agent' is set to 'SMNDA' this message element must indicate 'FRST' 510 | 511 | 512 | 513 | 514 | Depending on the agreement between the Creditor and the Creditor Bank, ‘Category Purpose’ may be forwarded to the Debtor Bank. 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | Only one occurrence of ‘Other’ is allowed, and no other sub-elements are allowed. 532 | Identification must be used with an identifier described in General Message Element Specifications, Chapter 1.5.2 of the Implementation Guide. 533 | Scheme Name’ under ‘Other’ must specify ‘SEPA’ under ‘Proprietary 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | Only codes from the ISO 20022 ExternalPurposeCode list are allowed. 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | When present, the receiving bank is not obliged to validate the reference information. 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | --------------------------------------------------------------------------------