SDKs
Python SDK
Official Python SDK for the Bag payment platform.
Python SDK
The official Bag Python SDK provides typed access to the Bag API with built-in retry logic, timeout handling, and idiomatic Python interfaces.
Installation
pip install bag-sdkQuick Start
import os
from bag_sdk import Bag
bag = Bag(api_key=os.environ["BAG_API_KEY"])
# Create a payment link
link = bag.payment_links.create(
name="Pro Plan",
amount=29.99,
network="base",
description="Monthly Pro subscription",
)
print(f"Payment URL: https://getbags.app/pay/{link.id}")Payment Links
# List payment links
result = bag.payment_links.list(limit=25)
for link in result.data:
print(f"{link.name}: ${link.amount}")
# Get a single link
link = bag.payment_links.get("link_id")
# Update a link
updated = bag.payment_links.update("link_id", amount=39.99, active=False)
# Delete a link
bag.payment_links.delete("link_id")Checkout
# Get a tax quote
quote = bag.checkout.get_tax_quote(
paymentLinkId="link_id",
customerAddress={
"address_line_1": "100 Main St",
"address_city": "San Francisco",
"address_province": "CA",
"address_postal_code": "94105",
"address_country": "US",
"address_type": "billing",
},
)
# Create a checkout session
session = bag.checkout.create_session(
linkId="link_id",
quoteToken=quote.quote_token,
walletAddress="0xCustomerWallet",
walletType="evm",
network="base",
customer={
"name": "Jane Doe",
"email": "jane@example.com",
"address": "100 Main St, San Francisco, CA 94105",
"country": "US",
},
totalsSnapshot={
"subtotalCents": quote.subtotal_cents,
"taxCents": quote.tax_cents,
"totalCents": quote.total_cents,
"calculationId": quote.calculation_id,
},
)
# Check session status
session = bag.checkout.get_session(session.id)
print(f"Status: {session.status}")
# Submit a transaction hash
bag.checkout.submit(session_id=session.id, tx_hash="0xabc123...")Transactions
# List transactions
result = bag.transactions.list(limit=50)
for tx in result.data:
print(f"{tx.status}: ${tx.amount} on {tx.network}")
# Record a transaction
tx = bag.transactions.create(
amount=29.99,
token="USDC",
network="base",
txHash="0xabc123...",
walletAddress="0xCustomerWallet",
customerEmail="customer@example.com",
paymentLinkId="link_id",
)Refunds
# List refunds
result = bag.refunds.list()
for refund in result.data:
print(f"Refund {refund.id}: ${refund.amount}")
# Create a refund
refund = bag.refunds.create(
transactionId="txn_123abc",
amount=29.99,
reason="customer_request",
)Webhooks
# List webhook endpoints and delivery history
wh = bag.webhooks.list()
for endpoint in wh.endpoints:
print(f"{endpoint.url}: {'active' if endpoint.active else 'paused'}")
print(f"Success rate (24h): {wh.health_stats.success_rate}%")
# Create a webhook endpoint
endpoint = bag.webhooks.create(
url="https://yourapp.com/webhooks/bag",
events=["payment.completed", "payment.failed"],
)
print(f"Secret (store this!): {endpoint.secret}")
# Update a webhook endpoint
bag.webhooks.update("endpoint_id", active=False)
# Delete a webhook endpoint
bag.webhooks.delete("endpoint_id")Verify webhook signatures
import hashlib
import hmac
import time
def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in signature_header.split(","))
timestamp = parts["t"]
expected = parts["v1"]
if abs(time.time() - int(timestamp)) > 300:
return False
message = f"{timestamp}.{raw_body.decode()}"
computed = hmac.new(
secret.encode(), message.encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed, expected)Events
# List all events
result = bag.events.list(limit=50)
for event in result.data:
print(f"{event.event}: {event.status} ({event.attempts} attempts)")
# Filter by type and status
failed = bag.events.list(event="payment.completed", status="failed")
# Filter by date range
recent = bag.events.list(since="2026-03-01T00:00:00Z", until="2026-04-01T00:00:00Z")Customers
# List customers
result = bag.customers.list(limit=25)
for customer in result.data:
print(f"{customer.email}: ${customer.total_spent} ({customer.transaction_count} txns)")
# Get a customer
customer = bag.customers.get("customer_id")
# Create a customer
customer = bag.customers.create(
email="alice@example.com",
name="Alice Johnson",
country="US",
)
# Update a customer
updated = bag.customers.update("customer_id", name="Alice J.", country="GB")Error Handling
from bag_sdk import Bag, BagError
bag = Bag(api_key="bag_test_sk_...")
try:
link = bag.payment_links.create(name="Test", amount=0, network="base")
except BagError as e:
print(f"Error {e.status_code}: {e}")
print(f"Code: {e.code}")Context Manager
The SDK supports Python's context manager protocol for automatic cleanup:
with Bag(api_key=os.environ["BAG_API_KEY"]) as bag:
links = bag.payment_links.list()
# connection is automatically closed when the block exits