---
title: FastAPI Integration
description: Integrate Payme, Click, Uzum, Paynet and Octo into a FastAPI project with PayTechUZ — async setup, SQLAlchemy models, routes and webhook handling.
source: https://pay-tech.uz/en/docs/integrations/fastapi
---

# FastAPI Integration

Complete guide for integrating PayTechUZ with FastAPI applications.

:::tip Ready Example Projects
Looking for ready-to-use FastAPI projects? Check out our examples:
* **[FastAPI Example](https://github.com/PayTechUz/fastapi_paytechuz)** - Full payment integration
* **[Course Bot](https://github.com/PayTechUz/Course_Bot)** - Telegram bot with subscription system
:::

## Installation

Install PayTechUZ with FastAPI support:

```bash
pip install paytechuz[fastapi]
```

## Configuration

Set up database models:

```python
from datetime import datetime, timezone

from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, ForeignKey

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)
    total_amount = Column(Float)
    created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))

# Create Invoice model
class Invoice(Base):
    __tablename__ = "invoices"

    id = Column(Integer, primary_key=True, index=True)
    order_id = Column(Integer, ForeignKey("orders.id"))
    amount = Column(Float)
    status = Column(String, default="pending")
    created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))

    order = relationship("Order")

# Create payment tables using run_migrations
run_migrations(engine)

# Create Order and Invoice tables
Base.metadata.create_all(bind=engine)

# Create session
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
```

## 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):
        invoice = self.db.query(Invoice).filter(Invoice.id == transaction.account_id).first()
        invoice.status = "paid"
        self.db.commit()

    def cancelled_payment(self, params, transaction):
        invoice = self.db.query(Invoice).filter(Invoice.id == transaction.account_id).first()
        invoice.status = "cancelled"
        self.db.commit()

class CustomClickWebhookHandler(ClickWebhookHandler):
    def successfully_payment(self, params, transaction):
        invoice = self.db.query(Invoice).filter(Invoice.id == transaction.account_id).first()
        invoice.status = "paid"
        self.db.commit()

    def cancelled_payment(self, params, transaction):
        invoice = self.db.query(Invoice).filter(Invoice.id == transaction.account_id).first()
        invoice.status = "cancelled"
        self.db.commit()

    def successfully_payment(self, params, transaction):
        invoice = self.db.query(Invoice).filter(Invoice.id == transaction.account_id).first()
        invoice.status = "paid"
        self.db.commit()

    def cancelled_payment(self, params, transaction):
        invoice = self.db.query(Invoice).filter(Invoice.id == transaction.account_id).first()
        invoice.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=Invoice,
        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",
        secret_key="your_secret_key",
        account_model=Invoice,
        account_field='id',
        one_time_payment=True
    )
    return await handler.handle_webhook(request)
```

## Creating Payment Links

```python
import os
from pydantic import BaseModel
from paytechuz.gateways.payme import PaymeGateway
from paytechuz.gateways.click import ClickGateway
    amount: float
    payment_type: str  # 'payme', 'click', or 'paynet'

@app.post("/order/create")
def create_order(order_data: OrderCreate, db: Session = Depends(get_db)):
    # 1. Create Order
    order = Order(
        product_name=order_data.product_name, 
        total_amount=order_data.amount
    )
    db.add(order)
    db.commit()
    db.refresh(order)

    # 2. Create Invoice linked to the Order
    invoice = Invoice(
        order_id=order.id, 
        amount=order.total_amount,
        status="pending"
    )
    db.add(invoice)
    db.commit()
    db.refresh(invoice)

    payment_url = None

    # 3. Generate Payment Link based on payment_type
    if order_data.payment_type == 'payme':
        gateway = PaymeGateway(
            payme_id='your_payme_id',
            payme_key='your_payme_key',
            is_test_mode=True
        )
        payment_url = gateway.create_payment(
            id=invoice.id,
            amount=invoice.amount,
            return_url="https://example.com/success",
            account_field_name="id" # your payme account field
        )

    elif order_data.payment_type == 'click':
        gateway = ClickGateway(
            service_id='your_click_service_id',
            merchant_id='your_click_merchant_id',
            merchant_user_id='your_click_merchant_user_id',
            secret_key='your_click_secret_key',
            is_test_mode=True
        )
        payment_url = gateway.create_payment(
            id=invoice.id,
            amount=invoice.amount,
            return_url="https://example.com/success"
        )

    elif order_data.payment_type == 'paynet':
        gateway = PaynetGateway(
            merchant_id='your_paynet_merchant_id',
            is_test_mode=True
        )
        # Generate Paynet payment URL
        # URL format: https://app.paynet.uz/?m={merchant_id}&c={payment_id}&a={amount}
        payment_url = gateway.create_payment(
            id=invoice.id,  # Payment ID (c parameter)
            amount=invoice.amount  # amount in tiyin (optional, a parameter)
        )
        # Or without amount (amount will be configured on Paynet's side)
        # payment_url = gateway.create_payment(id=invoice.id)

    return {
        "order_id": order.id, 
        "invoice_id": invoice.id, 
        "payment_url": payment_url
    }
```

## Next Steps

- **[Examples](/docs/examples)** - Complete working examples
- **[Getting Started](/docs/getting-started/installation)** - Basic installation guide
- **[Django Integration](/docs/integrations/django)** - Alternative framework integration
