by-square
Encoder and decoder of "by square" QR codes (PAY by square, INVOICE by square)
by-square is a Python library for encoding and decoding "by square" QR codes as
used in the Slovak banking and invoicing ecosystem. The library implements the
PAY by square and INVOICE by square standards for payment and invoice data.
This implementation follows the official by square schema and specifications.
Installation
pip install by-square
PAY by square
Create a payment QR code:
from datetime import date
from decimal import Decimal
from by_square import PayQR, Payment, PaymentOption, BankAccount
payment = Payment(
payment_options=PaymentOption.PAYMENT_ORDER,
amount=Decimal("34.50"),
currency_code="EUR",
bank_accounts=[BankAccount(iban="SK7700000000000000000000", bic="FIOZSKBAXXX")],
variable_symbol="102",
payment_due_date=date(2026, 1, 9),
payment_note="Payment for services",
)
pay_qr = PayQR(payments=[payment])
encoded = pay_qr.encode()
print(encoded)
Decode a payment QR code:
from by_square import PayQR
decoded = PayQR.decode(encoded)
print(decoded.payments[0].amount)
Or use the universal decoder that automatically detects the document type:
from by_square import decode_universal
decoded = decode_universal(encoded)
print(decoded.payments[0].amount)
INVOICE by square
Create an invoice QR code:
from datetime import date
from decimal import Decimal
from by_square import (
InvoiceQR, SupplierParty, CustomerParty, PostalAddress,
Contact, TaxCategorySummary, PaymentMean
)
invoice = InvoiceQR(
invoice_id="2025001",
issue_date=date(2026, 1, 10),
tax_point_date=date(2026, 1, 10),
local_currency_code="EUR",
supplier_party=SupplierParty(
party_name="Supplier, s.r.o.",
company_tax_id="0000000000",
company_vat_id="SK0000000000",
postal_address=PostalAddress(
street_name="Address",
building_number="10",
city_name="Bratislava",
postal_zone="800 00",
country="SVK",
),
contact=Contact(
name="Ján Mrva",
telephone="+421900000000",
email="info@example.com",
),
),
customer_party=CustomerParty(
party_name="Customer s.r.o.",
company_tax_id="0000000000",
),
tax_category_summaries=[
TaxCategorySummary(
classified_tax_category=Decimal("0.2"),
tax_exclusive_amount=Decimal("1000"),
tax_amount=Decimal("200"),
already_claimed_tax_exclusive_amount=Decimal(),
already_claimed_tax_amount=Decimal(),
)
],
number_of_invoice_lines=0,
payment_means=PaymentMean.MONEY_TRANSFER,
)
encoded = invoice.encode()
print(encoded)
Decode an invoice QR code:
from by_square import InvoiceQR
decoded = InvoiceQR.decode(encoded)
print(decoded.invoice_id)
Or use the universal decoder that automatically detects the document type:
from by_square import decode_universal
decoded = decode_universal(encoded)
print(decoded.invoice_id)
Supported invoice types:
InvoiceQR- Standard invoiceProformaInvoiceQR- Proforma invoiceCreditNoteQR- Credit noteDebitNoteQR- Debit noteAdvanceInvoiceQR- Advance invoice
Implementation notes
InvoiceItems
The by square specification defines a InvoiceItems document type, however these were not seen in the wild, and as I don't have any examples available, these were not implemented in the library.
Data validation
This library focuses solely on encoding and decoding "by square" codes. Validation of the contained data (such as IBAN checksums, VAT number formats, date ranges, etc.) is out of scope.
Optional complex types
The by square specification defines some complex types as optional (minOccurs="0"). According to the spec, these should be preceded by a count indicator (0 or 1) in the serialized sequence.
To simplify the serialization semantics, this library represents optional complex types as lists:
- Use an empty list
[]to omit the type (equivalent to count=0) - Use a single-element list
[instance]to include the type (equivalent to count=1)
Important: The specification allows at most one instance of optional complex types. While this library technically allows multiple items in these lists, generated encodings with more than one element will not be accepted by other implementations.
Examples of optional complex types:
Payment.standing_order_ext- Standing order extensionPayment.direct_debit_ext- Direct debit extension
by square quirks
The by square standard contains several inconsistencies and edge cases that differ from the written specification:
INVOICE by square encoding of optional types
While the specification describes how optional complex types should be encoded with a 0/1 count indicator, real-world INVOICE by square codes omit this entirely. Instead, optional types are simply included with all fields left empty.
MonetarySummary field
The INVOICE by square schema defines a MonetarySummary field for invoice totals.
However, in practice, no real QR codes have been observed containing meaningful
data in this field. The totals are typically derived from TaxCategorySummary
items instead.
If you encounter a QR code with actual MonetarySummary data, please report it as it would help improve interoperability testing.
Release files for by-square 0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| by_square-0.3.tar.gz | 10.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| by_square-0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.3 kB
Release files / by_square-0.3.tar.gz
| Download URL | by_square-0.3.tar.gz |
|---|---|
| Size | 10.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2f8e210fd47ecd6938a6cd806ec2f34d4c2302fb51c97f382072e0694884c1a9
|
|
BLAKE2b-256 checksum How to use checksums |
dc3b1dbb0d9900b49cace590363669ce81dd22ec77a4105742b79d8c231000a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / by_square-0.3-py3-none-any.whl
| Download URL | by_square-0.3-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
59433f9872d2202ad2068b2984f1f8e58b0a2f6ac65213d4be09f31e4818e634
|
|
BLAKE2b-256 checksum How to use checksums |
09c75c81b9763ed82440202b286b2f222613614f6e609c54419dd6676dda449d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|