# payOS Python SDK
[>)](https://pypi.org/project/payos/)
The payOS Python library provides convenient access to the payOS Merchant API from applications written in Python. The library includes type definitions for all request params and response fields, and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
To learn how to use payOS Merchant API, checkout our [API Reference](https://payos.vn/docs/api) and [Documentation](https://payos.vn/docs). We also have some examples in [Examples](./examples/).
## Requirements
Python 3.9 or higher.
## Installation
```bash
# install from PyPi
pip install payos
```
> [!IMPORTANT]
> If update from v0, check [Migration guide](./MIGRATION.md) for detail migration.
## Usage
### Basic usage
First you need to initialize the client to interacting with payOS Merchant API.
```python
from payos import PayOS
client = PayOS(
client_id=os.getenv("PAYOS_CLIENT_ID"),
api_key=os.getenv("PAYOS_API_KEY"),
checksum_key=os.getenv("PAYOS_CHECKSUM_KEY"),
# ... other options
)
```
Then you can interact with payOS Merchant API, example create a payment link using `payment_requests.create()`.
```python
from payos.types import CreatePaymentLinkRequest
response = client.payment_requests.create(payment_data=CreatePaymentLinkRequest(
order_code=int(time.time()),
amount=2000,
description="Thanh toan",
cancel_url="https://your-url.com/cancel",
return_url="https://your-url.com/success",
))
```
### Webhook verification
You can register an endpoint to receive the payment webhook.
```python
confirm_result = client.webhooks.confirm('https://your-url.com/webhooks')
```
Then using `webhooks.verify()` to verify and receive webhook data.
```python
# example using flask, more details in ./examples/webhooks_handling.py
@app.route("/webhooks", methods=["POST"])
def webhooks():
data = request.get_data()
try:
webhook_data = client.webhooks.verify(data)
except WebhookError as e:
return jsonify({"error": str(e)}), 400
return jsonify({"error": None, "data": webhook_data.model_dump_camel_case()})
```
For more information about webhooks, see [the API doc](https://payos.vn/docs/api/#tag/payment-webhook/operation/payment-webhook).
### Handling errors
When the API return a non-success status code(i.e, 4xx or 5xx response) or non-success code data (any code except '00'), a subclass of `payos.APIError` is raised.
```python
try:
response = client.payment_requests.create(payment_data=payment_data)
print(response)
except APIError as e:
print(e.error_code)
print(e.error_desc)
print(e.status_code)
```
### Asynchronous usage
Simply import `AsyncPayOS` instead of `PayOS` and use `await` with each API call:
```python
import asyncio
from payos import AsyncPayOS
from payos.types import CreatePaymentLinkRequest
async def main() -> None:
client = AsyncPayOS()
payment_data = CreatePaymentLinkRequest(
order_code=int(time.time()),
amount=2000,
description="Thanh toan",
cancel_url="https://your-url.com/cancel",
return_url="https://your-url.com/success",
)
try:
response = await client.payment_requests.create(payment_data=payment_data)
print(response)
except APIError as e:
print(e)
asyncio.run(main())
```
### Auto pagination
List method in the payOS Merchant API are paginated, the library provides auto-paginating iterators with each response.
```python
import os
from payos import PayOS
from payos.types import GetPayoutListParams
client = PayOS(
client_id=os.getenv("PAYOS_PAYOUT_CLIENT_ID"),
api_key=os.getenv("PAYOS_PAYOUT_API_KEY"),
checksum_key=os.getenv("PAYOS_PAYOUT_CHECKSUM_KEY"),
)
def main() -> None:
payouts = []
for payout in client.payouts.list(GetPayoutListParams(limit=3)):
payouts.append(payout)
# or
payouts_data = client.payouts.list(GetPayoutListParams(limit=3))
payouts = payout_data.to_list()
print(payouts)
main()
```
Or asynchronous:
```python
import asyncio
import os
from payos import AsyncPayOS
from payos.types import GetPayoutListParams
client = AsyncPayOS(
client_id=os.getenv("PAYOS_PAYOUT_CLIENT_ID"),
api_key=os.getenv("PAYOS_PAYOUT_API_KEY"),
checksum_key=os.getenv("PAYOS_PAYOUT_CHECKSUM_KEY"),
)
async def main() -> None:
payouts = []
async for payout in await client.payouts.list(GetPayoutListParams(limit=3)):
payouts.append(payout)
# or
payouts_data = await client.payouts.list(GetPayoutListParams(limit=3))
payouts = await payouts_data.to_list()
print(payouts)
asyncio.run(main())
```
Alternative, you can use the `.has_next_page()`, `.get_next_page()` methods for more control:
```python
# remove `await` for non-async usage
first_page = await client.payouts.list(GetPayoutListParams(limit=3))
if first_page.has_next_page():
next_page = await first_page.get_next_page()
print(f"number of items we just fetched: {len(next_page.data)}")
```
Or just work directly with the returned data:
```python
# remove `await` for non-async usage
first_page = await client.payouts.list(GetPayoutListParams(limit=3))
for payout in first_page.data:
print(payout.id)
```
### Advanced usage
#### Custom configuration
You can customize the PayOS client with various options:
```python
import os
import httpx
from payos import PayOS
client = PayOS(
client_id=os.getenv("PAYOS_CLIENT_ID"),
api_key=os.getenv("PAYOS_API_KEY"),
checksum_key=os.getenv("PAYOS_CHECKSUM_KEY"),
timeout=15.0,
max_retries=4,
http_client=httpx.Client(
proxy="http://my-proxy.com", transport=httpx.HTTPTransport(local_address="0.0.0.0")
),
)
```
#### Request-level options
You can override client-level settings for individual requests:
```python
from payos import PayOS
client = PayOS()
client.payment_requests.get(1757060811, timeout=2, max_retries=0)
```
#### Logging
We use standard library [`logging`](https://docs.python.org/3/library/logging.html) module. You can enable logging by setting the environment variable `PAYOS_LOG` to `info` or `debug`.
```bash
export PAYOS_LOG=info
```
#### Direct API access
For advanced use cases, you can make direct API calls:
```python
from payos import PayOS
client = PayOS()
response = client.get("/v2/payment-requests", cast_to=dict)
response = client.post(
"/v2/payment-requests",
body={
"orderCode": int(time()),
"amount": 2000,
"description": "thanh toan",
"returnUrl": "https://your-url.com/success",
"cancelUrl": "https://your-url.com/cancel",
"signature": "signature",
},
cast_to=dict,
)
```
#### Signature
The signature can be manually created by `.crypto`:
```python
# for create payment link signature
signature = client.crypto.create_signature_of_payment_request(
{
"orderCode": int(time()),
"amount": 2000,
"description": "thanh toan",
"returnUrl": "https://your-url.com/success",
"cancelUrl": "https://your-url.com/cancel",
},
client.checksum_key,
)
# for payment-requests and webhook signature
signature = client.crypto.create_signature_from_object(
data,
client.checksum_key,
)
# for payouts signature
signature = client.crypto.create_signature(client.checksum_key, data)
```
## Contributing
See [the contributing documentation](./CONTRIBUTING.md).
Raw data
{
"_id": null,
"home_page": null,
"name": "payos",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "payos, payment, payos-python, sdk, python",
"author": "payOS Team",
"author_email": "payOS Team <support@payos.vn>",
"download_url": "https://files.pythonhosted.org/packages/98/f0/329739ef6d1ff3bd3d6b484cc0019833bb2617acefe5849c7e3dd68fe9cd/payos-1.0.0.tar.gz",
"platform": null,
"description": "# payOS Python SDK\n\n[>)](https://pypi.org/project/payos/)\n\nThe payOS Python library provides convenient access to the payOS Merchant API from applications written in Python. The library includes type definitions for all request params and response fields, and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).\n\nTo learn how to use payOS Merchant API, checkout our [API Reference](https://payos.vn/docs/api) and [Documentation](https://payos.vn/docs). We also have some examples in [Examples](./examples/).\n\n## Requirements\n\nPython 3.9 or higher.\n\n## Installation\n\n```bash\n# install from PyPi\npip install payos\n```\n\n> [!IMPORTANT]\n> If update from v0, check [Migration guide](./MIGRATION.md) for detail migration.\n\n## Usage\n\n### Basic usage\n\nFirst you need to initialize the client to interacting with payOS Merchant API.\n\n```python\nfrom payos import PayOS\n\nclient = PayOS(\n client_id=os.getenv(\"PAYOS_CLIENT_ID\"),\n api_key=os.getenv(\"PAYOS_API_KEY\"),\n checksum_key=os.getenv(\"PAYOS_CHECKSUM_KEY\"),\n # ... other options\n)\n```\n\nThen you can interact with payOS Merchant API, example create a payment link using `payment_requests.create()`.\n\n```python\nfrom payos.types import CreatePaymentLinkRequest\n\nresponse = client.payment_requests.create(payment_data=CreatePaymentLinkRequest(\n order_code=int(time.time()),\n amount=2000,\n description=\"Thanh toan\",\n cancel_url=\"https://your-url.com/cancel\",\n return_url=\"https://your-url.com/success\",\n))\n```\n\n### Webhook verification\n\nYou can register an endpoint to receive the payment webhook.\n\n```python\nconfirm_result = client.webhooks.confirm('https://your-url.com/webhooks')\n```\n\nThen using `webhooks.verify()` to verify and receive webhook data.\n\n```python\n# example using flask, more details in ./examples/webhooks_handling.py\n@app.route(\"/webhooks\", methods=[\"POST\"])\ndef webhooks():\n data = request.get_data()\n\n try:\n webhook_data = client.webhooks.verify(data)\n except WebhookError as e:\n return jsonify({\"error\": str(e)}), 400\n\n return jsonify({\"error\": None, \"data\": webhook_data.model_dump_camel_case()})\n```\n\nFor more information about webhooks, see [the API doc](https://payos.vn/docs/api/#tag/payment-webhook/operation/payment-webhook).\n\n### Handling errors\n\nWhen the API return a non-success status code(i.e, 4xx or 5xx response) or non-success code data (any code except '00'), a subclass of `payos.APIError` is raised.\n\n```python\ntry:\n response = client.payment_requests.create(payment_data=payment_data)\n print(response)\nexcept APIError as e:\n print(e.error_code)\n print(e.error_desc)\n print(e.status_code)\n```\n\n### Asynchronous usage\n\nSimply import `AsyncPayOS` instead of `PayOS` and use `await` with each API call:\n\n```python\nimport asyncio\n\nfrom payos import AsyncPayOS\nfrom payos.types import CreatePaymentLinkRequest\n\nasync def main() -> None:\n client = AsyncPayOS()\n payment_data = CreatePaymentLinkRequest(\n order_code=int(time.time()),\n amount=2000,\n description=\"Thanh toan\",\n cancel_url=\"https://your-url.com/cancel\",\n return_url=\"https://your-url.com/success\",\n )\n try:\n response = await client.payment_requests.create(payment_data=payment_data)\n print(response)\n except APIError as e:\n print(e)\n\nasyncio.run(main())\n```\n\n### Auto pagination\n\nList method in the payOS Merchant API are paginated, the library provides auto-paginating iterators with each response.\n\n```python\nimport os\n\nfrom payos import PayOS\nfrom payos.types import GetPayoutListParams\n\nclient = PayOS(\n client_id=os.getenv(\"PAYOS_PAYOUT_CLIENT_ID\"),\n api_key=os.getenv(\"PAYOS_PAYOUT_API_KEY\"),\n checksum_key=os.getenv(\"PAYOS_PAYOUT_CHECKSUM_KEY\"),\n)\n\n\ndef main() -> None:\n payouts = []\n for payout in client.payouts.list(GetPayoutListParams(limit=3)):\n payouts.append(payout)\n # or\n payouts_data = client.payouts.list(GetPayoutListParams(limit=3))\n payouts = payout_data.to_list()\n\n print(payouts)\n\n\nmain()\n\n```\n\nOr asynchronous:\n\n```python\nimport asyncio\nimport os\n\nfrom payos import AsyncPayOS\nfrom payos.types import GetPayoutListParams\n\nclient = AsyncPayOS(\n client_id=os.getenv(\"PAYOS_PAYOUT_CLIENT_ID\"),\n api_key=os.getenv(\"PAYOS_PAYOUT_API_KEY\"),\n checksum_key=os.getenv(\"PAYOS_PAYOUT_CHECKSUM_KEY\"),\n)\n\n\nasync def main() -> None:\n payouts = []\n async for payout in await client.payouts.list(GetPayoutListParams(limit=3)):\n payouts.append(payout)\n # or\n payouts_data = await client.payouts.list(GetPayoutListParams(limit=3))\n payouts = await payouts_data.to_list()\n\n print(payouts)\n\n\nasyncio.run(main())\n\n```\n\nAlternative, you can use the `.has_next_page()`, `.get_next_page()` methods for more control:\n\n```python\n# remove `await` for non-async usage\nfirst_page = await client.payouts.list(GetPayoutListParams(limit=3))\nif first_page.has_next_page():\n next_page = await first_page.get_next_page()\n print(f\"number of items we just fetched: {len(next_page.data)}\")\n```\n\nOr just work directly with the returned data:\n\n```python\n# remove `await` for non-async usage\nfirst_page = await client.payouts.list(GetPayoutListParams(limit=3))\nfor payout in first_page.data:\n print(payout.id)\n```\n\n### Advanced usage\n\n#### Custom configuration\n\nYou can customize the PayOS client with various options:\n\n```python\nimport os\nimport httpx\n\nfrom payos import PayOS\n\nclient = PayOS(\n client_id=os.getenv(\"PAYOS_CLIENT_ID\"),\n api_key=os.getenv(\"PAYOS_API_KEY\"),\n checksum_key=os.getenv(\"PAYOS_CHECKSUM_KEY\"),\n timeout=15.0,\n max_retries=4,\n http_client=httpx.Client(\n proxy=\"http://my-proxy.com\", transport=httpx.HTTPTransport(local_address=\"0.0.0.0\")\n ),\n)\n```\n\n#### Request-level options\n\nYou can override client-level settings for individual requests:\n\n```python\nfrom payos import PayOS\n\nclient = PayOS()\n\nclient.payment_requests.get(1757060811, timeout=2, max_retries=0)\n```\n\n#### Logging\n\nWe use standard library [`logging`](https://docs.python.org/3/library/logging.html) module. You can enable logging by setting the environment variable `PAYOS_LOG` to `info` or `debug`.\n\n```bash\nexport PAYOS_LOG=info\n```\n\n#### Direct API access\n\nFor advanced use cases, you can make direct API calls:\n\n```python\nfrom payos import PayOS\n\nclient = PayOS()\n\nresponse = client.get(\"/v2/payment-requests\", cast_to=dict)\n\nresponse = client.post(\n \"/v2/payment-requests\",\n body={\n \"orderCode\": int(time()),\n \"amount\": 2000,\n \"description\": \"thanh toan\",\n \"returnUrl\": \"https://your-url.com/success\",\n \"cancelUrl\": \"https://your-url.com/cancel\",\n \"signature\": \"signature\",\n },\n cast_to=dict,\n)\n```\n\n#### Signature\n\nThe signature can be manually created by `.crypto`:\n\n```python\n# for create payment link signature\nsignature = client.crypto.create_signature_of_payment_request(\n {\n \"orderCode\": int(time()),\n \"amount\": 2000,\n \"description\": \"thanh toan\",\n \"returnUrl\": \"https://your-url.com/success\",\n \"cancelUrl\": \"https://your-url.com/cancel\",\n },\n client.checksum_key,\n)\n\n# for payment-requests and webhook signature\nsignature = client.crypto.create_signature_from_object(\n data,\n client.checksum_key,\n)\n\n# for payouts signature\nsignature = client.crypto.create_signature(client.checksum_key, data)\n```\n\n## Contributing\n\nSee [the contributing documentation](./CONTRIBUTING.md).\n",
"bugtrack_url": null,
"license": null,
"summary": "payOS Python SDK",
"version": "1.0.0",
"project_urls": {
"Bug Tracker": "https://github.com/payOSHQ/payos-lib-python/issues",
"Documentation": "https://payos.vn/docs",
"Homepage": "https://payos.vn",
"Repository": "https://github.com/payOSHQ/payos-lib-python"
},
"split_keywords": [
"payos",
" payment",
" payos-python",
" sdk",
" python"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c1398e646f2d6fa6611e14f3e8636a9ba49c7807d4b3ceb9ee0e86ccd34806ae",
"md5": "7d7736eea9e52bae0ed2f8a295c5ad2a",
"sha256": "347ac2c3d4f7014c4dc64f9f6b39b0aa53dbb59f8b01f064968dfff1e0e00dfd"
},
"downloads": -1,
"filename": "payos-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7d7736eea9e52bae0ed2f8a295c5ad2a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 42357,
"upload_time": "2025-09-11T04:41:37",
"upload_time_iso_8601": "2025-09-11T04:41:37.382565Z",
"url": "https://files.pythonhosted.org/packages/c1/39/8e646f2d6fa6611e14f3e8636a9ba49c7807d4b3ceb9ee0e86ccd34806ae/payos-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "98f0329739ef6d1ff3bd3d6b484cc0019833bb2617acefe5849c7e3dd68fe9cd",
"md5": "8466f21ff797607b1f8ccbd61a362b39",
"sha256": "e78e96309e40d2be934e756471627e7806a267fab59eb122139d0154a1e510ce"
},
"downloads": -1,
"filename": "payos-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "8466f21ff797607b1f8ccbd61a362b39",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 22194,
"upload_time": "2025-09-11T04:41:38",
"upload_time_iso_8601": "2025-09-11T04:41:38.514931Z",
"url": "https://files.pythonhosted.org/packages/98/f0/329739ef6d1ff3bd3d6b484cc0019833bb2617acefe5849c7e3dd68fe9cd/payos-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-11 04:41:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "payOSHQ",
"github_project": "payos-lib-python",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "payos"
}