# paytechuz
[](https://badge.fury.io/py/paytechuz)
[](https://pypi.org/project/paytechuz/)
[](https://opensource.org/licenses/MIT)
PayTechUZ is a unified payment library for integrating with popular payment systems in Uzbekistan. It provides a simple and consistent interface for working with Payme and Click payment gateways.
## Features
- 🔄 **API**: Consistent interface for multiple payment providers
- 🛡️ **Secure**: Built-in security features for payment processing
- 🔌 **Framework Integration**: Native support for Django and FastAPI
- 🌐 **Webhook Handling**: Easy-to-use webhook handlers for payment notifications
- 📊 **Transaction Management**: Automatic transaction tracking and management
- 🧩 **Extensible**: Easy to add new payment providers
## Installation
### Basic Installation
```bash
pip install paytechuz
```
### Framework-Specific Installation
```bash
# For Django
pip install paytechuz[django]
# For FastAPI
pip install paytechuz[fastapi]
```
## Quick Start
### Generate Payment Links
```python
from paytechuz.gateways.payme import PaymeGateway
from paytechuz.gateways.click import ClickGateway
# Initialize Payme gateway
payme = PaymeGateway(
payme_id="your_payme_id",
payme_key="your_payme_key",
is_test_mode=True # Set to False in production environment
)
# Initialize Click gateway
click = ClickGateway(
service_id="your_service_id",
merchant_id="your_merchant_id",
merchant_user_id="your_merchant_user_id",
secret_key="your_secret_key",
is_test_mode=True # Set to False in production environment
)
# Generate payment links
payme_link = payme.create_payment(
id="order_123",
amount=150000, # amount in UZS
return_url="https://example.com/return"
)
click_link = click.create_payment(
id="order_123",
amount=150000, # amount in UZS
description="Test payment",
return_url="https://example.com/return"
)
```
### Django Integration
1. Create Order model:
```python
# models.py
from django.db import models
from django.utils import timezone
class Order(models.Model):
STATUS_CHOICES = (
('pending', 'Pending'),
('paid', 'Paid'),
('cancelled', 'Cancelled'),
('delivered', 'Delivered'),
)
product_name = models.CharField(max_length=255)
amount = models.DecimalField(max_digits=12, decimal_places=2)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
created_at = models.DateTimeField(default=timezone.now)
def __str__(self):
return f"{self.id} - {self.product_name} ({self.amount})"
```
2. Add to `INSTALLED_APPS` and configure settings:
```python
# settings.py
INSTALLED_APPS = [
# ...
'paytechuz.integrations.django',
]
PAYME_ID = 'your_payme_merchant_id'
PAYME_KEY = 'your_payme_merchant_key'
PAYME_ACCOUNT_MODEL = 'your_app.models.Order' # For example: 'orders.models.Order'
PAYME_ACCOUNT_FIELD = 'id'
PAYME_AMOUNT_FIELD = 'amount' # Field for storing payment amount
PAYME_ONE_TIME_PAYMENT = True # Allow only one payment per account
CLICK_SERVICE_ID = 'your_click_service_id'
CLICK_MERCHANT_ID = 'your_click_merchant_id'
CLICK_SECRET_KEY = 'your_click_secret_key'
CLICK_ACCOUNT_MODEL = 'your_app.models.Order'
CLICK_COMMISSION_PERCENT = 0.0
```
3. Create webhook handlers:
```python
# views.py
from paytechuz.integrations.django.views import BasePaymeWebhookView, BaseClickWebhookView
from .models import Order
class PaymeWebhookView(BasePaymeWebhookView):
def successfully_payment(self, params, transaction):
order = Order.objects.get(id=transaction.account_id)
order.status = 'paid'
order.save()
def cancelled_payment(self, params, transaction):
order = Order.objects.get(id=transaction.account_id)
order.status = 'cancelled'
order.save()
class ClickWebhookView(BaseClickWebhookView):
def successfully_payment(self, params, transaction):
order = Order.objects.get(id=transaction.account_id)
order.status = 'paid'
order.save()
def cancelled_payment(self, params, transaction):
order = Order.objects.get(id=transaction.account_id)
order.status = 'cancelled'
order.save()
```
4. Add webhook URLs to `urls.py`:
```python
# urls.py
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from .views import PaymeWebhookView, ClickWebhookView
urlpatterns = [
# ...
path('payments/webhook/payme/', csrf_exempt(PaymeWebhookView.as_view()), name='payme_webhook'),
path('payments/webhook/click/', csrf_exempt(ClickWebhookView.as_view()), name='click_webhook'),
]
```
### FastAPI Integration
1. Set up database models:
```python
from datetime import datetime, timezone
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime
from paytechuz.integrations.fastapi import Base as PaymentsBase
from paytechuz.integrations.fastapi.models import run_migrations
# Create database engine
SQLALCHEMY_DATABASE_URL = "sqlite:///./payments.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
# Create base declarative class
Base = declarative_base()
# Create Order model
class Order(Base):
__tablename__ = "orders"
id = Column(Integer, primary_key=True, index=True)
product_name = Column(String, index=True)
amount = Column(Float)
status = Column(String, default="pending")
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
# Create payment tables using run_migrations
run_migrations(engine)
# Create Order table
Base.metadata.create_all(bind=engine)
# Create session
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
```
2. Create webhook handlers:
```python
from fastapi import FastAPI, Request, Depends
from sqlalchemy.orm import Session
from paytechuz.integrations.fastapi import PaymeWebhookHandler, ClickWebhookHandler
app = FastAPI()
# Dependency to get the database session
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
class CustomPaymeWebhookHandler(PaymeWebhookHandler):
def successfully_payment(self, params, transaction):
# Handle successful payment
order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
order.status = "paid"
self.db.commit()
def cancelled_payment(self, params, transaction):
# Handle cancelled payment
order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
order.status = "cancelled"
self.db.commit()
class CustomClickWebhookHandler(ClickWebhookHandler):
def successfully_payment(self, params, transaction):
# Handle successful payment
order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
order.status = "paid"
self.db.commit()
def cancelled_payment(self, params, transaction):
# Handle cancelled payment
order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
order.status = "cancelled"
self.db.commit()
@app.post("/payments/payme/webhook")
async def payme_webhook(request: Request, db: Session = Depends(get_db)):
handler = CustomPaymeWebhookHandler(
db=db,
payme_id="your_merchant_id",
payme_key="your_merchant_key",
account_model=Order,
account_field='id',
amount_field='amount'
)
return await handler.handle_webhook(request)
@app.post("/payments/click/webhook")
async def click_webhook(request: Request, db: Session = Depends(get_db)):
handler = CustomClickWebhookHandler(
db=db,
service_id="your_service_id",
merchant_id="your_merchant_id",
secret_key="your_secret_key",
account_model=Order
)
return await handler.handle_webhook(request)
```
## Documentation
Detailed documentation is available in multiple languages:
- 📖 [English Documentation](src/docs/en/index.md)
- 📖 [O'zbek tilidagi hujjatlar](src/docs/index.md)
### Framework-Specific Documentation
- [Django Integration Guide](src/docs/en/django_integration.md) | [Django integratsiyasi bo'yicha qo'llanma](src/docs/django_integration.md)
- [FastAPI Integration Guide](src/docs/en/fastapi_integration.md) | [FastAPI integratsiyasi bo'yicha qo'llanma](src/docs/fastapi_integration.md)
## Supported Payment Systems
- **Payme** - [Official Website](https://payme.uz)
- **Click** - [Official Website](https://click.uz)
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License - see the LICENSE file for details.
Raw data
{
"_id": null,
"home_page": "https://github.com/Muhammadali-Akbarov/paytechuz",
"name": "paytechuz",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": null,
"author": "Muhammadali Akbarov",
"author_email": "muhammadali17abc@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/3c/e9/a6f19fbaf995c91c61f7932024e2efd54c67e48709eb39cc9630ce877789/paytechuz-0.2.12.tar.gz",
"platform": null,
"description": "# paytechuz\n\n[](https://badge.fury.io/py/paytechuz)\n[](https://pypi.org/project/paytechuz/)\n[](https://opensource.org/licenses/MIT)\n\nPayTechUZ is a unified payment library for integrating with popular payment systems in Uzbekistan. It provides a simple and consistent interface for working with Payme and Click payment gateways.\n\n## Features\n\n- \ud83d\udd04 **API**: Consistent interface for multiple payment providers\n- \ud83d\udee1\ufe0f **Secure**: Built-in security features for payment processing\n- \ud83d\udd0c **Framework Integration**: Native support for Django and FastAPI\n- \ud83c\udf10 **Webhook Handling**: Easy-to-use webhook handlers for payment notifications\n- \ud83d\udcca **Transaction Management**: Automatic transaction tracking and management\n- \ud83e\udde9 **Extensible**: Easy to add new payment providers\n## Installation\n\n### Basic Installation\n\n```bash\npip install paytechuz\n```\n\n### Framework-Specific Installation\n\n```bash\n# For Django\npip install paytechuz[django]\n\n# For FastAPI\npip install paytechuz[fastapi]\n```\n\n## Quick Start\n\n### Generate Payment Links\n\n```python\nfrom paytechuz.gateways.payme import PaymeGateway\nfrom paytechuz.gateways.click import ClickGateway\n\n# Initialize Payme gateway\npayme = PaymeGateway(\n payme_id=\"your_payme_id\",\n payme_key=\"your_payme_key\",\n is_test_mode=True # Set to False in production environment\n)\n\n# Initialize Click gateway\nclick = ClickGateway(\n service_id=\"your_service_id\",\n merchant_id=\"your_merchant_id\",\n merchant_user_id=\"your_merchant_user_id\",\n secret_key=\"your_secret_key\",\n is_test_mode=True # Set to False in production environment\n)\n\n# Generate payment links\npayme_link = payme.create_payment(\n id=\"order_123\",\n amount=150000, # amount in UZS\n return_url=\"https://example.com/return\"\n)\n\nclick_link = click.create_payment(\n id=\"order_123\",\n amount=150000, # amount in UZS\n description=\"Test payment\",\n return_url=\"https://example.com/return\"\n)\n```\n\n### Django Integration\n\n1. Create Order model:\n\n```python\n# models.py\nfrom django.db import models\nfrom django.utils import timezone\n\nclass Order(models.Model):\n STATUS_CHOICES = (\n ('pending', 'Pending'),\n ('paid', 'Paid'),\n ('cancelled', 'Cancelled'),\n ('delivered', 'Delivered'),\n )\n\n product_name = models.CharField(max_length=255)\n amount = models.DecimalField(max_digits=12, decimal_places=2)\n status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')\n created_at = models.DateTimeField(default=timezone.now)\n\n def __str__(self):\n return f\"{self.id} - {self.product_name} ({self.amount})\"\n```\n\n2. Add to `INSTALLED_APPS` and configure settings:\n\n```python\n# settings.py\nINSTALLED_APPS = [\n # ...\n 'paytechuz.integrations.django',\n]\n\nPAYME_ID = 'your_payme_merchant_id'\nPAYME_KEY = 'your_payme_merchant_key'\nPAYME_ACCOUNT_MODEL = 'your_app.models.Order' # For example: 'orders.models.Order'\nPAYME_ACCOUNT_FIELD = 'id'\nPAYME_AMOUNT_FIELD = 'amount' # Field for storing payment amount\nPAYME_ONE_TIME_PAYMENT = True # Allow only one payment per account\n\nCLICK_SERVICE_ID = 'your_click_service_id'\nCLICK_MERCHANT_ID = 'your_click_merchant_id'\nCLICK_SECRET_KEY = 'your_click_secret_key'\nCLICK_ACCOUNT_MODEL = 'your_app.models.Order'\nCLICK_COMMISSION_PERCENT = 0.0\n```\n\n3. Create webhook handlers:\n\n```python\n# views.py\nfrom paytechuz.integrations.django.views import BasePaymeWebhookView, BaseClickWebhookView\nfrom .models import Order\n\nclass PaymeWebhookView(BasePaymeWebhookView):\n def successfully_payment(self, params, transaction):\n order = Order.objects.get(id=transaction.account_id)\n order.status = 'paid'\n order.save()\n\n def cancelled_payment(self, params, transaction):\n order = Order.objects.get(id=transaction.account_id)\n order.status = 'cancelled'\n order.save()\n\nclass ClickWebhookView(BaseClickWebhookView):\n def successfully_payment(self, params, transaction):\n order = Order.objects.get(id=transaction.account_id)\n order.status = 'paid'\n order.save()\n\n def cancelled_payment(self, params, transaction):\n order = Order.objects.get(id=transaction.account_id)\n order.status = 'cancelled'\n order.save()\n```\n\n4. Add webhook URLs to `urls.py`:\n\n```python\n# urls.py\nfrom django.urls import path\nfrom django.views.decorators.csrf import csrf_exempt\nfrom .views import PaymeWebhookView, ClickWebhookView\n\nurlpatterns = [\n # ...\n path('payments/webhook/payme/', csrf_exempt(PaymeWebhookView.as_view()), name='payme_webhook'),\n path('payments/webhook/click/', csrf_exempt(ClickWebhookView.as_view()), name='click_webhook'),\n]\n```\n\n### FastAPI Integration\n\n1. Set up database models:\n\n```python\nfrom datetime import datetime, timezone\n\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy import create_engine, Column, Integer, String, Float, DateTime\n\nfrom paytechuz.integrations.fastapi import Base as PaymentsBase\nfrom paytechuz.integrations.fastapi.models import run_migrations\n\n\n# Create database engine\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./payments.db\"\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\n\n# Create base declarative class\nBase = declarative_base()\n\n# Create Order model\nclass Order(Base):\n __tablename__ = \"orders\"\n\n id = Column(Integer, primary_key=True, index=True)\n product_name = Column(String, index=True)\n amount = Column(Float)\n status = Column(String, default=\"pending\")\n created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))\n\n# Create payment tables using run_migrations\nrun_migrations(engine)\n\n# Create Order table\nBase.metadata.create_all(bind=engine)\n\n# Create session\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n```\n\n2. Create webhook handlers:\n\n```python\nfrom fastapi import FastAPI, Request, Depends\n\nfrom sqlalchemy.orm import Session\n\nfrom paytechuz.integrations.fastapi import PaymeWebhookHandler, ClickWebhookHandler\n\n\napp = FastAPI()\n\n# Dependency to get the database session\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\nclass CustomPaymeWebhookHandler(PaymeWebhookHandler):\n def successfully_payment(self, params, transaction):\n # Handle successful payment\n order = self.db.query(Order).filter(Order.id == transaction.account_id).first()\n order.status = \"paid\"\n self.db.commit()\n\n def cancelled_payment(self, params, transaction):\n # Handle cancelled payment\n order = self.db.query(Order).filter(Order.id == transaction.account_id).first()\n order.status = \"cancelled\"\n self.db.commit()\n\nclass CustomClickWebhookHandler(ClickWebhookHandler):\n def successfully_payment(self, params, transaction):\n # Handle successful payment\n order = self.db.query(Order).filter(Order.id == transaction.account_id).first()\n order.status = \"paid\"\n self.db.commit()\n\n def cancelled_payment(self, params, transaction):\n # Handle cancelled payment\n order = self.db.query(Order).filter(Order.id == transaction.account_id).first()\n order.status = \"cancelled\"\n self.db.commit()\n\n@app.post(\"/payments/payme/webhook\")\nasync def payme_webhook(request: Request, db: Session = Depends(get_db)):\n handler = CustomPaymeWebhookHandler(\n db=db,\n payme_id=\"your_merchant_id\",\n payme_key=\"your_merchant_key\",\n account_model=Order,\n account_field='id',\n amount_field='amount'\n )\n return await handler.handle_webhook(request)\n\n@app.post(\"/payments/click/webhook\")\nasync def click_webhook(request: Request, db: Session = Depends(get_db)):\n handler = CustomClickWebhookHandler(\n db=db,\n service_id=\"your_service_id\",\n merchant_id=\"your_merchant_id\",\n secret_key=\"your_secret_key\",\n account_model=Order\n )\n return await handler.handle_webhook(request)\n```\n\n## Documentation\n\nDetailed documentation is available in multiple languages:\n\n- \ud83d\udcd6 [English Documentation](src/docs/en/index.md)\n- \ud83d\udcd6 [O'zbek tilidagi hujjatlar](src/docs/index.md)\n\n### Framework-Specific Documentation\n\n- [Django Integration Guide](src/docs/en/django_integration.md) | [Django integratsiyasi bo'yicha qo'llanma](src/docs/django_integration.md)\n- [FastAPI Integration Guide](src/docs/en/fastapi_integration.md) | [FastAPI integratsiyasi bo'yicha qo'llanma](src/docs/fastapi_integration.md)\n\n## Supported Payment Systems\n\n- **Payme** - [Official Website](https://payme.uz)\n- **Click** - [Official Website](https://click.uz)\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Unified Python package for Uzbekistan payment gateways",
"version": "0.2.12",
"project_urls": {
"Homepage": "https://github.com/Muhammadali-Akbarov/paytechuz"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "af1070b810a6556b0875d6068536f5c4dc2a20d3f6336d4aa7f1d44f9acc7a7a",
"md5": "22e286e7ad59ed129ac875eb5867d4b1",
"sha256": "5ce5e17cd01f02e80f53b5f43c99b970e6eceb11ba190fe66a63060b235c6aa7"
},
"downloads": -1,
"filename": "paytechuz-0.2.12-py3-none-any.whl",
"has_sig": false,
"md5_digest": "22e286e7ad59ed129ac875eb5867d4b1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 47652,
"upload_time": "2025-07-11T06:02:57",
"upload_time_iso_8601": "2025-07-11T06:02:57.940444Z",
"url": "https://files.pythonhosted.org/packages/af/10/70b810a6556b0875d6068536f5c4dc2a20d3f6336d4aa7f1d44f9acc7a7a/paytechuz-0.2.12-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "3ce9a6f19fbaf995c91c61f7932024e2efd54c67e48709eb39cc9630ce877789",
"md5": "9dadce5253866f9294ddddd71262fab1",
"sha256": "6e986caeb44776ccab78f981315359aea2909bcdc023daec2dc94924d9749190"
},
"downloads": -1,
"filename": "paytechuz-0.2.12.tar.gz",
"has_sig": false,
"md5_digest": "9dadce5253866f9294ddddd71262fab1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 4978226,
"upload_time": "2025-07-11T06:03:39",
"upload_time_iso_8601": "2025-07-11T06:03:39.123276Z",
"url": "https://files.pythonhosted.org/packages/3c/e9/a6f19fbaf995c91c61f7932024e2efd54c67e48709eb39cc9630ce877789/paytechuz-0.2.12.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-11 06:03:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Muhammadali-Akbarov",
"github_project": "paytechuz",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "paytechuz"
}