### Create, Get, List, and Archive Customers Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Demonstrates creating a new customer with custom data, retrieving a single customer by ID, listing all customers with auto-pagination, and archiving a customer. ```python from paddle_billing.Resources.Customers.Operations import CreateCustomer, UpdateCustomer from paddle_billing.Entities.Shared import CustomData # Create a customer customer = paddle.customers.create( CreateCustomer( email='alice@example.com', name='Alice Example', custom_data=CustomData({'crm_id': 'crm_789'}), locale='en', ) ) print(f"Customer {customer.id}: {customer.email}") # Get a single customer customer = paddle.customers.get('ctm_01abc') # List all customers (auto-paginated) for c in paddle.customers.list(): print(c.email) # Get credit balances for a customer for balance in paddle.customers.credit_balances('ctm_01abc'): print(f"{balance.currency_code}: {balance.balance.available}") # Generate a short-lived auth token (for Paddle.js) auth_token = paddle.customers.create_auth_token('ctm_01abc') print(f"Token: {auth_token.customer_auth_token} Expires: {auth_token.expires_at}") # Archive a customer paddle.customers.archive('ctm_01abc') ``` -------------------------------- ### Manage Subscription Lifecycle Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Examples for pausing, resuming, and canceling subscriptions. Also shows how to add one-time charges and retrieve payment method change transaction details. ```python paddle.subscriptions.pause('sub_01abc', PauseSubscription( effective_from=SubscriptionEffectiveFrom.NextBillingPeriod, )) ``` ```python paddle.subscriptions.resume('sub_01abc', ResumeSubscription( effective_from=SubscriptionEffectiveFrom.Immediately, )) ``` ```python paddle.subscriptions.cancel('sub_01abc', CancelSubscription( effective_from=SubscriptionEffectiveFrom.Immediately, )) ``` ```python paddle.subscriptions.create_one_time_charge( 'sub_01abc', CreateOneTimeCharge( effective_from=SubscriptionEffectiveFrom.Immediately, items=[SubscriptionUpdateItem(price_id='pri_addon', quantity=1)], ), ) ``` ```python txn = paddle.subscriptions.get_payment_method_change_transaction('sub_01abc') print(f"Checkout URL: {txn.checkout.url}") ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/CONTRIBUTING.md Install pre-commit hooks to ensure codestyle requirements are met before committing. ```bash pre-commit install ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/CONTRIBUTING.md Clone the Paddle Python SDK repository and install development dependencies. ```bash git clone https://github.com/PaddleHQ/paddle-python-sdk && \ cd paddle-python-sdk && \ pip install .[dev] ``` -------------------------------- ### Manage Subscriptions Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Provides examples for listing subscriptions, retrieving a subscription with its transaction history, and updating subscription items, including handling upgrades/downgrades with prorated billing. Ensure necessary operations and entities are imported. ```python from paddle_billing.Resources.Subscriptions.Operations import ( UpdateSubscription, PauseSubscription, ResumeSubscription, CancelSubscription, CreateOneTimeCharge, SubscriptionIncludes, ) from paddle_billing.Resources.Subscriptions.Operations.Update import SubscriptionUpdateItem from paddle_billing.Entities.Subscriptions import SubscriptionEffectiveFrom, SubscriptionProrationBillingMode # List subscriptions (auto-paginated) for sub in paddle.subscriptions.list(): print(sub.id, sub.status) # Get subscription with transaction history sub = paddle.subscriptions.get( 'sub_01abc', includes=[SubscriptionIncludes.RecurringTransactionDetails], ) # Update subscription items (upgrade/downgrade) paddle.subscriptions.update( 'sub_01abc', UpdateSubscription( items=[SubscriptionUpdateItem(price_id='pri_new_plan', quantity=2)], proration_billing_mode=SubscriptionProrationBillingMode.ProratedImmediately, ), ) ``` -------------------------------- ### Create, Get, and Preview Transactions Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Covers creating a draft transaction with items and checkout details, retrieving a transaction with included customer and address data, and previewing tax calculations for an anonymous IP address. Requires imports for various operations and entities. ```python from paddle_billing.Resources.Transactions.Operations import ( CreateTransaction, UpdateTransaction, PreviewTransaction, TransactionIncludes, ) from paddle_billing.Resources.Transactions.Operations.Create import TransactionCreateItem from paddle_billing.Entities.Shared import ( CurrencyCode, CollectionMode, TransactionStatus, Checkout, ) # Create a transaction (draft checkout) transaction = paddle.transactions.create( CreateTransaction( items=[TransactionCreateItem(price_id='pri_01abc', quantity=1)], customer_id='ctm_01abc', currency_code=CurrencyCode.USD, collection_mode=CollectionMode.Automatic, checkout=Checkout(url='https://example.com/thank-you'), ) ) print(f"Transaction {transaction.id}: {transaction.status}") # Get a transaction with customer and address included txn = paddle.transactions.get( transaction.id, includes=[TransactionIncludes.Customer, TransactionIncludes.Address], ) print(f"Customer email: {txn.customer.email}") # Preview tax for an anonymous IP address from paddle_billing.Resources.Transactions.Operations import PreviewTransactionByIP preview = paddle.transactions.preview( PreviewTransactionByIP( items=[TransactionCreateItem(price_id='pri_01abc', quantity=1)], customer_ip_address='8.8.8.8', ) ) print(f"Tax: {preview.details.totals.tax}") # Get invoice PDF URL invoice = paddle.transactions.get_invoice_pdf(transaction.id) print(f"Download: {invoice.url}") ``` -------------------------------- ### Get a Product by ID using Paddle SDK Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Retrieve a specific product by its ID using the `get()` method on the products resource. The method accepts the product's ID as an argument. ```python from paddle_billing import Client paddle = Client('PADDLE_API_SECRET_KEY') product = paddle.products.get('PRODUCT_ID') ``` -------------------------------- ### Create, List, and Delete Notification Settings Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Configure webhook endpoints for receiving Paddle notifications. Ensure the `paddle_billing` library is installed and configured with your API key. ```python from paddle_billing.Resources.NotificationSettings.Operations import ( CreateNotificationSetting, UpdateNotificationSetting, ) from paddle_billing.Entities.NotificationSettings import NotificationSettingType # Create a webhook endpoint subscribed to subscription events setting = paddle.notification_settings.create( CreateNotificationSetting( description='Production webhook', destination='https://example.com/paddle/webhook', subscribed_events=[ 'subscription.created', 'subscription.updated', 'subscription.canceled', 'transaction.completed', ], type=NotificationSettingType.Url, include_sensitive_fields=False, ) ) print(f"Notification setting {setting.id}, secret: {setting.endpoint_secret_key}") # List all notification settings for ns in paddle.notification_settings.list(): print(ns.destination, ns.active) # Delete a webhook endpoint paddle.notification_settings.delete(setting.id) ``` -------------------------------- ### Manage Products with Paddle Billing SDK Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Create, get, list, update, and archive products. Use `ProductIncludes` to eagerly fetch related data like prices. Handle API errors using `ApiError`. ```python from paddle_billing import Client, Environment, Options from paddle_billing.Entities.Shared import TaxCategory, Status, CustomData from paddle_billing.Resources.Products.Operations import ( CreateProduct, UpdateProduct, ListProducts, ProductIncludes, ) from paddle_billing.Exceptions.ApiError import ApiError paddle = Client('PADDLE_API_SECRET_KEY', options=Options(Environment.SANDBOX)) # Create a product try: product = paddle.products.create( CreateProduct( name='Pro Plan', tax_category=TaxCategory.Standard, description='Full-featured SaaS plan', image_url='https://example.com/pro.png', custom_data=CustomData({'tier': 'pro'}) ) ) print(f"Created: {product.id} — {product.name}") except ApiError as e: print(f"Error [{e.error_code}]: {e.detail}") # Get a product with its prices eagerly included product = paddle.products.get(product.id, includes=[ProductIncludes.Prices]) for price in product.prices: print(f" Price: {price.id} {price.description}") # List active products (auto-paginated iterator) for product in paddle.products.list(ListProducts(statuses=[Status.Active])): print(product.name) # Update a product paddle.products.update(product.id, UpdateProduct(name='Pro Plan v2')) # Archive (soft-delete) a product paddle.products.archive(product.id) ``` -------------------------------- ### Manage Prices with Paddle Billing SDK Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Create, get, update, and archive prices. Prices can include trial periods, quantity limits, and per-country overrides for unit prices. Use `PriceIncludes` to fetch related product details. ```python from paddle_billing.Entities.Shared import ( CurrencyCode, Money, Duration, Interval, PriceQuantity, UnitPriceOverride, CountryCode, CustomData, ) from paddle_billing.Resources.Prices.Operations import CreatePrice, UpdatePrice, PriceIncludes # Create a recurring annual price with a 1-week trial and a USD override for CA/US price = paddle.prices.create( CreatePrice( description='Pro Plan — Annual', product_id='pro_01abc123', unit_price=Money('4999', CurrencyCode.GBP), billing_cycle=Duration(Interval.Year, 1), trial_period=Duration(Interval.Week, 1), quantity=PriceQuantity(1, 100), custom_data=CustomData({'plan': 'pro'}) unit_price_overrides=[ UnitPriceOverride( [CountryCode.CA, CountryCode.US], Money('5999', CurrencyCode.USD), ), ], ) ) print(f"Price {price.id}: {price.unit_price.amount} {price.unit_price.currency_code}") # Get a price with product details price = paddle.prices.get(price.id, includes=[PriceIncludes.Product]) print(f"Belongs to product: {price.product.name}") # Update a price paddle.prices.update(price.id, UpdatePrice(description='Pro Plan — Annual (updated)')) # Archive a price paddle.prices.archive(price.id) ``` -------------------------------- ### Prices — `paddle.prices` Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Create and manage prices attached to products, including billing cycles, trial periods, and per-country overrides. Supports creating, getting, updating, and archiving prices. ```APIDOC ## Prices — `paddle.prices` Create and manage prices attached to products, including billing cycles, trial periods, and per-country overrides. ```python from paddle_billing.Entities.Shared import ( CurrencyCode, Money, Duration, Interval, PriceQuantity, UnitPriceOverride, CountryCode, CustomData, ) from paddle_billing.Resources.Prices.Operations import CreatePrice, UpdatePrice, PriceIncludes # Create a recurring annual price with a 1-week trial and a USD override for CA/US price = paddle.prices.create( CreatePrice( description='Pro Plan — Annual', product_id='pro_01abc123', unit_price=Money('4999', CurrencyCode.GBP), billing_cycle=Duration(Interval.Year, 1), trial_period=Duration(Interval.Week, 1), quantity=PriceQuantity(1, 100), custom_data=CustomData({'plan': 'pro'}), unit_price_overrides=[ UnitPriceOverride( [CountryCode.CA, CountryCode.US], Money('5999', CurrencyCode.USD), ), ], ) ) print(f"Price {price.id}: {price.unit_price.amount} {price.unit_price.currency_code}") # Get a price with product details price = paddle.prices.get(price.id, includes=[PriceIncludes.Product]) print(f"Belongs to product: {price.product.name}") # Update a price paddle.prices.update(price.id, UpdatePrice(description='Pro Plan — Annual (updated)')) # Archive a price paddle.prices.archive(price.id) ``` ``` -------------------------------- ### Products — `paddle.products` Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Manage the product catalog. Products are the top-level items sold; prices are attached to products. Supports creating, getting, listing, updating, and archiving products. ```APIDOC ## Products — `paddle.products` Manage the product catalog. Products are the top-level items sold; prices are attached to products. ```python from paddle_billing import Client, Environment, Options from paddle_billing.Entities.Shared import TaxCategory, Status, CustomData from paddle_billing.Resources.Products.Operations import ( CreateProduct, UpdateProduct, ListProducts, ProductIncludes, ) from paddle_billing.Exceptions.ApiError import ApiError paddle = Client('PADDLE_API_SECRET_KEY', options=Options(Environment.SANDBOX)) # Create a product try: product = paddle.products.create( CreateProduct( name='Pro Plan', tax_category=TaxCategory.Standard, description='Full-featured SaaS plan', image_url='https://example.com/pro.png', custom_data=CustomData({'tier': 'pro'}) ) ) print(f"Created: {product.id} — {product.name}") except ApiError as e: print(f"Error [{e.error_code}]: {e.detail}") # Get a product with its prices eagerly included product = paddle.products.get(product.id, includes=[ProductIncludes.Prices]) for price in product.prices: print(f" Price: {price.id} {price.description}") # List active products (auto-paginated iterator) for product in paddle.products.list(ListProducts(statuses=[Status.Active])): print(product.name) # Update a product paddle.products.update(product.id, UpdateProduct(name='Pro Plan v2')) # Archive (soft-delete) a product paddle.products.archive(product.id) ``` ``` -------------------------------- ### Get an Entity Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Retrieve a specific entity by its ID using the `get()` method. The method accepts the entity's ID and returns the entity object. ```APIDOC ## Get an Entity ### Description Retrieve a specific entity by its ID using the `get()` method. The method accepts the entity's ID and returns the entity object. ### Method ```python from paddle_billing import Client paddle = Client('PADDLE_API_SECRET_KEY') product = paddle.products.get('PRODUCT_ID') ``` ``` -------------------------------- ### Handle API Errors with ApiError Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Catch and handle ApiError exceptions raised by the SDK for API failures. This example shows how to inspect error details, check for rate limits, and handle field-specific errors. ```python from paddle_billing.Exceptions.ApiError import ApiError from paddle_billing import Client, Environment, Options import time paddle = Client('PADDLE_API_SECRET_KEY', options=Options(Environment.SANDBOX)) try: product = paddle.products.get('pro_nonexistent') except ApiError as e: print(f"Type: {e.error_type}") # e.g. "request_error" print(f"Code: {e.error_code}") # e.g. "not_found" print(f"Detail: {e.detail}") print(f"Docs: {e.docs_url}") if e.error_code == 'not_found': print("Product does not exist — handle gracefully") if e.error_code == 'too_many_requests' and e.retry_after: print(f"Rate limited — retry after {e.retry_after}s") time.sleep(e.retry_after) if e.field_errors: for fe in e.field_errors: print(f" Field '{fe.field}': {fe.message}") ``` -------------------------------- ### Verify Paddle Webhook Signature Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Verify the HMAC-SHA256 signature of incoming Paddle webhooks to ensure authenticity. This example is suitable for Django or Flask applications. Ensure `WEBHOOK_SECRET_KEY` is set securely. ```python # Django / Flask view example from paddle_billing.Notifications import Secret, Verifier from paddle_billing.Entities.Notifications import NotificationEvent from paddle_billing.Exceptions.ApiError import ApiError def paddle_webhook(request): # request must expose headers and body secret = Secret('WEBHOOK_SECRET_KEY') # Adjust allowed time drift (default: 5 seconds) integrity_check = Verifier(max_seconds_drift=30).verify(request, secret) if not integrity_check: return {'error': 'invalid signature'}, 403 event = NotificationEvent.from_request(request) print(f"Event ID: {event.event_id}") print(f"Event type: {event.event_type}") print(f"Occurred: {event.occurred_at}") # event.data is typed to the specific entity (Customer, Subscription, etc.) if 'subscription' in event.event_type.value: sub = event.data print(f"Subscription {sub.id} is now {sub.status}") return {'ok': True}, 200 ``` -------------------------------- ### Initialize Paddle Client with Sandbox Environment Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Configure the Paddle client to use the sandbox environment by providing an Options object with Environment.SANDBOX. ```python from paddle_billing import Client, Environment, Options paddle = Client('PADDLE_API_SECRET_KEY', options=Options(Environment.SANDBOX)) ``` -------------------------------- ### Client Initialization Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Initialize the Client with an API key. You can optionally specify the sandbox environment and a custom logger. The client also supports custom retry counts and timeouts. ```APIDOC ## Client Initialization Initialize the `Client` with an API key; optionally specify the sandbox environment and a custom logger. ```python from os import getenv from logging import getLogger from paddle_billing import Client, Environment, Options # Live environment (default) paddle = Client(getenv('PADDLE_API_SECRET_KEY')) # Sandbox environment with custom logger log = getLogger('my_app') paddle = Client( getenv('PADDLE_API_SECRET_KEY'), options=Options(Environment.SANDBOX), logger=log, ) # Custom retry count and timeout paddle = Client( getenv('PADDLE_API_SECRET_KEY'), retry_count=5, timeout=30.0, ) ``` ``` -------------------------------- ### Create Adjustments (Refunds and Credits) Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Demonstrates how to create partial or full refunds and retrieve credit note URLs. Ensure amounts are in the lowest currency unit. ```python from paddle_billing.Resources.Adjustments.Operations import CreateAdjustment, CreateAdjustmentItem from paddle_billing.Entities.Shared import Action, AdjustmentType # Partial refund on specific transaction items partial = paddle.adjustments.create( CreateAdjustment.partial( action=Action.Refund, items=[ CreateAdjustmentItem( item_id='txnitm_01abc', type=AdjustmentType.Partial, amount='500', # in lowest currency unit (e.g. cents) ) ], reason='Customer requested partial refund', transaction_id='txn_01abc', ) ) print(f"Partial adjustment: {partial.id}") ``` ```python # Full refund full = paddle.adjustments.create( CreateAdjustment.full( action=Action.Refund, reason='Duplicate charge', transaction_id='txn_01xyz', ) ) print(f"Full adjustment: {full.id}") ``` ```python # Retrieve credit note PDF URL credit_note = paddle.adjustments.get_credit_note(partial.id) print(f"Credit note URL: {credit_note.url}") ``` -------------------------------- ### Initialize Paddle Client Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Initialize the Paddle client with your API key. For security, consider using environment variables. ```python from paddle_billing import Client paddle = Client('PADDLE_API_SECRET_KEY') ``` ```python from os import getenv from paddle_billing import Client paddle = Client(getenv('PADDLE_API_SECRET_KEY')) ``` -------------------------------- ### Create a Product using Paddle SDK Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Create a new product by using the `create()` method on the products resource. This method requires a `CreateProduct` object containing the product details. ```python from paddle_billing import Client from paddle_billing.Entities.Shared.TaxCategory import TaxCategory from paddle_billing.Resources.Products.Operations import CreateProduct paddle = Client('PADDLE_API_SECRET_KEY') created_product = paddle.products.create(CreateProduct( name = 'My Product', tax_category = TaxCategory.Standard, )) ``` -------------------------------- ### Initialize Paddle Client Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Initialize a new Paddle client with your API secret key. You can also pass an environment to work with Paddle's sandbox. ```APIDOC ## Initialize Paddle Client ### Description Initialize a new Paddle client with your API secret key. You can also pass an environment to work with Paddle's sandbox. ### Method ```python from paddle_billing import Client paddle = Client('PADDLE_API_SECRET_KEY') ``` ### Using Environment Variable ```python from os import getenv from paddle_billing import Client paddle = Client(getenv('PADDLE_API_SECRET_KEY')) ``` ### Using Sandbox Environment ```python from paddle_billing import Client, Environment, Options paddle = Client('PADDLE_API_SECRET_KEY', options=Options(Environment.SANDBOX)) ``` ``` -------------------------------- ### Preview Pricing Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Calculate prices including taxes, discounts, and currency conversions before finalizing a transaction. Requires currency and address details. ```python from paddle_billing.Resources.PricingPreviews.Operations import PreviewPrice from paddle_billing.Entities.PricingPreviews import PricePreviewItem from paddle_billing.Entities.Shared import CurrencyCode, AddressPreview, CountryCode preview = paddle.pricing_previews.preview_prices( PreviewPrice( items=[PricePreviewItem(price_id='pri_01abc', quantity=2)], currency_code=CurrencyCode.USD, address=AddressPreview(country_code=CountryCode.US, postal_code='10001'), ) ) for item in preview.details.line_items: print(f"{item.price.description}: unit={item.unit_totals.subtotal} total={item.totals.subtotal}") print(f"Grand total: {preview.details.totals.subtotal} (tax: {preview.details.totals.tax})") ``` -------------------------------- ### Initialize Paddle Billing Client Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Initialize the Client with an API key. Optionally specify the sandbox environment and a custom logger. You can also configure retry counts and timeouts. ```python from os import getenv from logging import getLogger from paddle_billing import Client, Environment, Options # Live environment (default) paddle = Client(getenv('PADDLE_API_SECRET_KEY')) # Sandbox environment with custom logger log = getLogger('my_app') paddle = Client( getenv('PADDLE_API_SECRET_KEY'), options=Options(Environment.SANDBOX), logger=log, ) # Custom retry count and timeout paddle = Client( getenv('PADDLE_API_SECRET_KEY'), retry_count=5, timeout=30.0, ) ``` -------------------------------- ### List Products using Paddle SDK Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Fetch a list of products using the `list()` method on the products resource. This method returns an iterator that automatically handles pagination. ```python from paddle_billing import Client paddle = Client('PADDLE_API_SECRET_KEY') products = paddle.products.list() # list() returns an iterable, so pagination is automatically handled for product in products: print(f"Product's id: {product.id}") ``` -------------------------------- ### Simulations and Simulation Runs Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt This section demonstrates how to trigger test webhook events in the sandbox environment using the Simulations API. It shows how to create a simulation for a specific event type and then run it to fire the webhook, followed by inspecting the run events. ```APIDOC ## Simulations — `paddle.simulations` / `paddle.simulation_runs` Trigger test webhook events in the sandbox without needing to perform real transactions. ```python from paddle_billing.Resources.Simulations.Operations import CreateSimulation from paddle_billing.Resources.SimulationRuns.Operations import CreateSimulationRun # Create a simulation for a subscription.created event simulation = paddle.simulations.create( CreateSimulation( notification_setting_id='ntfset_01abc', type='subscription.created', ) ) print(f"Simulation: {simulation.id}") # Run the simulation (fires the webhook) run = paddle.simulation_runs.create(simulation.id, CreateSimulationRun()) print(f"Run {run.id}: {run.status}") # Inspect individual run events for run_event in paddle.simulation_run_events.list(simulation.id, run.id): print(run_event.status, run_event.response.status_code) ``` ``` -------------------------------- ### Pricing Previews Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Calculate prices with taxes, discounts, and currency conversions applied before creating a transaction. ```APIDOC ## Preview Prices ### Description Calculates estimated prices for a given set of items, currency, and address. ### Method `paddle.pricing_previews.preview_prices(PreviewPrice)` ### Parameters - `PreviewPrice` (object): An object containing pricing preview details, including `items`, `currency_code`, and `address`. - `items` (array of PricePreviewItem): A list of items for which to preview prices. Each item requires `price_id` and `quantity`. - `currency_code` (CurrencyCode): The desired currency for the preview. - `address` (AddressPreview): Customer address details for tax calculation, including `country_code` and `postal_code`. ### Response Example ```python preview = paddle.pricing_previews.preview_prices( PreviewPrice( items=[PricePreviewItem(price_id='pri_01abc', quantity=2)], currency_code=CurrencyCode.USD, address=AddressPreview(country_code=CountryCode.US, postal_code='10001'), ) ) for item in preview.details.line_items: print(f"{item.price.description}: unit={item.unit_totals.subtotal} total={item.totals.subtotal}") print(f"Grand total: {preview.details.totals.subtotal} (tax: {preview.details.totals.tax})") ``` ``` -------------------------------- ### Manage Discounts Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Code for creating, listing, updating, and archiving discount codes. Supports percentage and flat-rate discounts. ```python from paddle_billing.Resources.Discounts.Operations import CreateDiscount, UpdateDiscount from paddle_billing.Entities.Discounts import DiscountType from paddle_billing.Entities.Shared import CurrencyCode # Create a 20% discount with a custom code discount = paddle.discounts.create( CreateDiscount( amount='20', description='Launch week 20% off', type=DiscountType.Percentage, enabled_for_checkout=True, code='LAUNCH20', usage_limit=500, ) ) print(f"Discount {discount.id}: {discount.code}") ``` ```python # List all discounts (auto-paginated) for d in paddle.discounts.list(): print(d.code, d.status) ``` ```python # Update a discount paddle.discounts.update(discount.id, UpdateDiscount(description='Updated promo')) ``` ```python # Archive a discount paddle.discounts.archive(discount.id) ``` -------------------------------- ### Customers Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Create and manage customer records, retrieve credit balances, and generate auth tokens for client-side Paddle.js. ```APIDOC ## Customers — `paddle.customers` Create and manage customer records, retrieve credit balances, and generate auth tokens for client-side Paddle.js. ### Create Customer ```python import paddle from paddle_billing.Resources.Customers.Operations import CreateCustomer from paddle_billing.Entities.Shared import CustomData customer = paddle.customers.create( CreateCustomer( email='alice@example.com', name='Alice Example', custom_data=CustomData({'crm_id': 'crm_789'}) ) ) ``` ### Get Customer ```python customer = paddle.customers.get('ctm_01abc') ``` ### List Customers ```python for c in paddle.customers.list(): print(c.email) ``` ### Get Customer Credit Balances ```python for balance in paddle.customers.credit_balances('ctm_01abc'): print(f"{balance.currency_code}: {balance.balance.available}") ``` ### Create Customer Auth Token ```python auth_token = paddle.customers.create_auth_token('ctm_01abc') ``` ### Archive Customer ```python paddle.customers.archive('ctm_01abc') ``` ``` -------------------------------- ### Generate Customer Portal Sessions Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Create authenticated URLs for customers to manage their subscriptions and billing details. Supports general portal access and subscription-specific actions. ```python from paddle_billing.Resources.CustomerPortalSessions.Operations import CreateCustomerPortalSession session = paddle.customer_portal_sessions.create( 'ctm_01abc', CreateCustomerPortalSession( subscription_ids=['sub_01abc', 'sub_01xyz'], ) ) # General portal URL (update payment method, view invoices) print(f"General portal: {session.urls.general.overview}") # Subscription-specific cancel/update URL for sub_url in session.urls.subscriptions: print(f"Sub {sub_url.id} cancel URL: {sub_url.cancel_subscription}") ``` -------------------------------- ### Update a Product using Paddle SDK Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Update an existing product using the `update()` method on the products resource. This method requires the product's ID and an `UpdateProduct` object with the changes. ```python from paddle_billing import Client from paddle_billing.Resources.Products.Operations import UpdateProduct paddle = Client('PADDLE_API_SECRET_KEY') ``` -------------------------------- ### Format Code with Black Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/CONTRIBUTING.md Format the project's code using the Black code formatter. ```bash black . ``` -------------------------------- ### Generate and Download Financial Reports Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Generate and download financial CSV reports for transactions, adjustments, products/prices, discounts, and payouts. The report status must be 'ready' before downloading. ```python from paddle_billing.Resources.Reports.Operations import ( CreateTransactionsReport, CreateAdjustmentsReport, CreateProductsAndPricesReport, CreatePayoutReconciliationReport, ) # Request a transactions report report = paddle.reports.create(CreateTransactionsReport()) print(f"Report {report.id}: {report.status}") # Poll until ready, then download import time while report.status != 'ready': time.sleep(5) report = paddle.reports.get(report.id) csv_info = paddle.reports.get_report_csv(report.id) print(f"Download URL: {csv_info.url}") # URL expires after a short window # List all reports for r in paddle.reports.list(): print(r.id, r.type, r.status) ``` -------------------------------- ### Create an Entity Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Create a new entity using the `create()` method. This method requires a `CreateOperation` object corresponding to the entity type. ```APIDOC ## Create an Entity ### Description Create a new entity using the `create()` method. This method requires a `CreateOperation` object corresponding to the entity type. ### Method ```python from paddle_billing import Client from paddle_billing.Entities.Shared.TaxCategory import TaxCategory from paddle_billing.Resources.Products.Operations import CreateProduct paddle = Client('PADDLE_API_SECRET_KEY') created_product = paddle.products.create(CreateProduct( name = 'My Product', tax_category = TaxCategory.Standard, )) ``` ``` -------------------------------- ### Manage Customer Addresses Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Shows how to create, list, update, and archive billing addresses associated with a customer. Ensure the `CountryCode` enum is imported. ```python from paddle_billing.Resources.Addresses.Operations import CreateAddress, UpdateAddress from paddle_billing.Entities.Shared import CountryCode # Create an address for a customer address = paddle.addresses.create( 'ctm_01abc', CreateAddress( country_code=CountryCode.US, description='HQ', first_line='1 Main St', city='Austin', region='TX', postal_code='78701', ) ) print(f"Address {address.id}: {address.first_line}, {address.city}") # List addresses for a customer for addr in paddle.addresses.list('ctm_01abc'): print(addr.id, addr.country_code) # Update an address paddle.addresses.update('ctm_01abc', address.id, UpdateAddress(city='Dallas')) # Archive an address paddle.addresses.archive('ctm_01abc', address.id) ``` -------------------------------- ### Trigger Test Webhook Events with Simulations Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Use the Simulations API to create and run test webhook events in the sandbox environment. This is useful for testing your webhook handling logic without performing real transactions. ```python from paddle_billing.Resources.Simulations.Operations import CreateSimulation from paddle_billing.Resources.SimulationRuns.Operations import CreateSimulationRun # Create a simulation for a subscription.created event simulation = paddle.simulations.create( CreateSimulation( notification_setting_id='ntfset_01abc', type='subscription.created', ) ) print(f"Simulation: {simulation.id}") # Run the simulation (fires the webhook) run = paddle.simulation_runs.create(simulation.id, CreateSimulationRun()) print(f"Run {run.id}: {run.status}") # Inspect individual run events for run_event in paddle.simulation_run_events.list(simulation.id, run.id): print(run_event.status, run_event.response.status_code) ``` -------------------------------- ### Subscriptions Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Full subscription lifecycle management: update, pause, resume, cancel, activate, and one-time charges. ```APIDOC ## Subscriptions — `paddle.subscriptions` Full subscription lifecycle management: update, pause, resume, cancel, activate, and one-time charges. ### List Subscriptions ```python for sub in paddle.subscriptions.list(): print(sub.id, sub.status) ``` ### Get Subscription ```python from paddle_billing.Resources.Subscriptions.Operations import SubscriptionIncludes sub = paddle.subscriptions.get( 'sub_01abc', includes=[SubscriptionIncludes.RecurringTransactionDetails] ) ``` ### Update Subscription Items ```python from paddle_billing.Resources.Subscriptions.Operations import UpdateSubscription from paddle_billing.Resources.Subscriptions.Operations.Update import SubscriptionUpdateItem from paddle_billing.Entities.Subscriptions import SubscriptionProrationBillingMode paddle.subscriptions.update( 'sub_01abc', UpdateSubscription( items=[SubscriptionUpdateItem(price_id='pri_new_plan', quantity=2)], proration_billing_mode=SubscriptionProrationBillingMode.ProratedImmediately ) ) ``` ``` -------------------------------- ### Update Product Name with Paddle SDK Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Use the `update()` method to modify product details. Requires the product ID and an UpdateProduct object with the new name. ```python updated_product = paddle.products.update('PRODUCT_ID', UpdateProduct( name = 'My Improved Product' ) ) ``` -------------------------------- ### Discounts Operations Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Create and manage percentage, flat, and flat-per-seat discount codes. ```APIDOC ## Create Discount ### Description Creates a new discount code. ### Method `paddle.discounts.create(CreateDiscount)` ### Parameters - `CreateDiscount` (object): An object containing discount details, including `amount`, `description`, `type`, `enabled_for_checkout`, `code`, and `usage_limit`. ### Request Example ```python paddle.discounts.create( CreateDiscount( amount='20', description='Launch week 20% off', type=DiscountType.Percentage, enabled_for_checkout=True, code='LAUNCH20', usage_limit=500, ) ) ``` ## List Discounts ### Description Lists all available discounts. This operation is auto-paginated. ### Method `paddle.discounts.list()` ### Response Example ```python for d in paddle.discounts.list(): print(d.code, d.status) ``` ## Update Discount ### Description Updates an existing discount code. ### Method `paddle.discounts.update(discount_id, UpdateDiscount)` ### Parameters - `discount_id` (string): The ID of the discount to update. - `UpdateDiscount` (object): An object containing the fields to update. ### Request Example ```python paddle.discounts.update(discount.id, UpdateDiscount(description='Updated promo')) ``` ## Archive Discount ### Description Archives a discount code, making it inactive. ### Method `paddle.discounts.archive(discount_id)` ### Parameters - `discount_id` (string): The ID of the discount to archive. ### Request Example ```python paddle.discounts.archive(discount.id) ``` ``` -------------------------------- ### Metrics Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Retrieve time-series business metrics such as MRR, active subscribers, revenue, refunds, chargebacks, and checkout conversion using the `paddle.metrics` module. ```APIDOC ## Metrics — `paddle.metrics` Retrieve time-series business metrics: MRR, active subscribers, revenue, refunds, chargebacks, and checkout conversion. ```python from paddle_billing.Resources.Metrics.Operations import GetMetrics params = GetMetrics(date_from='2025-01-01', date_to='2025-06-30') mrr = paddle.metrics.get_monthly_recurring_revenue(params) print(f"MRR current: {mrr.period.value} {mrr.currency_code}") mrr_change = paddle.metrics.get_monthly_recurring_revenue_change(params) active = paddle.metrics.get_active_subscribers(params) revenue = paddle.metrics.get_revenue(params) refunds = paddle.metrics.get_refunds(params) chargebacks = paddle.metrics.get_chargebacks(params) conversion = paddle.metrics.get_checkout_conversion(params) for point in revenue.data: print(f" {point.period}: {point.value}") ``` ``` -------------------------------- ### List Entities Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md List supported entities using the `list()` method. This method returns an iterator to handle pagination automatically. ```APIDOC ## List Entities ### Description List supported entities using the `list()` method. This method returns an iterator to handle pagination automatically. ### Method ```python from paddle_billing import Client paddle = Client('PADDLE_API_SECRET_KEY') products = paddle.products.list() # list() returns an iterable, so pagination is automatically handled for product in products: print(f"Product's id: {product.id}") ``` ``` -------------------------------- ### Run Pytest Tests Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/CONTRIBUTING.md Execute Python pytest tests within the Paddle Python SDK project. ```bash cd paddle-python-sdk && .venv/bin/pytest ``` ```bash cd paddle-python-sdk && \ source .venv/bin/activate && \ pytest ``` -------------------------------- ### Customer Portal Sessions Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Generate authenticated portal URLs so customers can self-manage subscriptions and billing details. ```APIDOC ## Create Customer Portal Session ### Description Generates a secure URL for the customer portal, allowing customers to manage their subscriptions and billing information. ### Method `paddle.customer_portal_sessions.create(customer_id, CreateCustomerPortalSession)` ### Parameters - `customer_id` (string): The ID of the customer. - `CreateCustomerPortalSession` (object): An object containing session details, including `subscription_ids`. - `subscription_ids` (array of string): A list of subscription IDs to include in the portal session. ### Response Example ```python session = paddle.customer_portal_sessions.create( 'ctm_01abc', CreateCustomerPortalSession( subscription_ids=['sub_01abc', 'sub_01xyz'], ) ) # General portal URL (update payment method, view invoices) print(f"General portal: {session.urls.general.overview}") # Subscription-specific cancel/update URL for sub_url in session.urls.subscriptions: print(f"Sub {sub_url.id} cancel URL: {sub_url.cancel_subscription}") ``` ``` -------------------------------- ### Notifications & Webhook Settings Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Configure webhook endpoints and inspect delivered notification history using the `paddle.notification_settings` and `paddle.notifications` modules. ```APIDOC ## Notifications & Webhook Settings — `paddle.notification_settings` / `paddle.notifications` Configure webhook endpoints and inspect delivered notification history. ```python from paddle_billing.Resources.NotificationSettings.Operations import ( CreateNotificationSetting, UpdateNotificationSetting, ) from paddle_billing.Entities.NotificationSettings import NotificationSettingType # Create a webhook endpoint subscribed to subscription events setting = paddle.notification_settings.create( CreateNotificationSetting( description='Production webhook', destination='https://example.com/paddle/webhook', subscribed_events=[ 'subscription.created', 'subscription.updated', 'subscription.canceled', 'transaction.completed', ], type=NotificationSettingType.Url, include_sensitive_fields=False, ) ) print(f"Notification setting {setting.id}, secret: {setting.endpoint_secret_key}") # List all notification settings for ns in paddle.notification_settings.list(): print(ns.destination, ns.active) # Delete a webhook endpoint paddle.notification_settings.delete(setting.id) # List recent notification deliveries for notif in paddle.notifications.list(): print(notif.id, notif.status, notif.type) ``` ``` -------------------------------- ### Retrieve Business Metrics Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Retrieve time-series business metrics including MRR, active subscribers, revenue, refunds, chargebacks, and checkout conversion. Specify date ranges for the metrics. ```python from paddle_billing.Resources.Metrics.Operations import GetMetrics params = GetMetrics(date_from='2025-01-01', date_to='2025-06-30') mrr = paddle.metrics.get_monthly_recurring_revenue(params) print(f"MRR current: {mrr.period.value} {mrr.currency_code}") mrr_change = paddle.metrics.get_monthly_recurring_revenue_change(params) active = paddle.metrics.get_active_subscribers(params) revenue = paddle.metrics.get_revenue(params) refunds = paddle.metrics.get_refunds(params) chargebacks = paddle.metrics.get_chargebacks(params) conversion = paddle.metrics.get_checkout_conversion(params) for point in revenue.data: print(f" {point.period}: {point.value}") ``` -------------------------------- ### Reports Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Generate and download financial CSV reports for transactions, adjustments, products/prices, discounts, and payouts using the `paddle.reports` module. ```APIDOC ## Reports — `paddle.reports` Generate and download financial CSV reports for transactions, adjustments, products/prices, discounts, and payouts. ```python from paddle_billing.Resources.Reports.Operations import ( CreateTransactionsReport, CreateAdjustmentsReport, CreateProductsAndPricesReport, CreatePayoutReconciliationReport, ) # Request a transactions report report = paddle.reports.create(CreateTransactionsReport()) print(f"Report {report.id}: {report.status}") # Poll until ready, then download import time while report.status != 'ready': time.sleep(5) report = paddle.reports.get(report.id) csv_info = paddle.reports.get_report_csv(report.id) print(f"Download URL: {csv_info.url}") # URL expires after a short window # List all reports for r in paddle.reports.list(): print(r.id, r.type, r.status) ``` ``` -------------------------------- ### Update Address for Customer with Paddle SDK Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md The `update()` method can accept multiple IDs for operations involving related entities, such as updating an address for a specific customer. ```python updated_address = paddle.addresses.update( 'CUSTOMER_ID', 'ADDRESS_ID', operation_goes_here, ) ``` -------------------------------- ### Verify Webhook Signature with Paddle SDK Source: https://github.com/paddlehq/paddle-python-sdk/blob/main/README.md Utilize the `Verifier` class to check the integrity of incoming webhooks. Pass the request object and a `Secret` containing your webhook key. ```python from paddle_billing.Notifications import Secret, Verifier integrity_check = Verifier().verify(request, Secret('WEBHOOK_SECRET_KEY')) ``` -------------------------------- ### Error Handling with ApiError Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt This section details how the Paddle Billing Python SDK handles API errors. It explains that all API failures raise an `ApiError` and demonstrates how to catch this exception to inspect error details such as type, code, detail, and documentation URL, and how to handle specific error codes like 'not_found' or 'too_many_requests'. ```APIDOC ## Error Handling All API failures raise `ApiError`; rate-limit responses expose `retry_after` in seconds. ```python from paddle_billing.Exceptions.ApiError import ApiError from paddle_billing import Client, Environment, Options import time paddle = Client('PADDLE_API_SECRET_KEY', options=Options(Environment.SANDBOX)) try: product = paddle.products.get('pro_nonexistent') except ApiError as e: print(f"Type: {e.error_type}") # e.g. "request_error" print(f"Code: {e.error_code}") # e.g. "not_found" print(f"Detail: {e.detail}") print(f"Docs: {e.docs_url}") if e.error_code == 'not_found': print("Product does not exist — handle gracefully") if e.error_code == 'too_many_requests' and e.retry_after: print(f"Rate limited — retry after {e.retry_after}s") time.sleep(e.retry_after) if e.field_errors: for fe in e.field_errors: print(f" Field '{fe.field}': {fe.message}") ``` ``` -------------------------------- ### Transactions Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Create, read, and update transactions; preview tax calculations; and retrieve invoice PDFs. ```APIDOC ## Transactions — `paddle.transactions` Create, read, and update transactions; preview tax calculations; and retrieve invoice PDFs. ### Create Transaction ```python import paddle from paddle_billing.Resources.Transactions.Operations import CreateTransaction from paddle_billing.Resources.Transactions.Operations.Create import TransactionCreateItem from paddle_billing.Entities.Shared import CurrencyCode, CollectionMode, Checkout transaction = paddle.transactions.create( CreateTransaction( items=[TransactionCreateItem(price_id='pri_01abc', quantity=1)], customer_id='ctm_01abc', currency_code=CurrencyCode.USD, collection_mode=CollectionMode.Automatic, checkout=Checkout(url='https://example.com/thank-you') ) ) ``` ### Get Transaction ```python from paddle_billing.Resources.Transactions.Operations import TransactionIncludes txn = paddle.transactions.get( transaction.id, includes=[TransactionIncludes.Customer, TransactionIncludes.Address] ) ``` ### Preview Transaction by IP ```python from paddle_billing.Resources.Transactions.Operations import PreviewTransactionByIP from paddle_billing.Resources.Transactions.Operations.Create import TransactionCreateItem preview = paddle.transactions.preview( PreviewTransactionByIP( items=[TransactionCreateItem(price_id='pri_01abc', quantity=1)], customer_ip_address='8.8.8.8' ) ) ``` ### Get Invoice PDF URL ```python invoice = paddle.transactions.get_invoice_pdf(transaction.id) ``` ``` -------------------------------- ### Events Source: https://context7.com/paddlehq/paddle-python-sdk/llms.txt Poll the event log for replay, auditing, and missed-event recovery using cursor-based pagination with the `paddle.events` module. ```APIDOC ## Events — `paddle.events` Poll the event log for replay, auditing, and missed-event recovery using cursor-based pagination. ```python from paddle_billing.Resources.Events.Operations import ListEvents from paddle_billing.Resources.Shared.Operations import Pager from paddle_billing.Exceptions.ApiError import ApiError last_id = 'evt_01hfxx8t6ek9h399srcrp36jt3' try: events = paddle.events.list(ListEvents(Pager(after=last_id))) except ApiError as e: print(f"Error: {e.detail}") events = None if events: for event in events: last_id = event.event_id # persist for next poll print(f"{event.event_id} {event.event_type.value:30} {event.occurred_at}") ``` ```