Truemoney-Voucher (pip)
Zero-dependency client for the Truemoney-Voucher REST APIs — redeem TrueMoney gift vouchers from pip, uv, poetry or any Python runtime
English - Thai
A zero-dependency client for the Truemoney-Voucher API family — three backend ports share the same HTTP contract, and the client picks the fastest healthy one for you:
| Provider | Backend | Hosted at |
|---|---|---|
auto (default) |
probes all three, uses the fastest healthy one | failover on network errors |
go |
Go (uTLS HelloFirefox_148 + HTTP/2 framer) |
https://truemoney-voucher-go.vercel.app |
nestjs |
NestJS (cycletls Firefox 148 fingerprint) | https://truemoney-voucher-nestjs.vercel.app |
fastapi |
FastAPI (curl_cffi Firefox 147 fingerprint) | https://truemoney-voucher-fastapi.vercel.app |
Features
| Ability | Details |
|---|---|
| Redeem | Client.redeem(code, mobile) — raw code or full gift.truemoney.com campaign URL |
| Auto provider | default 'auto' probes all backends, picks the fastest healthy one, fails over on network errors |
| Static API | from truemoney_voucher import Client — no construction, no config, just Client.redeem(...) |
| Zero dependencies | Python standard library only — urllib + threading, no install deps |
| Universal runtime | CPython >= 3.10 (tested through 3.14), stdlib-only — no compiled extensions |
| Typed errors | TruemoneyApiError, TruemoneyTimeoutError, TruemoneyError with envelope access |
Quick Start
Install with any Python package manager:
pip install truemoney-voucher
# or
uv add truemoney-voucher
# or
poetry add truemoney-voucher
No setup needed — Client is a ready-to-use static wrapper around an auto-configured instance:
from truemoney_voucher import Client
# auto: probes the three hosted backends and uses the fastest healthy one
result = Client.redeem("12345678901234", "0812345678")
print(result.status.code) # e.g. "VOUCHER_NOT_FOUND", "TARGET_USER_REDEEMED"
# Liveness probe:
alive = Client.status()
# Service info:
info = Client.info()
Pin a provider (or configure your own)
from truemoney_voucher import create_client
# Pin one backend explicitly:
client = create_client(provider="nestjs") # "go" | "nestjs" | "fastapi"
# Or bring your own deployment (overrides `provider`):
custom = create_client(
base_url="https://api.example.com",
timeout_ms=15_000,
)
# Client.configure() re-creates the shared instance the same way:
Client.configure(provider="fastapi")
API Reference
Static Client (no construction)
| Method | Description |
|---|---|
Client.redeem(code, mobile) |
Redeem a raw code or full campaign URL through the fastest healthy backend |
Client.status() |
True when at least one hosted backend answers 2xx on /status |
Client.info() |
Service info + routes of the selected backend |
Client.configure(**kwargs) |
Replace the shared instance (auto by default) |
create_client(**kwargs) => TruemoneyClient
| Option | Type | Default | Description |
|---|---|---|---|
provider |
str |
'auto' |
Which hosted backend to call — 'auto' probes and picks the fastest healthy one |
base_url |
str | None |
provider URL | Full base URL (wins over provider) |
timeout_ms |
int |
30_000 |
Per-request timeout |
urlopen |
callable |
urllib.request.urlopen |
Custom opener (tests, proxies) |
user_agent |
str | None |
truemoney-voucher/1.1.0 |
User-Agent header |
headers |
dict[str, str] |
— | Extra headers on every request |
Auto provider
- On the first call (or after a 60 s cache TTL) all three backends are probed in parallel (thread pool,
GET /status, 3 s probe timeout) and ranked by latency. - Redeem,
status()andinfo()go to the fastest healthy backend; the ranking is cached for 60 seconds. - If a redeem fails with a network error, the client automatically retries the next healthy backend. Validation errors (
TruemoneyApiError) never trigger failover — a failed redeem can't be double-redeemed, so the worst case isTARGET_USER_REDEEMED. client.explicit_base_urlreturns the base URL of an explicitly selected backend (Nonefor auto).
client.redeem(code, mobile) => RedeemResult
Accepts a raw gift code or a full campaign URL (percent-encoded into the
path — the backends preserve %2F, matching the reference CLI).
- Returns
RedeemResult(ok=True, status=TrueMoneyStatus(message, code), data=...)when the upstream call succeeds. - Raises
TruemoneyApiErroron validation/routing errors ({ code, message }envelopes, or upstream Spring-style error bodies, which are normalized).
client.status() => bool
True on any 2xx, False otherwise — never raises, safe for uptime checks.
In auto mode, True when at least one backend is healthy.
client.info() => dict
Service name, deployed version (where exposed), and the route list.
Errors
| Error | When |
|---|---|
TruemoneyApiError |
API answered { code, message } (validation 400, not found 404, …) or a Spring-style error body. Exposes status, code, envelope. |
TruemoneyTimeoutError |
No response within timeout_ms. |
TruemoneyError |
Network failure, non-JSON response, unexpected envelope. |
All errors extend TruemoneyError:
from truemoney_voucher import TruemoneyApiError
try:
Client.redeem(code, mobile)
except TruemoneyApiError as err:
print(err.code, err.message) # 400 "Bad Request"
TrueMoney status codes
When the upstream call succeeds, result.status.code carries TrueMoney's answer:
| Code | Meaning |
|---|---|
SUCCESS |
Money received successfully |
TARGET_USER_REDEEMED |
You already redeemed this voucher |
VOUCHER_OUT_OF_STOCK |
Someone else already took it |
VOUCHER_EXPIRED |
The wallet voucher has expired |
VOUCHER_NOT_FOUND |
Voucher not found in the system |
CANNOT_GET_OWN_VOUCHER |
Cannot redeem your own voucher |
TARGET_USER_NOT_FOUND |
Phone number not found in the system |
INTERNAL_ERROR |
Voucher not found, or the URL is wrong |
Testing
pip install -e ".[dev]"
pytest tests/test_client.py tests/test_auto_client.py # offline unit tests
set LIVE=1 && pytest tests/test_live.py # live checks against the three hosted backends
The live suite runs status/info and an invalid-voucher check against all
three Vercel deployments, plus a real upstream call.
Contributing
Contributions are welcome! Please:
- Open an issue first for significant changes
- Keep
pytest testsgreen - Bump
versioninpyproject.tomltogether withsrc/truemoney_voucher/version.py
Disclaimer
For educational use or where the provider permits it. Redeeming is irreversible and governed by TrueMoney's Terms of Service. Voucher codes are cash-equivalent — never log full codes.
License
Licensed under the MIT License © 2026 ByteInDev
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 truemoney_voucher-1.1.1.tar.gz.
File metadata
- Download URL: truemoney_voucher-1.1.1.tar.gz
- Upload date:
- Size: 17.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
764a1ecc5a6031f065988f135ac03b8841484028e09a54540f59c05ac2ab525c
|
|
| MD5 |
a5f365588745feec3ac9cfc666517047
|
|
| BLAKE2b-256 |
9687cc96c43703e6ae2895a99a5130a2ad6033f154674e27caadf1726a6fa6c3
|
File details
Details for the file truemoney_voucher-1.1.1-py3-none-any.whl.
File metadata
- Download URL: truemoney_voucher-1.1.1-py3-none-any.whl
- Upload date:
- Size: 12.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
076e4bd3fe5acee0ef46aab5deb29aec0638124ce05f0130369988acf4009913
|
|
| MD5 |
d2949cd9edff53aac2c9883676967215
|
|
| BLAKE2b-256 |
71744b732a04942e220a758b15f191c43846a927699165270349aacfbc2b2c9b
|