Metadata-Version: 2.4
Name: pysip-qr
Version: 0.1.0
Summary: Generate EMV QRCPS / PY-QR (SIP) payment QR payloads for Paraguay. Standalone local generation; optional HubAdapter for PSP integration.
Home-page: https://github.com/Piuliss/pysip-qr
Author: Omayka / Lumi
Author-email: dev@omayka.tech
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: image
Requires-Dist: segno>=1.5.0; extra == "image"
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == "dev"
Requires-Dist: twine>=4.0.0; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-python
Dynamic: summary

# pysip-qr

Python library to generate **EMV® QRCPS** merchant-presented QR payloads with a **Paraguay SIP / PY-QR** profile.

**PyPI package:** `pysip-qr`  
**Import:** `import sip_qr`

## Important: generation vs QR Hub

1. **Generating** a PY-QR–compatible payload (and optional QR image) does **not** require access to the BCP QR Hub. Standalone mode works fully offline.
2. **Processing / settling** interoperable QR payments through the SIP / QR Hub **does** require a registered PSP/participant and integration with that entity.
3. This library defaults to **`standalone`**. **`integrated`** mode is opt-in via a `HubAdapter` you configure — the library does **not** ship BCP endpoints or claim direct BCP connectivity.
4. PSPs that offer QR payments must register with the BCP/SGGOF and follow the official PY-QR implementation guide. This package helps with payload construction; it does not replace regulatory onboarding.

## Install

```bash
pip install pysip-qr
# optional QR image rendering
pip install pysip-qr[image]
```

From source (editable):

```bash
pip install -e ".[image]"
```

## Quick start (standalone)

```python
from sip_qr.profiles.sip import SipQrBuilder
from sip_qr import validate_payload, to_qr_image

payload = (
    SipQrBuilder()
    .merchant_account(
        guid="com.example.psp",          # from your PSP — not invented by this lib
        psp_fields={"01": "MERCHANT001"}, # PSP-specific subtags
        root_tag=26,
    )
    .merchant(name="Farmacia Demo", city="Asuncion", mcc="5912")
    .dynamic()
    .amount("150000.00")
    .currency_pyg()
    .reference("VENTA-123")
    .build()
)

assert validate_payload(payload) == []
to_qr_image(payload, path="qr.png")  # requires pysip-qr[image]
```

Static QR without amount:

```python
payload = (
    SipQrBuilder()
    .merchant_account(guid="com.example.psp", psp_fields={"01": "M1"})
    .merchant(name="Farmacia Demo", city="Asuncion", mcc="5912")
    .static()
    .build()
)
```

## Integrated mode (optional)

```python
from sip_qr import OperatingMode, SipQrClient
from sip_qr.exceptions import MissingHubCredentials

# Provide your own HubAdapter implementation (PSP SDK / private API).
# No BCP URLs are hardcoded in this library.

client = SipQrClient(mode=OperatingMode.INTEGRATED, adapter=None)
try:
    client.submit_payment(payment_reference="ORD-1")
except MissingHubCredentials:
    ...
```

Implement `sip_qr.adapters.HubAdapter` (`is_configured`, `supports_participant`, `submit_payment`, `check_status`) using credentials and base URLs supplied by your approved PSP.

## CLI (offline)

```bash
python -m sip_qr generate --input examples/dynamic_with_amount.json
python -m sip_qr generate --input examples/static.json --output qr.png
python -m sip_qr validate --payload "000201..."
```

## Assumptions (until official PY-QR guide field map is wired)

- Country default: `PY`
- Currency default: `600` (PYG)
- Merchant Account Information GUID and PSP subtags are **injector-provided**
- Dynamic QR (POI `12`) requires amount by default; static (POI `11`) does not
- CRC: CRC-16/CCITT-FALSE over payload including `6304`
- PY-QR logo overlay is optional and not claimed as official branding compliance without the visual spec/asset

## Development

```bash
pip install -e ".[dev,image]"
python -m unittest discover -s tests -v
```

## Release

GitHub Actions:

- `ci.yml` — runs unittest on push/PR
- `release.yml` — manual `workflow_dispatch` with bump `patch|minor|major`: bump version, tag `vX.Y.Z`, build, publish to PyPI (Trusted Publishing)

Configure a PyPI Trusted Publisher for repo `Piuliss/pysip-qr`, workflow `release.yml`, environment `pypi`.

## License

MIT
