SEPAPython XML Generator
========================
This is a python implementation to generate SEPA XML files.
Limitations
-----------
Supported standards:
* SEPA PAIN.001.001.03 (v2009)
* SEPA PAIN.001.001.09 (v2019)
* SEPA PAIN.001.001.10
* SEPA PAIN.001.001.11
* SEPA PAIN.008.001.02 (v2009)
* SEPA PAIN.008.001.08 (v2019)
* SEPA PAIN.008.001.09
* SEPA PAIN.008.001.10
Usage
-----
Direct debit (SDD)
""""""""""""""""""
Example:
.. code:: python
from sepapy import SepaDebit
import datetime, uuid
config = {
"msg_id": "EXAMPLE-SDD-PAIN88-TEST",
"name": "Musée du SEPA",
"IBAN": "FR7610071750000012345678944",
"BIC": "TRPUFRP1",
"batch": True,
"creditor_id": "FR82ZZZ00000000000", # Identifier Creditor SEPA (ICS), supplied by your bank or financial authority
"currency": "EUR", # ISO 4217
# "instrument": "B2B", # - default is CORE (B2C)
"address": {
# The address and all of its fields are optional but in some countries they are required
"department": "Bureau de la conservation",
"subdepartment": None,
"street_name": "rue de la Banque",
"building_number": "666",
"postcode": "75002",
"town": "Paris",
"country": "FR",
"country_subdivision": None,
},
}
sepa = SepaDebit(config, schema="pain.008.001.08", clean=True)
payment1 = {
"name": "Client Lambda",
"IBAN": "FR7610107012340012345678952",
"BIC": "BREDFRPPXXX",
"amount": 5000, # in cents
"type": "RCUR", # FRST,RCUR,OOFF,FNAL
"collection_date": datetime.date.today(),
"mandate_id": "1234",
"mandate_date": datetime.date.today(),
"description": "Test transaction",
"endtoend_id": "AC12345678-DFT-SDD-25001-001", #str(uuid.uuid1()).replace("-", ""), # autogenerated if obmitted
"address": {
# The address and all of its fields are optional but in some countries they are required
"lines": ["1 rue du Client", "59000 Lille"],
},
}
payment2 = {
"name": "SARL Lambda",
"IBAN": "FR7620041010059876543210065",
"BIC": "PSSTFRPPXXX",
"amount": 5000, # in cents
"type": "RCUR", # FRST,RCUR,OOFF,FNAL
"collection_date": datetime.date.today(),
"mandate_id": "1234",
"mandate_date": datetime.date.today(),
"description": "Test transaction",
"endtoend_id": "AC12345678-DFT-SDD-25001-002", #str(uuid.uuid1()).replace("-", ""), # autogenerated if obmitted
"address": {
# The address and all of its fields are optional but in some countries they are required
"department": "Comptabilite",
"subdepartment": None,
"street_name": "rue des Immeubles-Industriels",
"building_number": "123",
"postcode": "75011",
"town": "Paris",
"country": "FR",
"country_subdivision": None,
},
}
sepa.add_payment(payment1)
sepa.add_payment(payment2)
print(sepa.export(validate=True, pretty_print=True))
Credit transfer (SCT)
"""""""""""""""""""""
Example:
.. code:: python
from sepapy import SepaCredit
import datetime, uuid
config = {
"msg_id": "EXAMPLE-SCT-PAIN19-TEST",
"name": "Test von Testenstein",
"IBAN": "NL50BANK1234567890",
"BIC": "BANKNL2A",
"batch": True,
# For non-SEPA transfers, set "domestic" to True, necessary e.g. for CH/LI
"currency": "EUR", # ISO 4217
"address": {
# The address and all of its fields are optional but in some countries they are required
"address_type": "ADDR", # valid: ADDR, PBOX, HOME, BIZZ, MLTO, DLVY
"department": "Head Office",
"subdepartment": None,
"street_name": "Musterstr.",
"building_number": "1",
"postcode": "12345",
"town": "Berlin",
"country": "DE",
"country_subdivision": None,
"lines": ["Line 1", "Line 2"],
},
}
sepa = SepaCredit(config, clean=True)
payment = {
"name": "Test von Testenstein",
"IBAN": "NL50BANK1234567890",
"BIC": "BANKNL2A",
"amount": 5000, # in cents
"execution_date": datetime.date.today() + datetime.timedelta(days=2),
"description": "Test transaction",
# "endtoend_id": str(uuid.uuid1()).replace("-", ""), # optional
"address": {
# The address and all of its fields are optional but in some countries they are required
"address_type": "ADDR", # valid: ADDR, PBOX, HOME, BIZZ, MLTO, DLVY
"department": "Head Office",
"subdepartment": None,
"street_name": "Musterstr.",
"building_number": "1",
"postcode": "12345",
"town": "Berlin",
"country": "DE",
"country_subdivision": None,
"lines": ["Line 1", "Line 2"],
},
}
sepa.add_payment(payment)
print(sepa.export(validate=True, pretty_print=True))
Development
-----------
To run the included tests::
pip install -r requirements_dev.txt
py.test tests
Credits and License
-------------------
Maintainer: Philippe-Alexandre PIERRE <pap@httpap.dev>
This basically started as a properly packaged, python 3 tested version
of the `PySepaDD`_ implementation that was released by The Congressus under the MIT license.
Thanks for your work!
This basically continued as a properly packaged, python 3 tested version
of the `python-sepaxml`_ implementation that was released by aphael Michel under the MIT license.
Thanks for your work!
The source code is released under MIT license.
Not part of the MIT-licensed project are the XML schemas in the ``sepaxml/schemas/``
folder which are copyrighted by the ISO 20022 organization but `allowed to be reproduced`_
freely.
.. _PySepaDD: https://github.com/congressus/PySepaDD
.. _python-sepaxml: https://github.com/raphaelm/python-sepaxml
.. _allowed to be reproduced: https://www.iso20022.org/terms-use
Raw data
{
"_id": null,
"home_page": null,
"name": "sepapy",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": "Philippe-Alexandre Pierre <pap@httpap.dev>",
"keywords": "banking, credit, debit, iso20022, sepa, xml, xsd",
"author": null,
"author_email": "Raphael Michel <mail@raphaelmichel.de>",
"download_url": "https://files.pythonhosted.org/packages/29/e1/c2d85e38e2387dcf180211750a7065d8f31b8cc2dc4948a8210f1b5a032c/sepapy-2.6.3.tar.gz",
"platform": null,
"description": "SEPAPython XML Generator\n========================\n\nThis is a python implementation to generate SEPA XML files.\n\nLimitations\n-----------\n\nSupported standards:\n\n* SEPA PAIN.001.001.03 (v2009)\n* SEPA PAIN.001.001.09 (v2019)\n* SEPA PAIN.001.001.10\n* SEPA PAIN.001.001.11\n* SEPA PAIN.008.001.02 (v2009)\n* SEPA PAIN.008.001.08 (v2019)\n* SEPA PAIN.008.001.09\n* SEPA PAIN.008.001.10\n\nUsage\n-----\n\nDirect debit (SDD)\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nExample:\n\n.. code:: python\n\n from sepapy import SepaDebit\n import datetime, uuid\n\n config = {\n \"msg_id\": \"EXAMPLE-SDD-PAIN88-TEST\",\n \"name\": \"Mus\u00e9e du SEPA\",\n \"IBAN\": \"FR7610071750000012345678944\",\n \"BIC\": \"TRPUFRP1\",\n \"batch\": True,\n \"creditor_id\": \"FR82ZZZ00000000000\", # Identifier Creditor SEPA (ICS), supplied by your bank or financial authority\n \"currency\": \"EUR\", # ISO 4217\n # \"instrument\": \"B2B\", # - default is CORE (B2C)\n \"address\": {\n # The address and all of its fields are optional but in some countries they are required\n \"department\": \"Bureau de la conservation\",\n \"subdepartment\": None,\n \"street_name\": \"rue de la Banque\",\n \"building_number\": \"666\",\n \"postcode\": \"75002\",\n \"town\": \"Paris\",\n \"country\": \"FR\",\n \"country_subdivision\": None,\n },\n }\n sepa = SepaDebit(config, schema=\"pain.008.001.08\", clean=True)\n\n payment1 = {\n \"name\": \"Client Lambda\",\n \"IBAN\": \"FR7610107012340012345678952\",\n \"BIC\": \"BREDFRPPXXX\",\n \"amount\": 5000, # in cents\n \"type\": \"RCUR\", # FRST,RCUR,OOFF,FNAL\n \"collection_date\": datetime.date.today(),\n \"mandate_id\": \"1234\",\n \"mandate_date\": datetime.date.today(),\n \"description\": \"Test transaction\",\n \"endtoend_id\": \"AC12345678-DFT-SDD-25001-001\", #str(uuid.uuid1()).replace(\"-\", \"\"), # autogenerated if obmitted\n \"address\": {\n # The address and all of its fields are optional but in some countries they are required\n \"lines\": [\"1 rue du Client\", \"59000 Lille\"],\n },\n }\n\n payment2 = {\n \"name\": \"SARL Lambda\",\n \"IBAN\": \"FR7620041010059876543210065\",\n \"BIC\": \"PSSTFRPPXXX\",\n \"amount\": 5000, # in cents\n \"type\": \"RCUR\", # FRST,RCUR,OOFF,FNAL\n \"collection_date\": datetime.date.today(),\n \"mandate_id\": \"1234\",\n \"mandate_date\": datetime.date.today(),\n \"description\": \"Test transaction\",\n \"endtoend_id\": \"AC12345678-DFT-SDD-25001-002\", #str(uuid.uuid1()).replace(\"-\", \"\"), # autogenerated if obmitted\n \"address\": {\n # The address and all of its fields are optional but in some countries they are required\n \"department\": \"Comptabilite\",\n \"subdepartment\": None,\n \"street_name\": \"rue des Immeubles-Industriels\",\n \"building_number\": \"123\",\n \"postcode\": \"75011\",\n \"town\": \"Paris\",\n \"country\": \"FR\",\n \"country_subdivision\": None,\n },\n }\n\n sepa.add_payment(payment1)\n sepa.add_payment(payment2)\n\n print(sepa.export(validate=True, pretty_print=True))\n\n\nCredit transfer (SCT)\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nExample:\n\n.. code:: python\n\n from sepapy import SepaCredit\n import datetime, uuid\n\n config = {\n \"msg_id\": \"EXAMPLE-SCT-PAIN19-TEST\",\n \"name\": \"Test von Testenstein\",\n \"IBAN\": \"NL50BANK1234567890\",\n \"BIC\": \"BANKNL2A\",\n \"batch\": True,\n # For non-SEPA transfers, set \"domestic\" to True, necessary e.g. for CH/LI\n \"currency\": \"EUR\", # ISO 4217\n \"address\": {\n # The address and all of its fields are optional but in some countries they are required\n \"address_type\": \"ADDR\", # valid: ADDR, PBOX, HOME, BIZZ, MLTO, DLVY\n \"department\": \"Head Office\",\n \"subdepartment\": None,\n \"street_name\": \"Musterstr.\",\n \"building_number\": \"1\",\n \"postcode\": \"12345\",\n \"town\": \"Berlin\",\n \"country\": \"DE\",\n \"country_subdivision\": None,\n \"lines\": [\"Line 1\", \"Line 2\"],\n },\n }\n sepa = SepaCredit(config, clean=True)\n\n payment = {\n \"name\": \"Test von Testenstein\",\n \"IBAN\": \"NL50BANK1234567890\",\n \"BIC\": \"BANKNL2A\",\n \"amount\": 5000, # in cents\n \"execution_date\": datetime.date.today() + datetime.timedelta(days=2),\n \"description\": \"Test transaction\",\n # \"endtoend_id\": str(uuid.uuid1()).replace(\"-\", \"\"), # optional\n \"address\": {\n # The address and all of its fields are optional but in some countries they are required\n \"address_type\": \"ADDR\", # valid: ADDR, PBOX, HOME, BIZZ, MLTO, DLVY\n \"department\": \"Head Office\",\n \"subdepartment\": None,\n \"street_name\": \"Musterstr.\",\n \"building_number\": \"1\",\n \"postcode\": \"12345\",\n \"town\": \"Berlin\",\n \"country\": \"DE\",\n \"country_subdivision\": None,\n \"lines\": [\"Line 1\", \"Line 2\"],\n },\n }\n sepa.add_payment(payment)\n\n print(sepa.export(validate=True, pretty_print=True))\n\n\nDevelopment\n-----------\n\nTo run the included tests::\n\n pip install -r requirements_dev.txt\n py.test tests\n\n\nCredits and License\n-------------------\n\nMaintainer: Philippe-Alexandre PIERRE <pap@httpap.dev>\n\nThis basically started as a properly packaged, python 3 tested version\nof the `PySepaDD`_ implementation that was released by The Congressus under the MIT license.\nThanks for your work!\n\nThis basically continued as a properly packaged, python 3 tested version\nof the `python-sepaxml`_ implementation that was released by aphael Michel under the MIT license.\nThanks for your work!\n\nThe source code is released under MIT license.\n\nNot part of the MIT-licensed project are the XML schemas in the ``sepaxml/schemas/``\nfolder which are copyrighted by the ISO 20022 organization but `allowed to be reproduced`_\nfreely.\n\n.. _PySepaDD: https://github.com/congressus/PySepaDD\n.. _python-sepaxml: https://github.com/raphaelm/python-sepaxml\n.. _allowed to be reproduced: https://www.iso20022.org/terms-use\n",
"bugtrack_url": null,
"license": null,
"summary": "Python SEPA XML implementations",
"version": "2.6.3",
"project_urls": {
"homepage": "https://gitlab.com/httpap/sepapy"
},
"split_keywords": [
"banking",
" credit",
" debit",
" iso20022",
" sepa",
" xml",
" xsd"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "83609b33e63a8587d40979baf8a8668f7751561183f82031387be9af805960e5",
"md5": "9037de920bbb04475f67bba86d5cb160",
"sha256": "0fd00bc467c803c7cf819876fc75d2843cc26607ce65df72b062b1049544c226"
},
"downloads": -1,
"filename": "sepapy-2.6.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9037de920bbb04475f67bba86d5cb160",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 61212,
"upload_time": "2025-02-10T17:55:52",
"upload_time_iso_8601": "2025-02-10T17:55:52.725262Z",
"url": "https://files.pythonhosted.org/packages/83/60/9b33e63a8587d40979baf8a8668f7751561183f82031387be9af805960e5/sepapy-2.6.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "29e1c2d85e38e2387dcf180211750a7065d8f31b8cc2dc4948a8210f1b5a032c",
"md5": "f76828bd4e7b7d1100fac5d9840db3ce",
"sha256": "63e9c1d178d509f59f9c69172a1af9ec11eadb2bce17f1452937b0357de2e688"
},
"downloads": -1,
"filename": "sepapy-2.6.3.tar.gz",
"has_sig": false,
"md5_digest": "f76828bd4e7b7d1100fac5d9840db3ce",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 52461,
"upload_time": "2025-02-10T17:55:55",
"upload_time_iso_8601": "2025-02-10T17:55:55.576817Z",
"url": "https://files.pythonhosted.org/packages/29/e1/c2d85e38e2387dcf180211750a7065d8f31b8cc2dc4948a8210f1b5a032c/sepapy-2.6.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-10 17:55:55",
"github": false,
"gitlab": true,
"bitbucket": false,
"codeberg": false,
"gitlab_user": "httpap",
"gitlab_project": "sepapy",
"lcname": "sepapy"
}