Skip to content

Python — tuppence

Terminal window
pip install tuppence
import os
from tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])
customer = tuppence.customers.create(name="Ada Lovelace", email="ada@example.com")
payment = tuppence.payments.create(amount=2000, currency="gbp", customer=customer.id)
print(payment.id, payment.status, payment.approval_url)
# Every item of a list, page by page, fetched only as you reach it.
for c in tuppence.customers.list_all(limit=100):
print(c.id, c.email)
break
from tuppence import AsyncTuppence
async with AsyncTuppence(os.environ["TUPPENCE_SECRET_KEY"]) as tuppence:
payment = await tuppence.payments.create(amount=2000, currency="gbp")
async for refund in tuppence.refunds.list_all(payment=payment.id):
...
  • pydantic models for every object, generated from the API’s contract. Money is always an int of minor units. Fields the API adds later are kept (model_extra).
  • An Idempotency-Key on every POST, reused across that call’s retries; pass idempotency_key= to choose it.
  • Retries — twice by default, with jittered backoff, honouring Retry-After — on network errors, timeouts, 5xx, 429 and a request still in flight. Never another 4xx.
  • Typed errors: CardError, InvalidRequestError, AuthenticationError, PermissionError, RateLimitError, IdempotencyError, APIError, ConnectionError — all TuppenceError, with code, param, decline_code and request_id.
  • Webhooks: tuppence.webhooks.construct_event(raw_body, signature_header, secret).
  • Anything else: tuppence.request("GET", "/v1/…").
Tuppence(key, api_version="2026-09-20", max_retries=4, timeout=10)
tuppence.balance.retrieve(max_retries=0, timeout=2) # per request

base_url= (or TUPPENCE_API_URL in the environment) points it at another API.