Metadata-Version: 2.4
Name: paddle-python-sdk
Version: 1.14.1
Summary: Paddle's Python SDK for Paddle Billing
Home-page: https://developer.paddle.com/api-reference/overview
Author: Paddle and contributors
Author-email: team-dx@paddle.com
License: Apache-2.0
Keywords: paddle,sdk,python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31
Requires-Dist: urllib3>=1.26.18
Provides-Extra: dev
Requires-Dist: pytest<9.1.0,>=7.4.4; extra == "dev"
Requires-Dist: pytest-cov<7.2,>=4.1; extra == "dev"
Requires-Dist: requests-mock~=1.11.0; extra == "dev"
Requires-Dist: setuptools>=69.0.3; extra == "dev"
Requires-Dist: pre-commit>=3.8.0; extra == "dev"
Requires-Dist: black>=24.8.0; extra == "dev"
Requires-Dist: flake8>=7.1.1; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

[![Build Status](https://img.shields.io/github/actions/workflow/status/PaddleHQ/paddle-python-sdk/publish_to_pypi.yml)](https://github.com/PaddleHQ/paddle-python-sdk/actions/?query=branch%3Amain)
[![PyPI](https://img.shields.io/pypi/v/paddle-python-sdk.svg)](https://pypi.python.org/pypi/paddle-python-sdk)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/paddle-python-sdk.svg)](https://pypi.python.org/pypi/paddle-python-sdk/)
[![License: Apache 2.0](https://img.shields.io/github/license/PaddleHQ/paddle-python-sdk)](http://www.apache.org/licenses/LICENSE-2.0)


# paddle-python-sdk
[Paddle Billing](https://developer.paddle.com/?utm_source=dx&utm_medium=paddle-python-sdk) is the developer-first merchant of record, designed for modern SaaS, AI, mobile app, and digital product businesses. We take care of payments, tax, subscriptions, and metrics with one unified API that does it all.

This is a [Python](https://www.python.org/) SDK that you can use to integrate Paddle Billing with applications written in Python.

For working with Paddle in your frontend, use [Paddle.js](https://developer.paddle.com/paddlejs/overview?utm_source=dx&utm_medium=paddle-python-sdk). You can open checkouts, securely collect payment information, build pricing pages, and integrate with Paddle Retain.

> **Important:** This package works with Paddle Billing. It does not support Paddle Classic. To work with Paddle Classic, see: [Paddle Classic dev docs](https://classic.paddle.com/?utm_source=dx&utm_medium=paddle-python-sdk)


## Table of contents
- [Requirements](#Requirements)
- [Install](#Install)
- [Usage](#Usage)
- [Examples](#Examples)
- [Resources](#Resources)

## Requirements
Python>=3.11 (for native type hinting, StrEnum, trailing commas, f-strings)

**Project dependencies** (automatically installed by pip):
- requests>=2.31
- urllib3>=2.1.0


## Install
Because `paddle-python-sdk` is [available on PyPi](https://pypi.org/project/paddle-python-sdk/), installation is as simple as running the following `pip` command: 

`pip install paddle-python-sdk`



## Usage
To authenticate, you'll need an API key. You can create and manage API keys in **Paddle > Developer tools > Authentication**.

Pass your API key while initializing a new Paddle client:
``` python
from paddle_billing import Client

paddle = Client('PADDLE_API_SECRET_KEY')
```

You can pass your Paddle API secret key into the SDK from an environment variable:
``` python
from os             import getenv
from paddle_billing import Client

paddle = Client(getenv('PADDLE_API_SECRET_KEY'))
```

You can also pass an environment to work with Paddle's sandbox:
``` python
from paddle_billing import Client, Environment, Options

paddle = Client('PADDLE_API_SECRET_KEY', options=Options(Environment.SANDBOX))
```

Keep in mind that API keys are separate for your sandbox and live accounts, so you'll need to generate keys for each environment.



## Examples
There are examples included in the [examples folder](https://github.com/PaddleHQ/paddle-python-sdk/tree/main/examples). To prevent leaking errors we recommend encapsulating Paddle operations inside Try/Except blocks. For brevity, most of the examples below do not do this.

### List entities
You can list supported entities with the `list()` method in the resource. It returns an iterator to help when working with multiple pages.
``` 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}")
```

### Get an entity
You can get an entity with the `get()` method in the resource. It accepts the `id` of the entity to get. The entity is returned.
``` python
from paddle_billing import Client

paddle = Client('PADDLE_API_SECRET_KEY')

product = paddle.products.get('PRODUCT_ID')
```

### Create an entity
You can create a supported entity with the `create()` method in the resource. It accepts the resource's corresponding `CreateOperation` e.g. `CreateProduct`. The created entity is returned.

``` 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,
))
```

### Update an entity
You can update a supported entity with the `update()` method in the resource. It accepts the `id` of the entity to update and the corresponding `UpdateOperation` e.g. `UpdateProduct`. The updated entity is returned.
``` python
from paddle_billing                        import Client
from paddle_billing.Resources.Products.Operations import UpdateProduct

paddle = Client('PADDLE_API_SECRET_KEY')

# Update the name of the product
updated_product = paddle.products.update('PRODUCT_ID', UpdateProduct(
    name = 'My Improved Product'
))
```

Where operations require more than one `id`, the `update()` method accepts multiple arguments. For example, to update an address for a customer, pass the `customerId` and the `addressId`:
``` python
updated_address = paddle.addresses.update(
    'CUSTOMER_ID',
    'ADDRESS_ID',
    operation_goes_here,
)
```

### Delete an entity
You can delete an entity with the `delete()` method in the resource. It accepts the `id` of the entity to delete. The deleted entity is returned.
``` python
from paddle_billing import Client

paddle = Client('PADDLE_API_SECRET_KEY')

deleted_product = paddle.products.delete('PRODUCT_ID')
```

### Error Handling

If a request fails, Paddle raises an `ApiError` that contains the same information as [errors returned by the API](https://developer.paddle.com/api-reference/about/errors?utm_source=dx&utm_medium=paddle-python-sdk). You can use the `code` attribute to search an error in [the error reference](https://developer.paddle.com/errors/overview?utm_source=dx&utm_medium=paddle-python-sdk) and to handle the error in your app. Validation errors also return an array of `errors` that tell you which fields failed validation. The `retry_after` property will be set for `too_many_requests` errors.

This example shows how to handle an error with the code `conflict`:

```python
from paddle_billing.Exceptions.ApiError import ApiError

try:
    # Call functions from the SDK
except ApiError as error:
    # error.error_code will always follow the error code defined in our documentation
    if error.error_code == 'conflict':
        # Handle Conflict error
```

## Resources

### Webhook signature verification
The SDK includes a helper class to verify webhook signatures sent by Notifications from Paddle.

``` python
from paddle_billing.Notifications import Secret, Verifier

integrity_check = Verifier().verify(request, Secret('WEBHOOK_SECRET_KEY'))
```

The `verify()` method currently accepts any request object matching the `paddle_billing.Notifications.Requests.Request` protocol, and supports popular frameworks such as Flask and Django.

Time drift max variance can be adjusted by passing `seconds` to `Verifier()` _(default: 5 seconds)_:

```python
integrity_check = Verifier(seconds).verify(request, Secret('WEBHOOK_SECRET_KEY'))
```

## Learn more
- [Paddle API reference](https://developer.paddle.com/api-reference/overview?utm_source=dx&utm_medium=paddle-python-sdk)
- [Sign up for Paddle Billing](https://login.paddle.com/signup?utm_source=dx&utm_medium=paddle-python-sdk)
