Skip to main content

Bank-Slip-Verifier (pip)

Zero-dependency client for the OIIO Service Slip Verify API — verify Thai bank transfer slips with pip, uv, poetry or any Python 3.10+ runtime

License: MIT Python Zero dependencies Stdlib only

English - Thai


Three verification modes, one client — verify that a "paid" slip image or QR payload really moved money in the bank system:

Mode Endpoint Speed
detect_amount(img) POST /api/slip Slowest — reads the amount from the image with OCR, then verifies it
verify_amount(img, amount) POST /api/slip/:amount Faster — you give the expected amount, OCR is skipped
verify_qr_code(qr_code_data, amount) POST /api/slip/:amount/no_slip Fastest — QR payload only, no image

Features

Ability Details
Three endpoints OCR amount detection, image + expected amount, and QR-only verification — same typed result for all
Static API from bank_slip_verifier import Client — no construction, Client.verify_amount(...) just works against the hosted deployment
Zero dependencies pure standard library (urllib), no install scripts, no native binaries
Typed errors SlipApiError carries the HTTP status, the documented slug (amount-not-verified, slip-not-found, ...) and the raw envelope, plus SlipTimeoutError and SlipError
Timeout-aware defaults to a 35 s HTTP timeout — verification can take up to 25 s (OCR)
npm parity same endpoints, payloads, error slugs and messages as the npm SDK (@byteindev/bank-slip-verifier)

Quick Start

Install with any package manager:

pip install bank-slip-verifier
# or
uv add bank-slip-verifier
# or
poetry add bank-slip-verifier

Client is a ready-to-use static wrapper around the hosted deployment — no setup needed:

from bank_slip_verifier import Client

# 1. Verify a QR payload only, no image (fastest):
result = Client.verify_qr_code(qr_code_data="004...", amount=100)
print(result.data.ref)  # bank transaction reference

# 2. Verify a slip image against a known amount (recommended — faster):
data = Client.verify_amount(img="data:image/jpeg;base64,...", amount=100).data
print(data.amount == 100)  # True — the bank confirmed the transfer

# 3. Unknown amount — let OCR read it from the image (slowest):
detected = Client.detect_amount(img="data:image/jpeg;base64,...").data
print(detected.amount)  # amount found by OCR, then verified

Every result has the same shape:

SlipResult(
    ok=True,
    message="Slip processed successfully.",
    from_cache=False,  # True when answered from the server cache
    data=SlipData(
        ref="202602032204376094",
        date="2026-03-17T10:00:00.000Z",
        amount=100.0,
        sender_bank="004",
        sender_name="John Doe",
        sender_id="xxx-x-xxxxx-x",
        receiver_bank="014",
        receiver_name="Jane Doe",
        receiver_id="xxx-x-xxxxx-x",
    ),
)

Extra fields come back on rich responses (verified, reference_1/2/3, sender_bank_details, receiver_bank_details).

Bring your own deployment (or configure)

from bank_slip_verifier import create_client

client = create_client()  # hosted: https://slip-c.oiio.download
# or
custom = create_client(base_url="https://your-deployment.example.com")
# or configure the static client:
Client.configure(base_url="https://your-deployment.example.com")

result = custom.verify_amount(img="data:image/jpeg;base64,...", amount=100)

Base URL resolution order: base_url option > BANK_SLIP_VERIFIER_BASE_URL environment variable > hosted deployment:

BANK_SLIP_VERIFIER_BASE_URL=https://staging.example.com python app.py

Timeout

Verification can take up to 25 seconds (OCR endpoint). The API docs require an HTTP timeout of 30 s or more — this client defaults to 35 s and raises SlipTimeoutError when a response does not arrive in time. Tighten it only if you know what you are doing:

client = create_client(timeout_ms=60_000)  # or lower, but >= 30_000

Terms of Service

The API rejects every request unless TOS, privacy and EULA are accepted. The client sends {"tos": True, "privacy": True, "eula": True} by default (using the service implies consent). Override at client level or per call:

create_client(consent={"tos": True, "privacy": False, "eula": True})  # client-level
client.detect_amount(img, consent={"tos": False})  # per-call (wins)

Error handling

All errors extend SlipError. The API's failures arrive as SlipApiError with the HTTP status, the documented error slug and the raw envelope:

from bank_slip_verifier import Client, SlipApiError, SlipTimeoutError, SlipError

try:
    result = Client.verify_amount(img=img, amount=100)
except SlipApiError as err:
    print(err.status, err.slug, err.message)
    # 422 'amount-not-verified' '[amount-not-verified] Amount not verified'
    if err.slug == "amount-not-verified":
        # show the customer the expected amount again — the slip does not match
        ...
except SlipTimeoutError:
    # verification took longer than timeout_ms — retry later
    ...
HTTP slug Cause
400 bad-request malformed body / missing field
400 terms-not-accepted TOS/Privacy/EULA not accepted
400 invalid-image base64 image is invalid
422 qr-not-found no QR found in the image
422 invalid-qr QR format invalid
422 amount-not-found OCR could not read the amount
422 amount-not-verified amount read, but did not match the bank record
422 invalid-slip-data slip data incomplete
404 slip-not-found slip not found in the bank system

SlipApiError.slug is one of these values (SLIP_ERROR_SLUGS and is_slip_error_slug are exported for runtime checks).

Live smoke tests

The package ships live smoke tests against the real deployment (skipped by default):

LIVE=1 pytest

API

Export Description
Client static wrapper around a shared instance (hosted deployment by default)
create_client(**options) new SlipClient connected to hosted or custom base_url
SlipClient the client class; detect_amount, verify_amount, verify_qr_code
DEFAULT_BASE_URL https://slip-c.oiio.download
ENV_BASE_URL BANK_SLIP_VERIFIER_BASE_URL — env-var fallback for the base URL
SlipError / SlipApiError / SlipTimeoutError typed errors
SLIP_ERROR_SLUGS, is_slip_error_slug error slug constants + guard
SlipData / SlipResult result types
__version__ package version

Credits

Powered by the OIIO Service Slip Verify API.

License

MIT © ByteInDev

Metadata

Release files for bank-slip-verifier 1.0.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 bank-slip-verifier 1.0.0
File Size Uploaded Provenance Actions
bank_slip_verifier-1.0.0.tar.gz 17.8 kB Without provenance Details for bank_slip_verifier-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bank-slip-verifier 1.0.0
File Interpreter ABI Platform Actions
bank_slip_verifier-1.0.0-py3-none-any.whl Python 3 none any Details for bank_slip_verifier-1.0.0-py3-none-any.whl

Total release size: 31.1 kB

Release files / bank_slip_verifier-1.0.0.tar.gz

Download URL bank_slip_verifier-1.0.0.tar.gz
Size 17.8 kB
Tags Source
SHA-256 checksum
How to use checksums
cd7ca6b274592895d8f9d2ae054bbbf54a26a5756590e69d9705919d3243fb06
BLAKE2b-256 checksum
How to use checksums
232abbb70e4465f8c2e62f6749068f820a8c8e8be778f9a5256237bb4917124b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / bank_slip_verifier-1.0.0-py3-none-any.whl

Download URL bank_slip_verifier-1.0.0-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd70cda48b69b51465533f2340b0c61068170d6c17457de082a95f0f35ecec08
BLAKE2b-256 checksum
How to use checksums
3154693563aaa5d5ca5e2025d3823eb1a3bea9c00c317191db288d7b152b93df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for bank-slip-verifier 1.0.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

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