All-In-One Sellers API
English | Русский
Contents
- Installation
- Documentation
- Configuration
- Quick Start: PlayerOK
- Quick Start: FunPay
- Quick Start: GGsel
- Multi-account hub
- Durable listener state
- Examples
- Development Status: PlayerOK
- Development Status: FunPay
- Development Status: GGsel
- Limitations
- Security
- Development
- Related projects
- Contributing
- License
- Support the project
Asynchronous Python wrapper for digital trading platforms: FunPay, PlayerOK and GGsel. One package, one event model, one multi-account hub.
Stack: Python 3.12+, asyncio, Pydantic v2, TLS requests, websockets and SQLite. The library talks to the platforms directly: FunPay over HTTP forms and HTML parsing, PlayerOK over GraphQL and WebSocket subscriptions, GGsel over the official Seller API V1. There is no proxy service, telemetry, or third-party backend in the request path.
Status: pre-1.0. The core, transports and listeners are covered by tests, and the public API is documented in docstrings and this README; coverage of the high-level wrappers is still growing. Minor releases may still change behavior. See CHANGELOG.md.
Installation
Install the fork from GitHub:
pip install "git+https://github.com/nechel12/aiosellers.git"
or via uv:
uv add "git+https://github.com/nechel12/aiosellers.git"
The distribution name is aiosellers-nechel12; the import package remains
aiosellers. Install it from PyPI:
pip install aiosellers-nechel12
pip install aiosellers installs the upstream package from PyPI, not this
fork. Pin a commit or tag for reproducible installs:
pip install "git+https://github.com/nechel12/aiosellers.git@<tag>"
Requirements: Python 3.12+.
Documentation
- API overview — public entry points and modules.
- Migration from upstream — install name, changed behavior and upgrade steps.
Configuration
Tokens can be passed to the constructor or through environment variables:
export PLAYEROK_ACCESS_TOKEN="your_token_here"
export FUNPAY_GOLDEN_KEY="your_golden_key"
export GGSEL_API_KEY="your_api_key"
export GGSEL_SELLER_ID="123456"
Playerok(), FunPay() and GGsel() read these variables. Credentials can
also be passed directly: Playerok("token"), FunPay("golden-key") or
GGsel(GGselClientConfig(api_key="key", seller_id=123456)).
Set bot_mark=False in FunPayClientConfig to stop adding the invisible bot
marker to outgoing messages and reviews.
All adapters accept an optional proxy URL:
FunPay(FunPayClientConfig(golden_key="...", proxy="http://user:pass@proxy:8080"))
Playerok(PlayerokClientConfig(access_token="...", proxy="http://proxy:8080"))
GGsel(GGselClientConfig(api_key="...", seller_id=123456, proxy="http://proxy:8080"))
Playerok uses it for HTTP, uploads, downloads and WebSocket subscriptions; GGsel
uses it for ApiLogin and every Seller API request. Proxy credentials are omitted
from config repr.
Quick Start: PlayerOK
import asyncio
from aiosellers.playerok import Playerok
async def main():
async with Playerok() as client:
me = await client.account.me()
profile = await client.account.profile()
print(f"{me.username} | {me.email}")
print(f"Rating: {profile.rating} ({profile.reviews_count} reviews)")
print(f"Available: {profile.balance.available}")
print(f"Pending: {profile.balance.pending_income}")
asyncio.run(main())
Quick Start: FunPay
import asyncio
from aiosellers.funpay import FunPay
async def main():
async with FunPay() as client:
me = await client.account.profile()
balance = await client.finance.balance()
print(f"{me.username} id={me.id}")
print(f"RUB {balance.rub} | USD {balance.usd} | EUR {balance.eur}")
asyncio.run(main())
Quick Start: GGsel
The GGsel adapter uses the official Seller API V1: the client signs a login request with the API key, keeps the access token and polls chats, sales and reviews because GGsel has no webhooks.
import asyncio
from aiosellers.ggsel import GGsel
async def main() -> None:
# Or pass GGselClientConfig(api_key="...", seller_id=123456)
async with GGsel() as client:
balance = await client.account.balance()
print(f"Seller {client.seller_id}: free={balance.free} locked={balance.locked}")
chats = await client.chats.list()
for chat in chats:
print(chat.id, chat.buyer_email, chat.unread_count)
products = await client.products.my(limit=5)
for product in products:
print(product.id, product.name, product.price, product.currency)
asyncio.run(main())
GGsel() reads GGSEL_API_KEY and GGSEL_SELLER_ID; pass
GGselClientConfig explicitly to override either value. client.seller_id is
populated after the client starts, and client.products.update_price() /
update_prices() return a task id that can be checked with
client.products.task_status().
Multi-account hub
SellerHub runs several FunPay, Playerok and GGsel sessions together and merges
their events into one stream. Every item carries the platform and session id,
while the payload stays the original typed event.
import asyncio
from aiosellers import (
FunPay,
GGsel,
GGselClientConfig,
Platform,
Playerok,
SellerHub,
)
async def main():
hub = SellerHub()
hub.add(FunPay("golden-key"), platform=Platform.FUNPAY, session_id="funpay-main")
hub.add(
Playerok("access-token"),
platform=Platform.PLAYEROK,
session_id="playerok-main",
listen_options={"reviews": True},
)
hub.add(
GGsel(GGselClientConfig(api_key="api-key", seller_id=123456)),
platform=Platform.GGSEL,
session_id="ggsel-main",
)
await hub.start()
try:
async for item in hub.stream():
print(item.platform, item.session_id, item.kind, item.event)
finally:
await hub.close()
asyncio.run(main())
item.kind is a portable EventKind (MESSAGE, REVIEW, ORDER, DEAL, ...).
Session.capabilities tells what a platform supports, so shared code can branch
without hardcoding platform names. Clients also expose stop() to end
start_polling() from another task.
Durable listener state
Pass a StateStore in the client config to keep chat cursors, processed message
ids and order snapshots across process restarts. Without a store, listeners
rebuild their state on every launch and emit only the initial snapshots.
import asyncio
from aiosellers import (
FunPay,
FunPayClientConfig,
GGsel,
GGselClientConfig,
Playerok,
PlayerokClientConfig,
SQLiteStateStore,
)
async def main():
store = SQLiteStateStore("sellers.db")
funpay = FunPay(FunPayClientConfig(golden_key="...", state=store))
playerok = Playerok(PlayerokClientConfig(access_token="...", state=store))
ggsel = GGsel(
GGselClientConfig(api_key="...", seller_id=123456, state=store)
)
# ... run the clients ...
await store.close()
asyncio.run(main())
MemoryStateStore keeps the same semantics in process memory, which is handy
for tests. State keys are funpay:{account_id}:listener,
playerok:{user_id}:listener and ggsel:{seller_id}:listener; a malformed
snapshot is ignored with a warning, and a failed write never stops polling.
Examples
Runnable samples are in examples/.
| Script | What it does |
|---|---|
playerok_account.py |
Profile and balance |
playerok_chats.py |
Unread chats and latest messages |
playerok_deals.py |
Paid and sent deals |
playerok_market.py |
Search items and average price |
playerok_bot.py |
Commands and deal events |
transactions.py |
Pending transactions and cards |
funpay_account.py |
Profile, balance, transactions |
funpay_orders.py |
Sales and an order card |
funpay_chats.py |
Chats and message history |
funpay_lots.py |
Lots |
funpay_bot.py |
New order and a chat reply |
funpay_reviews.py |
Reply to a new review |
funpay_backtest.py |
Replay saved chat history |
ggsel_account.py |
Balance and receipts |
ggsel_bot.py |
Chat replies and new sales |
uv run python examples/playerok_account.py
uv run python examples/funpay_account.py
uv run python examples/ggsel_account.py
Development Status: PlayerOK
| Module | Raw API | High-level |
|---|---|---|
| Account | ✅ | ✅ |
| Games / Categories | ✅ | ✅ |
| Items | ✅ | ✅ |
| Deals | ✅ | ✅ |
| Chats | ✅ | ✅ |
| Transactions | ✅ | ✅ |
| Event Feed | ✅ | ✅ |
Development Status: FunPay
| Module | Raw API | High-level |
|---|---|---|
| Account | ✅ | ✅ |
| Balance | ✅ | ✅ |
| Orders / Sales | ✅ | ✅ |
| Chats | ✅ | ✅ |
| Lots | ✅ | ✅ |
| Reviews | ✅ | ✅ |
| Event Feed | ✅ | ✅ |
Development Status: GGsel
GGsel is covered through the official Seller API V1 (https://seller.ggsel.com/).
There are no webhooks, so the listener polls chats, sales and reviews with
durable cursors when a StateStore is configured.
| Module | Raw API | High-level |
|---|---|---|
| Account / Balance | ✅ | ✅ |
| Receipts | ✅ | ✅ |
| Categories | ✅ | ✅ |
| Products / Prices | ✅ | ✅ |
| Sales / Purchases | ✅ | ✅ |
| Chats | ✅ | ✅ |
| Reviews | ✅ | ✅ |
| Event Feed | ✅ | ✅ |
Not implemented yet: the V2 offer API (offer creation/editing) and the legacy
XML /xml/shop_search.asp endpoint. The V1 adapter is enough for order
processing, messaging, reviews and price updates.
Limitations
- FunPay and PlayerOK do not provide official seller APIs; those adapters rely on the same HTTP forms, GraphQL documents and WebSocket feeds the websites use. Platform changes can break them, so pin a version and watch the CHANGELOG.
- GGsel is implemented against Seller API V1 only.
- The library is a client, not a scheduler: the application runs the event loop and decides how to deploy, scale and supervise bots.
- Platform rules, rate limits and account bans are outside the library's control. Use the APIs responsibly and at your own risk.
Security
See SECURITY.md for vulnerability reporting. The library stores
tokens in memory, passes them only to the platform endpoints, and keeps
listener state in the provided StateStore. Do not log credentials, and
protect the SQLite state file if it contains chat metadata.
Report vulnerabilities through GitHub's private advisory flow, not a public issue.
Development
Requires Python 3.12+ and uv.
uv sync --locked
uv run ruff check .
uv run ruff format --check .
uv run mypy aiosellers
uv run pytest -q
uv run pytest -q --cov=aiosellers --cov-fail-under=65
uv run python examples/funpay_account.py
uv build
Structure: aiosellers/core (platforms, events, hub, state stores),
aiosellers/funpay, aiosellers/playerok, aiosellers/ggsel (each with
api, raw, schemas, entities, transport and listener), tests/ and
examples/.
Related projects
- Zewsic/aiosellers — the upstream project this repository is forked from.
- PlayerokAPI — PlayerOK API reference.
- FunPayAPI — FunPay API reference.
- FunPayCardinal — FunPay bot built on the same ideas.
- fpx — another FunPay client.
Contributing
Bug reports and pull requests are welcome. See CONTRIBUTING.md
for the development workflow. By participating, you agree to the
Code of Conduct. Before sending a change, run
uv run ruff check . and uv run pytest -q. Report security issues through
SECURITY.md, not a public issue. Release notes live in
CHANGELOG.md; maintainers can follow RELEASING.md.
License
The code is licensed under Apache-2.0; see LICENSE. The upstream
copyright and license notices are preserved. The PyPI package aiosellers is
maintained by the upstream project and is not affiliated with this fork.
Support the project
All-In-One Sellers API is free and open source. If the project saves time, support is welcome:
Crypto
| Network | Address |
|---|---|
| TRON | TMM2Cdm4tJx1nKRRq5RCBcdwfn9cHuJZy9 |
| TON | UQBlVvOfTleWn4pkY384mYWiGyhdHBryoC_N1Si1OSWAxPKl |
| Bitcoin | bc1qagjtnutjya2rss3u3ls8ur7qk0u7zutc6t6fwc |
| BNB Smart Chain | 0x423aF840f67355371bf32480744A84069dfab5ff |
Metadata
Release files for aiosellers-nechel12 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| aiosellers_nechel12-0.3.2.tar.gz | 249.0 kB | With provenance | Details for aiosellers_nechel12-0.3.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| aiosellers_nechel12-0.3.2-py3-none-any.whl | Python 3 | none | any | Details for aiosellers_nechel12-0.3.2-py3-none-any.whl |
Total release size: 436.8 kB
Release files / aiosellers_nechel12-0.3.2.tar.gz
| Download URL | aiosellers_nechel12-0.3.2.tar.gz |
|---|---|
| Size | 249.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9b7d4533260946f9896b87d3ee2010c29177924ac1321cfc119c45061d8fe446
|
|
BLAKE2b-256 checksum How to use checksums |
932529289bad3d1869c7774de5580c55a6a13df7130f30618e777f4817b0fa7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 30, 2026.
Transparency logRelease files / aiosellers_nechel12-0.3.2-py3-none-any.whl
| Download URL | aiosellers_nechel12-0.3.2-py3-none-any.whl |
|---|---|
| Size | 187.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
760ba1356cffe98590920b2e41422afc9b61eec6646004424ecdc844fd48e27a
|
|
BLAKE2b-256 checksum How to use checksums |
020b7e04bd76865ca5ce74e383110f2d78a928ef99745fffb47dd77806982007
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 30, 2026.
Transparency logSecurity for aiosellers-nechel12 0.3.2
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for aiosellers_nechel12-0.3.2.tar.gz
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 Oct 30, 2026.
Transparency logA 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.