Skip to main content

Cheqi Python SDK

Python SDK for resolving receipt recipients and issuing end-to-end encrypted Cheqi receipts and credit notes. It also provides client-encrypted receipt downloads, receipt-envelope decryption, integrity helpers, and store management.

The SDK preserves Cheqi's zero-knowledge boundary: the issuer supplies definitive receipt values, which are encrypted locally for each owner device. The SDK does not calculate totals, enrich payment data, fiscalize receipts, or submit plaintext receipt bodies to Cheqi on the digital route.

Install

pip install cheqi-sdk

Python 3.9 or newer is required.

Version 1.1.1 matches the Java SDK 2.3 contract, including company-expense receipt attribution, member receipt identities, employee invitation roles, and the latest encrypted delivery metadata.

Initialize

from cheqi import CheqiSDK, Environment

sdk = CheqiSDK(
    environment=Environment.SANDBOX,
    api_key="your_api_key",
)

For OAuth, omit api_key and pass access_token= to service calls. A custom backend can be used with custom_api_endpoint= and, when needed, receipt_download_base_url=.

An existing synchronous httpx.Client can be injected with http_client=. The SDK leaves an injected client open; clients created by the SDK are closed by sdk.close() or the context manager.

Issue a receipt

The generated classes are the canonical API contract. Handwritten receipt classes subclass that contract only to add Python-friendly Decimal handling and small convenience methods.

from datetime import datetime, timezone

from cheqi.models import (
    CardDetails,
    IdentificationDetails,
    PaymentDetails,
    PaymentType,
    Product,
    ReceiptPayload,
    Tax,
    UnitCode,
)

identification = IdentificationDetails(
    payment_type=PaymentType.CARD_PAYMENT,
    card_details=CardDetails(
        payment_account_reference="PAR123456789",
        card_provider="VISA",
        last_four_digits="4242",
    ),
)

product = Product(
    name="Coffee beans",
    brand_name="Cheqi Coffee",
    identifier="SKU-COFFEE-001",
    quantity=1,
    base_quantity=1,
    unit_code=UnitCode.C62,
    unit_price="10.00",
    subtotal="10.00",
    total="12.10",
).add_tax(21, "VAT", "10.00", "2.10")

payload = ReceiptPayload(
    document_number="POS-2026-0001",
    issue_date=datetime.now(timezone.utc),
    currency="EUR",
    receipt_subtotal="10.00",
    total_before_tax="10.00",
    total_tax_amount="2.10",
    total_amount="12.10",
    taxes_applied=True,
    products=[product],
    taxes=[Tax(rate=21, type="VAT", taxable_amount="10.00", amount="2.10")],
    payment_details=PaymentDetails(
        payment_means_code="48",
        description="Card payment",
        card_provider="VISA",
        card_last_four="4242",
        merchant_id="MID-123",
        payment_terminal_id="TID-456",
    ),
)

result = sdk.receipt_service.issue_receipt(identification, payload)

if result.is_accepted:
    print(result.cheqi_receipt_id)
elif result.email_receipt_required:
    # Generate and submit the permitted email-fallback receipt explicitly.
    pass
elif result.download_envelope_required:
    # Generate the final ReceiptEnvelope locally and complete the fallback.
    pass

To associate a receipt with a store or use OAuth:

result = sdk.receipt_service.issue_receipt(
    identification,
    payload,
    store_id=store_id,
    access_token=access_token,
)

All monetary, tax, payment, barcode, and jurisdictional values remain caller-supplied. For example, Product.add_tax(...) only appends the supplied tax; it does not calculate it.

Delivery routes and downloads

The backend selects DIGITAL, DOWNLOAD_FALLBACK, or EMAIL_FALLBACK.

  • Digital receipts are independently encrypted for every matched device and submitted immediately.
  • Download fallback is completed automatically when IdentificationDetails.payment_type is set.
  • Without local payment context, download_envelope_required asks the caller for a final generated ReceiptEnvelope.
  • Email fallback is returned as an explicit action and is not performed automatically.

An explicit customer-without-Cheqi flow can skip matching:

result = sdk.receipt_service.issue_download_receipt(
    IdentificationDetails(payment_type=PaymentType.CASH),
    payload,
    access_token=access_token,
)
print(result.download_url)

The AES key is stored only in the URL fragment and is never sent to Cheqi.

Credit notes and return requests

Definitive merchant-issued credit notes use the same device encryption model and a separate API envelope:

result = sdk.credit_note_service.issue_credit_note(
    identification,
    parent_cheqi_receipt_id,
    credit_note_payload,
    access_token=access_token,
)

Customer return requests are represented by CreditNoteInitiationRequest, ReturnLineItem, ReturnReasonCode, and RefundPreference. Pydantic validates positive return quantities and the bank-account rules for BANK_TRANSFER. Receiving issuers can decrypt and validate queued or webhook requests in one call:

request = sdk.decryption_service.decrypt_credit_note_initiation_request(
    encrypted_request,
    private_key_base64,
)

Receipt decryption

envelope = sdk.decryption_service.decrypt_receipt(
    encrypted_receipt_delivery_or_webhook_envelope,
    private_key_base64,
)

The plaintext is the generated ReceiptEnvelope; no backend-context merge step is required. For company-expense deliveries, its optional expense_submission field contains the encrypted ExpenseSubmissionEnvelope attribution metadata.

Lower-level operations

The matching, encryption, submission, download, verification, and store services are exposed on CheqiSDK. Examples include:

resolution = sdk.matching_service.match_customer(identification, access_token)
delivery = sdk.encryption_service.encrypt_for_device(payload.to_json(), resolution.recipients[0])
receipt_hash = sdk.verification_service.calculate_cheqi_receipt_hash(payload.to_json())
canonical_json = sdk.verification_service.canonicalize_cheqi_receipt(payload)
ubl_hash = sdk.verification_service.calculate_ubl_hash(ubl_xml)
stores = sdk.store_service.get_stores(company_id, access_token=access_token)

Development

python -m pip install -e '.[dev]'
pytest
ruff check src tests
mypy src/cheqi

Release files for cheqi-sdk 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cheqi-sdk 1.1.1
File Size Uploaded
cheqi_sdk-1.1.1.tar.gz 85.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cheqi-sdk 1.1.1
File Interpreter ABI Platform
cheqi_sdk-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 264.0 kB

Release files / cheqi_sdk-1.1.1.tar.gz

Download URL cheqi_sdk-1.1.1.tar.gz
Size 85.1 kB
Tags Source
SHA-256 checksum
How to use checksums
3a944dc4ce467a2583d38517674711bd49d075228af32dc4578bafadb5276103
BLAKE2b-256 checksum
How to use checksums
4c3ebcad2e3ea6e926e5f07c59a5a0b2dd278bc748b2173bbd78fddbd491cc37
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / cheqi_sdk-1.1.1-py3-none-any.whl

Download URL cheqi_sdk-1.1.1-py3-none-any.whl
Size 178.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
68c4d950f2732c704ecb34750d9019ada35dbc4ebe689f42bea08453cd5603cb
BLAKE2b-256 checksum
How to use checksums
d3f9ddac677e87e95c0b588169fb949010bfdafbaa3df6b758d779f245fed60b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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