Official Python SDK for the TangentoPay API
Project description
tangentopay-python
Official Python SDK for the TangentoPay API.
Requirements
- Python 3.9+
httpx(installed automatically)
Installation
pip install tangentopay
Quick start
1. Storefront — accept a customer payment
Use ServiceClient with your public service API key (pk_live_...).
Get it from: TangentoPay Dashboard → Services → your service → API Keys.
import tangentopay
client = tangentopay.ServiceClient("pk_live_your_key_here")
session = client.checkout.create(
products=[
{"name": "Pro Plan", "price": 49.99, "quantity": 1},
],
currency_code="USD",
customer_email="buyer@example.com",
return_url="https://myshop.com/thank-you",
cancel_url="https://myshop.com/cart",
)
# Redirect your customer to Stripe's hosted checkout:
redirect(session.redirect_url)
2. Success page — confirm payment before fulfilling
# On your /thank-you page, the URL contains ?session_id=...
# Extract the transaction_uid and poll:
status = client.checkout.wait_for_completion(transaction_uid, timeout=60)
if status.is_completed:
fulfill_order()
3. Backend — manage payments with a Bearer token
import tangentopay
merchant = tangentopay.MerchantClient(api_token=os.environ["TANGENTOPAY_API_TOKEN"])
# List payments
page = merchant.payments.list(per_page=20)
for txn in page.data:
print(txn.transaction_uid, txn.transaction_status)
# Issue a refund (Stripe)
refund = merchant.refunds.create(
transaction_uid="TXN-ABC123",
amount=49.99,
reason="Customer request",
pin="1234",
recipient_type="stripe",
)
# Check wallet balance
balances = merchant.wallets.main_balance()
4. Verify incoming webhooks
Always verify the signature before trusting webhook payloads.
import tangentopay
WEBHOOK_SECRET = os.environ["TANGENTOPAY_WEBHOOK_SECRET"]
def handle_webhook(raw_body: bytes, signature_header: str):
try:
event = tangentopay.Webhook.construct_event(
payload=raw_body,
signature=signature_header,
secret=WEBHOOK_SECRET,
)
except tangentopay.WebhookSignatureError:
return 400 # reject
if event.event == "transaction.payment_completed":
fulfill_order(event.payload["transaction_uid"])
return 200
Authentication
| Client | Auth method | When to use |
|---|---|---|
ServiceClient |
X-Service-Key: pk_live_... |
Storefront, checkout, success pages |
MerchantClient |
Authorization: Bearer <token> |
Backend, dashboard, refunds, payouts |
Obtaining a Bearer token
# Step 1: submit credentials (triggers OTP)
challenge = auth_http.post("/auth/sign-in", json={"email": "...", "password": "..."})
# Step 2: verify OTP
token = tangentopay.login(email="me@example.com", password="secret", otp="123456")
merchant = tangentopay.MerchantClient(api_token=token)
Store the token securely (environment variable or secrets manager). It does not expire on its own — call merchant.auth.logout() to revoke it.
Resources
| Resource | Client | Methods |
|---|---|---|
checkout |
ServiceClient |
create(), get_status(), wait_for_completion() |
payments |
MerchantClient |
list(), get(), create_manual() |
refunds |
MerchantClient |
create(), list() |
topups |
MerchantClient |
create(), list() |
payouts |
MerchantClient |
create(), bulk(), list() |
transfers |
MerchantClient |
to_main(), list() |
wallets |
MerchantClient |
main_balance(), service_balance(), manual_balance() |
services |
MerchantClient |
list(), get(), create(), update(), delete(), create_api_key(), list_api_keys(), revoke_api_key(), update_webhook() |
customers |
MerchantClient |
list(), get(), create(), update(), delete(), import_csv() |
analytics |
MerchantClient |
dashboard(), payments_chart(), gross_volume(), total_payouts(), … |
auth |
MerchantClient |
login(), verify_otp(), me(), logout(), change_password() |
Async support
All clients have async equivalents — AsyncServiceClient and AsyncMerchantClient.
import tangentopay
async def main():
async with tangentopay.AsyncServiceClient("pk_live_...") as client:
session = await client.checkout.create(
products=[{"name": "Pro Plan", "price": 49.99, "quantity": 1}],
currency_code="USD",
)
print(session.redirect_url)
Error handling
try:
refund = merchant.refunds.create(...)
except tangentopay.ValidationError as e:
print(e.errors) # {"amount": ["must match original"]}
except tangentopay.AuthenticationError:
print("Invalid token — re-login")
except tangentopay.RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after}s")
except tangentopay.TangentoPayError as e:
print(f"API error {e.http_status}: {e.message}")
| Exception | HTTP status |
|---|---|
AuthenticationError |
401 |
PermissionError |
403 |
NotFoundError |
404 |
ValidationError |
422 |
RateLimitError |
429 |
ServerError |
5xx |
NetworkError |
timeout / DNS failure |
WebhookSignatureError |
— |
Supported currencies
TangentoPay supports Stripe's full currency list including:
USD— US DollarEUR— EuroGBP— British PoundXAF— Central African CFA Franc (Cameroon, Central Africa)NGN— Nigerian NairaGHS— Ghanaian CediKES— Kenyan ShillingZAR— South African Rand
Development
git clone https://github.com/tangentopay/tangentopay-python
cd tangentopay-python
pip install -e ".[dev]"
pytest
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tangentopay-0.1.0.tar.gz.
File metadata
- Download URL: tangentopay-0.1.0.tar.gz
- Upload date:
- Size: 31.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9f812947f2cf88004c8747542f0ee823085de816d3b16e10309ad04606c27a1
|
|
| MD5 |
c9049c915bccdb35860bf33d4b3d5289
|
|
| BLAKE2b-256 |
4a6e166912e718cfd977454a42147ed088fac7d650b11224b6ed7bb2894c48fc
|
File details
Details for the file tangentopay-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tangentopay-0.1.0-py3-none-any.whl
- Upload date:
- Size: 32.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5357c151d7aea48a6dd6b25026280d7369b0a5b86823794149f8221c97c173ec
|
|
| MD5 |
e375e5024053903d47afbf4d90f32bd3
|
|
| BLAKE2b-256 |
e23d513fd1a629fcc32132eadff103c66a5fc53caa703edda5b980c6b93ae93b
|