Metadata-Version: 2.4
Name: nlannuzel.sgqr
Version: 0.0.1
Summary: Reads and produces SGQR codes
Author-email: Nicolas Lannuzel <nlannuzel@gmail.com>
Project-URL: Homepage, https://github.com/nlannuzel/sgqr
Keywords: emv,emvco,qrcode,payment,singapore,paynow
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Topic :: Office/Business :: Financial :: Point-Of-Sale
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: COPYING
Requires-Dist: pyyaml
Dynamic: license-file

# SGQR

## Description
SGQR is a Python module for encoding and decoding payment QR codes
also known as [EMV QRcodes](https://www.emvco.com/emv-technologies/qr-codes/).
The specifications are public, and freely available.

**Link to project:** https://github.com/nlannuzel/sgrqr

## Restrictions
The module only supports "merchant presented mode" in which a user
scans a QR code with a mobile phone in order to make a payment. The QR
code is usually pasted prominently at the merchant counter, or
dynamically generated by a POS system.

So far, only [PayNow](https://www.abs.org.sg/e-payments/pay-now) to a
mobile number is supported.

The module itself doesn't produce QR code images. A module such as
[qrcode](https://pypi.org/project/qrcode/) on PyPi can read the string
generated by SGQR and encode it as a QR code that can be scanned by a
mobile phone.

## EMV QR codes
At the base, EMV QR codes contain a string of characters made of
multiple data fields concatenated together. Each field contains:
  - an identifier: two numeric characters from `00` to `99`
  - a length: two numeric characters from `01` to `99`
  - a value: a string of up to `99` characters

For example 6009Singapore:
  - field ID: `60` (Merchant City)
  - field length: `09`
  - field value: `Singapore`

The field value can be a bare string, like the shop name, or the price
of the transaction. It can also be a so-called "template", and
represents another code that requires further decoding.

The last data field of a EMV QR Code is the CRC (id 63, length 4), as
a 4 characters hexadecimal value, for example `630461CE` (id: `63`, length
`4`, value `61CE`)

Example of a EMV code:
```
00020101021226560009SG.PAYNOW010100211+659999999903011041420260201230310520430005303702540512.345802SG59006009Singapore62110107comment63042259
```

Some data fields are mandatory or optional, some are reserved for
vendors, or are country specific.

The EMV (and other) specifications document the allocation and exact
format of each data field, as well as which ones are plain strings, or
templates. Unfortunately, the specifictions for country or vendors
specific data fields are sometimes proprietary, and not easily
available.

More information is available from this [Introduction and
Background](https://www.w3.org/2020/Talks/emvco-qr-20201021.pdf)
document.

## YAML representation
The module reads (encoding) and generates (decoding) YAML files.

The YAML output (or input) is an array of dictionaries with keys:
  - id: mandatory, contains the data ID 2 characters from 00 to 99
  - value: mandatory, the actual value of the data field as a string,
    or as a list of dictionaries for templates
  - name: optional, the name or description of the data field as
    documented in the specifications. Ignored when encoding.

Example:
```yaml
- id: '00'
  name: Payload Format Indicator
  value: '01'
- id: '01'
  name: Point of Initiation Method
  value: '12'
- id: '26'
  name: Merchant Account Information
  value:
  - id: '00'
    value: SG.PAYNOW
    name: UID
  - id: '01'
    value: '0'
    name: Proxy Type
  - id: '02'
    value: '+6599999999'
    name: payee
  - id: '03'
    value: '1'
    name: Editable Transaction amount indicator
  - id: '04'
    value: '20260201230310'
    name: Expiry Timestamp
- id: '52'
  name: Merchant Category Code
  value: '3000'
- id: '53'
  name: Transaction Currency
  value: '702'
- id: '54'
  name: Transaction Amount
  value: '12.34'
- id: '58'
  name: Country Code
  value: SG
- id: '60'
  name: Merchant City
  value: Singapore
- id: '62'
  name: Additional Data Field Template
  value:
  - id: '01'
    name: Bill Number
    value: comment
- id: '63'
  name: CRC
  value: 2259
```
## Package installation
From PyPI
```shell
pip3 install nlannuzel.sgqr
```

## Package usage
### With the built-in script:
```shell
# Encoding
encode-sgqr < description.yaml
```
```shell
# Encoding, and displaying a QR code in the terminal
# with https://pypi.org/project/qrcode/:
encode-sgqr < description.yaml | qr
```

For decoding an existing QR code image, the text string must first be
extracted from the QR code. This can be done with a mobile phone and a
QR code scanner application (like the built-in Android QR code
scanner), or by a Python module like
[qreader](https://pypi.org/project/qreader/) (WARNING: qreader and its
dependencies take 7Gb of disk space).


```shell
# Decoding
decode-sgqr < qr.txt > description.yaml
decode-sgqr <<< '00020101021226560009SG.PAYNOW010100211+659999999903011041420260201230310520450005303702540512.345802SG6009Singapore62110107comment630461CE' > description.yaml
```

### In a Python script:
```python
#!/usr/bin/env python3

import yaml
from nlannuzel.sgqr.encode import encode_sgqr
from nlannuzel.sgqr.decode import decode_sgqr

with open("some_file.yaml") as f:
    entries = yaml.load(f, Loader=yaml.Loader)

# encode
encoded = encode_sgqr(entries)
print(encoded)

# decode again:
decoded = decode_sgqr(encoded)

# show YAML output
print(yaml.dump(decoded))

```

## references
|  description                           | URL                                                 |
|----------------------------------------|-----------------------------------------------------|
| Presentation of the EMV code           | https://www.w3.org/2020/Talks/emvco-qr-20201021.pdf |
| Merchant presented specifications      |https://www.emvco.com/specifications/emv-qr-code-specification-for-payment-systems-emv-qrcps-merchant-presented-mode/ |
| Consumer presented specifications      | https://www.emvco.com/specifications/emv-qr-code-specification-for-payment-systems-emv-qrcps-consumer-presented-mode/ |
