Reads and produces SGQR codes
Project description
SGQR
Description
SGQR is a Python module for encoding and decoding payment QR codes also known as EMV QRcodes. 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 to a mobile number is supported.
The module itself doesn't produce QR code images. A module such as 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
00to99 - a length: two numeric characters from
01to99 - a value: a string of up to
99characters
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 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:
- 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
pip3 install nlannuzel.sgqr
Package usage
With the built-in script:
# Encoding
encode-sgqr < description.yaml
# 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 (WARNING: qreader and its dependencies take 7Gb of disk space).
# Decoding
decode-sgqr < qr.txt > description.yaml
decode-sgqr <<< '00020101021226560009SG.PAYNOW010100211+659999999903011041420260201230310520450005303702540512.345802SG6009Singapore62110107comment630461CE' > description.yaml
In a Python script:
#!/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/ |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nlannuzel_sgqr-0.0.1.tar.gz.
File metadata
- Download URL: nlannuzel_sgqr-0.0.1.tar.gz
- Upload date:
- Size: 34.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1f694e8bf2135f84312a965fdf7cc4aca6b0ff23dfe912f615f569541087947
|
|
| MD5 |
960696ed1de9175d8feb61fb50d4cc2e
|
|
| BLAKE2b-256 |
125aa41a67b789bb1b7efb51e184ae37b647446bc4c49ae2d311e679101f1852
|
File details
Details for the file nlannuzel_sgqr-0.0.1-py3-none-any.whl.
File metadata
- Download URL: nlannuzel_sgqr-0.0.1-py3-none-any.whl
- Upload date:
- Size: 34.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38e0d4112979ffca40af1b1e665fb8de5855b5fdaf8ec2982b8b7c207cafc860
|
|
| MD5 |
6c4e96c3a7273787ff9f47d6be036373
|
|
| BLAKE2b-256 |
3ad5ce4b11872f8e4e7a7cf66bcb35cc746629d42683102d3c22677ba0129078
|