Skip to main content

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 invoice
  • ProformaInvoiceQR - Proforma invoice
  • CreditNoteQR - Credit note
  • DebitNoteQR - Debit note
  • AdvanceInvoiceQR - 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 extension
  • Payment.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)

Source distribution for by-square 0.3
File Size Uploaded
by_square-0.3.tar.gz 10.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for by-square 0.3
File Interpreter ABI Platform
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}

Release history Release notifications | RSS feed

This release

0.3 This release

2 release files

0.2

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page