Official Python SDK for Shieldz — non-custodial crypto payments with $0 fees.
Accept USDC/USDT across Base, Arbitrum, Optimism, Polygon, and Ethereum, plus native Bitcoin and shielded Zcash. Funds settle straight to your own wallet — Shieldz never holds them, and never asks for your keys.
- 🪪 Non-custodial — payments go wallet → wallet; you keep the keys.
- 🌐 Zero dependencies — pure Python standard library (
urllib,hmac,hashlib). - 🔁 Resilient — automatic retries with backoff, idempotent invoice creation, and cursor auto-pagination.
pip install shieldzRequires Python 3.8+.
import os
from shieldz import Shieldz
shieldz = Shieldz(os.environ["SHIELDZ_API_KEY"])
invoice = shieldz.invoices.create(
amount_usd_cents=5000, # $50.00
memo="Order #1234",
metadata={"order_id": "1234"},
)
print(invoice["id"], invoice["status"], invoice["pay_url"])
# → send your customer to invoice["pay_url"] (the hosted checkout)inv = shieldz.invoices.retrieve("Qgvz8WQw0mnv2M8")
page = shieldz.invoices.list(limit=20, status="paid")
for invoice in shieldz.invoices.list_all(status="paid"):
print(invoice["id"])Retryable POSTs get an auto idempotency_key so a retried create can't duplicate. Pass your own to tie it to your order:
shieldz.invoices.create(amount_usd_cents=5000, idempotency_key="order_1234")Register an HTTPS endpoint in the dashboard and save the whsec_… signing secret. Verify against the raw request body (e.g. Flask):
from flask import Flask, request
from shieldz import construct_event, SignatureVerificationError
app = Flask(__name__)
@app.post("/webhooks/shieldz")
def webhook():
try:
event = construct_event(
request.get_data(), # raw bytes
request.headers.get("X-Shieldz-Signature", ""),
os.environ["SHIELDZ_WEBHOOK_SECRET"],
)
except SignatureVerificationError:
return "", 400
if event["type"] == "invoice.paid":
... # fulfill — dedupe on X-Shieldz-Delivery (at-least-once)
return "", 200verify_signature(raw_body, header, secret) is also exported if you just want a bool. During the 24h after a secret rotation the header carries both signatures and either matches.
from shieldz import ShieldzError
try:
shieldz.invoices.create(amount_usd_cents=1)
except ShieldzError as e:
print(e.status, e.type, e.code, e.param, e.request_id)Shieldz(
api_key="sk_live_…",
base_url="https://shieldz.cash/api/v1", # default
timeout=30.0, # seconds
max_retries=2, # 0 disables
max_retry_delay=8.0,
)- API reference (pdoc): https://shieldzcash.github.io/shieldz-python/
- Docs / API quickstart: https://shieldz.cash/docs
- Is it safe? (non-custodial proof): https://shieldz.cash/verify
- Node/TypeScript SDK: https://github.com/ShieldZCash/shieldz-sdk
MIT © Deniz Yanbollu / Shieldz