Stablevoy Python SDK
Python client for Stablevoy, the non-custodial gateway for USDT and USDC payments. Customers pay on chain and the money goes straight to your own wallet: USDC and USDT on Base, Arbitrum, Optimism, Avalanche, Polygon and BNB Chain, and USDT (TRC20) on Tron with no fee.
The library creates invoices, reads them, and verifies the signed webhooks that tell your shop an order is paid. It has no dependencies, needs Python 3.11 or newer and is fully typed.
Install
pip install stablevoy
Create an invoice and send the buyer to pay
Create an API key for your store in the Stablevoy dashboard.
import os
from stablevoy import Stablevoy
stablevoy = Stablevoy.create(os.environ["STABLEVOY_API_KEY"])
created = stablevoy.invoices.create(
2599, # $25.99 in US cents
external_reference="order-1042", # your order id, sent back in webhooks
return_url="https://shop.example/orders/1042",
idempotency_key="order-1042", # a retry returns the same invoice, never a second one
)
# Send the buyer to created.checkout_url
Read an invoice with stablevoy.invoices.get(invoice_id), or walk them all:
for invoice in stablevoy.invoices.all(status="paid"):
print(invoice.external_reference, invoice.amount_usd_cents)
Verify webhooks
Stablevoy posts an event to your webhook URL when an invoice is paid, overpaid, underpaid, expired, paid late or put on hold. Check the signature before you trust it, using the signing secret shown when you set the webhook in the dashboard. Pass the raw body, exactly as received.
Flask:
from flask import Flask, request
from stablevoy import SignatureError, WebhookVerifier
verifier = WebhookVerifier(os.environ["STABLEVOY_WEBHOOK_SECRET"])
app = Flask(__name__)
@app.post("/stablevoy/webhook")
def stablevoy_webhook():
try:
event = verifier.verify(request.get_data(), request.headers.get("X-Stablevoy-Signature"))
except SignatureError:
return "", 400
if event.invoice is not None and event.invoice.is_paid():
... # mark the order event.invoice.external_reference as paid; use event.id to handle each event once
return "", 200
Django: verifier.verify(request.body, request.headers.get("X-Stablevoy-Signature")). FastAPI: verifier.verify(await request.body(), request.headers.get("X-Stablevoy-Signature")).
Errors and retries
Every error extends StablevoyError. API errors are ApiError with the HTTP status, a stable code, a readable detail and a link to the error catalog; the ones you may want to handle on their own are AuthenticationError, ValidationError (with issues), NotFoundError, RateLimitedError and MaintenanceError. TransportError means no answer at all.
Reads, and creates that carry an idempotency key, are retried on rate limits, maintenance and failed connections, at most twice and only for waits of up to 10 seconds. Anything longer reaches you with retry_after_seconds, so a request never hangs. Every request times out after 30 seconds.
from stablevoy import RetryPolicy, Stablevoy
stablevoy = Stablevoy.create(api_key, retries=RetryPolicy(max_retries=3, max_wait_seconds=30), timeout_seconds=10)
Links
License
MIT
Metadata
Release files for stablevoy 1.0.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 | Provenance | |
|---|---|---|---|---|
| stablevoy-1.0.0.tar.gz | 14.8 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| stablevoy-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.3 kB
Release files / stablevoy-1.0.0.tar.gz
| Download URL | stablevoy-1.0.0.tar.gz |
|---|---|
| Size | 14.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c371f3541aced0aed84a4a5a60e2e3d5a65d750c2a24283a2cff489d2bd5b1c
|
|
BLAKE2b-256 checksum How to use checksums |
96d4ca617e4834ccb900154e99f48f422deb93dd7582ff4ed08738d095cca1fb
|
| 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 25, 2026.
Transparency logRelease files / stablevoy-1.0.0-py3-none-any.whl
| Download URL | stablevoy-1.0.0-py3-none-any.whl |
|---|---|
| Size | 28.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5c1d3f815ca7094cb1359b84d13e3a7c95ec2dfb56f9ea27c287e09941228c1
|
|
BLAKE2b-256 checksum How to use checksums |
d657d8d1abf7297b9d7146d56f5dd7ae93f4052fb72d60911bea00bd355c93fc
|
| 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 25, 2026.
Transparency logSecurity for stablevoy 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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for stablevoy-1.0.0.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 25, 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.