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.0 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.0

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.0
File Size Uploaded
cheqi_sdk-1.1.0.tar.gz 85.1 kB Details

Built distribution (wheel)

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

Total release size: 264.0 kB

Release files / cheqi_sdk-1.1.0.tar.gz

Download URL cheqi_sdk-1.1.0.tar.gz
Size 85.1 kB
Tags Source
SHA-256 checksum
How to use checksums
29fee06f020c413062a4ae681300c9df2eb4122d70c6c63b989c752d2277bb9b
BLAKE2b-256 checksum
How to use checksums
851b44689bb519f4761bed5110cb0b2438e64d181608a4d05ad5081279cdbb79
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 24, 2026.

Transparency log

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

Download URL cheqi_sdk-1.1.0-py3-none-any.whl
Size 178.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
534c2f32d72c69c3abd99b779dfe02cf96a04ed1e0bb60ca15fc47383f646038
BLAKE2b-256 checksum
How to use checksums
030600b03275adb807c9bfcc73831f424d591b719c5aa32ec9185b5b8f2f561b
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 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

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