QrisMerchantID — Unofficial Indonesian QRIS merchant API client for Python
One Python package for Indonesia's QRIS merchant APIs — read your own merchant data with typed, tested, offline-friendly code:
- 🧾 GoPay / GoBiz — OTP + password login, merchants, transactions, payouts, dynamic QRIS, payment watcher.
- 🛍️ ShopeePay — OTP login (or manual
B:token), stores, normalized feed, payment watcher. - 🔬 Researched, not guessed — every endpoint traced to a capture or a reference repo; unknowns are marked TODO, never shipped as fact.
Each merchant has its own guide with the full tutorial and flow diagrams:
| Provider | Guide | Status |
|---|---|---|
| GoPay / GoBiz merchant | docs/gopay/ | ✅ auth, users, merchants, transactions, payouts, QRIS, watcher |
| ShopeePay partner | docs/shopee/ | ✅ OTP login, stores, transactions, watcher (login or manual B: token) |
Research/educational use only. Not affiliated with GoTo/GoPay/GoBiz or Shopee/Sea Group. Read-only by design in v0.2.0 — it only reads your own merchant data (login + history + payouts) and never moves money.
⚠️ Disclaimer — harap dibaca dulu
English. This is an unofficial, independent research project. It is NOT
affiliated with, endorsed by, or supported by GoTo, GoPay, GoBiz, Shopee, Sea
Group, or any reference-repo author. It is provided for research and
educational purposes only, without warranty of any kind. Using unofficial
APIs may violate the providers' Terms of Service and can lead to rate limits,
suspension, or termination of your accounts. You use this software entirely
at your own risk — the author (AlfinAI) shall not be liable for any loss,
damage, account action, or legal consequence arising from its use. Credentials
and tokens you enter stay on your machine (they are only ever sent to the
providers' own official servers) — never commit .env, *.har, or token/OTP
cache files to any repository.
Bahasa Indonesia. Ini adalah proyek riset independen yang tidak resmi
(unofficial). TIDAK berafiliasi, didukung, atau disetujui oleh GoTo, GoPay,
GoBiz, Shopee, Sea Group, maupun author repo referensi mana pun. Disediakan
hanya untuk riset dan edukasi, tanpa jaminan apa pun. Penggunaan API tidak
resmi dapat melanggar Syarat & Ketentuan penyedia dan berakibat akun dibatasi,
ditangguhkan, atau dihapus. Segala risiko dan akibat yang timbul sepenuhnya
menjadi tanggung jawab pengguna — author (AlfinAI) tidak bertanggung jawab atas
kerugian, kerusakan, tindakan terhadap akun, atau konsekuensi hukum apa pun dari
penggunaan software ini. Kredensial/token hanya tersimpan di mesin Anda (dan
hanya dikirim ke server resmi penyedia) — jangan pernah commit file .env,
*.har, atau cache token/OTP ke repo mana pun.
Contents
- Installation
- Core concepts (money · sessions · errors)
- Quickstart
- Provider guides
- Roadmap
- Development · Research · Credits · Contributing · Contact
Installation
pip install QrisMerchantID
Requires Python 3.10+ and one dependency: httpx.
Core concepts
Three things to understand before anything else:
- Money differs per provider — never mix them. GoPay answers minor units
(sen):
gross_amount: 10600000= Rp106.000, convert withgopay.money.to_rupiah(). ShopeePay answers whole rupiah as grouped strings:"409.662"= Rp409.662, parse withshopee.money.parse_id_amount(). Never guess. - Sessions are yours to keep. GoPay: cache the
access_token, revalidate cheaply (merchants.search()); on HTTP 401, log in again. ShopeePay: log in with OTP andrefresh_session()without re-OTP, or paste a manualB:token; on codes200020/2010000, renew it. - Every HTTP error raises
ApiException. It carries.http_status,.code(when the provider sent one),.payload(full body), and a readable message. Transport errors (DNS/connect/timeout) retry with backoff; HTTP errors never retry.
Quickstart
from qrismerchantid import GoPayMerchant, ShopeePayPartner
# --- GoPay: OTP login, then read your history ---
gopay = GoPayMerchant()
otp = gopay.auth.request_otp("0812xxxxxxx")
session = gopay.auth.login_with_otp(input("OTP: "), otp["otp_token"])
txns = gopay.transactions.analytics("G...", days=7)
print(txns["total"], "transactions")
# --- ShopeePay: token (or sp.auth OTP login), then watch a store ---
sp = ShopeePayPartner(token="B:...") # token how-to: docs/shopee/token.md
print(sp.stores.list_stores())
watcher = sp.watch(7)
watcher.seed()
paid = watcher.wait_for_payment(409662, timeout=300) # Rp409.662
print("PAID:", paid["id"])
Provider guides
- GoPay / GoBiz merchant → — login (OTP + password), session cache, users, merchants, transactions, payouts, dynamic QRIS, payment watcher, configuration, and the login/payment flow diagrams.
- ShopeePay partner → — OTP login + session renewal, manual-token setup, stores, normalized transaction feed, whole-rupiah money rules, payment watcher, configuration, and the payment flow diagram.
Roadmap
- GoPay provider — auth, merchants, transactions, payouts, QRIS, watcher.
- ShopeePay provider — OTP login, stores, feed, watcher.
- Live verification against real partner accounts (TODO-S1) — field reports welcome in Discussions.
-
v0.2.0PyPI release. - Your idea here — open a Discussion or a feature request.
Development
pip install -e ".[dev]"
pytest # 100% offline — never hits the real API
ruff check src tests && ruff format --check src tests
mypy src # strict
python -m build
Runnable flows (need real merchant credentials via env, except QRIS):
examples/ — 01_login_otp.py, 02_merchants.py, 03_transactions.py,
04_qris_dynamic.py, 05_watch_payment.py, 06_shopee_stores.py,
07_shopee_transactions.py, 08_shopee_watch.py, 09_shopee_login_otp.py.
Research
Full endpoint research (repos surveyed + anonymized HAR verification):
research/RESEARCH_GOPAY_SHOPEEPAY.md + the ShopeePay deep-dive
research/ANALYSIS_SHOPEEPAY_PHASE_B.md. Per-service pages: docs/gopay/,
docs/shopee/.
Credits
API knowledge: kavionn/gobiz-payment, warungerik/API-GOPAY-MERCHANT, alhifnywahid/merchantid, ahmadzakiyox/gopay-api-gateaway, ahmadzakiyox/shoppepay-api-gateway, namtxs/gopay-api. Python package maintained by AlfinAI.
Contributing
- 🐞 Found a bug? Open a bug report — offline repro snippets get fixed fastest.
- 💡 Want an endpoint? Request it with a traffic sample or upstream link as evidence.
- 💬 Questions, ideas, show-and-tell → Discussions.
- 🔒 Security issue? See SECURITY.md — never file it publicly.
- 🤝 Pull requests welcome — see CONTRIBUTING.md.
Contact
Questions, bug reports, or research collaboration — reach me on Telegram: @JoestarMojo.
License
MIT — see LICENSE.
Release files for QrisMerchantID 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qrismerchantid-0.2.0.tar.gz | 53.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qrismerchantid-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.6 kB
Release files / qrismerchantid-0.2.0.tar.gz
| Download URL | qrismerchantid-0.2.0.tar.gz |
|---|---|
| Size | 53.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96ccaa9e88e259358c91b1718c2c48d3487625d428488f38ce8942641a2fa3ca
|
|
BLAKE2b-256 checksum How to use checksums |
eec4a5cf1c37413dd9dee920d9dfcf7298be779d205a924946fcfb13520d826c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / qrismerchantid-0.2.0-py3-none-any.whl
| Download URL | qrismerchantid-0.2.0-py3-none-any.whl |
|---|---|
| Size | 45.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ab5e7d13484f9a129d001a49ddd0c696bb2874e7ee8284508b9ab2b1a0ec44e
|
|
BLAKE2b-256 checksum How to use checksums |
c059ddc8983691f780fb8f812fbfe3b465a82124f572726424390265c7fd036c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency log