Python SDK
Official ZynPay SDK for Python applications. Perfect for FastAPI backends with MetaMask frontend integration.
v0.2.0TestnetPython ≥3.8
Key Features
- 💳 Accept USDC payments with MetaMask integration
- 🔁 Refunds: Full and partial refunds, enforced by smart contract
- 📊 Payment logs: Fetch on-chain payment history for dashboards & analytics
- 🔒 Non-custodial: Payments go directly to your wallet
- ⚡ Zero backend complexity: No API keys or servers required
Currently Available on Testnet | Mainnet deployment coming soon!
Installation
pip install zynpayQuick Start
Backend (FastAPI)
from fastapi import FastAPI
from zynpay import ZynPayClient, Environment
app = FastAPI()
client = ZynPayClient(
merchant_wallet="0xYourBusinessWallet",
environment=Environment.TESTNET
)
@app.post("/api/payment/create")
async def create_payment(amount: float):
payment = client.payments.create(amount=amount, chain="base")
return {
'payment_id': payment.id,
'amount': payment.amount,
'router_address': payment.router_address
}💡 Frontend pays with MetaMask - no private keys on your server!
API Reference
ZynPayClient(config)
Initialize the SDK client
client = ZynPayClient(
merchant_wallet="0x...",
environment=Environment.TESTNET,
default_chain="base"
)client.payments.create()
Create a new payment request
payment = client.payments.create(
amount=49.99,
chain="base",
metadata={"order_id": "123"}
)client.payments.verify()
Verify payment on blockchain
verified = client.payments.verify(payment, tx_hash="0x...")client.payments.list_payments() – Payment log (on-chain history)
Fetch an on-chain payment log for a merchant
Under the hood, this reads
PaymentSplitgetLogs# Basic: all payments for the configured merchant wallet
payments = client.payments.list_payments()
# Or for another merchant wallet:
payments = client.payments.list_payments(
merchant_address="0xMerchantAddress..."
)
# With filters:
payments = client.payments.list_payments(
merchant_address="0xMerchantAddress...",
network="base-sepolia",
from_block="34000000",
to_block="latest",
)
for p in payments:
amount = float(p["amountTotal"]) / 1e6
merchant_amount = float(p["amountToMerchant"]) / 1e6
fee = float(p["amountToPlatform"]) / 1e6
print("Payment: $" + format(amount, ".2f") + " USDC")
print(" You receive: $" + format(merchant_amount, ".2f") + " USDC")
print(" Platform fee: $" + format(fee, ".2f") + " USDC")
print(" TX: " + p['txHash'])
print(" Payer: " + p['payer'])
if p.get("metadata"):
print(" Metadata: " + str(p['metadata']))Use cases:
- Build a merchant dashboard (revenue, average order value, etc.)
- Export payments to your own database / BI tool
- Reconcile off-chain orders with on-chain payments using metadata (e.g. order_id)
client.payments.refund() – Refund a payment
Refunds are initiated by the merchant wallet that originally received the funds
Use this when you need to refund a customer (full or partial). Refunds are merchant-driven and on-chain.
from zynpay import ZynPayClient, Environment
client = ZynPayClient(
merchant_wallet="0xYourMerchantWallet",
environment=Environment.TESTNET,
)
# Example: refund 5.00 USDC from a previous payment
refund_tx = client.payments.refund(
payment_id="PAYMENT_REQUEST_ID_FROM_BACKEND",
amount=5.00,
chain="base", # optional if default_chain is set
)
print(f"✅ Refund sent! TX: {refund_tx.hash}")How refunds work:
- Refunds are merchant-driven: Only the merchant (the wallet that received the payment) can initiate a refund.
- Refunds are on-chain: The merchant sends USDC back to the payer via the router contract.
- Supports: ✅ Full refunds (up to 100% of the original amount) ✅ Multiple partial refunds
- The smart contract guarantees: You can never refund more than the original amount (cumulative limit). Platform fee is not automatically refunded – if you refund 100%, that extra few % comes from your balance.
🔐 The SDK handles the on-chain call for you. You just decide which payment and how much to refund.
client.web3.get_balance()
Check USDC and native token balance
balance = client.web3.get_balance(wallet="0x...", chain="base")client.web3.estimate_gas()
Estimate gas cost for payment
estimate = client.web3.estimate_gas(amount=10.0, chain="base")client.testnet.get_faucet_url()
Get testnet faucet URL (testnet only)
url = client.testnet.get_faucet_url("base")Environment Management
from zynpay import Environment
# Testnet
client = ZynPayClient(
merchant_wallet="0x...",
environment=Environment.TESTNET
)
# Mainnet (coming soon)
client = ZynPayClient(
merchant_wallet="0x...",
environment=Environment.MAINNET
)Error Handling
from zynpay import (
InsufficientFundsException,
PaymentFailedException
)
try:
payment = client.payments.create(amount=5.00)
except InsufficientFundsException as e:
print(f"Not enough funds: {e.required} USDC required")
except PaymentFailedException as e:
print(f"Payment failed: {e.reason}")Supported Networks
Base Sepolia (Recommended)
chain="base"
Arc Testnet
chain="arc"
Why No API Keys?
ZynPay works directly with the blockchain - no servers, no accounts, no authentication needed. The 3% fee is enforced by smart contracts, making it truly decentralized and permissionless.